OSDN Git Service

2006-10-29 Richard Guenther <rguenther@suse.de>
[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
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
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156   ])
157
158 (define_constants
159   [(UNSPECV_BLOCKAGE            0)
160    (UNSPECV_STACK_PROBE         1)
161    (UNSPECV_EMMS                2)
162    (UNSPECV_LDMXCSR             3)
163    (UNSPECV_STMXCSR             4)
164    (UNSPECV_FEMMS               5)
165    (UNSPECV_CLFLUSH             6)
166    (UNSPECV_ALIGN               7)
167    (UNSPECV_MONITOR             8)
168    (UNSPECV_MWAIT               9)
169    (UNSPECV_CMPXCHG_1           10)
170    (UNSPECV_CMPXCHG_2           11)
171    (UNSPECV_XCHG                12)
172    (UNSPECV_LOCK                13)
173   ])
174
175 ;; Registers by name.
176 (define_constants
177   [(BP_REG                       6)
178    (SP_REG                       7)
179    (FLAGS_REG                   17)
180    (FPSR_REG                    18)
181    (FPCR_REG                    19)
182    (DIRFLAG_REG                 20)
183    (R11_REG                     41)
184   ])
185
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
187 ;; from i386.c.
188
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first.  This allows for better optimization.  For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
193
194 \f
195 ;; Processor type.  This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,generic32,generic64"
198   (const (symbol_ref "ix86_tune")))
199
200 ;; A basic instruction type.  Refinements due to arguments to be
201 ;; provided in other attributes.
202 (define_attr "type"
203   "other,multi,
204    alu,alu1,negnot,imov,imovx,lea,
205    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206    icmp,test,ibr,setcc,icmov,
207    push,pop,call,callv,leave,
208    str,cld,
209    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210    sselog,sselog1,sseiadd,sseishft,sseimul,
211    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213   (const_string "other"))
214
215 ;; Main data type used by the insn
216 (define_attr "mode"
217   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218   (const_string "unknown"))
219
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223            (const_string "i387")
224          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
226            (const_string "sse")
227          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
228            (const_string "mmx")
229          (eq_attr "type" "other")
230            (const_string "unknown")]
231          (const_string "integer")))
232
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
236            (const_int 0)
237          (eq_attr "unit" "i387,sse,mmx")
238            (const_int 0)
239          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
240                           imul,icmp,push,pop")
241            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242          (eq_attr "type" "imov,test")
243            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244          (eq_attr "type" "call")
245            (if_then_else (match_operand 0 "constant_call_address_operand" "")
246              (const_int 4)
247              (const_int 0))
248          (eq_attr "type" "callv")
249            (if_then_else (match_operand 1 "constant_call_address_operand" "")
250              (const_int 4)
251              (const_int 0))
252          ;; We don't know the size before shorten_branches.  Expect
253          ;; the instruction to fit for better scheduling.
254          (eq_attr "type" "ibr")
255            (const_int 1)
256          ]
257          (symbol_ref "/* Update immediate_length and other attributes! */
258                       gcc_unreachable (),1")))
259
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
263            (const_int 0)
264          (and (eq_attr "type" "call")
265               (match_operand 0 "constant_call_address_operand" ""))
266              (const_int 0)
267          (and (eq_attr "type" "callv")
268               (match_operand 1 "constant_call_address_operand" ""))
269              (const_int 0)
270          ]
271          (symbol_ref "ix86_attr_length_address_default (insn)")))
272
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275   (if_then_else (ior (eq_attr "mode" "HI")
276                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
277     (const_int 1)
278     (const_int 0)))
279
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" "" 
282   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
288   (if_then_else 
289     (ior (eq_attr "type" "imovx,setcc,icmov")
290          (eq_attr "unit" "sse,mmx"))
291     (const_int 1)
292     (const_int 0)))
293
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296   (cond [(and (eq_attr "mode" "DI")
297               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
298            (const_int 1)
299          (and (eq_attr "mode" "QI")
300               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
301                   (const_int 0)))
302            (const_int 1)
303          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
304              (const_int 0))
305            (const_int 1)
306         ]
307         (const_int 0)))
308
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311   (cond [(eq_attr "type" "str,cld,leave")
312            (const_int 0)
313          (eq_attr "unit" "i387")
314            (const_int 0)
315          (and (eq_attr "type" "incdec")
316               (ior (match_operand:SI 1 "register_operand" "")
317                    (match_operand:HI 1 "register_operand" "")))
318            (const_int 0)
319          (and (eq_attr "type" "push")
320               (not (match_operand 1 "memory_operand" "")))
321            (const_int 0)
322          (and (eq_attr "type" "pop")
323               (not (match_operand 0 "memory_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "imov")
326               (ior (and (match_operand 0 "register_operand" "")
327                         (match_operand 1 "immediate_operand" ""))
328                    (ior (and (match_operand 0 "ax_reg_operand" "")
329                              (match_operand 1 "memory_displacement_only_operand" ""))
330                         (and (match_operand 0 "memory_displacement_only_operand" "")
331                              (match_operand 1 "ax_reg_operand" "")))))
332            (const_int 0)
333          (and (eq_attr "type" "call")
334               (match_operand 0 "constant_call_address_operand" ""))
335              (const_int 0)
336          (and (eq_attr "type" "callv")
337               (match_operand 1 "constant_call_address_operand" ""))
338              (const_int 0)
339          ]
340          (const_int 1)))
341
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
345 ;; other insns.
346 (define_attr "length" ""
347   (cond [(eq_attr "type" "other,multi,fistp,frndint")
348            (const_int 16)
349          (eq_attr "type" "fcmp")
350            (const_int 4)
351          (eq_attr "unit" "i387")
352            (plus (const_int 2)
353                  (plus (attr "prefix_data16")
354                        (attr "length_address")))]
355          (plus (plus (attr "modrm")
356                      (plus (attr "prefix_0f")
357                            (plus (attr "prefix_rex")
358                                  (const_int 1))))
359                (plus (attr "prefix_rep")
360                      (plus (attr "prefix_data16")
361                            (plus (attr "length_immediate")
362                                  (attr "length_address")))))))
363
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
367
368 (define_attr "memory" "none,load,store,both,unknown"
369   (cond [(eq_attr "type" "other,multi,str")
370            (const_string "unknown")
371          (eq_attr "type" "lea,fcmov,fpspc,cld")
372            (const_string "none")
373          (eq_attr "type" "fistp,leave")
374            (const_string "both")
375          (eq_attr "type" "frndint")
376            (const_string "load")
377          (eq_attr "type" "push")
378            (if_then_else (match_operand 1 "memory_operand" "")
379              (const_string "both")
380              (const_string "store"))
381          (eq_attr "type" "pop")
382            (if_then_else (match_operand 0 "memory_operand" "")
383              (const_string "both")
384              (const_string "load"))
385          (eq_attr "type" "setcc")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "store")
388              (const_string "none"))
389          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390            (if_then_else (ior (match_operand 0 "memory_operand" "")
391                               (match_operand 1 "memory_operand" ""))
392              (const_string "load")
393              (const_string "none"))
394          (eq_attr "type" "ibr")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "load")
397              (const_string "none"))
398          (eq_attr "type" "call")
399            (if_then_else (match_operand 0 "constant_call_address_operand" "")
400              (const_string "none")
401              (const_string "load"))
402          (eq_attr "type" "callv")
403            (if_then_else (match_operand 1 "constant_call_address_operand" "")
404              (const_string "none")
405              (const_string "load"))
406          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407               (match_operand 1 "memory_operand" ""))
408            (const_string "both")
409          (and (match_operand 0 "memory_operand" "")
410               (match_operand 1 "memory_operand" ""))
411            (const_string "both")
412          (match_operand 0 "memory_operand" "")
413            (const_string "store")
414          (match_operand 1 "memory_operand" "")
415            (const_string "load")
416          (and (eq_attr "type"
417                  "!alu1,negnot,ishift1,
418                    imov,imovx,icmp,test,
419                    fmov,fcmp,fsgn,
420                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421                    mmx,mmxmov,mmxcmp,mmxcvt")
422               (match_operand 2 "memory_operand" ""))
423            (const_string "load")
424          (and (eq_attr "type" "icmov")
425               (match_operand 3 "memory_operand" ""))
426            (const_string "load")
427         ]
428         (const_string "none")))
429
430 ;; Indicates if an instruction has both an immediate and a displacement.
431
432 (define_attr "imm_disp" "false,true,unknown"
433   (cond [(eq_attr "type" "other,multi")
434            (const_string "unknown")
435          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436               (and (match_operand 0 "memory_displacement_operand" "")
437                    (match_operand 1 "immediate_operand" "")))
438            (const_string "true")
439          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440               (and (match_operand 0 "memory_displacement_operand" "")
441                    (match_operand 2 "immediate_operand" "")))
442            (const_string "true")
443         ]
444         (const_string "false")))
445
446 ;; Indicates if an FP operation has an integer source.
447
448 (define_attr "fp_int_src" "false,true"
449   (const_string "false"))
450
451 ;; Defines rounding mode of an FP operation.
452
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454   (const_string "any"))
455
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458   [(set_attr "length" "128")
459    (set_attr "type" "multi")])
460
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
463  
464 ;; All integer modes handled by x87 fisttp operator.
465 (define_mode_macro X87MODEI [HI SI DI])
466
467 ;; All integer modes handled by integer x87 operators.
468 (define_mode_macro X87MODEI12 [HI SI])
469
470 ;; All SSE floating point modes
471 (define_mode_macro SSEMODEF [SF DF])
472  
473 ;; All integer modes handled by SSE cvtts?2si* operators.
474 (define_mode_macro SSEMODEI24 [SI DI])
475
476 \f
477 ;; Scheduling descriptions
478
479 (include "pentium.md")
480 (include "ppro.md")
481 (include "k6.md")
482 (include "athlon.md")
483 (include "geode.md")
484
485 \f
486 ;; Operand and operator predicates and constraints
487
488 (include "predicates.md")
489 (include "constraints.md")
490
491 \f
492 ;; Compare instructions.
493
494 ;; All compare insns have expanders that save the operands away without
495 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
496 ;; after the cmp) will actually emit the cmpM.
497
498 (define_expand "cmpti"
499   [(set (reg:CC FLAGS_REG)
500         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
501                     (match_operand:TI 1 "x86_64_general_operand" "")))]
502   "TARGET_64BIT"
503 {
504   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
505     operands[0] = force_reg (TImode, operands[0]);
506   ix86_compare_op0 = operands[0];
507   ix86_compare_op1 = operands[1];
508   DONE;
509 })
510
511 (define_expand "cmpdi"
512   [(set (reg:CC FLAGS_REG)
513         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
514                     (match_operand:DI 1 "x86_64_general_operand" "")))]
515   ""
516 {
517   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
518     operands[0] = force_reg (DImode, operands[0]);
519   ix86_compare_op0 = operands[0];
520   ix86_compare_op1 = operands[1];
521   DONE;
522 })
523
524 (define_expand "cmpsi"
525   [(set (reg:CC FLAGS_REG)
526         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
527                     (match_operand:SI 1 "general_operand" "")))]
528   ""
529 {
530   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
531     operands[0] = force_reg (SImode, operands[0]);
532   ix86_compare_op0 = operands[0];
533   ix86_compare_op1 = operands[1];
534   DONE;
535 })
536
537 (define_expand "cmphi"
538   [(set (reg:CC FLAGS_REG)
539         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
540                     (match_operand:HI 1 "general_operand" "")))]
541   ""
542 {
543   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
544     operands[0] = force_reg (HImode, operands[0]);
545   ix86_compare_op0 = operands[0];
546   ix86_compare_op1 = operands[1];
547   DONE;
548 })
549
550 (define_expand "cmpqi"
551   [(set (reg:CC FLAGS_REG)
552         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
553                     (match_operand:QI 1 "general_operand" "")))]
554   "TARGET_QIMODE_MATH"
555 {
556   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
557     operands[0] = force_reg (QImode, operands[0]);
558   ix86_compare_op0 = operands[0];
559   ix86_compare_op1 = operands[1];
560   DONE;
561 })
562
563 (define_insn "cmpdi_ccno_1_rex64"
564   [(set (reg FLAGS_REG)
565         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
566                  (match_operand:DI 1 "const0_operand" "n,n")))]
567   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
568   "@
569    test{q}\t{%0, %0|%0, %0}
570    cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "test,icmp")
572    (set_attr "length_immediate" "0,1")
573    (set_attr "mode" "DI")])
574
575 (define_insn "*cmpdi_minus_1_rex64"
576   [(set (reg FLAGS_REG)
577         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
578                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
579                  (const_int 0)))]
580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
581   "cmp{q}\t{%1, %0|%0, %1}"
582   [(set_attr "type" "icmp")
583    (set_attr "mode" "DI")])
584
585 (define_expand "cmpdi_1_rex64"
586   [(set (reg:CC FLAGS_REG)
587         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
588                     (match_operand:DI 1 "general_operand" "")))]
589   "TARGET_64BIT"
590   "")
591
592 (define_insn "cmpdi_1_insn_rex64"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
595                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
596   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
597   "cmp{q}\t{%1, %0|%0, %1}"
598   [(set_attr "type" "icmp")
599    (set_attr "mode" "DI")])
600
601
602 (define_insn "*cmpsi_ccno_1"
603   [(set (reg FLAGS_REG)
604         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
605                  (match_operand:SI 1 "const0_operand" "n,n")))]
606   "ix86_match_ccmode (insn, CCNOmode)"
607   "@
608    test{l}\t{%0, %0|%0, %0}
609    cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "test,icmp")
611    (set_attr "length_immediate" "0,1")
612    (set_attr "mode" "SI")])
613
614 (define_insn "*cmpsi_minus_1"
615   [(set (reg FLAGS_REG)
616         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                            (match_operand:SI 1 "general_operand" "ri,mr"))
618                  (const_int 0)))]
619   "ix86_match_ccmode (insn, CCGOCmode)"
620   "cmp{l}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "SI")])
623
624 (define_expand "cmpsi_1"
625   [(set (reg:CC FLAGS_REG)
626         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
627                     (match_operand:SI 1 "general_operand" "ri,mr")))]
628   ""
629   "")
630
631 (define_insn "*cmpsi_1_insn"
632   [(set (reg FLAGS_REG)
633         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634                  (match_operand:SI 1 "general_operand" "ri,mr")))]
635   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
636     && ix86_match_ccmode (insn, CCmode)"
637   "cmp{l}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "icmp")
639    (set_attr "mode" "SI")])
640
641 (define_insn "*cmphi_ccno_1"
642   [(set (reg FLAGS_REG)
643         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
644                  (match_operand:HI 1 "const0_operand" "n,n")))]
645   "ix86_match_ccmode (insn, CCNOmode)"
646   "@
647    test{w}\t{%0, %0|%0, %0}
648    cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "test,icmp")
650    (set_attr "length_immediate" "0,1")
651    (set_attr "mode" "HI")])
652
653 (define_insn "*cmphi_minus_1"
654   [(set (reg FLAGS_REG)
655         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656                            (match_operand:HI 1 "general_operand" "ri,mr"))
657                  (const_int 0)))]
658   "ix86_match_ccmode (insn, CCGOCmode)"
659   "cmp{w}\t{%1, %0|%0, %1}"
660   [(set_attr "type" "icmp")
661    (set_attr "mode" "HI")])
662
663 (define_insn "*cmphi_1"
664   [(set (reg FLAGS_REG)
665         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
666                  (match_operand:HI 1 "general_operand" "ri,mr")))]
667   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
668    && ix86_match_ccmode (insn, CCmode)"
669   "cmp{w}\t{%1, %0|%0, %1}"
670   [(set_attr "type" "icmp")
671    (set_attr "mode" "HI")])
672
673 (define_insn "*cmpqi_ccno_1"
674   [(set (reg FLAGS_REG)
675         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
676                  (match_operand:QI 1 "const0_operand" "n,n")))]
677   "ix86_match_ccmode (insn, CCNOmode)"
678   "@
679    test{b}\t{%0, %0|%0, %0}
680    cmp{b}\t{$0, %0|%0, 0}"
681   [(set_attr "type" "test,icmp")
682    (set_attr "length_immediate" "0,1")
683    (set_attr "mode" "QI")])
684
685 (define_insn "*cmpqi_1"
686   [(set (reg FLAGS_REG)
687         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688                  (match_operand:QI 1 "general_operand" "qi,mq")))]
689   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
690     && ix86_match_ccmode (insn, CCmode)"
691   "cmp{b}\t{%1, %0|%0, %1}"
692   [(set_attr "type" "icmp")
693    (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_minus_1"
696   [(set (reg FLAGS_REG)
697         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
698                            (match_operand:QI 1 "general_operand" "qi,mq"))
699                  (const_int 0)))]
700   "ix86_match_ccmode (insn, CCGOCmode)"
701   "cmp{b}\t{%1, %0|%0, %1}"
702   [(set_attr "type" "icmp")
703    (set_attr "mode" "QI")])
704
705 (define_insn "*cmpqi_ext_1"
706   [(set (reg FLAGS_REG)
707         (compare
708           (match_operand:QI 0 "general_operand" "Qm")
709           (subreg:QI
710             (zero_extract:SI
711               (match_operand 1 "ext_register_operand" "Q")
712               (const_int 8)
713               (const_int 8)) 0)))]
714   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
715   "cmp{b}\t{%h1, %0|%0, %h1}"
716   [(set_attr "type" "icmp")
717    (set_attr "mode" "QI")])
718
719 (define_insn "*cmpqi_ext_1_rex64"
720   [(set (reg FLAGS_REG)
721         (compare
722           (match_operand:QI 0 "register_operand" "Q")
723           (subreg:QI
724             (zero_extract:SI
725               (match_operand 1 "ext_register_operand" "Q")
726               (const_int 8)
727               (const_int 8)) 0)))]
728   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
729   "cmp{b}\t{%h1, %0|%0, %h1}"
730   [(set_attr "type" "icmp")
731    (set_attr "mode" "QI")])
732
733 (define_insn "*cmpqi_ext_2"
734   [(set (reg FLAGS_REG)
735         (compare
736           (subreg:QI
737             (zero_extract:SI
738               (match_operand 0 "ext_register_operand" "Q")
739               (const_int 8)
740               (const_int 8)) 0)
741           (match_operand:QI 1 "const0_operand" "n")))]
742   "ix86_match_ccmode (insn, CCNOmode)"
743   "test{b}\t%h0, %h0"
744   [(set_attr "type" "test")
745    (set_attr "length_immediate" "0")
746    (set_attr "mode" "QI")])
747
748 (define_expand "cmpqi_ext_3"
749   [(set (reg:CC FLAGS_REG)
750         (compare:CC
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "general_operand" "")))]
757   ""
758   "")
759
760 (define_insn "cmpqi_ext_3_insn"
761   [(set (reg FLAGS_REG)
762         (compare
763           (subreg:QI
764             (zero_extract:SI
765               (match_operand 0 "ext_register_operand" "Q")
766               (const_int 8)
767               (const_int 8)) 0)
768           (match_operand:QI 1 "general_operand" "Qmn")))]
769   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
770   "cmp{b}\t{%1, %h0|%h0, %1}"
771   [(set_attr "type" "icmp")
772    (set_attr "mode" "QI")])
773
774 (define_insn "cmpqi_ext_3_insn_rex64"
775   [(set (reg FLAGS_REG)
776         (compare
777           (subreg:QI
778             (zero_extract:SI
779               (match_operand 0 "ext_register_operand" "Q")
780               (const_int 8)
781               (const_int 8)) 0)
782           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
783   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
784   "cmp{b}\t{%1, %h0|%h0, %1}"
785   [(set_attr "type" "icmp")
786    (set_attr "mode" "QI")])
787
788 (define_insn "*cmpqi_ext_4"
789   [(set (reg FLAGS_REG)
790         (compare
791           (subreg:QI
792             (zero_extract:SI
793               (match_operand 0 "ext_register_operand" "Q")
794               (const_int 8)
795               (const_int 8)) 0)
796           (subreg:QI
797             (zero_extract:SI
798               (match_operand 1 "ext_register_operand" "Q")
799               (const_int 8)
800               (const_int 8)) 0)))]
801   "ix86_match_ccmode (insn, CCmode)"
802   "cmp{b}\t{%h1, %h0|%h0, %h1}"
803   [(set_attr "type" "icmp")
804    (set_attr "mode" "QI")])
805
806 ;; These implement float point compares.
807 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
808 ;; which would allow mix and match FP modes on the compares.  Which is what
809 ;; the old patterns did, but with many more of them.
810
811 (define_expand "cmpxf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
814                     (match_operand:XF 1 "nonmemory_operand" "")))]
815   "TARGET_80387"
816 {
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
820 })
821
822 (define_expand "cmpdf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
827 {
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
831 })
832
833 (define_expand "cmpsf"
834   [(set (reg:CC FLAGS_REG)
835         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
836                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
837   "TARGET_80387 || TARGET_SSE_MATH"
838 {
839   ix86_compare_op0 = operands[0];
840   ix86_compare_op1 = operands[1];
841   DONE;
842 })
843
844 ;; FP compares, step 1:
845 ;; Set the FP condition codes.
846 ;;
847 ;; CCFPmode     compare with exceptions
848 ;; CCFPUmode    compare with no exceptions
849
850 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
851 ;; used to manage the reg stack popping would not be preserved.
852
853 (define_insn "*cmpfp_0"
854   [(set (match_operand:HI 0 "register_operand" "=a")
855         (unspec:HI
856           [(compare:CCFP
857              (match_operand 1 "register_operand" "f")
858              (match_operand 2 "const0_operand" "X"))]
859         UNSPEC_FNSTSW))]
860   "TARGET_80387
861    && FLOAT_MODE_P (GET_MODE (operands[1]))
862    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
863   "* return output_fp_compare (insn, operands, 0, 0);"
864   [(set_attr "type" "multi")
865    (set_attr "unit" "i387")
866    (set (attr "mode")
867      (cond [(match_operand:SF 1 "" "")
868               (const_string "SF")
869             (match_operand:DF 1 "" "")
870               (const_string "DF")
871            ]
872            (const_string "XF")))])
873
874 (define_insn "*cmpfp_sf"
875   [(set (match_operand:HI 0 "register_operand" "=a")
876         (unspec:HI
877           [(compare:CCFP
878              (match_operand:SF 1 "register_operand" "f")
879              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
880           UNSPEC_FNSTSW))]
881   "TARGET_80387"
882   "* return output_fp_compare (insn, operands, 0, 0);"
883   [(set_attr "type" "multi")
884    (set_attr "unit" "i387")
885    (set_attr "mode" "SF")])
886
887 (define_insn "*cmpfp_df"
888   [(set (match_operand:HI 0 "register_operand" "=a")
889         (unspec:HI
890           [(compare:CCFP
891              (match_operand:DF 1 "register_operand" "f")
892              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
893           UNSPEC_FNSTSW))]
894   "TARGET_80387"
895   "* return output_fp_compare (insn, operands, 0, 0);"
896   [(set_attr "type" "multi")
897    (set_attr "unit" "i387")
898    (set_attr "mode" "DF")])
899
900 (define_insn "*cmpfp_xf"
901   [(set (match_operand:HI 0 "register_operand" "=a")
902         (unspec:HI
903           [(compare:CCFP
904              (match_operand:XF 1 "register_operand" "f")
905              (match_operand:XF 2 "register_operand" "f"))]
906           UNSPEC_FNSTSW))]
907   "TARGET_80387"
908   "* return output_fp_compare (insn, operands, 0, 0);"
909   [(set_attr "type" "multi")
910    (set_attr "unit" "i387")
911    (set_attr "mode" "XF")])
912
913 (define_insn "*cmpfp_u"
914   [(set (match_operand:HI 0 "register_operand" "=a")
915         (unspec:HI
916           [(compare:CCFPU
917              (match_operand 1 "register_operand" "f")
918              (match_operand 2 "register_operand" "f"))]
919           UNSPEC_FNSTSW))]
920   "TARGET_80387
921    && FLOAT_MODE_P (GET_MODE (operands[1]))
922    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923   "* return output_fp_compare (insn, operands, 0, 1);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set (attr "mode")
927      (cond [(match_operand:SF 1 "" "")
928               (const_string "SF")
929             (match_operand:DF 1 "" "")
930               (const_string "DF")
931            ]
932            (const_string "XF")))])
933
934 (define_insn "*cmpfp_<mode>"
935   [(set (match_operand:HI 0 "register_operand" "=a")
936         (unspec:HI
937           [(compare:CCFP
938              (match_operand 1 "register_operand" "f")
939              (match_operator 3 "float_operator"
940                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
941           UNSPEC_FNSTSW))]
942   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
943    && FLOAT_MODE_P (GET_MODE (operands[1]))
944    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
945   "* return output_fp_compare (insn, operands, 0, 0);"
946   [(set_attr "type" "multi")
947    (set_attr "unit" "i387")
948    (set_attr "fp_int_src" "true")
949    (set_attr "mode" "<MODE>")])
950
951 ;; FP compares, step 2
952 ;; Move the fpsw to ax.
953
954 (define_insn "x86_fnstsw_1"
955   [(set (match_operand:HI 0 "register_operand" "=a")
956         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
957   "TARGET_80387"
958   "fnstsw\t%0"
959   [(set_attr "length" "2")
960    (set_attr "mode" "SI")
961    (set_attr "unit" "i387")])
962
963 ;; FP compares, step 3
964 ;; Get ax into flags, general case.
965
966 (define_insn "x86_sahf_1"
967   [(set (reg:CC FLAGS_REG)
968         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
969   "!TARGET_64BIT"
970   "sahf"
971   [(set_attr "length" "1")
972    (set_attr "athlon_decode" "vector")
973    (set_attr "mode" "SI")])
974
975 ;; Pentium Pro can do steps 1 through 3 in one go.
976
977 (define_insn "*cmpfp_i_mixed"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "f,x")
980                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
981   "TARGET_MIX_SSE_I387
982    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984   "* return output_fp_compare (insn, operands, 1, 0);"
985   [(set_attr "type" "fcmp,ssecomi")
986    (set (attr "mode")
987      (if_then_else (match_operand:SF 1 "" "")
988         (const_string "SF")
989         (const_string "DF")))
990    (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_i_sse"
993   [(set (reg:CCFP FLAGS_REG)
994         (compare:CCFP (match_operand 0 "register_operand" "x")
995                       (match_operand 1 "nonimmediate_operand" "xm")))]
996   "TARGET_SSE_MATH
997    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999   "* return output_fp_compare (insn, operands, 1, 0);"
1000   [(set_attr "type" "ssecomi")
1001    (set (attr "mode")
1002      (if_then_else (match_operand:SF 1 "" "")
1003         (const_string "SF")
1004         (const_string "DF")))
1005    (set_attr "athlon_decode" "vector")])
1006
1007 (define_insn "*cmpfp_i_i387"
1008   [(set (reg:CCFP FLAGS_REG)
1009         (compare:CCFP (match_operand 0 "register_operand" "f")
1010                       (match_operand 1 "register_operand" "f")))]
1011   "TARGET_80387 && TARGET_CMOVE
1012    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1013    && FLOAT_MODE_P (GET_MODE (operands[0]))
1014    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1015   "* return output_fp_compare (insn, operands, 1, 0);"
1016   [(set_attr "type" "fcmp")
1017    (set (attr "mode")
1018      (cond [(match_operand:SF 1 "" "")
1019               (const_string "SF")
1020             (match_operand:DF 1 "" "")
1021               (const_string "DF")
1022            ]
1023            (const_string "XF")))
1024    (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_mixed"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1029                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1030   "TARGET_MIX_SSE_I387
1031    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 1);"
1034   [(set_attr "type" "fcmp,ssecomi")
1035    (set (attr "mode")
1036      (if_then_else (match_operand:SF 1 "" "")
1037         (const_string "SF")
1038         (const_string "DF")))
1039    (set_attr "athlon_decode" "vector")])
1040
1041 (define_insn "*cmpfp_iu_sse"
1042   [(set (reg:CCFPU FLAGS_REG)
1043         (compare:CCFPU (match_operand 0 "register_operand" "x")
1044                        (match_operand 1 "nonimmediate_operand" "xm")))]
1045   "TARGET_SSE_MATH
1046    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048   "* return output_fp_compare (insn, operands, 1, 1);"
1049   [(set_attr "type" "ssecomi")
1050    (set (attr "mode")
1051      (if_then_else (match_operand:SF 1 "" "")
1052         (const_string "SF")
1053         (const_string "DF")))
1054    (set_attr "athlon_decode" "vector")])
1055
1056 (define_insn "*cmpfp_iu_387"
1057   [(set (reg:CCFPU FLAGS_REG)
1058         (compare:CCFPU (match_operand 0 "register_operand" "f")
1059                        (match_operand 1 "register_operand" "f")))]
1060   "TARGET_80387 && TARGET_CMOVE
1061    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1062    && FLOAT_MODE_P (GET_MODE (operands[0]))
1063    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1064   "* return output_fp_compare (insn, operands, 1, 1);"
1065   [(set_attr "type" "fcmp")
1066    (set (attr "mode")
1067      (cond [(match_operand:SF 1 "" "")
1068               (const_string "SF")
1069             (match_operand:DF 1 "" "")
1070               (const_string "DF")
1071            ]
1072            (const_string "XF")))
1073    (set_attr "athlon_decode" "vector")])
1074 \f
1075 ;; Move instructions.
1076
1077 ;; General case of fullword move.
1078
1079 (define_expand "movsi"
1080   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1081         (match_operand:SI 1 "general_operand" ""))]
1082   ""
1083   "ix86_expand_move (SImode, operands); DONE;")
1084
1085 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1086 ;; general_operand.
1087 ;;
1088 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1089 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1090 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1091 ;; targets without our curiosities, and it is just as easy to represent
1092 ;; this differently.
1093
1094 (define_insn "*pushsi2"
1095   [(set (match_operand:SI 0 "push_operand" "=<")
1096         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1097   "!TARGET_64BIT"
1098   "push{l}\t%1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1101
1102 ;; For 64BIT abi we always round up to 8 bytes.
1103 (define_insn "*pushsi2_rex64"
1104   [(set (match_operand:SI 0 "push_operand" "=X")
1105         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1106   "TARGET_64BIT"
1107   "push{q}\t%q1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*pushsi2_prologue"
1112   [(set (match_operand:SI 0 "push_operand" "=<")
1113         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "push{l}\t%1"
1117   [(set_attr "type" "push")
1118    (set_attr "mode" "SI")])
1119
1120 (define_insn "*popsi1_epilogue"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))
1125    (clobber (mem:BLK (scratch)))]
1126   "!TARGET_64BIT"
1127   "pop{l}\t%0"
1128   [(set_attr "type" "pop")
1129    (set_attr "mode" "SI")])
1130
1131 (define_insn "popsi1"
1132   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1133         (mem:SI (reg:SI SP_REG)))
1134    (set (reg:SI SP_REG)
1135         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1136   "!TARGET_64BIT"
1137   "pop{l}\t%0"
1138   [(set_attr "type" "pop")
1139    (set_attr "mode" "SI")])
1140
1141 (define_insn "*movsi_xor"
1142   [(set (match_operand:SI 0 "register_operand" "=r")
1143         (match_operand:SI 1 "const0_operand" "i"))
1144    (clobber (reg:CC FLAGS_REG))]
1145   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1146   "xor{l}\t{%0, %0|%0, %0}"
1147   [(set_attr "type" "alu1")
1148    (set_attr "mode" "SI")
1149    (set_attr "length_immediate" "0")])
1150  
1151 (define_insn "*movsi_or"
1152   [(set (match_operand:SI 0 "register_operand" "=r")
1153         (match_operand:SI 1 "immediate_operand" "i"))
1154    (clobber (reg:CC FLAGS_REG))]
1155   "reload_completed
1156    && operands[1] == constm1_rtx
1157    && (TARGET_PENTIUM || optimize_size)"
1158 {
1159   operands[1] = constm1_rtx;
1160   return "or{l}\t{%1, %0|%0, %1}";
1161 }
1162   [(set_attr "type" "alu1")
1163    (set_attr "mode" "SI")
1164    (set_attr "length_immediate" "1")])
1165
1166 (define_insn "*movsi_1"
1167   [(set (match_operand:SI 0 "nonimmediate_operand"
1168                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1169         (match_operand:SI 1 "general_operand"
1170                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1171   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSELOG1:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "pxor\t%0, %0";
1178       return "xorps\t%0, %0";
1179
1180     case TYPE_SSEMOV:
1181       switch (get_attr_mode (insn))
1182         {
1183         case MODE_TI:
1184           return "movdqa\t{%1, %0|%0, %1}";
1185         case MODE_V4SF:
1186           return "movaps\t{%1, %0|%0, %1}";
1187         case MODE_SI:
1188           return "movd\t{%1, %0|%0, %1}";
1189         case MODE_SF:
1190           return "movss\t{%1, %0|%0, %1}";
1191         default:
1192           gcc_unreachable ();
1193         }
1194
1195     case TYPE_MMXADD:
1196       return "pxor\t%0, %0";
1197
1198     case TYPE_MMXMOV:
1199       if (get_attr_mode (insn) == MODE_DI)
1200         return "movq\t{%1, %0|%0, %1}";
1201       return "movd\t{%1, %0|%0, %1}";
1202
1203     case TYPE_LEA:
1204       return "lea{l}\t{%1, %0|%0, %1}";
1205
1206     default:
1207       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1208       return "mov{l}\t{%1, %0|%0, %1}";
1209     }
1210 }
1211   [(set (attr "type")
1212      (cond [(eq_attr "alternative" "2")
1213               (const_string "mmxadd")
1214             (eq_attr "alternative" "3,4,5")
1215               (const_string "mmxmov")
1216             (eq_attr "alternative" "6")
1217               (const_string "sselog1")
1218             (eq_attr "alternative" "7,8,9,10,11")
1219               (const_string "ssemov")
1220             (match_operand:DI 1 "pic_32bit_operand" "")
1221               (const_string "lea")
1222            ]
1223            (const_string "imov")))
1224    (set (attr "mode")
1225      (cond [(eq_attr "alternative" "2,3")
1226               (const_string "DI")
1227             (eq_attr "alternative" "6,7")
1228               (if_then_else
1229                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1230                 (const_string "V4SF")
1231                 (const_string "TI"))
1232             (and (eq_attr "alternative" "8,9,10,11")
1233                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1234               (const_string "SF")
1235            ]
1236            (const_string "SI")))])
1237
1238 ;; Stores and loads of ax to arbitrary constant address.
1239 ;; We fake an second form of instruction to force reload to load address
1240 ;; into register when rax is not available
1241 (define_insn "*movabssi_1_rex64"
1242   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1243         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1244   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1245   "@
1246    movabs{l}\t{%1, %P0|%P0, %1}
1247    mov{l}\t{%1, %a0|%a0, %1}"
1248   [(set_attr "type" "imov")
1249    (set_attr "modrm" "0,*")
1250    (set_attr "length_address" "8,0")
1251    (set_attr "length_immediate" "0,*")
1252    (set_attr "memory" "store")
1253    (set_attr "mode" "SI")])
1254
1255 (define_insn "*movabssi_2_rex64"
1256   [(set (match_operand:SI 0 "register_operand" "=a,r")
1257         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1258   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1259   "@
1260    movabs{l}\t{%P1, %0|%0, %P1}
1261    mov{l}\t{%a1, %0|%0, %a1}"
1262   [(set_attr "type" "imov")
1263    (set_attr "modrm" "0,*")
1264    (set_attr "length_address" "8,0")
1265    (set_attr "length_immediate" "0")
1266    (set_attr "memory" "load")
1267    (set_attr "mode" "SI")])
1268
1269 (define_insn "*swapsi"
1270   [(set (match_operand:SI 0 "register_operand" "+r")
1271         (match_operand:SI 1 "register_operand" "+r"))
1272    (set (match_dup 1)
1273         (match_dup 0))]
1274   ""
1275   "xchg{l}\t%1, %0"
1276   [(set_attr "type" "imov")
1277    (set_attr "mode" "SI")
1278    (set_attr "pent_pair" "np")
1279    (set_attr "athlon_decode" "vector")])
1280
1281 (define_expand "movhi"
1282   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1283         (match_operand:HI 1 "general_operand" ""))]
1284   ""
1285   "ix86_expand_move (HImode, operands); DONE;")
1286
1287 (define_insn "*pushhi2"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1290   "!TARGET_64BIT"
1291   "push{l}\t%k1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "SI")])
1294
1295 ;; For 64BIT abi we always round up to 8 bytes.
1296 (define_insn "*pushhi2_rex64"
1297   [(set (match_operand:HI 0 "push_operand" "=X")
1298         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1299   "TARGET_64BIT"
1300   "push{q}\t%q1"
1301   [(set_attr "type" "push")
1302    (set_attr "mode" "DI")])
1303
1304 (define_insn "*movhi_1"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1306         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1307   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1308 {
1309   switch (get_attr_type (insn))
1310     {
1311     case TYPE_IMOVX:
1312       /* movzwl is faster than movw on p2 due to partial word stalls,
1313          though not as fast as an aligned movl.  */
1314       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1315     default:
1316       if (get_attr_mode (insn) == MODE_SI)
1317         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1318       else
1319         return "mov{w}\t{%1, %0|%0, %1}";
1320     }
1321 }
1322   [(set (attr "type")
1323      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1324               (const_string "imov")
1325             (and (eq_attr "alternative" "0")
1326                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1327                           (const_int 0))
1328                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1329                           (const_int 0))))
1330               (const_string "imov")
1331             (and (eq_attr "alternative" "1,2")
1332                  (match_operand:HI 1 "aligned_operand" ""))
1333               (const_string "imov")
1334             (and (ne (symbol_ref "TARGET_MOVX")
1335                      (const_int 0))
1336                  (eq_attr "alternative" "0,2"))
1337               (const_string "imovx")
1338            ]
1339            (const_string "imov")))
1340     (set (attr "mode")
1341       (cond [(eq_attr "type" "imovx")
1342                (const_string "SI")
1343              (and (eq_attr "alternative" "1,2")
1344                   (match_operand:HI 1 "aligned_operand" ""))
1345                (const_string "SI")
1346              (and (eq_attr "alternative" "0")
1347                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1348                            (const_int 0))
1349                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1350                            (const_int 0))))
1351                (const_string "SI")
1352             ]
1353             (const_string "HI")))])
1354
1355 ;; Stores and loads of ax to arbitrary constant address.
1356 ;; We fake an second form of instruction to force reload to load address
1357 ;; into register when rax is not available
1358 (define_insn "*movabshi_1_rex64"
1359   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1360         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1361   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1362   "@
1363    movabs{w}\t{%1, %P0|%P0, %1}
1364    mov{w}\t{%1, %a0|%a0, %1}"
1365   [(set_attr "type" "imov")
1366    (set_attr "modrm" "0,*")
1367    (set_attr "length_address" "8,0")
1368    (set_attr "length_immediate" "0,*")
1369    (set_attr "memory" "store")
1370    (set_attr "mode" "HI")])
1371
1372 (define_insn "*movabshi_2_rex64"
1373   [(set (match_operand:HI 0 "register_operand" "=a,r")
1374         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1375   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1376   "@
1377    movabs{w}\t{%P1, %0|%0, %P1}
1378    mov{w}\t{%a1, %0|%0, %a1}"
1379   [(set_attr "type" "imov")
1380    (set_attr "modrm" "0,*")
1381    (set_attr "length_address" "8,0")
1382    (set_attr "length_immediate" "0")
1383    (set_attr "memory" "load")
1384    (set_attr "mode" "HI")])
1385
1386 (define_insn "*swaphi_1"
1387   [(set (match_operand:HI 0 "register_operand" "+r")
1388         (match_operand:HI 1 "register_operand" "+r"))
1389    (set (match_dup 1)
1390         (match_dup 0))]
1391   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1392   "xchg{l}\t%k1, %k0"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "SI")
1395    (set_attr "pent_pair" "np")
1396    (set_attr "athlon_decode" "vector")])
1397
1398 (define_insn "*swaphi_2"
1399   [(set (match_operand:HI 0 "register_operand" "+r")
1400         (match_operand:HI 1 "register_operand" "+r"))
1401    (set (match_dup 1)
1402         (match_dup 0))]
1403   "TARGET_PARTIAL_REG_STALL"
1404   "xchg{w}\t%1, %0"
1405   [(set_attr "type" "imov")
1406    (set_attr "mode" "HI")
1407    (set_attr "pent_pair" "np")
1408    (set_attr "athlon_decode" "vector")])
1409
1410 (define_expand "movstricthi"
1411   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1412         (match_operand:HI 1 "general_operand" ""))]
1413   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1414 {
1415   /* Don't generate memory->memory moves, go through a register */
1416   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1417     operands[1] = force_reg (HImode, operands[1]);
1418 })
1419
1420 (define_insn "*movstricthi_1"
1421   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1422         (match_operand:HI 1 "general_operand" "rn,m"))]
1423   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1424    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1425   "mov{w}\t{%1, %0|%0, %1}"
1426   [(set_attr "type" "imov")
1427    (set_attr "mode" "HI")])
1428
1429 (define_insn "*movstricthi_xor"
1430   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1431         (match_operand:HI 1 "const0_operand" "i"))
1432    (clobber (reg:CC FLAGS_REG))]
1433   "reload_completed
1434    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1435   "xor{w}\t{%0, %0|%0, %0}"
1436   [(set_attr "type" "alu1")
1437    (set_attr "mode" "HI")
1438    (set_attr "length_immediate" "0")])
1439
1440 (define_expand "movqi"
1441   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442         (match_operand:QI 1 "general_operand" ""))]
1443   ""
1444   "ix86_expand_move (QImode, operands); DONE;")
1445
1446 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1447 ;; "push a byte".  But actually we use pushl, which has the effect
1448 ;; of rounding the amount pushed up to a word.
1449
1450 (define_insn "*pushqi2"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1453   "!TARGET_64BIT"
1454   "push{l}\t%k1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "SI")])
1457
1458 ;; For 64BIT abi we always round up to 8 bytes.
1459 (define_insn "*pushqi2_rex64"
1460   [(set (match_operand:QI 0 "push_operand" "=X")
1461         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1462   "TARGET_64BIT"
1463   "push{q}\t%q1"
1464   [(set_attr "type" "push")
1465    (set_attr "mode" "DI")])
1466
1467 ;; Situation is quite tricky about when to choose full sized (SImode) move
1468 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1469 ;; partial register dependency machines (such as AMD Athlon), where QImode
1470 ;; moves issue extra dependency and for partial register stalls machines
1471 ;; that don't use QImode patterns (and QImode move cause stall on the next
1472 ;; instruction).
1473 ;;
1474 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1475 ;; register stall machines with, where we use QImode instructions, since
1476 ;; partial register stall can be caused there.  Then we use movzx.
1477 (define_insn "*movqi_1"
1478   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1479         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1480   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1481 {
1482   switch (get_attr_type (insn))
1483     {
1484     case TYPE_IMOVX:
1485       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1486       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1487     default:
1488       if (get_attr_mode (insn) == MODE_SI)
1489         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1490       else
1491         return "mov{b}\t{%1, %0|%0, %1}";
1492     }
1493 }
1494   [(set (attr "type")
1495      (cond [(and (eq_attr "alternative" "5")
1496                  (not (match_operand:QI 1 "aligned_operand" "")))
1497               (const_string "imovx")
1498             (ne (symbol_ref "optimize_size") (const_int 0))
1499               (const_string "imov")
1500             (and (eq_attr "alternative" "3")
1501                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1502                           (const_int 0))
1503                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1504                           (const_int 0))))
1505               (const_string "imov")
1506             (eq_attr "alternative" "3,5")
1507               (const_string "imovx")
1508             (and (ne (symbol_ref "TARGET_MOVX")
1509                      (const_int 0))
1510                  (eq_attr "alternative" "2"))
1511               (const_string "imovx")
1512            ]
1513            (const_string "imov")))
1514    (set (attr "mode")
1515       (cond [(eq_attr "alternative" "3,4,5")
1516                (const_string "SI")
1517              (eq_attr "alternative" "6")
1518                (const_string "QI")
1519              (eq_attr "type" "imovx")
1520                (const_string "SI")
1521              (and (eq_attr "type" "imov")
1522                   (and (eq_attr "alternative" "0,1")
1523                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1524                                 (const_int 0))
1525                             (and (eq (symbol_ref "optimize_size")
1526                                      (const_int 0))
1527                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528                                      (const_int 0))))))
1529                (const_string "SI")
1530              ;; Avoid partial register stalls when not using QImode arithmetic
1531              (and (eq_attr "type" "imov")
1532                   (and (eq_attr "alternative" "0,1")
1533                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534                                 (const_int 0))
1535                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1536                                 (const_int 0)))))
1537                (const_string "SI")
1538            ]
1539            (const_string "QI")))])
1540
1541 (define_expand "reload_outqi"
1542   [(parallel [(match_operand:QI 0 "" "=m")
1543               (match_operand:QI 1 "register_operand" "r")
1544               (match_operand:QI 2 "register_operand" "=&q")])]
1545   ""
1546 {
1547   rtx op0, op1, op2;
1548   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1549
1550   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1551   if (! q_regs_operand (op1, QImode))
1552     {
1553       emit_insn (gen_movqi (op2, op1));
1554       op1 = op2;
1555     }
1556   emit_insn (gen_movqi (op0, op1));
1557   DONE;
1558 })
1559
1560 (define_insn "*swapqi_1"
1561   [(set (match_operand:QI 0 "register_operand" "+r")
1562         (match_operand:QI 1 "register_operand" "+r"))
1563    (set (match_dup 1)
1564         (match_dup 0))]
1565   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1566   "xchg{l}\t%k1, %k0"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "SI")
1569    (set_attr "pent_pair" "np")
1570    (set_attr "athlon_decode" "vector")])
1571
1572 (define_insn "*swapqi_2"
1573   [(set (match_operand:QI 0 "register_operand" "+q")
1574         (match_operand:QI 1 "register_operand" "+q"))
1575    (set (match_dup 1)
1576         (match_dup 0))]
1577   "TARGET_PARTIAL_REG_STALL"
1578   "xchg{b}\t%1, %0"
1579   [(set_attr "type" "imov")
1580    (set_attr "mode" "QI")
1581    (set_attr "pent_pair" "np")
1582    (set_attr "athlon_decode" "vector")])
1583
1584 (define_expand "movstrictqi"
1585   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1586         (match_operand:QI 1 "general_operand" ""))]
1587   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1588 {
1589   /* Don't generate memory->memory moves, go through a register.  */
1590   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1591     operands[1] = force_reg (QImode, operands[1]);
1592 })
1593
1594 (define_insn "*movstrictqi_1"
1595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1596         (match_operand:QI 1 "general_operand" "*qn,m"))]
1597   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1599   "mov{b}\t{%1, %0|%0, %1}"
1600   [(set_attr "type" "imov")
1601    (set_attr "mode" "QI")])
1602
1603 (define_insn "*movstrictqi_xor"
1604   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1605         (match_operand:QI 1 "const0_operand" "i"))
1606    (clobber (reg:CC FLAGS_REG))]
1607   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1608   "xor{b}\t{%0, %0|%0, %0}"
1609   [(set_attr "type" "alu1")
1610    (set_attr "mode" "QI")
1611    (set_attr "length_immediate" "0")])
1612
1613 (define_insn "*movsi_extv_1"
1614   [(set (match_operand:SI 0 "register_operand" "=R")
1615         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1616                          (const_int 8)
1617                          (const_int 8)))]
1618   ""
1619   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1620   [(set_attr "type" "imovx")
1621    (set_attr "mode" "SI")])
1622
1623 (define_insn "*movhi_extv_1"
1624   [(set (match_operand:HI 0 "register_operand" "=R")
1625         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1626                          (const_int 8)
1627                          (const_int 8)))]
1628   ""
1629   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1630   [(set_attr "type" "imovx")
1631    (set_attr "mode" "SI")])
1632
1633 (define_insn "*movqi_extv_1"
1634   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1635         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1636                          (const_int 8)
1637                          (const_int 8)))]
1638   "!TARGET_64BIT"
1639 {
1640   switch (get_attr_type (insn))
1641     {
1642     case TYPE_IMOVX:
1643       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1644     default:
1645       return "mov{b}\t{%h1, %0|%0, %h1}";
1646     }
1647 }
1648   [(set (attr "type")
1649      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1650                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1651                              (ne (symbol_ref "TARGET_MOVX")
1652                                  (const_int 0))))
1653         (const_string "imovx")
1654         (const_string "imov")))
1655    (set (attr "mode")
1656      (if_then_else (eq_attr "type" "imovx")
1657         (const_string "SI")
1658         (const_string "QI")))])
1659
1660 (define_insn "*movqi_extv_1_rex64"
1661   [(set (match_operand:QI 0 "register_operand" "=Q,?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 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabsqi_1_rex64"
1691   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1693   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1694   "@
1695    movabs{b}\t{%1, %P0|%P0, %1}
1696    mov{b}\t{%1, %a0|%a0, %1}"
1697   [(set_attr "type" "imov")
1698    (set_attr "modrm" "0,*")
1699    (set_attr "length_address" "8,0")
1700    (set_attr "length_immediate" "0,*")
1701    (set_attr "memory" "store")
1702    (set_attr "mode" "QI")])
1703
1704 (define_insn "*movabsqi_2_rex64"
1705   [(set (match_operand:QI 0 "register_operand" "=a,r")
1706         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1708   "@
1709    movabs{b}\t{%P1, %0|%0, %P1}
1710    mov{b}\t{%a1, %0|%0, %a1}"
1711   [(set_attr "type" "imov")
1712    (set_attr "modrm" "0,*")
1713    (set_attr "length_address" "8,0")
1714    (set_attr "length_immediate" "0")
1715    (set_attr "memory" "load")
1716    (set_attr "mode" "QI")])
1717
1718 (define_insn "*movdi_extzv_1"
1719   [(set (match_operand:DI 0 "register_operand" "=R")
1720         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1721                          (const_int 8)
1722                          (const_int 8)))]
1723   "TARGET_64BIT"
1724   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1725   [(set_attr "type" "imovx")
1726    (set_attr "mode" "DI")])
1727
1728 (define_insn "*movsi_extzv_1"
1729   [(set (match_operand:SI 0 "register_operand" "=R")
1730         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1731                          (const_int 8)
1732                          (const_int 8)))]
1733   ""
1734   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1735   [(set_attr "type" "imovx")
1736    (set_attr "mode" "SI")])
1737
1738 (define_insn "*movqi_extzv_2"
1739   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1740         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1741                                     (const_int 8)
1742                                     (const_int 8)) 0))]
1743   "!TARGET_64BIT"
1744 {
1745   switch (get_attr_type (insn))
1746     {
1747     case TYPE_IMOVX:
1748       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1749     default:
1750       return "mov{b}\t{%h1, %0|%0, %h1}";
1751     }
1752 }
1753   [(set (attr "type")
1754      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1755                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1756                              (ne (symbol_ref "TARGET_MOVX")
1757                                  (const_int 0))))
1758         (const_string "imovx")
1759         (const_string "imov")))
1760    (set (attr "mode")
1761      (if_then_else (eq_attr "type" "imovx")
1762         (const_string "SI")
1763         (const_string "QI")))])
1764
1765 (define_insn "*movqi_extzv_2_rex64"
1766   [(set (match_operand:QI 0 "register_operand" "=Q,?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 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1782                         (ne (symbol_ref "TARGET_MOVX")
1783                             (const_int 0)))
1784         (const_string "imovx")
1785         (const_string "imov")))
1786    (set (attr "mode")
1787      (if_then_else (eq_attr "type" "imovx")
1788         (const_string "SI")
1789         (const_string "QI")))])
1790
1791 (define_insn "movsi_insv_1"
1792   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1793                          (const_int 8)
1794                          (const_int 8))
1795         (match_operand:SI 1 "general_operand" "Qmn"))]
1796   "!TARGET_64BIT"
1797   "mov{b}\t{%b1, %h0|%h0, %b1}"
1798   [(set_attr "type" "imov")
1799    (set_attr "mode" "QI")])
1800
1801 (define_insn "movdi_insv_1_rex64"
1802   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1803                          (const_int 8)
1804                          (const_int 8))
1805         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1806   "TARGET_64BIT"
1807   "mov{b}\t{%b1, %h0|%h0, %b1}"
1808   [(set_attr "type" "imov")
1809    (set_attr "mode" "QI")])
1810
1811 (define_insn "*movqi_insv_2"
1812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813                          (const_int 8)
1814                          (const_int 8))
1815         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1816                      (const_int 8)))]
1817   ""
1818   "mov{b}\t{%h1, %h0|%h0, %h1}"
1819   [(set_attr "type" "imov")
1820    (set_attr "mode" "QI")])
1821
1822 (define_expand "movdi"
1823   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1824         (match_operand:DI 1 "general_operand" ""))]
1825   ""
1826   "ix86_expand_move (DImode, operands); DONE;")
1827
1828 (define_insn "*pushdi"
1829   [(set (match_operand:DI 0 "push_operand" "=<")
1830         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1831   "!TARGET_64BIT"
1832   "#")
1833
1834 (define_insn "*pushdi2_rex64"
1835   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1836         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1837   "TARGET_64BIT"
1838   "@
1839    push{q}\t%1
1840    #"
1841   [(set_attr "type" "push,multi")
1842    (set_attr "mode" "DI")])
1843
1844 ;; Convert impossible pushes of immediate to existing instructions.
1845 ;; First try to get scratch register and go through it.  In case this
1846 ;; fails, push sign extended lower part first and then overwrite
1847 ;; upper part by 32bit move.
1848 (define_peephole2
1849   [(match_scratch:DI 2 "r")
1850    (set (match_operand:DI 0 "push_operand" "")
1851         (match_operand:DI 1 "immediate_operand" ""))]
1852   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853    && !x86_64_immediate_operand (operands[1], DImode)"
1854   [(set (match_dup 2) (match_dup 1))
1855    (set (match_dup 0) (match_dup 2))]
1856   "")
1857
1858 ;; We need to define this as both peepholer and splitter for case
1859 ;; peephole2 pass is not run.
1860 ;; "&& 1" is needed to keep it from matching the previous pattern.
1861 (define_peephole2
1862   [(set (match_operand:DI 0 "push_operand" "")
1863         (match_operand:DI 1 "immediate_operand" ""))]
1864   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1865    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1866   [(set (match_dup 0) (match_dup 1))
1867    (set (match_dup 2) (match_dup 3))]
1868   "split_di (operands + 1, 1, operands + 2, operands + 3);
1869    operands[1] = gen_lowpart (DImode, operands[2]);
1870    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871                                                     GEN_INT (4)));
1872   ")
1873
1874 (define_split
1875   [(set (match_operand:DI 0 "push_operand" "")
1876         (match_operand:DI 1 "immediate_operand" ""))]
1877   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1878                     ? flow2_completed : reload_completed)
1879    && !symbolic_operand (operands[1], DImode)
1880    && !x86_64_immediate_operand (operands[1], DImode)"
1881   [(set (match_dup 0) (match_dup 1))
1882    (set (match_dup 2) (match_dup 3))]
1883   "split_di (operands + 1, 1, operands + 2, operands + 3);
1884    operands[1] = gen_lowpart (DImode, operands[2]);
1885    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1886                                                     GEN_INT (4)));
1887   ")
1888
1889 (define_insn "*pushdi2_prologue_rex64"
1890   [(set (match_operand:DI 0 "push_operand" "=<")
1891         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1892    (clobber (mem:BLK (scratch)))]
1893   "TARGET_64BIT"
1894   "push{q}\t%1"
1895   [(set_attr "type" "push")
1896    (set_attr "mode" "DI")])
1897
1898 (define_insn "*popdi1_epilogue_rex64"
1899   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900         (mem:DI (reg:DI SP_REG)))
1901    (set (reg:DI SP_REG)
1902         (plus:DI (reg:DI SP_REG) (const_int 8)))
1903    (clobber (mem:BLK (scratch)))]
1904   "TARGET_64BIT"
1905   "pop{q}\t%0"
1906   [(set_attr "type" "pop")
1907    (set_attr "mode" "DI")])
1908
1909 (define_insn "popdi1"
1910   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1911         (mem:DI (reg:DI SP_REG)))
1912    (set (reg:DI SP_REG)
1913         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1914   "TARGET_64BIT"
1915   "pop{q}\t%0"
1916   [(set_attr "type" "pop")
1917    (set_attr "mode" "DI")])
1918
1919 (define_insn "*movdi_xor_rex64"
1920   [(set (match_operand:DI 0 "register_operand" "=r")
1921         (match_operand:DI 1 "const0_operand" "i"))
1922    (clobber (reg:CC FLAGS_REG))]
1923   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1924    && reload_completed"
1925   "xor{l}\t{%k0, %k0|%k0, %k0}"
1926   [(set_attr "type" "alu1")
1927    (set_attr "mode" "SI")
1928    (set_attr "length_immediate" "0")])
1929
1930 (define_insn "*movdi_or_rex64"
1931   [(set (match_operand:DI 0 "register_operand" "=r")
1932         (match_operand:DI 1 "const_int_operand" "i"))
1933    (clobber (reg:CC FLAGS_REG))]
1934   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1935    && reload_completed
1936    && operands[1] == constm1_rtx"
1937 {
1938   operands[1] = constm1_rtx;
1939   return "or{q}\t{%1, %0|%0, %1}";
1940 }
1941   [(set_attr "type" "alu1")
1942    (set_attr "mode" "DI")
1943    (set_attr "length_immediate" "1")])
1944
1945 (define_insn "*movdi_2"
1946   [(set (match_operand:DI 0 "nonimmediate_operand"
1947                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1948         (match_operand:DI 1 "general_operand"
1949                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1950   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951   "@
1952    #
1953    #
1954    pxor\t%0, %0
1955    movq\t{%1, %0|%0, %1}
1956    movq\t{%1, %0|%0, %1}
1957    pxor\t%0, %0
1958    movq\t{%1, %0|%0, %1}
1959    movdqa\t{%1, %0|%0, %1}
1960    movq\t{%1, %0|%0, %1}
1961    xorps\t%0, %0
1962    movlps\t{%1, %0|%0, %1}
1963    movaps\t{%1, %0|%0, %1}
1964    movlps\t{%1, %0|%0, %1}"
1965   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1966    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1967
1968 (define_split
1969   [(set (match_operand:DI 0 "push_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973   [(const_int 0)]
1974   "ix86_split_long_move (operands); DONE;")
1975
1976 ;; %%% This multiword shite has got to go.
1977 (define_split
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979         (match_operand:DI 1 "general_operand" ""))]
1980   "!TARGET_64BIT && reload_completed
1981    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1983   [(const_int 0)]
1984   "ix86_split_long_move (operands); DONE;")
1985
1986 (define_insn "*movdi_1_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand"
1988                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1989         (match_operand:DI 1 "general_operand"
1990                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1991   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (which_alternative == 13)
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000     case TYPE_SSEMOV:
2001       if (get_attr_mode (insn) == MODE_TI)
2002           return "movdqa\t{%1, %0|%0, %1}";
2003       /* FALLTHRU */
2004     case TYPE_MMXMOV:
2005       /* Moves from and into integer register is done using movd opcode with
2006          REX prefix.  */
2007       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008           return "movd\t{%1, %0|%0, %1}";
2009       return "movq\t{%1, %0|%0, %1}";
2010     case TYPE_SSELOG1:
2011     case TYPE_MMXADD:
2012       return "pxor\t%0, %0";
2013     case TYPE_MULTI:
2014       return "#";
2015     case TYPE_LEA:
2016       return "lea{q}\t{%a1, %0|%0, %a1}";
2017     default:
2018       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019       if (get_attr_mode (insn) == MODE_SI)
2020         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021       else if (which_alternative == 2)
2022         return "movabs{q}\t{%1, %0|%0, %1}";
2023       else
2024         return "mov{q}\t{%1, %0|%0, %1}";
2025     }
2026 }
2027   [(set (attr "type")
2028      (cond [(eq_attr "alternative" "5")
2029               (const_string "mmxadd")
2030             (eq_attr "alternative" "6,7,8")
2031               (const_string "mmxmov")
2032             (eq_attr "alternative" "9")
2033               (const_string "sselog1")
2034             (eq_attr "alternative" "10,11,12")
2035               (const_string "ssemov")
2036             (eq_attr "alternative" "13,14")
2037               (const_string "ssecvt")
2038             (eq_attr "alternative" "4")
2039               (const_string "multi")
2040             (match_operand:DI 1 "pic_32bit_operand" "")
2041               (const_string "lea")
2042            ]
2043            (const_string "imov")))
2044    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2045    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2046    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2047
2048 ;; Stores and loads of ax to arbitrary constant address.
2049 ;; We fake an second form of instruction to force reload to load address
2050 ;; into register when rax is not available
2051 (define_insn "*movabsdi_1_rex64"
2052   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2053         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2054   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2055   "@
2056    movabs{q}\t{%1, %P0|%P0, %1}
2057    mov{q}\t{%1, %a0|%a0, %1}"
2058   [(set_attr "type" "imov")
2059    (set_attr "modrm" "0,*")
2060    (set_attr "length_address" "8,0")
2061    (set_attr "length_immediate" "0,*")
2062    (set_attr "memory" "store")
2063    (set_attr "mode" "DI")])
2064
2065 (define_insn "*movabsdi_2_rex64"
2066   [(set (match_operand:DI 0 "register_operand" "=a,r")
2067         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2068   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2069   "@
2070    movabs{q}\t{%P1, %0|%0, %P1}
2071    mov{q}\t{%a1, %0|%0, %a1}"
2072   [(set_attr "type" "imov")
2073    (set_attr "modrm" "0,*")
2074    (set_attr "length_address" "8,0")
2075    (set_attr "length_immediate" "0")
2076    (set_attr "memory" "load")
2077    (set_attr "mode" "DI")])
2078
2079 ;; Convert impossible stores of immediate to existing instructions.
2080 ;; First try to get scratch register and go through it.  In case this
2081 ;; fails, move by 32bit parts.
2082 (define_peephole2
2083   [(match_scratch:DI 2 "r")
2084    (set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087    && !x86_64_immediate_operand (operands[1], DImode)"
2088   [(set (match_dup 2) (match_dup 1))
2089    (set (match_dup 0) (match_dup 2))]
2090   "")
2091
2092 ;; We need to define this as both peepholer and splitter for case
2093 ;; peephole2 pass is not run.
2094 ;; "&& 1" is needed to keep it from matching the previous pattern.
2095 (define_peephole2
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2100   [(set (match_dup 2) (match_dup 3))
2101    (set (match_dup 4) (match_dup 5))]
2102   "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_split
2105   [(set (match_operand:DI 0 "memory_operand" "")
2106         (match_operand:DI 1 "immediate_operand" ""))]
2107   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2108                     ? flow2_completed : reload_completed)
2109    && !symbolic_operand (operands[1], DImode)
2110    && !x86_64_immediate_operand (operands[1], DImode)"
2111   [(set (match_dup 2) (match_dup 3))
2112    (set (match_dup 4) (match_dup 5))]
2113   "split_di (operands, 2, operands + 2, operands + 4);")
2114
2115 (define_insn "*swapdi_rex64"
2116   [(set (match_operand:DI 0 "register_operand" "+r")
2117         (match_operand:DI 1 "register_operand" "+r"))
2118    (set (match_dup 1)
2119         (match_dup 0))]
2120   "TARGET_64BIT"
2121   "xchg{q}\t%1, %0"
2122   [(set_attr "type" "imov")
2123    (set_attr "mode" "DI")
2124    (set_attr "pent_pair" "np")
2125    (set_attr "athlon_decode" "vector")])
2126
2127 (define_expand "movti"
2128   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2129         (match_operand:TI 1 "nonimmediate_operand" ""))]
2130   "TARGET_SSE || TARGET_64BIT"
2131 {
2132   if (TARGET_64BIT)
2133     ix86_expand_move (TImode, operands);
2134   else
2135     ix86_expand_vector_move (TImode, operands);
2136   DONE;
2137 })
2138
2139 (define_insn "*movti_internal"
2140   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2141         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2142   "TARGET_SSE && !TARGET_64BIT
2143    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2144 {
2145   switch (which_alternative)
2146     {
2147     case 0:
2148       if (get_attr_mode (insn) == MODE_V4SF)
2149         return "xorps\t%0, %0";
2150       else
2151         return "pxor\t%0, %0";
2152     case 1:
2153     case 2:
2154       if (get_attr_mode (insn) == MODE_V4SF)
2155         return "movaps\t{%1, %0|%0, %1}";
2156       else
2157         return "movdqa\t{%1, %0|%0, %1}";
2158     default:
2159       gcc_unreachable ();
2160     }
2161 }
2162   [(set_attr "type" "sselog1,ssemov,ssemov")
2163    (set (attr "mode")
2164         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2165                     (ne (symbol_ref "optimize_size") (const_int 0)))
2166                  (const_string "V4SF")
2167                (and (eq_attr "alternative" "2")
2168                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2169                         (const_int 0)))
2170                  (const_string "V4SF")]
2171               (const_string "TI")))])
2172
2173 (define_insn "*movti_rex64"
2174   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2175         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2176   "TARGET_64BIT
2177    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2178 {
2179   switch (which_alternative)
2180     {
2181     case 0:
2182     case 1:
2183       return "#";
2184     case 2:
2185       if (get_attr_mode (insn) == MODE_V4SF)
2186         return "xorps\t%0, %0";
2187       else
2188         return "pxor\t%0, %0";
2189     case 3:
2190     case 4:
2191       if (get_attr_mode (insn) == MODE_V4SF)
2192         return "movaps\t{%1, %0|%0, %1}";
2193       else
2194         return "movdqa\t{%1, %0|%0, %1}";
2195     default:
2196       gcc_unreachable ();
2197     }
2198 }
2199   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2200    (set (attr "mode")
2201         (cond [(eq_attr "alternative" "2,3")
2202                  (if_then_else
2203                    (ne (symbol_ref "optimize_size")
2204                        (const_int 0))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))
2207                (eq_attr "alternative" "4")
2208                  (if_then_else
2209                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2210                             (const_int 0))
2211                         (ne (symbol_ref "optimize_size")
2212                             (const_int 0)))
2213                    (const_string "V4SF")
2214                    (const_string "TI"))]
2215                (const_string "DI")))])
2216
2217 (define_split
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2219         (match_operand:TI 1 "general_operand" ""))]
2220   "reload_completed && !SSE_REG_P (operands[0])
2221    && !SSE_REG_P (operands[1])"
2222   [(const_int 0)]
2223   "ix86_split_long_move (operands); DONE;")
2224
2225 (define_expand "movsf"
2226   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2227         (match_operand:SF 1 "general_operand" ""))]
2228   ""
2229   "ix86_expand_move (SFmode, operands); DONE;")
2230
2231 (define_insn "*pushsf"
2232   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2233         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2234   "!TARGET_64BIT"
2235 {
2236   /* Anything else should be already split before reg-stack.  */
2237   gcc_assert (which_alternative == 1);
2238   return "push{l}\t%1";
2239 }
2240   [(set_attr "type" "multi,push,multi")
2241    (set_attr "unit" "i387,*,*")
2242    (set_attr "mode" "SF,SI,SF")])
2243
2244 (define_insn "*pushsf_rex64"
2245   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2246         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2247   "TARGET_64BIT"
2248 {
2249   /* Anything else should be already split before reg-stack.  */
2250   gcc_assert (which_alternative == 1);
2251   return "push{q}\t%q1";
2252 }
2253   [(set_attr "type" "multi,push,multi")
2254    (set_attr "unit" "i387,*,*")
2255    (set_attr "mode" "SF,DI,SF")])
2256
2257 (define_split
2258   [(set (match_operand:SF 0 "push_operand" "")
2259         (match_operand:SF 1 "memory_operand" ""))]
2260   "reload_completed
2261    && GET_CODE (operands[1]) == MEM
2262    && constant_pool_reference_p (operands[1])"
2263   [(set (match_dup 0)
2264         (match_dup 1))]
2265   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2266
2267
2268 ;; %%% Kill this when call knows how to work this out.
2269 (define_split
2270   [(set (match_operand:SF 0 "push_operand" "")
2271         (match_operand:SF 1 "any_fp_register_operand" ""))]
2272   "!TARGET_64BIT"
2273   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2274    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2275
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "any_fp_register_operand" ""))]
2279   "TARGET_64BIT"
2280   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2281    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2282
2283 (define_insn "*movsf_1"
2284   [(set (match_operand:SF 0 "nonimmediate_operand"
2285           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2286         (match_operand:SF 1 "general_operand"
2287           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2288   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2289    && (reload_in_progress || reload_completed
2290        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2291        || GET_CODE (operands[1]) != CONST_DOUBLE
2292        || memory_operand (operands[0], SFmode))" 
2293 {
2294   switch (which_alternative)
2295     {
2296     case 0:
2297       return output_387_reg_move (insn, operands);
2298
2299     case 1:
2300       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2301         return "fstp%z0\t%y0";
2302       else
2303         return "fst%z0\t%y0";
2304
2305     case 2:
2306       return standard_80387_constant_opcode (operands[1]);
2307
2308     case 3:
2309     case 4:
2310       return "mov{l}\t{%1, %0|%0, %1}";
2311     case 5:
2312       if (get_attr_mode (insn) == MODE_TI)
2313         return "pxor\t%0, %0";
2314       else
2315         return "xorps\t%0, %0";
2316     case 6:
2317       if (get_attr_mode (insn) == MODE_V4SF)
2318         return "movaps\t{%1, %0|%0, %1}";
2319       else
2320         return "movss\t{%1, %0|%0, %1}";
2321     case 7:
2322     case 8:
2323       return "movss\t{%1, %0|%0, %1}";
2324
2325     case 9:
2326     case 10:
2327       return "movd\t{%1, %0|%0, %1}";
2328
2329     case 11:
2330       return "movq\t{%1, %0|%0, %1}";
2331
2332     default:
2333       gcc_unreachable ();
2334     }
2335 }
2336   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2337    (set (attr "mode")
2338         (cond [(eq_attr "alternative" "3,4,9,10")
2339                  (const_string "SI")
2340                (eq_attr "alternative" "5")
2341                  (if_then_else
2342                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2343                                  (const_int 0))
2344                              (ne (symbol_ref "TARGET_SSE2")
2345                                  (const_int 0)))
2346                         (eq (symbol_ref "optimize_size")
2347                             (const_int 0)))
2348                    (const_string "TI")
2349                    (const_string "V4SF"))
2350                /* For architectures resolving dependencies on
2351                   whole SSE registers use APS move to break dependency
2352                   chains, otherwise use short move to avoid extra work. 
2353
2354                   Do the same for architectures resolving dependencies on
2355                   the parts.  While in DF mode it is better to always handle
2356                   just register parts, the SF mode is different due to lack
2357                   of instructions to load just part of the register.  It is
2358                   better to maintain the whole registers in single format
2359                   to avoid problems on using packed logical operations.  */
2360                (eq_attr "alternative" "6")
2361                  (if_then_else
2362                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2363                             (const_int 0))
2364                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2365                             (const_int 0)))
2366                    (const_string "V4SF")
2367                    (const_string "SF"))
2368                (eq_attr "alternative" "11")
2369                  (const_string "DI")]
2370                (const_string "SF")))])
2371
2372 (define_insn "*swapsf"
2373   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2374         (match_operand:SF 1 "fp_register_operand" "+f"))
2375    (set (match_dup 1)
2376         (match_dup 0))]
2377   "reload_completed || TARGET_80387"
2378 {
2379   if (STACK_TOP_P (operands[0]))
2380     return "fxch\t%1";
2381   else
2382     return "fxch\t%0";
2383 }
2384   [(set_attr "type" "fxch")
2385    (set_attr "mode" "SF")])
2386
2387 (define_expand "movdf"
2388   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2389         (match_operand:DF 1 "general_operand" ""))]
2390   ""
2391   "ix86_expand_move (DFmode, operands); DONE;")
2392
2393 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2394 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2395 ;; On the average, pushdf using integers can be still shorter.  Allow this
2396 ;; pattern for optimize_size too.
2397
2398 (define_insn "*pushdf_nointeger"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2401   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2402 {
2403   /* This insn should be already split before reg-stack.  */
2404   gcc_unreachable ();
2405 }
2406   [(set_attr "type" "multi")
2407    (set_attr "unit" "i387,*,*,*")
2408    (set_attr "mode" "DF,SI,SI,DF")])
2409
2410 (define_insn "*pushdf_integer"
2411   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2412         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2413   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2414 {
2415   /* This insn should be already split before reg-stack.  */
2416   gcc_unreachable ();
2417 }
2418   [(set_attr "type" "multi")
2419    (set_attr "unit" "i387,*,*")
2420    (set_attr "mode" "DF,SI,DF")])
2421
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "!TARGET_64BIT && reload_completed"
2427   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429   "")
2430
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "any_fp_register_operand" ""))]
2434   "TARGET_64BIT && reload_completed"
2435   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437   "")
2438
2439 (define_split
2440   [(set (match_operand:DF 0 "push_operand" "")
2441         (match_operand:DF 1 "general_operand" ""))]
2442   "reload_completed"
2443   [(const_int 0)]
2444   "ix86_split_long_move (operands); DONE;")
2445
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2449
2450 (define_insn "*movdf_nointeger"
2451   [(set (match_operand:DF 0 "nonimmediate_operand"
2452                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2453         (match_operand:DF 1 "general_operand"
2454                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2455   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457    && (reload_in_progress || reload_completed
2458        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459        || GET_CODE (operands[1]) != CONST_DOUBLE
2460        || memory_operand (operands[0], DFmode))" 
2461 {
2462   switch (which_alternative)
2463     {
2464     case 0:
2465       return output_387_reg_move (insn, operands);
2466
2467     case 1:
2468       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469         return "fstp%z0\t%y0";
2470       else
2471         return "fst%z0\t%y0";
2472
2473     case 2:
2474       return standard_80387_constant_opcode (operands[1]);
2475
2476     case 3:
2477     case 4:
2478       return "#";
2479     case 5:
2480       switch (get_attr_mode (insn))
2481         {
2482         case MODE_V4SF:
2483           return "xorps\t%0, %0";
2484         case MODE_V2DF:
2485           return "xorpd\t%0, %0";
2486         case MODE_TI:
2487           return "pxor\t%0, %0";
2488         default:
2489           gcc_unreachable ();
2490         }
2491     case 6:
2492     case 7:
2493     case 8:
2494       switch (get_attr_mode (insn))
2495         {
2496         case MODE_V4SF:
2497           return "movaps\t{%1, %0|%0, %1}";
2498         case MODE_V2DF:
2499           return "movapd\t{%1, %0|%0, %1}";
2500         case MODE_TI:
2501           return "movdqa\t{%1, %0|%0, %1}";
2502         case MODE_DI:
2503           return "movq\t{%1, %0|%0, %1}";
2504         case MODE_DF:
2505           return "movsd\t{%1, %0|%0, %1}";
2506         case MODE_V1DF:
2507           return "movlpd\t{%1, %0|%0, %1}";
2508         case MODE_V2SF:
2509           return "movlps\t{%1, %0|%0, %1}";
2510         default:
2511           gcc_unreachable ();
2512         }
2513
2514     default:
2515       gcc_unreachable ();
2516     }
2517 }
2518   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2519    (set (attr "mode")
2520         (cond [(eq_attr "alternative" "0,1,2")
2521                  (const_string "DF")
2522                (eq_attr "alternative" "3,4")
2523                  (const_string "SI")
2524
2525                /* For SSE1, we have many fewer alternatives.  */
2526                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527                  (cond [(eq_attr "alternative" "5,6")
2528                           (const_string "V4SF")
2529                        ]
2530                    (const_string "V2SF"))
2531
2532                /* xorps is one byte shorter.  */
2533                (eq_attr "alternative" "5")
2534                  (cond [(ne (symbol_ref "optimize_size")
2535                             (const_int 0))
2536                           (const_string "V4SF")
2537                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538                             (const_int 0))
2539                           (const_string "TI")
2540                        ]
2541                        (const_string "V2DF"))
2542
2543                /* For architectures resolving dependencies on
2544                   whole SSE registers use APD move to break dependency
2545                   chains, otherwise use short move to avoid extra work.
2546
2547                   movaps encodes one byte shorter.  */
2548                (eq_attr "alternative" "6")
2549                  (cond
2550                    [(ne (symbol_ref "optimize_size")
2551                         (const_int 0))
2552                       (const_string "V4SF")
2553                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554                         (const_int 0))
2555                       (const_string "V2DF")
2556                    ]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2564                        (const_int 0))
2565                    (const_string "V1DF")
2566                    (const_string "DF"))
2567               ]
2568               (const_string "DF")))])
2569
2570 (define_insn "*movdf_integer"
2571   [(set (match_operand:DF 0 "nonimmediate_operand"
2572                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2573         (match_operand:DF 1 "general_operand"
2574                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2575   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577    && (reload_in_progress || reload_completed
2578        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579        || GET_CODE (operands[1]) != CONST_DOUBLE
2580        || memory_operand (operands[0], DFmode))" 
2581 {
2582   switch (which_alternative)
2583     {
2584     case 0:
2585       return output_387_reg_move (insn, operands);
2586
2587     case 1:
2588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589         return "fstp%z0\t%y0";
2590       else
2591         return "fst%z0\t%y0";
2592
2593     case 2:
2594       return standard_80387_constant_opcode (operands[1]);
2595
2596     case 3:
2597     case 4:
2598       return "#";
2599
2600     case 5:
2601       switch (get_attr_mode (insn))
2602         {
2603         case MODE_V4SF:
2604           return "xorps\t%0, %0";
2605         case MODE_V2DF:
2606           return "xorpd\t%0, %0";
2607         case MODE_TI:
2608           return "pxor\t%0, %0";
2609         default:
2610           gcc_unreachable ();
2611         }
2612     case 6:
2613     case 7:
2614     case 8:
2615       switch (get_attr_mode (insn))
2616         {
2617         case MODE_V4SF:
2618           return "movaps\t{%1, %0|%0, %1}";
2619         case MODE_V2DF:
2620           return "movapd\t{%1, %0|%0, %1}";
2621         case MODE_TI:
2622           return "movdqa\t{%1, %0|%0, %1}";
2623         case MODE_DI:
2624           return "movq\t{%1, %0|%0, %1}";
2625         case MODE_DF:
2626           return "movsd\t{%1, %0|%0, %1}";
2627         case MODE_V1DF:
2628           return "movlpd\t{%1, %0|%0, %1}";
2629         case MODE_V2SF:
2630           return "movlps\t{%1, %0|%0, %1}";
2631         default:
2632           gcc_unreachable ();
2633         }
2634
2635     default:
2636       gcc_unreachable();
2637     }
2638 }
2639   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2640    (set (attr "mode")
2641         (cond [(eq_attr "alternative" "0,1,2")
2642                  (const_string "DF")
2643                (eq_attr "alternative" "3,4")
2644                  (const_string "SI")
2645
2646                /* For SSE1, we have many fewer alternatives.  */
2647                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648                  (cond [(eq_attr "alternative" "5,6")
2649                           (const_string "V4SF")
2650                        ]
2651                    (const_string "V2SF"))
2652
2653                /* xorps is one byte shorter.  */
2654                (eq_attr "alternative" "5")
2655                  (cond [(ne (symbol_ref "optimize_size")
2656                             (const_int 0))
2657                           (const_string "V4SF")
2658                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659                             (const_int 0))
2660                           (const_string "TI")
2661                        ]
2662                        (const_string "V2DF"))
2663
2664                /* For architectures resolving dependencies on
2665                   whole SSE registers use APD move to break dependency
2666                   chains, otherwise use short move to avoid extra work.
2667
2668                   movaps encodes one byte shorter.  */
2669                (eq_attr "alternative" "6")
2670                  (cond
2671                    [(ne (symbol_ref "optimize_size")
2672                         (const_int 0))
2673                       (const_string "V4SF")
2674                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675                         (const_int 0))
2676                       (const_string "V2DF")
2677                    ]
2678                    (const_string "DF"))
2679                /* For architectures resolving dependencies on register
2680                   parts we may avoid extra work to zero out upper part
2681                   of register.  */
2682                (eq_attr "alternative" "7")
2683                  (if_then_else
2684                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685                        (const_int 0))
2686                    (const_string "V1DF")
2687                    (const_string "DF"))
2688               ]
2689               (const_string "DF")))])
2690
2691 (define_split
2692   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693         (match_operand:DF 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696    && ! (ANY_FP_REG_P (operands[0]) || 
2697          (GET_CODE (operands[0]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699    && ! (ANY_FP_REG_P (operands[1]) || 
2700          (GET_CODE (operands[1]) == SUBREG
2701           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702   [(const_int 0)]
2703   "ix86_split_long_move (operands); DONE;")
2704
2705 (define_insn "*swapdf"
2706   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707         (match_operand:DF 1 "fp_register_operand" "+f"))
2708    (set (match_dup 1)
2709         (match_dup 0))]
2710   "reload_completed || TARGET_80387"
2711 {
2712   if (STACK_TOP_P (operands[0]))
2713     return "fxch\t%1";
2714   else
2715     return "fxch\t%0";
2716 }
2717   [(set_attr "type" "fxch")
2718    (set_attr "mode" "DF")])
2719
2720 (define_expand "movxf"
2721   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722         (match_operand:XF 1 "general_operand" ""))]
2723   ""
2724   "ix86_expand_move (XFmode, operands); DONE;")
2725
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;;  handled elsewhere).
2732
2733 (define_insn "*pushxf_nointeger"
2734   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736   "optimize_size"
2737 {
2738   /* This insn should be already split before reg-stack.  */
2739   gcc_unreachable ();
2740 }
2741   [(set_attr "type" "multi")
2742    (set_attr "unit" "i387,*,*")
2743    (set_attr "mode" "XF,SI,SI")])
2744
2745 (define_insn "*pushxf_integer"
2746   [(set (match_operand:XF 0 "push_operand" "=<,<")
2747         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2748   "!optimize_size"
2749 {
2750   /* This insn should be already split before reg-stack.  */
2751   gcc_unreachable ();
2752 }
2753   [(set_attr "type" "multi")
2754    (set_attr "unit" "i387,*")
2755    (set_attr "mode" "XF,SI")])
2756
2757 (define_split
2758   [(set (match_operand 0 "push_operand" "")
2759         (match_operand 1 "general_operand" ""))]
2760   "reload_completed
2761    && (GET_MODE (operands[0]) == XFmode
2762        || GET_MODE (operands[0]) == DFmode)
2763    && !ANY_FP_REG_P (operands[1])"
2764   [(const_int 0)]
2765   "ix86_split_long_move (operands); DONE;")
2766
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "!TARGET_64BIT"
2771   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 (define_split
2776   [(set (match_operand:XF 0 "push_operand" "")
2777         (match_operand:XF 1 "any_fp_register_operand" ""))]
2778   "TARGET_64BIT"
2779   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2780    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2781   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2782
2783 ;; Do not use integer registers when optimizing for size
2784 (define_insn "*movxf_nointeger"
2785   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2786         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2787   "optimize_size
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && (reload_in_progress || reload_completed
2790        || GET_CODE (operands[1]) != CONST_DOUBLE
2791        || memory_operand (operands[0], XFmode))" 
2792 {
2793   switch (which_alternative)
2794     {
2795     case 0:
2796       return output_387_reg_move (insn, operands);
2797
2798     case 1:
2799       /* There is no non-popping store to memory for XFmode.  So if
2800          we need one, follow the store with a load.  */
2801       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802         return "fstp%z0\t%y0\;fld%z0\t%y0";
2803       else
2804         return "fstp%z0\t%y0";
2805
2806     case 2:
2807       return standard_80387_constant_opcode (operands[1]);
2808
2809     case 3: case 4:
2810       return "#";
2811     default:
2812       gcc_unreachable ();
2813     }
2814 }
2815   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2816    (set_attr "mode" "XF,XF,XF,SI,SI")])
2817
2818 (define_insn "*movxf_integer"
2819   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2820         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2821   "!optimize_size
2822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2823    && (reload_in_progress || reload_completed
2824        || GET_CODE (operands[1]) != CONST_DOUBLE
2825        || memory_operand (operands[0], XFmode))" 
2826 {
2827   switch (which_alternative)
2828     {
2829     case 0:
2830       return output_387_reg_move (insn, operands);
2831
2832     case 1:
2833       /* There is no non-popping store to memory for XFmode.  So if
2834          we need one, follow the store with a load.  */
2835       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836         return "fstp%z0\t%y0\;fld%z0\t%y0";
2837       else
2838         return "fstp%z0\t%y0";
2839
2840     case 2:
2841       return standard_80387_constant_opcode (operands[1]);
2842
2843     case 3: case 4:
2844       return "#";
2845
2846     default:
2847       gcc_unreachable ();
2848     }
2849 }
2850   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2851    (set_attr "mode" "XF,XF,XF,SI,SI")])
2852
2853 (define_split
2854   [(set (match_operand 0 "nonimmediate_operand" "")
2855         (match_operand 1 "general_operand" ""))]
2856   "reload_completed
2857    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2858    && GET_MODE (operands[0]) == XFmode
2859    && ! (ANY_FP_REG_P (operands[0]) || 
2860          (GET_CODE (operands[0]) == SUBREG
2861           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2862    && ! (ANY_FP_REG_P (operands[1]) || 
2863          (GET_CODE (operands[1]) == SUBREG
2864           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2865   [(const_int 0)]
2866   "ix86_split_long_move (operands); DONE;")
2867
2868 (define_split
2869   [(set (match_operand 0 "register_operand" "")
2870         (match_operand 1 "memory_operand" ""))]
2871   "reload_completed
2872    && GET_CODE (operands[1]) == MEM
2873    && (GET_MODE (operands[0]) == XFmode
2874        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2875    && constant_pool_reference_p (operands[1])"
2876   [(set (match_dup 0) (match_dup 1))]
2877 {
2878   rtx c = avoid_constant_pool_reference (operands[1]);
2879   rtx r = operands[0];
2880
2881   if (GET_CODE (r) == SUBREG)
2882     r = SUBREG_REG (r);
2883
2884   if (SSE_REG_P (r))
2885     {
2886       if (!standard_sse_constant_p (c))
2887         FAIL;
2888     }
2889   else if (FP_REG_P (r))
2890     {
2891       if (!standard_80387_constant_p (c))
2892         FAIL;
2893     }
2894   else if (MMX_REG_P (r))
2895     FAIL;
2896
2897   operands[1] = c;
2898 })
2899
2900 (define_insn "swapxf"
2901   [(set (match_operand:XF 0 "register_operand" "+f")
2902         (match_operand:XF 1 "register_operand" "+f"))
2903    (set (match_dup 1)
2904         (match_dup 0))]
2905   "TARGET_80387"
2906 {
2907   if (STACK_TOP_P (operands[0]))
2908     return "fxch\t%1";
2909   else
2910     return "fxch\t%0";
2911 }
2912   [(set_attr "type" "fxch")
2913    (set_attr "mode" "XF")])
2914
2915 (define_expand "movtf"
2916   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2917         (match_operand:TF 1 "nonimmediate_operand" ""))]
2918   "TARGET_64BIT"
2919 {
2920   ix86_expand_move (TFmode, operands);
2921   DONE;
2922 })
2923
2924 (define_insn "*movtf_internal"
2925   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2926         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2927   "TARGET_64BIT
2928    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2929 {
2930   switch (which_alternative)
2931     {
2932     case 0:
2933     case 1:
2934       return "#";
2935     case 2:
2936       if (get_attr_mode (insn) == MODE_V4SF)
2937         return "xorps\t%0, %0";
2938       else
2939         return "pxor\t%0, %0";
2940     case 3:
2941     case 4:
2942       if (get_attr_mode (insn) == MODE_V4SF)
2943         return "movaps\t{%1, %0|%0, %1}";
2944       else
2945         return "movdqa\t{%1, %0|%0, %1}";
2946     default:
2947       gcc_unreachable ();
2948     }
2949 }
2950   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2951    (set (attr "mode")
2952         (cond [(eq_attr "alternative" "2,3")
2953                  (if_then_else
2954                    (ne (symbol_ref "optimize_size")
2955                        (const_int 0))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))
2958                (eq_attr "alternative" "4")
2959                  (if_then_else
2960                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2961                             (const_int 0))
2962                         (ne (symbol_ref "optimize_size")
2963                             (const_int 0)))
2964                    (const_string "V4SF")
2965                    (const_string "TI"))]
2966                (const_string "DI")))])
2967
2968 (define_split
2969   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2970         (match_operand:TF 1 "general_operand" ""))]
2971   "reload_completed && !SSE_REG_P (operands[0])
2972    && !SSE_REG_P (operands[1])"
2973   [(const_int 0)]
2974   "ix86_split_long_move (operands); DONE;")
2975 \f
2976 ;; Zero extension instructions
2977
2978 (define_expand "zero_extendhisi2"
2979   [(set (match_operand:SI 0 "register_operand" "")
2980      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2981   ""
2982 {
2983   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2984     {
2985       operands[1] = force_reg (HImode, operands[1]);
2986       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2987       DONE;
2988     }
2989 })
2990
2991 (define_insn "zero_extendhisi2_and"
2992   [(set (match_operand:SI 0 "register_operand" "=r")
2993      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2994    (clobber (reg:CC FLAGS_REG))]
2995   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996   "#"
2997   [(set_attr "type" "alu1")
2998    (set_attr "mode" "SI")])
2999
3000 (define_split
3001   [(set (match_operand:SI 0 "register_operand" "")
3002         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3003    (clobber (reg:CC FLAGS_REG))]
3004   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3005   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3006               (clobber (reg:CC FLAGS_REG))])]
3007   "")
3008
3009 (define_insn "*zero_extendhisi2_movzwl"
3010   [(set (match_operand:SI 0 "register_operand" "=r")
3011      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3012   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013   "movz{wl|x}\t{%1, %0|%0, %1}"
3014   [(set_attr "type" "imovx")
3015    (set_attr "mode" "SI")])
3016
3017 (define_expand "zero_extendqihi2"
3018   [(parallel
3019     [(set (match_operand:HI 0 "register_operand" "")
3020        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3021      (clobber (reg:CC FLAGS_REG))])]
3022   ""
3023   "")
3024
3025 (define_insn "*zero_extendqihi2_and"
3026   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3027      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3028    (clobber (reg:CC FLAGS_REG))]
3029   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3030   "#"
3031   [(set_attr "type" "alu1")
3032    (set_attr "mode" "HI")])
3033
3034 (define_insn "*zero_extendqihi2_movzbw_and"
3035   [(set (match_operand:HI 0 "register_operand" "=r,r")
3036      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3037    (clobber (reg:CC FLAGS_REG))]
3038   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3039   "#"
3040   [(set_attr "type" "imovx,alu1")
3041    (set_attr "mode" "HI")])
3042
3043 ; zero extend to SImode here to avoid partial register stalls
3044 (define_insn "*zero_extendqihi2_movzbl"
3045   [(set (match_operand:HI 0 "register_operand" "=r")
3046      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3047   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3048   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3049   [(set_attr "type" "imovx")
3050    (set_attr "mode" "SI")])
3051
3052 ;; For the movzbw case strip only the clobber
3053 (define_split
3054   [(set (match_operand:HI 0 "register_operand" "")
3055         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "reload_completed 
3058    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3059    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3060   [(set (match_operand:HI 0 "register_operand" "")
3061         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3062
3063 ;; When source and destination does not overlap, clear destination
3064 ;; first and then do the movb
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && ANY_QI_REG_P (operands[0])
3071    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3072    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3073   [(set (match_dup 0) (const_int 0))
3074    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3075   "operands[2] = gen_lowpart (QImode, operands[0]);")
3076
3077 ;; Rest is handled by single and.
3078 (define_split
3079   [(set (match_operand:HI 0 "register_operand" "")
3080         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "reload_completed
3083    && true_regnum (operands[0]) == true_regnum (operands[1])"
3084   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3085               (clobber (reg:CC FLAGS_REG))])]
3086   "")
3087
3088 (define_expand "zero_extendqisi2"
3089   [(parallel
3090     [(set (match_operand:SI 0 "register_operand" "")
3091        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092      (clobber (reg:CC FLAGS_REG))])]
3093   ""
3094   "")
3095
3096 (define_insn "*zero_extendqisi2_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101   "#"
3102   [(set_attr "type" "alu1")
3103    (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw_and"
3106   [(set (match_operand:SI 0 "register_operand" "=r,r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3108    (clobber (reg:CC FLAGS_REG))]
3109   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3110   "#"
3111   [(set_attr "type" "imovx,alu1")
3112    (set_attr "mode" "SI")])
3113
3114 (define_insn "*zero_extendqisi2_movzbw"
3115   [(set (match_operand:SI 0 "register_operand" "=r")
3116      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3117   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3118   "movz{bl|x}\t{%1, %0|%0, %1}"
3119   [(set_attr "type" "imovx")
3120    (set_attr "mode" "SI")])
3121
3122 ;; For the movzbl case strip only the clobber
3123 (define_split
3124   [(set (match_operand:SI 0 "register_operand" "")
3125         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126    (clobber (reg:CC FLAGS_REG))]
3127   "reload_completed 
3128    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3129    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3130   [(set (match_dup 0)
3131         (zero_extend:SI (match_dup 1)))])
3132
3133 ;; When source and destination does not overlap, clear destination
3134 ;; first and then do the movb
3135 (define_split
3136   [(set (match_operand:SI 0 "register_operand" "")
3137         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3138    (clobber (reg:CC FLAGS_REG))]
3139   "reload_completed
3140    && ANY_QI_REG_P (operands[0])
3141    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3142    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3143    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3144   [(set (match_dup 0) (const_int 0))
3145    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3146   "operands[2] = gen_lowpart (QImode, operands[0]);")
3147
3148 ;; Rest is handled by single and.
3149 (define_split
3150   [(set (match_operand:SI 0 "register_operand" "")
3151         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3152    (clobber (reg:CC FLAGS_REG))]
3153   "reload_completed
3154    && true_regnum (operands[0]) == true_regnum (operands[1])"
3155   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3156               (clobber (reg:CC FLAGS_REG))])]
3157   "")
3158
3159 ;; %%% Kill me once multi-word ops are sane.
3160 (define_expand "zero_extendsidi2"
3161   [(set (match_operand:DI 0 "register_operand" "=r")
3162      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3163   ""
3164   "if (!TARGET_64BIT)
3165      {
3166        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3167        DONE;
3168      }
3169   ")
3170
3171 (define_insn "zero_extendsidi2_32"
3172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3173         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3174    (clobber (reg:CC FLAGS_REG))]
3175   "!TARGET_64BIT"
3176   "@
3177    #
3178    #
3179    #
3180    movd\t{%1, %0|%0, %1}
3181    movd\t{%1, %0|%0, %1}"
3182   [(set_attr "mode" "SI,SI,SI,DI,TI")
3183    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3184
3185 (define_insn "zero_extendsidi2_rex64"
3186   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3187      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3188   "TARGET_64BIT"
3189   "@
3190    mov\t{%k1, %k0|%k0, %k1}
3191    #
3192    movd\t{%1, %0|%0, %1}
3193    movd\t{%1, %0|%0, %1}"
3194   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3195    (set_attr "mode" "SI,DI,SI,SI")])
3196
3197 (define_split
3198   [(set (match_operand:DI 0 "memory_operand" "")
3199      (zero_extend:DI (match_dup 0)))]
3200   "TARGET_64BIT"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split 
3205   [(set (match_operand:DI 0 "register_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && true_regnum (operands[0]) == true_regnum (operands[1])"
3210   [(set (match_dup 4) (const_int 0))]
3211   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3212
3213 (define_split 
3214   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3215         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3216    (clobber (reg:CC FLAGS_REG))]
3217   "!TARGET_64BIT && reload_completed
3218    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3219   [(set (match_dup 3) (match_dup 1))
3220    (set (match_dup 4) (const_int 0))]
3221   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223 (define_insn "zero_extendhidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3230
3231 (define_insn "zero_extendqidi2"
3232   [(set (match_operand:DI 0 "register_operand" "=r")
3233      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3234   "TARGET_64BIT"
3235   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3236   [(set_attr "type" "imovx")
3237    (set_attr "mode" "DI")])
3238 \f
3239 ;; Sign extension instructions
3240
3241 (define_expand "extendsidi2"
3242   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3243                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3244               (clobber (reg:CC FLAGS_REG))
3245               (clobber (match_scratch:SI 2 ""))])]
3246   ""
3247 {
3248   if (TARGET_64BIT)
3249     {
3250       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3251       DONE;
3252     }
3253 })
3254
3255 (define_insn "*extendsidi2_1"
3256   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3257         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3258    (clobber (reg:CC FLAGS_REG))
3259    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3260   "!TARGET_64BIT"
3261   "#")
3262
3263 (define_insn "extendsidi2_rex64"
3264   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3265         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3266   "TARGET_64BIT"
3267   "@
3268    {cltq|cdqe}
3269    movs{lq|x}\t{%1,%0|%0, %1}"
3270   [(set_attr "type" "imovx")
3271    (set_attr "mode" "DI")
3272    (set_attr "prefix_0f" "0")
3273    (set_attr "modrm" "0,1")])
3274
3275 (define_insn "extendhidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3278   "TARGET_64BIT"
3279   "movs{wq|x}\t{%1,%0|%0, %1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "DI")])
3282
3283 (define_insn "extendqidi2"
3284   [(set (match_operand:DI 0 "register_operand" "=r")
3285         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3286   "TARGET_64BIT"
3287   "movs{bq|x}\t{%1,%0|%0, %1}"
3288    [(set_attr "type" "imovx")
3289     (set_attr "mode" "DI")])
3290
3291 ;; Extend to memory case when source register does die.
3292 (define_split 
3293   [(set (match_operand:DI 0 "memory_operand" "")
3294         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295    (clobber (reg:CC FLAGS_REG))
3296    (clobber (match_operand:SI 2 "register_operand" ""))]
3297   "(reload_completed
3298     && dead_or_set_p (insn, operands[1])
3299     && !reg_mentioned_p (operands[1], operands[0]))"
3300   [(set (match_dup 3) (match_dup 1))
3301    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3302               (clobber (reg:CC FLAGS_REG))])
3303    (set (match_dup 4) (match_dup 1))]
3304   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3305
3306 ;; Extend to memory case when source register does not die.
3307 (define_split 
3308   [(set (match_operand:DI 0 "memory_operand" "")
3309         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310    (clobber (reg:CC FLAGS_REG))
3311    (clobber (match_operand:SI 2 "register_operand" ""))]
3312   "reload_completed"
3313   [(const_int 0)]
3314 {
3315   split_di (&operands[0], 1, &operands[3], &operands[4]);
3316
3317   emit_move_insn (operands[3], operands[1]);
3318
3319   /* Generate a cltd if possible and doing so it profitable.  */
3320   if (true_regnum (operands[1]) == 0
3321       && true_regnum (operands[2]) == 1
3322       && (optimize_size || TARGET_USE_CLTD))
3323     {
3324       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3325     }
3326   else
3327     {
3328       emit_move_insn (operands[2], operands[1]);
3329       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3330     }
3331   emit_move_insn (operands[4], operands[2]);
3332   DONE;
3333 })
3334
3335 ;; Extend to register case.  Optimize case where source and destination
3336 ;; registers match and cases where we can use cltd.
3337 (define_split 
3338   [(set (match_operand:DI 0 "register_operand" "")
3339         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3340    (clobber (reg:CC FLAGS_REG))
3341    (clobber (match_scratch:SI 2 ""))]
3342   "reload_completed"
3343   [(const_int 0)]
3344 {
3345   split_di (&operands[0], 1, &operands[3], &operands[4]);
3346
3347   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3348     emit_move_insn (operands[3], operands[1]);
3349
3350   /* Generate a cltd if possible and doing so it profitable.  */
3351   if (true_regnum (operands[3]) == 0
3352       && (optimize_size || TARGET_USE_CLTD))
3353     {
3354       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3355       DONE;
3356     }
3357
3358   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3359     emit_move_insn (operands[4], operands[1]);
3360
3361   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3362   DONE;
3363 })
3364
3365 (define_insn "extendhisi2"
3366   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3367         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3368   ""
3369 {
3370   switch (get_attr_prefix_0f (insn))
3371     {
3372     case 0:
3373       return "{cwtl|cwde}";
3374     default:
3375       return "movs{wl|x}\t{%1,%0|%0, %1}";
3376     }
3377 }
3378   [(set_attr "type" "imovx")
3379    (set_attr "mode" "SI")
3380    (set (attr "prefix_0f")
3381      ;; movsx is short decodable while cwtl is vector decoded.
3382      (if_then_else (and (eq_attr "cpu" "!k6")
3383                         (eq_attr "alternative" "0"))
3384         (const_string "0")
3385         (const_string "1")))
3386    (set (attr "modrm")
3387      (if_then_else (eq_attr "prefix_0f" "0")
3388         (const_string "0")
3389         (const_string "1")))])
3390
3391 (define_insn "*extendhisi2_zext"
3392   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3393         (zero_extend:DI
3394           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3395   "TARGET_64BIT"
3396 {
3397   switch (get_attr_prefix_0f (insn))
3398     {
3399     case 0:
3400       return "{cwtl|cwde}";
3401     default:
3402       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3403     }
3404 }
3405   [(set_attr "type" "imovx")
3406    (set_attr "mode" "SI")
3407    (set (attr "prefix_0f")
3408      ;; movsx is short decodable while cwtl is vector decoded.
3409      (if_then_else (and (eq_attr "cpu" "!k6")
3410                         (eq_attr "alternative" "0"))
3411         (const_string "0")
3412         (const_string "1")))
3413    (set (attr "modrm")
3414      (if_then_else (eq_attr "prefix_0f" "0")
3415         (const_string "0")
3416         (const_string "1")))])
3417
3418 (define_insn "extendqihi2"
3419   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3420         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3421   ""
3422 {
3423   switch (get_attr_prefix_0f (insn))
3424     {
3425     case 0:
3426       return "{cbtw|cbw}";
3427     default:
3428       return "movs{bw|x}\t{%1,%0|%0, %1}";
3429     }
3430 }
3431   [(set_attr "type" "imovx")
3432    (set_attr "mode" "HI")
3433    (set (attr "prefix_0f")
3434      ;; movsx is short decodable while cwtl is vector decoded.
3435      (if_then_else (and (eq_attr "cpu" "!k6")
3436                         (eq_attr "alternative" "0"))
3437         (const_string "0")
3438         (const_string "1")))
3439    (set (attr "modrm")
3440      (if_then_else (eq_attr "prefix_0f" "0")
3441         (const_string "0")
3442         (const_string "1")))])
3443
3444 (define_insn "extendqisi2"
3445   [(set (match_operand:SI 0 "register_operand" "=r")
3446         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3447   ""
3448   "movs{bl|x}\t{%1,%0|%0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3451
3452 (define_insn "*extendqisi2_zext"
3453   [(set (match_operand:DI 0 "register_operand" "=r")
3454         (zero_extend:DI
3455           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3456   "TARGET_64BIT"
3457   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3458    [(set_attr "type" "imovx")
3459     (set_attr "mode" "SI")])
3460 \f
3461 ;; Conversions between float and double.
3462
3463 ;; These are all no-ops in the model used for the 80387.  So just
3464 ;; emit moves.
3465
3466 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3467 (define_insn "*dummy_extendsfdf2"
3468   [(set (match_operand:DF 0 "push_operand" "=<")
3469         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3470   "0"
3471   "#")
3472
3473 (define_split
3474   [(set (match_operand:DF 0 "push_operand" "")
3475         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476   "!TARGET_64BIT"
3477   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3478    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3479
3480 (define_split
3481   [(set (match_operand:DF 0 "push_operand" "")
3482         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3483   "TARGET_64BIT"
3484   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3485    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3486
3487 (define_insn "*dummy_extendsfxf2"
3488   [(set (match_operand:XF 0 "push_operand" "=<")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3490   "0"
3491   "#")
3492
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   ""
3497   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3498    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3504   "TARGET_64BIT"
3505   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   ""
3513   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3514    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517 (define_split
3518   [(set (match_operand:XF 0 "push_operand" "")
3519         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3520   "TARGET_64BIT"
3521   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3522    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3523   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3524
3525 (define_expand "extendsfdf2"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3527         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3528   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3529 {
3530   /* ??? Needed for compress_float_constant since all fp constants
3531      are LEGITIMATE_CONSTANT_P.  */
3532   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3533     {
3534       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3535           && standard_80387_constant_p (operands[1]) > 0)
3536         {
3537           operands[1] = simplify_const_unary_operation
3538             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3539           emit_move_insn_1 (operands[0], operands[1]);
3540           DONE;
3541         }
3542       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3543     }
3544 })
3545
3546 (define_insn "*extendsfdf2_mixed"
3547   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3550 {
3551   switch (which_alternative)
3552     {
3553     case 0:
3554       return output_387_reg_move (insn, operands);
3555
3556     case 1:
3557       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3558         return "fstp%z0\t%y0";
3559       else
3560         return "fst%z0\t%y0";
3561
3562     case 2:
3563       return "cvtss2sd\t{%1, %0|%0, %1}";
3564
3565     default:
3566       gcc_unreachable ();
3567     }
3568 }
3569   [(set_attr "type" "fmov,fmov,ssecvt")
3570    (set_attr "mode" "SF,XF,DF")])
3571
3572 (define_insn "*extendsfdf2_sse"
3573   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3574         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3575   "TARGET_SSE2 && TARGET_SSE_MATH"
3576   "cvtss2sd\t{%1, %0|%0, %1}"
3577   [(set_attr "type" "ssecvt")
3578    (set_attr "mode" "DF")])
3579
3580 (define_insn "*extendsfdf2_i387"
3581   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3582         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3583   "TARGET_80387"
3584 {
3585   switch (which_alternative)
3586     {
3587     case 0:
3588       return output_387_reg_move (insn, operands);
3589
3590     case 1:
3591       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592         return "fstp%z0\t%y0";
3593       else
3594         return "fst%z0\t%y0";
3595
3596     default:
3597       gcc_unreachable ();
3598     }
3599 }
3600   [(set_attr "type" "fmov")
3601    (set_attr "mode" "SF,XF")])
3602
3603 (define_expand "extendsfxf2"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3606   "TARGET_80387"
3607 {
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     {
3612       if (standard_80387_constant_p (operands[1]) > 0)
3613         {
3614           operands[1] = simplify_const_unary_operation
3615             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3616           emit_move_insn_1 (operands[0], operands[1]);
3617           DONE;
3618         }
3619       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3620     }
3621 })
3622
3623 (define_insn "*extendsfxf2_i387"
3624   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626   "TARGET_80387"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641     default:
3642       gcc_unreachable ();
3643     }
3644 }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "SF,XF")])
3647
3648 (define_expand "extenddfxf2"
3649   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651   "TARGET_80387"
3652 {
3653   /* ??? Needed for compress_float_constant since all fp constants
3654      are LEGITIMATE_CONSTANT_P.  */
3655   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656     {
3657       if (standard_80387_constant_p (operands[1]) > 0)
3658         {
3659           operands[1] = simplify_const_unary_operation
3660             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661           emit_move_insn_1 (operands[0], operands[1]);
3662           DONE;
3663         }
3664       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665     }
3666 })
3667
3668 (define_insn "*extenddfxf2_i387"
3669   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3670         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3671   "TARGET_80387"
3672 {
3673   switch (which_alternative)
3674     {
3675     case 0:
3676       return output_387_reg_move (insn, operands);
3677
3678     case 1:
3679       /* There is no non-popping store to memory for XFmode.  So if
3680          we need one, follow the store with a load.  */
3681       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3683       else
3684         return "fstp%z0\t%y0";
3685
3686     default:
3687       gcc_unreachable ();
3688     }
3689 }
3690   [(set_attr "type" "fmov")
3691    (set_attr "mode" "DF,XF")])
3692
3693 ;; %%% This seems bad bad news.
3694 ;; This cannot output into an f-reg because there is no way to be sure
3695 ;; of truncating in that case.  Otherwise this is just like a simple move
3696 ;; insn.  So we pretend we can output to a reg in order to get better
3697 ;; register preferencing, but we really use a stack slot.
3698
3699 ;; Conversion from DFmode to SFmode.
3700
3701 (define_expand "truncdfsf2"
3702   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3703         (float_truncate:SF
3704           (match_operand:DF 1 "nonimmediate_operand" "")))]
3705   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3706 {
3707   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3708     ;
3709   else if (flag_unsafe_math_optimizations)
3710     ;
3711   else
3712     {
3713       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3714       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3715       DONE;
3716     }
3717 })
3718
3719 (define_expand "truncdfsf2_with_temp"
3720   [(parallel [(set (match_operand:SF 0 "" "")
3721                    (float_truncate:SF (match_operand:DF 1 "" "")))
3722               (clobber (match_operand:SF 2 "" ""))])]
3723   "")
3724
3725 (define_insn "*truncdfsf_fast_mixed"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3729   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3730 {
3731   switch (which_alternative)
3732     {
3733     case 0:
3734       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735         return "fstp%z0\t%y0";
3736       else
3737         return "fst%z0\t%y0";
3738     case 1:
3739       return output_387_reg_move (insn, operands);
3740     case 2:
3741       return "cvtsd2ss\t{%1, %0|%0, %1}";
3742     default:
3743       gcc_unreachable ();
3744     }
3745 }
3746   [(set_attr "type" "fmov,fmov,ssecvt")
3747    (set_attr "mode" "SF")])
3748
3749 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3750 ;; because nothing we do here is unsafe.
3751 (define_insn "*truncdfsf_fast_sse"
3752   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3753         (float_truncate:SF
3754           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3755   "TARGET_SSE2 && TARGET_SSE_MATH"
3756   "cvtsd2ss\t{%1, %0|%0, %1}"
3757   [(set_attr "type" "ssecvt")
3758    (set_attr "mode" "SF")])
3759
3760 (define_insn "*truncdfsf_fast_i387"
3761   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3762         (float_truncate:SF
3763           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3764   "TARGET_80387 && flag_unsafe_math_optimizations"
3765   "* return output_387_reg_move (insn, operands);"
3766   [(set_attr "type" "fmov")
3767    (set_attr "mode" "SF")])
3768
3769 (define_insn "*truncdfsf_mixed"
3770   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3771         (float_truncate:SF
3772           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3773    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3774   "TARGET_MIX_SSE_I387"
3775 {
3776   switch (which_alternative)
3777     {
3778     case 0:
3779       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780         return "fstp%z0\t%y0";
3781       else
3782         return "fst%z0\t%y0";
3783     case 1:
3784       return "#";
3785     case 2:
3786       return "cvtsd2ss\t{%1, %0|%0, %1}";
3787     default:
3788       gcc_unreachable ();
3789     }
3790 }
3791   [(set_attr "type" "fmov,multi,ssecvt")
3792    (set_attr "unit" "*,i387,*")
3793    (set_attr "mode" "SF")])
3794
3795 (define_insn "*truncdfsf_i387"
3796   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3797         (float_truncate:SF
3798           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3799    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3800   "TARGET_80387"
3801 {
3802   switch (which_alternative)
3803     {
3804     case 0:
3805       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806         return "fstp%z0\t%y0";
3807       else
3808         return "fst%z0\t%y0";
3809     case 1:
3810       return "#";
3811     default:
3812       gcc_unreachable ();
3813     }
3814 }
3815   [(set_attr "type" "fmov,multi")
3816    (set_attr "unit" "*,i387")
3817    (set_attr "mode" "SF")])
3818
3819 (define_insn "*truncdfsf2_i387_1"
3820   [(set (match_operand:SF 0 "memory_operand" "=m")
3821         (float_truncate:SF
3822           (match_operand:DF 1 "register_operand" "f")))]
3823   "TARGET_80387
3824    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3825    && !TARGET_MIX_SSE_I387"
3826 {
3827   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828     return "fstp%z0\t%y0";
3829   else
3830     return "fst%z0\t%y0";
3831 }
3832   [(set_attr "type" "fmov")
3833    (set_attr "mode" "SF")])
3834
3835 (define_split
3836   [(set (match_operand:SF 0 "register_operand" "")
3837         (float_truncate:SF
3838          (match_operand:DF 1 "fp_register_operand" "")))
3839    (clobber (match_operand 2 "" ""))]
3840   "reload_completed"
3841   [(set (match_dup 2) (match_dup 1))
3842    (set (match_dup 0) (match_dup 2))]
3843 {
3844   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3845 })
3846
3847 ;; Conversion from XFmode to SFmode.
3848
3849 (define_expand "truncxfsf2"
3850   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3851                    (float_truncate:SF
3852                     (match_operand:XF 1 "register_operand" "")))
3853               (clobber (match_dup 2))])]
3854   "TARGET_80387"
3855 {
3856   if (flag_unsafe_math_optimizations)
3857     {
3858       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3859       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3860       if (reg != operands[0])
3861         emit_move_insn (operands[0], reg);
3862       DONE;
3863     }
3864   else
3865     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3866 })
3867
3868 (define_insn "*truncxfsf2_mixed"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3873   "TARGET_MIX_SSE_I387"
3874 {
3875   gcc_assert (!which_alternative);
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878   else
3879     return "fst%z0\t%y0";
3880 }
3881   [(set_attr "type" "fmov,multi,multi,multi")
3882    (set_attr "unit" "*,i387,i387,i387")
3883    (set_attr "mode" "SF")])
3884
3885 (define_insn "truncxfsf2_i387_noop"
3886   [(set (match_operand:SF 0 "register_operand" "=f")
3887         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3888   "TARGET_80387 && flag_unsafe_math_optimizations"
3889 {
3890   return output_387_reg_move (insn, operands);
3891 }
3892   [(set_attr "type" "fmov")
3893    (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncxfsf2_i387"
3896   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "f,f,f")))
3899    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3900   "TARGET_80387"
3901 {
3902   gcc_assert (!which_alternative);
3903   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904     return "fstp%z0\t%y0";
3905    else
3906      return "fst%z0\t%y0";
3907 }
3908   [(set_attr "type" "fmov,multi,multi")
3909    (set_attr "unit" "*,i387,i387")
3910    (set_attr "mode" "SF")])
3911
3912 (define_insn "*truncxfsf2_i387_1"
3913   [(set (match_operand:SF 0 "memory_operand" "=m")
3914         (float_truncate:SF
3915          (match_operand:XF 1 "register_operand" "f")))]
3916   "TARGET_80387"
3917 {
3918   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3919     return "fstp%z0\t%y0";
3920   else
3921     return "fst%z0\t%y0";
3922 }
3923   [(set_attr "type" "fmov")
3924    (set_attr "mode" "SF")])
3925
3926 (define_split
3927   [(set (match_operand:SF 0 "register_operand" "")
3928         (float_truncate:SF
3929          (match_operand:XF 1 "register_operand" "")))
3930    (clobber (match_operand:SF 2 "memory_operand" ""))]
3931   "TARGET_80387 && reload_completed"
3932   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3933    (set (match_dup 0) (match_dup 2))]
3934   "")
3935
3936 (define_split
3937   [(set (match_operand:SF 0 "memory_operand" "")
3938         (float_truncate:SF
3939          (match_operand:XF 1 "register_operand" "")))
3940    (clobber (match_operand:SF 2 "memory_operand" ""))]
3941   "TARGET_80387"
3942   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3943   "")
3944
3945 ;; Conversion from XFmode to DFmode.
3946
3947 (define_expand "truncxfdf2"
3948   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3949                    (float_truncate:DF
3950                     (match_operand:XF 1 "register_operand" "")))
3951               (clobber (match_dup 2))])]
3952   "TARGET_80387"
3953 {
3954   if (flag_unsafe_math_optimizations)
3955     {
3956       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3957       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3958       if (reg != operands[0])
3959         emit_move_insn (operands[0], reg);
3960       DONE;
3961     }
3962   else
3963     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3964 })
3965
3966 (define_insn "*truncxfdf2_mixed"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3972 {
3973   gcc_assert (!which_alternative);
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3978 }
3979   [(set_attr "type" "fmov,multi,multi,multi")
3980    (set_attr "unit" "*,i387,i387,i387")
3981    (set_attr "mode" "DF")])
3982
3983 (define_insn "truncxfdf2_i387_noop"
3984   [(set (match_operand:DF 0 "register_operand" "=f")
3985         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3986   "TARGET_80387 && flag_unsafe_math_optimizations"
3987 {
3988   return output_387_reg_move (insn, operands);
3989 }
3990   [(set_attr "type" "fmov")
3991    (set_attr "mode" "DF")])
3992
3993 (define_insn "*truncxfdf2_i387"
3994   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3995         (float_truncate:DF
3996          (match_operand:XF 1 "register_operand" "f,f,f")))
3997    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3998   "TARGET_80387"
3999 {
4000   gcc_assert (!which_alternative);
4001   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002     return "fstp%z0\t%y0";
4003   else
4004     return "fst%z0\t%y0";
4005 }
4006   [(set_attr "type" "fmov,multi,multi")
4007    (set_attr "unit" "*,i387,i387")
4008    (set_attr "mode" "DF")])
4009
4010 (define_insn "*truncxfdf2_i387_1"
4011   [(set (match_operand:DF 0 "memory_operand" "=m")
4012         (float_truncate:DF
4013           (match_operand:XF 1 "register_operand" "f")))]
4014   "TARGET_80387"
4015 {
4016   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4017     return "fstp%z0\t%y0";
4018   else
4019     return "fst%z0\t%y0";
4020 }
4021   [(set_attr "type" "fmov")
4022    (set_attr "mode" "DF")])
4023
4024 (define_split
4025   [(set (match_operand:DF 0 "register_operand" "")
4026         (float_truncate:DF
4027          (match_operand:XF 1 "register_operand" "")))
4028    (clobber (match_operand:DF 2 "memory_operand" ""))]
4029   "TARGET_80387 && reload_completed"
4030   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4031    (set (match_dup 0) (match_dup 2))]
4032   "")
4033
4034 (define_split
4035   [(set (match_operand:DF 0 "memory_operand" "")
4036         (float_truncate:DF
4037          (match_operand:XF 1 "register_operand" "")))
4038    (clobber (match_operand:DF 2 "memory_operand" ""))]
4039   "TARGET_80387"
4040   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4041   "")
4042 \f
4043 ;; Signed conversion to DImode.
4044
4045 (define_expand "fix_truncxfdi2"
4046   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4047                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4048               (clobber (reg:CC FLAGS_REG))])]
4049   "TARGET_80387"
4050 {
4051   if (TARGET_FISTTP)
4052    {
4053      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4054      DONE;
4055    }
4056 })
4057
4058 (define_expand "fix_trunc<mode>di2"
4059   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4060                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4061               (clobber (reg:CC FLAGS_REG))])]
4062   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4063 {
4064   if (TARGET_FISTTP
4065       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4066    {
4067      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4068      DONE;
4069    }
4070   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4071    {
4072      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4073      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4074      if (out != operands[0])
4075         emit_move_insn (operands[0], out);
4076      DONE;
4077    }
4078 })
4079
4080 ;; Signed conversion to SImode.
4081
4082 (define_expand "fix_truncxfsi2"
4083   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4084                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4085               (clobber (reg:CC FLAGS_REG))])]
4086   "TARGET_80387"
4087 {
4088   if (TARGET_FISTTP)
4089    {
4090      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4091      DONE;
4092    }
4093 })
4094
4095 (define_expand "fix_trunc<mode>si2"
4096   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4097                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4098               (clobber (reg:CC FLAGS_REG))])]
4099   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4100 {
4101   if (TARGET_FISTTP
4102       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4103    {
4104      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4105      DONE;
4106    }
4107   if (SSE_FLOAT_MODE_P (<MODE>mode))
4108    {
4109      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4110      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4111      if (out != operands[0])
4112         emit_move_insn (operands[0], out);
4113      DONE;
4114    }
4115 })
4116
4117 ;; Signed conversion to HImode.
4118
4119 (define_expand "fix_trunc<mode>hi2"
4120   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4121                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4122               (clobber (reg:CC FLAGS_REG))])]
4123   "TARGET_80387
4124    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4125 {
4126   if (TARGET_FISTTP)
4127    {
4128      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4129      DONE;
4130    }
4131 })
4132
4133 ;; When SSE is available, it is always faster to use it!
4134 (define_insn "fix_truncsfdi_sse"
4135   [(set (match_operand:DI 0 "register_operand" "=r,r")
4136         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4137   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttss2si{q}\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "SF")
4141    (set_attr "athlon_decode" "double,vector")])
4142
4143 (define_insn "fix_truncdfdi_sse"
4144   [(set (match_operand:DI 0 "register_operand" "=r,r")
4145         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4147   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148   [(set_attr "type" "sseicvt")
4149    (set_attr "mode" "DF")
4150    (set_attr "athlon_decode" "double,vector")])
4151
4152 (define_insn "fix_truncsfsi_sse"
4153   [(set (match_operand:SI 0 "register_operand" "=r,r")
4154         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4155   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4156   "cvttss2si\t{%1, %0|%0, %1}"
4157   [(set_attr "type" "sseicvt")
4158    (set_attr "mode" "DF")
4159    (set_attr "athlon_decode" "double,vector")])
4160
4161 (define_insn "fix_truncdfsi_sse"
4162   [(set (match_operand:SI 0 "register_operand" "=r,r")
4163         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4164   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4165   "cvttsd2si\t{%1, %0|%0, %1}"
4166   [(set_attr "type" "sseicvt")
4167    (set_attr "mode" "DF")
4168    (set_attr "athlon_decode" "double,vector")])
4169
4170 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4171 (define_peephole2
4172   [(set (match_operand:DF 0 "register_operand" "")
4173         (match_operand:DF 1 "memory_operand" ""))
4174    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4175         (fix:SSEMODEI24 (match_dup 0)))]
4176   "!TARGET_K8
4177    && peep2_reg_dead_p (2, operands[0])"
4178   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4179   "")
4180
4181 (define_peephole2
4182   [(set (match_operand:SF 0 "register_operand" "")
4183         (match_operand:SF 1 "memory_operand" ""))
4184    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4185         (fix:SSEMODEI24 (match_dup 0)))]
4186   "!TARGET_K8
4187    && peep2_reg_dead_p (2, operands[0])"
4188   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4189   "")
4190
4191 ;; Avoid vector decoded forms of the instruction.
4192 (define_peephole2
4193   [(match_scratch:DF 2 "Y")
4194    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4196   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197   [(set (match_dup 2) (match_dup 1))
4198    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199   "")
4200
4201 (define_peephole2
4202   [(match_scratch:SF 2 "x")
4203    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4204         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4205   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4206   [(set (match_dup 2) (match_dup 1))
4207    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4208   "")
4209
4210 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4211   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4213   "TARGET_FISTTP
4214    && FLOAT_MODE_P (GET_MODE (operands[1]))
4215    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4216          && (TARGET_64BIT || <MODE>mode != DImode))
4217         && TARGET_SSE_MATH)
4218    && !(reload_completed || reload_in_progress)"
4219   "#"
4220   "&& 1"
4221   [(const_int 0)]
4222 {
4223   if (memory_operand (operands[0], VOIDmode))
4224     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4225   else
4226     {
4227       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4229                                                             operands[1],
4230                                                             operands[2]));
4231     }
4232   DONE;
4233 }
4234   [(set_attr "type" "fisttp")
4235    (set_attr "mode" "<MODE>")])
4236
4237 (define_insn "fix_trunc<mode>_i387_fisttp"
4238   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4239         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4240    (clobber (match_scratch:XF 2 "=&1f"))]
4241   "TARGET_FISTTP
4242    && FLOAT_MODE_P (GET_MODE (operands[1]))
4243    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4244          && (TARGET_64BIT || <MODE>mode != DImode))
4245         && TARGET_SSE_MATH)"
4246   "* return output_fix_trunc (insn, operands, 1);"
4247   [(set_attr "type" "fisttp")
4248    (set_attr "mode" "<MODE>")])
4249
4250 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4254    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4255   "TARGET_FISTTP
4256    && FLOAT_MODE_P (GET_MODE (operands[1]))
4257    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258         && (TARGET_64BIT || <MODE>mode != DImode))
4259         && TARGET_SSE_MATH)"
4260   "#"
4261   [(set_attr "type" "fisttp")
4262    (set_attr "mode" "<MODE>")])
4263
4264 (define_split
4265   [(set (match_operand:X87MODEI 0 "register_operand" "")
4266         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4267    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4268    (clobber (match_scratch 3 ""))]
4269   "reload_completed"
4270   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4271               (clobber (match_dup 3))])
4272    (set (match_dup 0) (match_dup 2))]
4273   "")
4274
4275 (define_split
4276   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4278    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4279    (clobber (match_scratch 3 ""))]
4280   "reload_completed"
4281   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4282               (clobber (match_dup 3))])]
4283   "")
4284
4285 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4286 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4287 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4288 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4289 ;; function in i386.c.
4290 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4291   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293    (clobber (reg:CC FLAGS_REG))]
4294   "TARGET_80387 && !TARGET_FISTTP
4295    && FLOAT_MODE_P (GET_MODE (operands[1]))
4296    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297          && (TARGET_64BIT || <MODE>mode != DImode))
4298    && !(reload_completed || reload_in_progress)"
4299   "#"
4300   "&& 1"
4301   [(const_int 0)]
4302 {
4303   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4304
4305   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4306   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4307   if (memory_operand (operands[0], VOIDmode))
4308     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4309                                          operands[2], operands[3]));
4310   else
4311     {
4312       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4313       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4314                                                      operands[2], operands[3],
4315                                                      operands[4]));
4316     }
4317   DONE;
4318 }
4319   [(set_attr "type" "fistp")
4320    (set_attr "i387_cw" "trunc")
4321    (set_attr "mode" "<MODE>")])
4322
4323 (define_insn "fix_truncdi_i387"
4324   [(set (match_operand:DI 0 "memory_operand" "=m")
4325         (fix:DI (match_operand 1 "register_operand" "f")))
4326    (use (match_operand:HI 2 "memory_operand" "m"))
4327    (use (match_operand:HI 3 "memory_operand" "m"))
4328    (clobber (match_scratch:XF 4 "=&1f"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332   "* return output_fix_trunc (insn, operands, 0);"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "DI")])
4336
4337 (define_insn "fix_truncdi_i387_with_temp"
4338   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4339         (fix:DI (match_operand 1 "register_operand" "f,f")))
4340    (use (match_operand:HI 2 "memory_operand" "m,m"))
4341    (use (match_operand:HI 3 "memory_operand" "m,m"))
4342    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4343    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4344   "TARGET_80387 && !TARGET_FISTTP
4345    && FLOAT_MODE_P (GET_MODE (operands[1]))
4346    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4347   "#"
4348   [(set_attr "type" "fistp")
4349    (set_attr "i387_cw" "trunc")
4350    (set_attr "mode" "DI")])
4351
4352 (define_split 
4353   [(set (match_operand:DI 0 "register_operand" "")
4354         (fix:DI (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:DI 4 "memory_operand" ""))
4358    (clobber (match_scratch 5 ""))]
4359   "reload_completed"
4360   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4361               (use (match_dup 2))
4362               (use (match_dup 3))
4363               (clobber (match_dup 5))])
4364    (set (match_dup 0) (match_dup 4))]
4365   "")
4366
4367 (define_split 
4368   [(set (match_operand:DI 0 "memory_operand" "")
4369         (fix:DI (match_operand 1 "register_operand" "")))
4370    (use (match_operand:HI 2 "memory_operand" ""))
4371    (use (match_operand:HI 3 "memory_operand" ""))
4372    (clobber (match_operand:DI 4 "memory_operand" ""))
4373    (clobber (match_scratch 5 ""))]
4374   "reload_completed"
4375   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4376               (use (match_dup 2))
4377               (use (match_dup 3))
4378               (clobber (match_dup 5))])]
4379   "")
4380
4381 (define_insn "fix_trunc<mode>_i387"
4382   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4383         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4384    (use (match_operand:HI 2 "memory_operand" "m"))
4385    (use (match_operand:HI 3 "memory_operand" "m"))]
4386   "TARGET_80387 && !TARGET_FISTTP
4387    && FLOAT_MODE_P (GET_MODE (operands[1]))
4388    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389   "* return output_fix_trunc (insn, operands, 0);"
4390   [(set_attr "type" "fistp")
4391    (set_attr "i387_cw" "trunc")
4392    (set_attr "mode" "<MODE>")])
4393
4394 (define_insn "fix_trunc<mode>_i387_with_temp"
4395   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4396         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4397    (use (match_operand:HI 2 "memory_operand" "m,m"))
4398    (use (match_operand:HI 3 "memory_operand" "m,m"))
4399    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4400   "TARGET_80387 && !TARGET_FISTTP
4401    && FLOAT_MODE_P (GET_MODE (operands[1]))
4402    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403   "#"
4404   [(set_attr "type" "fistp")
4405    (set_attr "i387_cw" "trunc")
4406    (set_attr "mode" "<MODE>")])
4407
4408 (define_split 
4409   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4410         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4411    (use (match_operand:HI 2 "memory_operand" ""))
4412    (use (match_operand:HI 3 "memory_operand" ""))
4413    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))])
4418    (set (match_dup 0) (match_dup 4))]
4419   "")
4420
4421 (define_split 
4422   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4423         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4424    (use (match_operand:HI 2 "memory_operand" ""))
4425    (use (match_operand:HI 3 "memory_operand" ""))
4426    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4427   "reload_completed"
4428   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4429               (use (match_dup 2))
4430               (use (match_dup 3))])]
4431   "")
4432
4433 (define_insn "x86_fnstcw_1"
4434   [(set (match_operand:HI 0 "memory_operand" "=m")
4435         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4436   "TARGET_80387"
4437   "fnstcw\t%0"
4438   [(set_attr "length" "2")
4439    (set_attr "mode" "HI")
4440    (set_attr "unit" "i387")])
4441
4442 (define_insn "x86_fldcw_1"
4443   [(set (reg:HI FPCR_REG)
4444         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4445   "TARGET_80387"
4446   "fldcw\t%0"
4447   [(set_attr "length" "2")
4448    (set_attr "mode" "HI")
4449    (set_attr "unit" "i387")
4450    (set_attr "athlon_decode" "vector")])
4451 \f
4452 ;; Conversion between fixed point and floating point.
4453
4454 ;; Even though we only accept memory inputs, the backend _really_
4455 ;; wants to be able to do this between registers.
4456
4457 (define_expand "floathisf2"
4458   [(set (match_operand:SF 0 "register_operand" "")
4459         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4460   "TARGET_80387 || TARGET_SSE_MATH"
4461 {
4462   if (TARGET_SSE_MATH)
4463     {
4464       emit_insn (gen_floatsisf2 (operands[0],
4465                                  convert_to_mode (SImode, operands[1], 0)));
4466       DONE;
4467     }
4468 })
4469
4470 (define_insn "*floathisf2_i387"
4471   [(set (match_operand:SF 0 "register_operand" "=f,f")
4472         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4473   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4474   "@
4475    fild%z1\t%1
4476    #"
4477   [(set_attr "type" "fmov,multi")
4478    (set_attr "mode" "SF")
4479    (set_attr "unit" "*,i387")
4480    (set_attr "fp_int_src" "true")])
4481
4482 (define_expand "floatsisf2"
4483   [(set (match_operand:SF 0 "register_operand" "")
4484         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485   "TARGET_80387 || TARGET_SSE_MATH"
4486   "")
4487
4488 (define_insn "*floatsisf2_mixed"
4489   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491   "TARGET_MIX_SSE_I387"
4492   "@
4493    fild%z1\t%1
4494    #
4495    cvtsi2ss\t{%1, %0|%0, %1}
4496    cvtsi2ss\t{%1, %0|%0, %1}"
4497   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498    (set_attr "mode" "SF")
4499    (set_attr "unit" "*,i387,*,*")
4500    (set_attr "athlon_decode" "*,*,vector,double")
4501    (set_attr "fp_int_src" "true")])
4502
4503 (define_insn "*floatsisf2_sse"
4504   [(set (match_operand:SF 0 "register_operand" "=x,x")
4505         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4506   "TARGET_SSE_MATH"
4507   "cvtsi2ss\t{%1, %0|%0, %1}"
4508   [(set_attr "type" "sseicvt")
4509    (set_attr "mode" "SF")
4510    (set_attr "athlon_decode" "vector,double")
4511    (set_attr "fp_int_src" "true")])
4512
4513 (define_insn "*floatsisf2_i387"
4514   [(set (match_operand:SF 0 "register_operand" "=f,f")
4515         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4516   "TARGET_80387"
4517   "@
4518    fild%z1\t%1
4519    #"
4520   [(set_attr "type" "fmov,multi")
4521    (set_attr "mode" "SF")
4522    (set_attr "unit" "*,i387")
4523    (set_attr "fp_int_src" "true")])
4524
4525 (define_expand "floatdisf2"
4526   [(set (match_operand:SF 0 "register_operand" "")
4527         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4528   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4529   "")
4530
4531 (define_insn "*floatdisf2_mixed"
4532   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4534   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4535   "@
4536    fild%z1\t%1
4537    #
4538    cvtsi2ss{q}\t{%1, %0|%0, %1}
4539    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4540   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4541    (set_attr "mode" "SF")
4542    (set_attr "unit" "*,i387,*,*")
4543    (set_attr "athlon_decode" "*,*,vector,double")
4544    (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatdisf2_sse"
4547   [(set (match_operand:SF 0 "register_operand" "=x,x")
4548         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549   "TARGET_64BIT && TARGET_SSE_MATH"
4550   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "sseicvt")
4552    (set_attr "mode" "SF")
4553    (set_attr "athlon_decode" "vector,double")
4554    (set_attr "fp_int_src" "true")])
4555
4556 (define_insn "*floatdisf2_i387"
4557   [(set (match_operand:SF 0 "register_operand" "=f,f")
4558         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4559   "TARGET_80387"
4560   "@
4561    fild%z1\t%1
4562    #"
4563   [(set_attr "type" "fmov,multi")
4564    (set_attr "mode" "SF")
4565    (set_attr "unit" "*,i387")
4566    (set_attr "fp_int_src" "true")])
4567
4568 (define_expand "floathidf2"
4569   [(set (match_operand:DF 0 "register_operand" "")
4570         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4571   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4572 {
4573   if (TARGET_SSE2 && TARGET_SSE_MATH)
4574     {
4575       emit_insn (gen_floatsidf2 (operands[0],
4576                                  convert_to_mode (SImode, operands[1], 0)));
4577       DONE;
4578     }
4579 })
4580
4581 (define_insn "*floathidf2_i387"
4582   [(set (match_operand:DF 0 "register_operand" "=f,f")
4583         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4584   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4585   "@
4586    fild%z1\t%1
4587    #"
4588   [(set_attr "type" "fmov,multi")
4589    (set_attr "mode" "DF")
4590    (set_attr "unit" "*,i387")
4591    (set_attr "fp_int_src" "true")])
4592
4593 (define_expand "floatsidf2"
4594   [(set (match_operand:DF 0 "register_operand" "")
4595         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4597   "")
4598
4599 (define_insn "*floatsidf2_mixed"
4600   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4602   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4603   "@
4604    fild%z1\t%1
4605    #
4606    cvtsi2sd\t{%1, %0|%0, %1}
4607    cvtsi2sd\t{%1, %0|%0, %1}"
4608   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4609    (set_attr "mode" "DF")
4610    (set_attr "unit" "*,i387,*,*")
4611    (set_attr "athlon_decode" "*,*,double,direct")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatsidf2_sse"
4615   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4616         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4617   "TARGET_SSE2 && TARGET_SSE_MATH"
4618   "cvtsi2sd\t{%1, %0|%0, %1}"
4619   [(set_attr "type" "sseicvt")
4620    (set_attr "mode" "DF")
4621    (set_attr "athlon_decode" "double,direct")
4622    (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_i387"
4625   [(set (match_operand:DF 0 "register_operand" "=f,f")
4626         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4627   "TARGET_80387"
4628   "@
4629    fild%z1\t%1
4630    #"
4631   [(set_attr "type" "fmov,multi")
4632    (set_attr "mode" "DF")
4633    (set_attr "unit" "*,i387")
4634    (set_attr "fp_int_src" "true")])
4635
4636 (define_expand "floatdidf2"
4637   [(set (match_operand:DF 0 "register_operand" "")
4638         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4639   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4640   "")
4641
4642 (define_insn "*floatdidf2_mixed"
4643   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4644         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4645   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4646   "@
4647    fild%z1\t%1
4648    #
4649    cvtsi2sd{q}\t{%1, %0|%0, %1}
4650    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4651   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4652    (set_attr "mode" "DF")
4653    (set_attr "unit" "*,i387,*,*")
4654    (set_attr "athlon_decode" "*,*,double,direct")
4655    (set_attr "fp_int_src" "true")])
4656
4657 (define_insn "*floatdidf2_sse"
4658   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4661   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662   [(set_attr "type" "sseicvt")
4663    (set_attr "mode" "DF")
4664    (set_attr "athlon_decode" "double,direct")
4665    (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "*floatdidf2_i387"
4668   [(set (match_operand:DF 0 "register_operand" "=f,f")
4669         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4670   "TARGET_80387"
4671   "@
4672    fild%z1\t%1
4673    #"
4674   [(set_attr "type" "fmov,multi")
4675    (set_attr "mode" "DF")
4676    (set_attr "unit" "*,i387")
4677    (set_attr "fp_int_src" "true")])
4678
4679 (define_insn "floathixf2"
4680   [(set (match_operand:XF 0 "register_operand" "=f,f")
4681         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4682   "TARGET_80387"
4683   "@
4684    fild%z1\t%1
4685    #"
4686   [(set_attr "type" "fmov,multi")
4687    (set_attr "mode" "XF")
4688    (set_attr "unit" "*,i387")
4689    (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "floatsixf2"
4692   [(set (match_operand:XF 0 "register_operand" "=f,f")
4693         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4694   "TARGET_80387"
4695   "@
4696    fild%z1\t%1
4697    #"
4698   [(set_attr "type" "fmov,multi")
4699    (set_attr "mode" "XF")
4700    (set_attr "unit" "*,i387")
4701    (set_attr "fp_int_src" "true")])
4702
4703 (define_insn "floatdixf2"
4704   [(set (match_operand:XF 0 "register_operand" "=f,f")
4705         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4706   "TARGET_80387"
4707   "@
4708    fild%z1\t%1
4709    #"
4710   [(set_attr "type" "fmov,multi")
4711    (set_attr "mode" "XF")
4712    (set_attr "unit" "*,i387")
4713    (set_attr "fp_int_src" "true")])
4714
4715 ;; %%% Kill these when reload knows how to do it.
4716 (define_split
4717   [(set (match_operand 0 "fp_register_operand" "")
4718         (float (match_operand 1 "register_operand" "")))]
4719   "reload_completed
4720    && TARGET_80387
4721    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4722   [(const_int 0)]
4723 {
4724   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4725   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4726   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4727   ix86_free_from_memory (GET_MODE (operands[1]));
4728   DONE;
4729 })
4730
4731 (define_expand "floatunssisf2"
4732   [(use (match_operand:SF 0 "register_operand" ""))
4733    (use (match_operand:SI 1 "register_operand" ""))]
4734   "!TARGET_64BIT && TARGET_SSE_MATH"
4735   "x86_emit_floatuns (operands); DONE;")
4736
4737 (define_expand "floatunsdisf2"
4738   [(use (match_operand:SF 0 "register_operand" ""))
4739    (use (match_operand:DI 1 "register_operand" ""))]
4740   "TARGET_64BIT && TARGET_SSE_MATH"
4741   "x86_emit_floatuns (operands); DONE;")
4742
4743 (define_expand "floatunsdidf2"
4744   [(use (match_operand:DF 0 "register_operand" ""))
4745    (use (match_operand:DI 1 "register_operand" ""))]
4746   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4747   "x86_emit_floatuns (operands); DONE;")
4748 \f
4749 ;; SSE extract/set expanders
4750
4751 \f
4752 ;; Add instructions
4753
4754 ;; %%% splits for addditi3
4755
4756 (define_expand "addti3"
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759                  (match_operand:TI 2 "x86_64_general_operand" "")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT"
4762   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4763
4764 (define_insn "*addti3_1"
4765   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4766         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4767                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4770   "#")
4771
4772 (define_split
4773   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4774         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4775                  (match_operand:TI 2 "general_operand" "")))
4776    (clobber (reg:CC FLAGS_REG))]
4777   "TARGET_64BIT && reload_completed"
4778   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779                                           UNSPEC_ADD_CARRY))
4780               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4781    (parallel [(set (match_dup 3)
4782                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4783                                      (match_dup 4))
4784                             (match_dup 5)))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "split_ti (operands+0, 1, operands+0, operands+3);
4787    split_ti (operands+1, 1, operands+1, operands+4);
4788    split_ti (operands+2, 1, operands+2, operands+5);")
4789
4790 ;; %%% splits for addsidi3
4791 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4792 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4793 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4794
4795 (define_expand "adddi3"
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798                  (match_operand:DI 2 "x86_64_general_operand" "")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   ""
4801   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4802
4803 (define_insn "*adddi3_1"
4804   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4805         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4806                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4807    (clobber (reg:CC FLAGS_REG))]
4808   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4809   "#")
4810
4811 (define_split
4812   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4814                  (match_operand:DI 2 "general_operand" "")))
4815    (clobber (reg:CC FLAGS_REG))]
4816   "!TARGET_64BIT && reload_completed"
4817   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818                                           UNSPEC_ADD_CARRY))
4819               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4820    (parallel [(set (match_dup 3)
4821                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4822                                      (match_dup 4))
4823                             (match_dup 5)))
4824               (clobber (reg:CC FLAGS_REG))])]
4825   "split_di (operands+0, 1, operands+0, operands+3);
4826    split_di (operands+1, 1, operands+1, operands+4);
4827    split_di (operands+2, 1, operands+2, operands+5);")
4828
4829 (define_insn "adddi3_carry_rex64"
4830   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4836   "adc{q}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "DI")])
4840
4841 (define_insn "*adddi3_cc_rex64"
4842   [(set (reg:CC FLAGS_REG)
4843         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4845                    UNSPEC_ADD_CARRY))
4846    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4847         (plus:DI (match_dup 1) (match_dup 2)))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849   "add{q}\t{%2, %0|%0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "mode" "DI")])
4852
4853 (define_insn "addqi3_carry"
4854   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4855           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4856                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4857                    (match_operand:QI 2 "general_operand" "qi,qm")))
4858    (clobber (reg:CC FLAGS_REG))]
4859   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4860   "adc{b}\t{%2, %0|%0, %2}"
4861   [(set_attr "type" "alu")
4862    (set_attr "pent_pair" "pu")
4863    (set_attr "mode" "QI")])
4864
4865 (define_insn "addhi3_carry"
4866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4867           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4868                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4869                    (match_operand:HI 2 "general_operand" "ri,rm")))
4870    (clobber (reg:CC FLAGS_REG))]
4871   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4872   "adc{w}\t{%2, %0|%0, %2}"
4873   [(set_attr "type" "alu")
4874    (set_attr "pent_pair" "pu")
4875    (set_attr "mode" "HI")])
4876
4877 (define_insn "addsi3_carry"
4878   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4880                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4881                    (match_operand:SI 2 "general_operand" "ri,rm")))
4882    (clobber (reg:CC FLAGS_REG))]
4883   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4884   "adc{l}\t{%2, %0|%0, %2}"
4885   [(set_attr "type" "alu")
4886    (set_attr "pent_pair" "pu")
4887    (set_attr "mode" "SI")])
4888
4889 (define_insn "*addsi3_carry_zext"
4890   [(set (match_operand:DI 0 "register_operand" "=r")
4891           (zero_extend:DI 
4892             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4893                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4894                      (match_operand:SI 2 "general_operand" "rim"))))
4895    (clobber (reg:CC FLAGS_REG))]
4896   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4897   "adc{l}\t{%2, %k0|%k0, %2}"
4898   [(set_attr "type" "alu")
4899    (set_attr "pent_pair" "pu")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*addsi3_cc"
4903   [(set (reg:CC FLAGS_REG)
4904         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4905                     (match_operand:SI 2 "general_operand" "ri,rm")]
4906                    UNSPEC_ADD_CARRY))
4907    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4908         (plus:SI (match_dup 1) (match_dup 2)))]
4909   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4910   "add{l}\t{%2, %0|%0, %2}"
4911   [(set_attr "type" "alu")
4912    (set_attr "mode" "SI")])
4913
4914 (define_insn "addqi3_cc"
4915   [(set (reg:CC FLAGS_REG)
4916         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4917                     (match_operand:QI 2 "general_operand" "qi,qm")]
4918                    UNSPEC_ADD_CARRY))
4919    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4920         (plus:QI (match_dup 1) (match_dup 2)))]
4921   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4922   "add{b}\t{%2, %0|%0, %2}"
4923   [(set_attr "type" "alu")
4924    (set_attr "mode" "QI")])
4925
4926 (define_expand "addsi3"
4927   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4928                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4929                             (match_operand:SI 2 "general_operand" "")))
4930               (clobber (reg:CC FLAGS_REG))])]
4931   ""
4932   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4933
4934 (define_insn "*lea_1"
4935   [(set (match_operand:SI 0 "register_operand" "=r")
4936         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4937   "!TARGET_64BIT"
4938   "lea{l}\t{%a1, %0|%0, %a1}"
4939   [(set_attr "type" "lea")
4940    (set_attr "mode" "SI")])
4941
4942 (define_insn "*lea_1_rex64"
4943   [(set (match_operand:SI 0 "register_operand" "=r")
4944         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4945   "TARGET_64BIT"
4946   "lea{l}\t{%a1, %0|%0, %a1}"
4947   [(set_attr "type" "lea")
4948    (set_attr "mode" "SI")])
4949
4950 (define_insn "*lea_1_zext"
4951   [(set (match_operand:DI 0 "register_operand" "=r")
4952         (zero_extend:DI
4953          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4954   "TARGET_64BIT"
4955   "lea{l}\t{%a1, %k0|%k0, %a1}"
4956   [(set_attr "type" "lea")
4957    (set_attr "mode" "SI")])
4958
4959 (define_insn "*lea_2_rex64"
4960   [(set (match_operand:DI 0 "register_operand" "=r")
4961         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4962   "TARGET_64BIT"
4963   "lea{q}\t{%a1, %0|%0, %a1}"
4964   [(set_attr "type" "lea")
4965    (set_attr "mode" "DI")])
4966
4967 ;; The lea patterns for non-Pmodes needs to be matched by several
4968 ;; insns converted to real lea by splitters.
4969
4970 (define_insn_and_split "*lea_general_1"
4971   [(set (match_operand 0 "register_operand" "=r")
4972         (plus (plus (match_operand 1 "index_register_operand" "l")
4973                     (match_operand 2 "register_operand" "r"))
4974               (match_operand 3 "immediate_operand" "i")))]
4975   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4976     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4977    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4978    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4979    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4980    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981        || GET_MODE (operands[3]) == VOIDmode)"
4982   "#"
4983   "&& reload_completed"
4984   [(const_int 0)]
4985 {
4986   rtx pat;
4987   operands[0] = gen_lowpart (SImode, operands[0]);
4988   operands[1] = gen_lowpart (Pmode, operands[1]);
4989   operands[2] = gen_lowpart (Pmode, operands[2]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4992                       operands[3]);
4993   if (Pmode != SImode)
4994     pat = gen_rtx_SUBREG (SImode, pat, 0);
4995   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996   DONE;
4997 }
4998   [(set_attr "type" "lea")
4999    (set_attr "mode" "SI")])
5000
5001 (define_insn_and_split "*lea_general_1_zext"
5002   [(set (match_operand:DI 0 "register_operand" "=r")
5003         (zero_extend:DI
5004           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5005                             (match_operand:SI 2 "register_operand" "r"))
5006                    (match_operand:SI 3 "immediate_operand" "i"))))]
5007   "TARGET_64BIT"
5008   "#"
5009   "&& reload_completed"
5010   [(set (match_dup 0)
5011         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5012                                                      (match_dup 2))
5013                                             (match_dup 3)) 0)))]
5014 {
5015   operands[1] = gen_lowpart (Pmode, operands[1]);
5016   operands[2] = gen_lowpart (Pmode, operands[2]);
5017   operands[3] = gen_lowpart (Pmode, operands[3]);
5018 }
5019   [(set_attr "type" "lea")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn_and_split "*lea_general_2"
5023   [(set (match_operand 0 "register_operand" "=r")
5024         (plus (mult (match_operand 1 "index_register_operand" "l")
5025                     (match_operand 2 "const248_operand" "i"))
5026               (match_operand 3 "nonmemory_operand" "ri")))]
5027   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5032        || GET_MODE (operands[3]) == VOIDmode)"
5033   "#"
5034   "&& reload_completed"
5035   [(const_int 0)]
5036 {
5037   rtx pat;
5038   operands[0] = gen_lowpart (SImode, operands[0]);
5039   operands[1] = gen_lowpart (Pmode, operands[1]);
5040   operands[3] = gen_lowpart (Pmode, operands[3]);
5041   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5042                       operands[3]);
5043   if (Pmode != SImode)
5044     pat = gen_rtx_SUBREG (SImode, pat, 0);
5045   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5046   DONE;
5047 }
5048   [(set_attr "type" "lea")
5049    (set_attr "mode" "SI")])
5050
5051 (define_insn_and_split "*lea_general_2_zext"
5052   [(set (match_operand:DI 0 "register_operand" "=r")
5053         (zero_extend:DI
5054           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5055                             (match_operand:SI 2 "const248_operand" "n"))
5056                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5057   "TARGET_64BIT"
5058   "#"
5059   "&& reload_completed"
5060   [(set (match_dup 0)
5061         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5062                                                      (match_dup 2))
5063                                             (match_dup 3)) 0)))]
5064 {
5065   operands[1] = gen_lowpart (Pmode, operands[1]);
5066   operands[3] = gen_lowpart (Pmode, operands[3]);
5067 }
5068   [(set_attr "type" "lea")
5069    (set_attr "mode" "SI")])
5070
5071 (define_insn_and_split "*lea_general_3"
5072   [(set (match_operand 0 "register_operand" "=r")
5073         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5074                           (match_operand 2 "const248_operand" "i"))
5075                     (match_operand 3 "register_operand" "r"))
5076               (match_operand 4 "immediate_operand" "i")))]
5077   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5078     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5079    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5080    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5081    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5082   "#"
5083   "&& reload_completed"
5084   [(const_int 0)]
5085 {
5086   rtx pat;
5087   operands[0] = gen_lowpart (SImode, operands[0]);
5088   operands[1] = gen_lowpart (Pmode, operands[1]);
5089   operands[3] = gen_lowpart (Pmode, operands[3]);
5090   operands[4] = gen_lowpart (Pmode, operands[4]);
5091   pat = gen_rtx_PLUS (Pmode,
5092                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5093                                                          operands[2]),
5094                                     operands[3]),
5095                       operands[4]);
5096   if (Pmode != SImode)
5097     pat = gen_rtx_SUBREG (SImode, pat, 0);
5098   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5099   DONE;
5100 }
5101   [(set_attr "type" "lea")
5102    (set_attr "mode" "SI")])
5103
5104 (define_insn_and_split "*lea_general_3_zext"
5105   [(set (match_operand:DI 0 "register_operand" "=r")
5106         (zero_extend:DI
5107           (plus:SI (plus:SI (mult:SI
5108                               (match_operand:SI 1 "index_register_operand" "l")
5109                               (match_operand:SI 2 "const248_operand" "n"))
5110                             (match_operand:SI 3 "register_operand" "r"))
5111                    (match_operand:SI 4 "immediate_operand" "i"))))]
5112   "TARGET_64BIT"
5113   "#"
5114   "&& reload_completed"
5115   [(set (match_dup 0)
5116         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5117                                                               (match_dup 2))
5118                                                      (match_dup 3))
5119                                             (match_dup 4)) 0)))]
5120 {
5121   operands[1] = gen_lowpart (Pmode, operands[1]);
5122   operands[3] = gen_lowpart (Pmode, operands[3]);
5123   operands[4] = gen_lowpart (Pmode, operands[4]);
5124 }
5125   [(set_attr "type" "lea")
5126    (set_attr "mode" "SI")])
5127
5128 (define_insn "*adddi_1_rex64"
5129   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5130         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5131                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5132    (clobber (reg:CC FLAGS_REG))]
5133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134 {
5135   switch (get_attr_type (insn))
5136     {
5137     case TYPE_LEA:
5138       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5139       return "lea{q}\t{%a2, %0|%0, %a2}";
5140
5141     case TYPE_INCDEC:
5142       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5143       if (operands[2] == const1_rtx)
5144         return "inc{q}\t%0";
5145       else
5146         {
5147           gcc_assert (operands[2] == constm1_rtx);
5148           return "dec{q}\t%0";
5149         }
5150
5151     default:
5152       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5153
5154       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5155          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5156       if (GET_CODE (operands[2]) == CONST_INT
5157           /* Avoid overflows.  */
5158           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5159           && (INTVAL (operands[2]) == 128
5160               || (INTVAL (operands[2]) < 0
5161                   && INTVAL (operands[2]) != -128)))
5162         {
5163           operands[2] = GEN_INT (-INTVAL (operands[2]));
5164           return "sub{q}\t{%2, %0|%0, %2}";
5165         }
5166       return "add{q}\t{%2, %0|%0, %2}";
5167     }
5168 }
5169   [(set (attr "type")
5170      (cond [(eq_attr "alternative" "2")
5171               (const_string "lea")
5172             ; Current assemblers are broken and do not allow @GOTOFF in
5173             ; ought but a memory context.
5174             (match_operand:DI 2 "pic_symbolic_operand" "")
5175               (const_string "lea")
5176             (match_operand:DI 2 "incdec_operand" "")
5177               (const_string "incdec")
5178            ]
5179            (const_string "alu")))
5180    (set_attr "mode" "DI")])
5181
5182 ;; Convert lea to the lea pattern to avoid flags dependency.
5183 (define_split
5184   [(set (match_operand:DI 0 "register_operand" "")
5185         (plus:DI (match_operand:DI 1 "register_operand" "")
5186                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5187    (clobber (reg:CC FLAGS_REG))]
5188   "TARGET_64BIT && reload_completed
5189    && true_regnum (operands[0]) != true_regnum (operands[1])"
5190   [(set (match_dup 0)
5191         (plus:DI (match_dup 1)
5192                  (match_dup 2)))]
5193   "")
5194
5195 (define_insn "*adddi_2_rex64"
5196   [(set (reg FLAGS_REG)
5197         (compare
5198           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5199                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5200           (const_int 0)))                       
5201    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5202         (plus:DI (match_dup 1) (match_dup 2)))]
5203   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5204    && ix86_binary_operator_ok (PLUS, DImode, operands)
5205    /* Current assemblers are broken and do not allow @GOTOFF in
5206       ought but a memory context.  */
5207    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208 {
5209   switch (get_attr_type (insn))
5210     {
5211     case TYPE_INCDEC:
5212       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5213       if (operands[2] == const1_rtx)
5214         return "inc{q}\t%0";
5215       else
5216         {
5217           gcc_assert (operands[2] == constm1_rtx);
5218           return "dec{q}\t%0";
5219         }
5220
5221     default:
5222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223       /* ???? We ought to handle there the 32bit case too
5224          - do we need new constraint?  */
5225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5227       if (GET_CODE (operands[2]) == CONST_INT
5228           /* Avoid overflows.  */
5229           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230           && (INTVAL (operands[2]) == 128
5231               || (INTVAL (operands[2]) < 0
5232                   && INTVAL (operands[2]) != -128)))
5233         {
5234           operands[2] = GEN_INT (-INTVAL (operands[2]));
5235           return "sub{q}\t{%2, %0|%0, %2}";
5236         }
5237       return "add{q}\t{%2, %0|%0, %2}";
5238     }
5239 }
5240   [(set (attr "type")
5241      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242         (const_string "incdec")
5243         (const_string "alu")))
5244    (set_attr "mode" "DI")])
5245
5246 (define_insn "*adddi_3_rex64"
5247   [(set (reg FLAGS_REG)
5248         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5249                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5250    (clobber (match_scratch:DI 0 "=r"))]
5251   "TARGET_64BIT
5252    && ix86_match_ccmode (insn, CCZmode)
5253    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5254    /* Current assemblers are broken and do not allow @GOTOFF in
5255       ought but a memory context.  */
5256    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5257 {
5258   switch (get_attr_type (insn))
5259     {
5260     case TYPE_INCDEC:
5261       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262       if (operands[2] == const1_rtx)
5263         return "inc{q}\t%0";
5264       else
5265         {
5266           gcc_assert (operands[2] == constm1_rtx);
5267           return "dec{q}\t%0";
5268         }
5269
5270     default:
5271       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5272       /* ???? We ought to handle there the 32bit case too
5273          - do we need new constraint?  */
5274       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5276       if (GET_CODE (operands[2]) == CONST_INT
5277           /* Avoid overflows.  */
5278           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5279           && (INTVAL (operands[2]) == 128
5280               || (INTVAL (operands[2]) < 0
5281                   && INTVAL (operands[2]) != -128)))
5282         {
5283           operands[2] = GEN_INT (-INTVAL (operands[2]));
5284           return "sub{q}\t{%2, %0|%0, %2}";
5285         }
5286       return "add{q}\t{%2, %0|%0, %2}";
5287     }
5288 }
5289   [(set (attr "type")
5290      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291         (const_string "incdec")
5292         (const_string "alu")))
5293    (set_attr "mode" "DI")])
5294
5295 ; For comparisons against 1, -1 and 128, we may generate better code
5296 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5297 ; is matched then.  We can't accept general immediate, because for
5298 ; case of overflows,  the result is messed up.
5299 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5300 ; when negated.
5301 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5302 ; only for comparisons not depending on it.
5303 (define_insn "*adddi_4_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5306                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5307    (clobber (match_scratch:DI 0 "=rm"))]
5308   "TARGET_64BIT
5309    &&  ix86_match_ccmode (insn, CCGCmode)"
5310 {
5311   switch (get_attr_type (insn))
5312     {
5313     case TYPE_INCDEC:
5314       if (operands[2] == constm1_rtx)
5315         return "inc{q}\t%0";
5316       else
5317         {
5318           gcc_assert (operands[2] == const1_rtx);
5319           return "dec{q}\t%0";
5320         }
5321
5322     default:
5323       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5326       if ((INTVAL (operands[2]) == -128
5327            || (INTVAL (operands[2]) > 0
5328                && INTVAL (operands[2]) != 128))
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5331         return "sub{q}\t{%2, %0|%0, %2}";
5332       operands[2] = GEN_INT (-INTVAL (operands[2]));
5333       return "add{q}\t{%2, %0|%0, %2}";
5334     }
5335 }
5336   [(set (attr "type")
5337      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5338         (const_string "incdec")
5339         (const_string "alu")))
5340    (set_attr "mode" "DI")])
5341
5342 (define_insn "*adddi_5_rex64"
5343   [(set (reg FLAGS_REG)
5344         (compare
5345           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5346                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5347           (const_int 0)))                       
5348    (clobber (match_scratch:DI 0 "=r"))]
5349   "TARGET_64BIT
5350    && ix86_match_ccmode (insn, CCGOCmode)
5351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5352    /* Current assemblers are broken and do not allow @GOTOFF in
5353       ought but a memory context.  */
5354    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5355 {
5356   switch (get_attr_type (insn))
5357     {
5358     case TYPE_INCDEC:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360       if (operands[2] == const1_rtx)
5361         return "inc{q}\t%0";
5362       else
5363         {
5364           gcc_assert (operands[2] == constm1_rtx);
5365           return "dec{q}\t%0";
5366         }
5367
5368     default:
5369       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           /* Avoid overflows.  */
5374           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375           && (INTVAL (operands[2]) == 128
5376               || (INTVAL (operands[2]) < 0
5377                   && INTVAL (operands[2]) != -128)))
5378         {
5379           operands[2] = GEN_INT (-INTVAL (operands[2]));
5380           return "sub{q}\t{%2, %0|%0, %2}";
5381         }
5382       return "add{q}\t{%2, %0|%0, %2}";
5383     }
5384 }
5385   [(set (attr "type")
5386      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387         (const_string "incdec")
5388         (const_string "alu")))
5389    (set_attr "mode" "DI")])
5390
5391
5392 (define_insn "*addsi_1"
5393   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5394         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5395                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5396    (clobber (reg:CC FLAGS_REG))]
5397   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5398 {
5399   switch (get_attr_type (insn))
5400     {
5401     case TYPE_LEA:
5402       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5403       return "lea{l}\t{%a2, %0|%0, %a2}";
5404
5405     case TYPE_INCDEC:
5406       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5407       if (operands[2] == const1_rtx)
5408         return "inc{l}\t%0";
5409       else
5410         {
5411           gcc_assert (operands[2] == constm1_rtx);
5412           return "dec{l}\t%0";
5413         }
5414
5415     default:
5416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417
5418       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5419          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5420       if (GET_CODE (operands[2]) == CONST_INT
5421           && (INTVAL (operands[2]) == 128
5422               || (INTVAL (operands[2]) < 0
5423                   && INTVAL (operands[2]) != -128)))
5424         {
5425           operands[2] = GEN_INT (-INTVAL (operands[2]));
5426           return "sub{l}\t{%2, %0|%0, %2}";
5427         }
5428       return "add{l}\t{%2, %0|%0, %2}";
5429     }
5430 }
5431   [(set (attr "type")
5432      (cond [(eq_attr "alternative" "2")
5433               (const_string "lea")
5434             ; Current assemblers are broken and do not allow @GOTOFF in
5435             ; ought but a memory context.
5436             (match_operand:SI 2 "pic_symbolic_operand" "")
5437               (const_string "lea")
5438             (match_operand:SI 2 "incdec_operand" "")
5439               (const_string "incdec")
5440            ]
5441            (const_string "alu")))
5442    (set_attr "mode" "SI")])
5443
5444 ;; Convert lea to the lea pattern to avoid flags dependency.
5445 (define_split
5446   [(set (match_operand 0 "register_operand" "")
5447         (plus (match_operand 1 "register_operand" "")
5448               (match_operand 2 "nonmemory_operand" "")))
5449    (clobber (reg:CC FLAGS_REG))]
5450   "reload_completed
5451    && true_regnum (operands[0]) != true_regnum (operands[1])"
5452   [(const_int 0)]
5453 {
5454   rtx pat;
5455   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5456      may confuse gen_lowpart.  */
5457   if (GET_MODE (operands[0]) != Pmode)
5458     {
5459       operands[1] = gen_lowpart (Pmode, operands[1]);
5460       operands[2] = gen_lowpart (Pmode, operands[2]);
5461     }
5462   operands[0] = gen_lowpart (SImode, operands[0]);
5463   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5464   if (Pmode != SImode)
5465     pat = gen_rtx_SUBREG (SImode, pat, 0);
5466   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5467   DONE;
5468 })
5469
5470 ;; It may seem that nonimmediate operand is proper one for operand 1.
5471 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5472 ;; we take care in ix86_binary_operator_ok to not allow two memory
5473 ;; operands so proper swapping will be done in reload.  This allow
5474 ;; patterns constructed from addsi_1 to match.
5475 (define_insn "addsi_1_zext"
5476   [(set (match_operand:DI 0 "register_operand" "=r,r")
5477         (zero_extend:DI
5478           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5479                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5480    (clobber (reg:CC FLAGS_REG))]
5481   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482 {
5483   switch (get_attr_type (insn))
5484     {
5485     case TYPE_LEA:
5486       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5487       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5488
5489     case TYPE_INCDEC:
5490       if (operands[2] == const1_rtx)
5491         return "inc{l}\t%k0";
5492       else
5493         {
5494           gcc_assert (operands[2] == constm1_rtx);
5495           return "dec{l}\t%k0";
5496         }
5497
5498     default:
5499       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5501       if (GET_CODE (operands[2]) == CONST_INT
5502           && (INTVAL (operands[2]) == 128
5503               || (INTVAL (operands[2]) < 0
5504                   && INTVAL (operands[2]) != -128)))
5505         {
5506           operands[2] = GEN_INT (-INTVAL (operands[2]));
5507           return "sub{l}\t{%2, %k0|%k0, %2}";
5508         }
5509       return "add{l}\t{%2, %k0|%k0, %2}";
5510     }
5511 }
5512   [(set (attr "type")
5513      (cond [(eq_attr "alternative" "1")
5514               (const_string "lea")
5515             ; Current assemblers are broken and do not allow @GOTOFF in
5516             ; ought but a memory context.
5517             (match_operand:SI 2 "pic_symbolic_operand" "")
5518               (const_string "lea")
5519             (match_operand:SI 2 "incdec_operand" "")
5520               (const_string "incdec")
5521            ]
5522            (const_string "alu")))
5523    (set_attr "mode" "SI")])
5524
5525 ;; Convert lea to the lea pattern to avoid flags dependency.
5526 (define_split
5527   [(set (match_operand:DI 0 "register_operand" "")
5528         (zero_extend:DI
5529           (plus:SI (match_operand:SI 1 "register_operand" "")
5530                    (match_operand:SI 2 "nonmemory_operand" ""))))
5531    (clobber (reg:CC FLAGS_REG))]
5532   "TARGET_64BIT && reload_completed
5533    && true_regnum (operands[0]) != true_regnum (operands[1])"
5534   [(set (match_dup 0)
5535         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5536 {
5537   operands[1] = gen_lowpart (Pmode, operands[1]);
5538   operands[2] = gen_lowpart (Pmode, operands[2]);
5539 })
5540
5541 (define_insn "*addsi_2"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5545                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5546           (const_int 0)))                       
5547    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5548         (plus:SI (match_dup 1) (match_dup 2)))]
5549   "ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5559       if (operands[2] == const1_rtx)
5560         return "inc{l}\t%0";
5561       else
5562         {
5563           gcc_assert (operands[2] == constm1_rtx);
5564           return "dec{l}\t%0";
5565         }
5566
5567     default:
5568       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5569       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5570          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5571       if (GET_CODE (operands[2]) == CONST_INT
5572           && (INTVAL (operands[2]) == 128
5573               || (INTVAL (operands[2]) < 0
5574                   && INTVAL (operands[2]) != -128)))
5575         {
5576           operands[2] = GEN_INT (-INTVAL (operands[2]));
5577           return "sub{l}\t{%2, %0|%0, %2}";
5578         }
5579       return "add{l}\t{%2, %0|%0, %2}";
5580     }
5581 }
5582   [(set (attr "type")
5583      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5584         (const_string "incdec")
5585         (const_string "alu")))
5586    (set_attr "mode" "SI")])
5587
5588 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589 (define_insn "*addsi_2_zext"
5590   [(set (reg FLAGS_REG)
5591         (compare
5592           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5593                    (match_operand:SI 2 "general_operand" "rmni"))
5594           (const_int 0)))                       
5595    (set (match_operand:DI 0 "register_operand" "=r")
5596         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598    && ix86_binary_operator_ok (PLUS, SImode, operands)
5599    /* Current assemblers are broken and do not allow @GOTOFF in
5600       ought but a memory context.  */
5601    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5602 {
5603   switch (get_attr_type (insn))
5604     {
5605     case TYPE_INCDEC:
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%k0";
5608       else
5609         {
5610           gcc_assert (operands[2] == constm1_rtx);
5611           return "dec{l}\t%k0";
5612         }
5613
5614     default:
5615       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5617       if (GET_CODE (operands[2]) == CONST_INT
5618           && (INTVAL (operands[2]) == 128
5619               || (INTVAL (operands[2]) < 0
5620                   && INTVAL (operands[2]) != -128)))
5621         {
5622           operands[2] = GEN_INT (-INTVAL (operands[2]));
5623           return "sub{l}\t{%2, %k0|%k0, %2}";
5624         }
5625       return "add{l}\t{%2, %k0|%k0, %2}";
5626     }
5627 }
5628   [(set (attr "type")
5629      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630         (const_string "incdec")
5631         (const_string "alu")))
5632    (set_attr "mode" "SI")])
5633
5634 (define_insn "*addsi_3"
5635   [(set (reg FLAGS_REG)
5636         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5637                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5638    (clobber (match_scratch:SI 0 "=r"))]
5639   "ix86_match_ccmode (insn, CCZmode)
5640    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5641    /* Current assemblers are broken and do not allow @GOTOFF in
5642       ought but a memory context.  */
5643    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644 {
5645   switch (get_attr_type (insn))
5646     {
5647     case TYPE_INCDEC:
5648       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649       if (operands[2] == const1_rtx)
5650         return "inc{l}\t%0";
5651       else
5652         {
5653           gcc_assert (operands[2] == constm1_rtx);
5654           return "dec{l}\t%0";
5655         }
5656
5657     default:
5658       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %0|%0, %2}";
5668         }
5669       return "add{l}\t{%2, %0|%0, %2}";
5670     }
5671 }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5677
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680   [(set (reg FLAGS_REG)
5681         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5682                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5683    (set (match_operand:DI 0 "register_operand" "=r")
5684         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5685   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5686    && ix86_binary_operator_ok (PLUS, SImode, operands)
5687    /* Current assemblers are broken and do not allow @GOTOFF in
5688       ought but a memory context.  */
5689    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690 {
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (operands[2] == const1_rtx)
5695         return "inc{l}\t%k0";
5696       else
5697         {
5698           gcc_assert (operands[2] == constm1_rtx);
5699           return "dec{l}\t%k0";
5700         }
5701
5702     default:
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if (GET_CODE (operands[2]) == CONST_INT
5706           && (INTVAL (operands[2]) == 128
5707               || (INTVAL (operands[2]) < 0
5708                   && INTVAL (operands[2]) != -128)))
5709         {
5710           operands[2] = GEN_INT (-INTVAL (operands[2]));
5711           return "sub{l}\t{%2, %k0|%k0, %2}";
5712         }
5713       return "add{l}\t{%2, %k0|%k0, %2}";
5714     }
5715 }
5716   [(set (attr "type")
5717      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5718         (const_string "incdec")
5719         (const_string "alu")))
5720    (set_attr "mode" "SI")])
5721
5722 ; For comparisons against 1, -1 and 128, we may generate better code
5723 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5724 ; is matched then.  We can't accept general immediate, because for
5725 ; case of overflows,  the result is messed up.
5726 ; This pattern also don't hold of 0x80000000, since the value overflows
5727 ; when negated.
5728 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5729 ; only for comparisons not depending on it.
5730 (define_insn "*addsi_4"
5731   [(set (reg FLAGS_REG)
5732         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5733                  (match_operand:SI 2 "const_int_operand" "n")))
5734    (clobber (match_scratch:SI 0 "=rm"))]
5735   "ix86_match_ccmode (insn, CCGCmode)
5736    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5737 {
5738   switch (get_attr_type (insn))
5739     {
5740     case TYPE_INCDEC:
5741       if (operands[2] == constm1_rtx)
5742         return "inc{l}\t%0";
5743       else
5744         {
5745           gcc_assert (operands[2] == const1_rtx);
5746           return "dec{l}\t%0";
5747         }
5748
5749     default:
5750       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5753       if ((INTVAL (operands[2]) == -128
5754            || (INTVAL (operands[2]) > 0
5755                && INTVAL (operands[2]) != 128)))
5756         return "sub{l}\t{%2, %0|%0, %2}";
5757       operands[2] = GEN_INT (-INTVAL (operands[2]));
5758       return "add{l}\t{%2, %0|%0, %2}";
5759     }
5760 }
5761   [(set (attr "type")
5762      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5763         (const_string "incdec")
5764         (const_string "alu")))
5765    (set_attr "mode" "SI")])
5766
5767 (define_insn "*addsi_5"
5768   [(set (reg FLAGS_REG)
5769         (compare
5770           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5771                    (match_operand:SI 2 "general_operand" "rmni"))
5772           (const_int 0)))                       
5773    (clobber (match_scratch:SI 0 "=r"))]
5774   "ix86_match_ccmode (insn, CCGOCmode)
5775    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5776    /* Current assemblers are broken and do not allow @GOTOFF in
5777       ought but a memory context.  */
5778    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5779 {
5780   switch (get_attr_type (insn))
5781     {
5782     case TYPE_INCDEC:
5783       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784       if (operands[2] == const1_rtx)
5785         return "inc{l}\t%0";
5786       else
5787         {
5788           gcc_assert (operands[2] == constm1_rtx);
5789           return "dec{l}\t%0";
5790         }
5791
5792     default:
5793       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5795          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5796       if (GET_CODE (operands[2]) == CONST_INT
5797           && (INTVAL (operands[2]) == 128
5798               || (INTVAL (operands[2]) < 0
5799                   && INTVAL (operands[2]) != -128)))
5800         {
5801           operands[2] = GEN_INT (-INTVAL (operands[2]));
5802           return "sub{l}\t{%2, %0|%0, %2}";
5803         }
5804       return "add{l}\t{%2, %0|%0, %2}";
5805     }
5806 }
5807   [(set (attr "type")
5808      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5809         (const_string "incdec")
5810         (const_string "alu")))
5811    (set_attr "mode" "SI")])
5812
5813 (define_expand "addhi3"
5814   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5815                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5816                             (match_operand:HI 2 "general_operand" "")))
5817               (clobber (reg:CC FLAGS_REG))])]
5818   "TARGET_HIMODE_MATH"
5819   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5820
5821 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5822 ;; type optimizations enabled by define-splits.  This is not important
5823 ;; for PII, and in fact harmful because of partial register stalls.
5824
5825 (define_insn "*addhi_1_lea"
5826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5827         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5828                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "!TARGET_PARTIAL_REG_STALL
5831    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832 {
5833   switch (get_attr_type (insn))
5834     {
5835     case TYPE_LEA:
5836       return "#";
5837     case TYPE_INCDEC:
5838       if (operands[2] == const1_rtx)
5839         return "inc{w}\t%0";
5840       else
5841         {
5842           gcc_assert (operands[2] == constm1_rtx);
5843           return "dec{w}\t%0";
5844         }
5845
5846     default:
5847       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5849       if (GET_CODE (operands[2]) == CONST_INT
5850           && (INTVAL (operands[2]) == 128
5851               || (INTVAL (operands[2]) < 0
5852                   && INTVAL (operands[2]) != -128)))
5853         {
5854           operands[2] = GEN_INT (-INTVAL (operands[2]));
5855           return "sub{w}\t{%2, %0|%0, %2}";
5856         }
5857       return "add{w}\t{%2, %0|%0, %2}";
5858     }
5859 }
5860   [(set (attr "type")
5861      (if_then_else (eq_attr "alternative" "2")
5862         (const_string "lea")
5863         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5864            (const_string "incdec")
5865            (const_string "alu"))))
5866    (set_attr "mode" "HI,HI,SI")])
5867
5868 (define_insn "*addhi_1"
5869   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5870         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871                  (match_operand:HI 2 "general_operand" "ri,rm")))
5872    (clobber (reg:CC FLAGS_REG))]
5873   "TARGET_PARTIAL_REG_STALL
5874    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5875 {
5876   switch (get_attr_type (insn))
5877     {
5878     case TYPE_INCDEC:
5879       if (operands[2] == const1_rtx)
5880         return "inc{w}\t%0";
5881       else
5882         {
5883           gcc_assert (operands[2] == constm1_rtx);
5884           return "dec{w}\t%0";
5885         }
5886
5887     default:
5888       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5890       if (GET_CODE (operands[2]) == CONST_INT
5891           && (INTVAL (operands[2]) == 128
5892               || (INTVAL (operands[2]) < 0
5893                   && INTVAL (operands[2]) != -128)))
5894         {
5895           operands[2] = GEN_INT (-INTVAL (operands[2]));
5896           return "sub{w}\t{%2, %0|%0, %2}";
5897         }
5898       return "add{w}\t{%2, %0|%0, %2}";
5899     }
5900 }
5901   [(set (attr "type")
5902      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903         (const_string "incdec")
5904         (const_string "alu")))
5905    (set_attr "mode" "HI")])
5906
5907 (define_insn "*addhi_2"
5908   [(set (reg FLAGS_REG)
5909         (compare
5910           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5912           (const_int 0)))                       
5913    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5914         (plus:HI (match_dup 1) (match_dup 2)))]
5915   "ix86_match_ccmode (insn, CCGOCmode)
5916    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5917 {
5918   switch (get_attr_type (insn))
5919     {
5920     case TYPE_INCDEC:
5921       if (operands[2] == const1_rtx)
5922         return "inc{w}\t%0";
5923       else
5924         {
5925           gcc_assert (operands[2] == constm1_rtx);
5926           return "dec{w}\t%0";
5927         }
5928
5929     default:
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 (GET_CODE (operands[2]) == CONST_INT
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{w}\t{%2, %0|%0, %2}";
5939         }
5940       return "add{w}\t{%2, %0|%0, %2}";
5941     }
5942 }
5943   [(set (attr "type")
5944      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5945         (const_string "incdec")
5946         (const_string "alu")))
5947    (set_attr "mode" "HI")])
5948
5949 (define_insn "*addhi_3"
5950   [(set (reg FLAGS_REG)
5951         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5952                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5953    (clobber (match_scratch:HI 0 "=r"))]
5954   "ix86_match_ccmode (insn, CCZmode)
5955    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5956 {
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_INCDEC:
5960       if (operands[2] == const1_rtx)
5961         return "inc{w}\t%0";
5962       else
5963         {
5964           gcc_assert (operands[2] == constm1_rtx);
5965           return "dec{w}\t%0";
5966         }
5967
5968     default:
5969       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5971       if (GET_CODE (operands[2]) == CONST_INT
5972           && (INTVAL (operands[2]) == 128
5973               || (INTVAL (operands[2]) < 0
5974                   && INTVAL (operands[2]) != -128)))
5975         {
5976           operands[2] = GEN_INT (-INTVAL (operands[2]));
5977           return "sub{w}\t{%2, %0|%0, %2}";
5978         }
5979       return "add{w}\t{%2, %0|%0, %2}";
5980     }
5981 }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu")))
5986    (set_attr "mode" "HI")])
5987
5988 ; See comments above addsi_4 for details.
5989 (define_insn "*addhi_4"
5990   [(set (reg FLAGS_REG)
5991         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5992                  (match_operand:HI 2 "const_int_operand" "n")))
5993    (clobber (match_scratch:HI 0 "=rm"))]
5994   "ix86_match_ccmode (insn, CCGCmode)
5995    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5996 {
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == constm1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == const1_rtx);
6005           return "dec{w}\t%0";
6006         }
6007
6008     default:
6009       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6012       if ((INTVAL (operands[2]) == -128
6013            || (INTVAL (operands[2]) > 0
6014                && INTVAL (operands[2]) != 128)))
6015         return "sub{w}\t{%2, %0|%0, %2}";
6016       operands[2] = GEN_INT (-INTVAL (operands[2]));
6017       return "add{w}\t{%2, %0|%0, %2}";
6018     }
6019 }
6020   [(set (attr "type")
6021      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022         (const_string "incdec")
6023         (const_string "alu")))
6024    (set_attr "mode" "SI")])
6025
6026
6027 (define_insn "*addhi_5"
6028   [(set (reg FLAGS_REG)
6029         (compare
6030           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6031                    (match_operand:HI 2 "general_operand" "rmni"))
6032           (const_int 0)))                       
6033    (clobber (match_scratch:HI 0 "=r"))]
6034   "ix86_match_ccmode (insn, CCGOCmode)
6035    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6036 {
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == const1_rtx)
6041         return "inc{w}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == constm1_rtx);
6045           return "dec{w}\t%0";
6046         }
6047
6048     default:
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if (GET_CODE (operands[2]) == CONST_INT
6052           && (INTVAL (operands[2]) == 128
6053               || (INTVAL (operands[2]) < 0
6054                   && INTVAL (operands[2]) != -128)))
6055         {
6056           operands[2] = GEN_INT (-INTVAL (operands[2]));
6057           return "sub{w}\t{%2, %0|%0, %2}";
6058         }
6059       return "add{w}\t{%2, %0|%0, %2}";
6060     }
6061 }
6062   [(set (attr "type")
6063      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6064         (const_string "incdec")
6065         (const_string "alu")))
6066    (set_attr "mode" "HI")])
6067
6068 (define_expand "addqi3"
6069   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6070                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6071                             (match_operand:QI 2 "general_operand" "")))
6072               (clobber (reg:CC FLAGS_REG))])]
6073   "TARGET_QIMODE_MATH"
6074   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6075
6076 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6077 (define_insn "*addqi_1_lea"
6078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6079         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6080                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "!TARGET_PARTIAL_REG_STALL
6083    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084 {
6085   int widen = (which_alternative == 2);
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_LEA:
6089       return "#";
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6118 }
6119   [(set (attr "type")
6120      (if_then_else (eq_attr "alternative" "3")
6121         (const_string "lea")
6122         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6123            (const_string "incdec")
6124            (const_string "alu"))))
6125    (set_attr "mode" "QI,QI,SI,SI")])
6126
6127 (define_insn "*addqi_1"
6128   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6129         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6130                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6131    (clobber (reg:CC FLAGS_REG))]
6132   "TARGET_PARTIAL_REG_STALL
6133    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6134 {
6135   int widen = (which_alternative == 2);
6136   switch (get_attr_type (insn))
6137     {
6138     case TYPE_INCDEC:
6139       if (operands[2] == const1_rtx)
6140         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6141       else
6142         {
6143           gcc_assert (operands[2] == constm1_rtx);
6144           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6145         }
6146
6147     default:
6148       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6150       if (GET_CODE (operands[2]) == CONST_INT
6151           && (INTVAL (operands[2]) == 128
6152               || (INTVAL (operands[2]) < 0
6153                   && INTVAL (operands[2]) != -128)))
6154         {
6155           operands[2] = GEN_INT (-INTVAL (operands[2]));
6156           if (widen)
6157             return "sub{l}\t{%2, %k0|%k0, %2}";
6158           else
6159             return "sub{b}\t{%2, %0|%0, %2}";
6160         }
6161       if (widen)
6162         return "add{l}\t{%k2, %k0|%k0, %k2}";
6163       else
6164         return "add{b}\t{%2, %0|%0, %2}";
6165     }
6166 }
6167   [(set (attr "type")
6168      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6169         (const_string "incdec")
6170         (const_string "alu")))
6171    (set_attr "mode" "QI,QI,SI")])
6172
6173 (define_insn "*addqi_1_slp"
6174   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6175         (plus:QI (match_dup 0)
6176                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6177    (clobber (reg:CC FLAGS_REG))]
6178   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6179    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6180 {
6181   switch (get_attr_type (insn))
6182     {
6183     case TYPE_INCDEC:
6184       if (operands[1] == const1_rtx)
6185         return "inc{b}\t%0";
6186       else
6187         {
6188           gcc_assert (operands[1] == constm1_rtx);
6189           return "dec{b}\t%0";
6190         }
6191
6192     default:
6193       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6194       if (GET_CODE (operands[1]) == CONST_INT
6195           && INTVAL (operands[1]) < 0)
6196         {
6197           operands[1] = GEN_INT (-INTVAL (operands[1]));
6198           return "sub{b}\t{%1, %0|%0, %1}";
6199         }
6200       return "add{b}\t{%1, %0|%0, %1}";
6201     }
6202 }
6203   [(set (attr "type")
6204      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6205         (const_string "incdec")
6206         (const_string "alu1")))
6207    (set (attr "memory")
6208      (if_then_else (match_operand 1 "memory_operand" "")
6209         (const_string "load")
6210         (const_string "none")))
6211    (set_attr "mode" "QI")])
6212
6213 (define_insn "*addqi_2"
6214   [(set (reg FLAGS_REG)
6215         (compare
6216           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6217                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6218           (const_int 0)))
6219    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6220         (plus:QI (match_dup 1) (match_dup 2)))]
6221   "ix86_match_ccmode (insn, CCGOCmode)
6222    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223 {
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_INCDEC:
6227       if (operands[2] == const1_rtx)
6228         return "inc{b}\t%0";
6229       else
6230         {
6231           gcc_assert (operands[2] == constm1_rtx
6232                       || (GET_CODE (operands[2]) == CONST_INT
6233                           && INTVAL (operands[2]) == 255));
6234           return "dec{b}\t%0";
6235         }
6236
6237     default:
6238       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6239       if (GET_CODE (operands[2]) == CONST_INT
6240           && INTVAL (operands[2]) < 0)
6241         {
6242           operands[2] = GEN_INT (-INTVAL (operands[2]));
6243           return "sub{b}\t{%2, %0|%0, %2}";
6244         }
6245       return "add{b}\t{%2, %0|%0, %2}";
6246     }
6247 }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set_attr "mode" "QI")])
6253
6254 (define_insn "*addqi_3"
6255   [(set (reg FLAGS_REG)
6256         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6257                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6258    (clobber (match_scratch:QI 0 "=q"))]
6259   "ix86_match_ccmode (insn, CCZmode)
6260    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6261 {
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       if (operands[2] == const1_rtx)
6266         return "inc{b}\t%0";
6267       else
6268         {
6269           gcc_assert (operands[2] == constm1_rtx
6270                       || (GET_CODE (operands[2]) == CONST_INT
6271                           && INTVAL (operands[2]) == 255));
6272           return "dec{b}\t%0";
6273         }
6274
6275     default:
6276       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6277       if (GET_CODE (operands[2]) == CONST_INT
6278           && INTVAL (operands[2]) < 0)
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           return "sub{b}\t{%2, %0|%0, %2}";
6282         }
6283       return "add{b}\t{%2, %0|%0, %2}";
6284     }
6285 }
6286   [(set (attr "type")
6287      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288         (const_string "incdec")
6289         (const_string "alu")))
6290    (set_attr "mode" "QI")])
6291
6292 ; See comments above addsi_4 for details.
6293 (define_insn "*addqi_4"
6294   [(set (reg FLAGS_REG)
6295         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6296                  (match_operand:QI 2 "const_int_operand" "n")))
6297    (clobber (match_scratch:QI 0 "=qm"))]
6298   "ix86_match_ccmode (insn, CCGCmode)
6299    && (INTVAL (operands[2]) & 0xff) != 0x80"
6300 {
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == constm1_rtx
6305           || (GET_CODE (operands[2]) == CONST_INT
6306               && INTVAL (operands[2]) == 255))
6307         return "inc{b}\t%0";
6308       else
6309         {
6310           gcc_assert (operands[2] == const1_rtx);
6311           return "dec{b}\t%0";
6312         }
6313
6314     default:
6315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6316       if (INTVAL (operands[2]) < 0)
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           return "add{b}\t{%2, %0|%0, %2}";
6320         }
6321       return "sub{b}\t{%2, %0|%0, %2}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "QI")])
6329
6330
6331 (define_insn "*addqi_5"
6332   [(set (reg FLAGS_REG)
6333         (compare
6334           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6335                    (match_operand:QI 2 "general_operand" "qmni"))
6336           (const_int 0)))
6337    (clobber (match_scratch:QI 0 "=q"))]
6338   "ix86_match_ccmode (insn, CCGOCmode)
6339    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == const1_rtx)
6345         return "inc{b}\t%0";
6346       else
6347         {
6348           gcc_assert (operands[2] == constm1_rtx
6349                       || (GET_CODE (operands[2]) == CONST_INT
6350                           && INTVAL (operands[2]) == 255));
6351           return "dec{b}\t%0";
6352         }
6353
6354     default:
6355       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6356       if (GET_CODE (operands[2]) == CONST_INT
6357           && INTVAL (operands[2]) < 0)
6358         {
6359           operands[2] = GEN_INT (-INTVAL (operands[2]));
6360           return "sub{b}\t{%2, %0|%0, %2}";
6361         }
6362       return "add{b}\t{%2, %0|%0, %2}";
6363     }
6364 }
6365   [(set (attr "type")
6366      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367         (const_string "incdec")
6368         (const_string "alu")))
6369    (set_attr "mode" "QI")])
6370
6371
6372 (define_insn "addqi_ext_1"
6373   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6374                          (const_int 8)
6375                          (const_int 8))
6376         (plus:SI
6377           (zero_extract:SI
6378             (match_operand 1 "ext_register_operand" "0")
6379             (const_int 8)
6380             (const_int 8))
6381           (match_operand:QI 2 "general_operand" "Qmn")))
6382    (clobber (reg:CC FLAGS_REG))]
6383   "!TARGET_64BIT"
6384 {
6385   switch (get_attr_type (insn))
6386     {
6387     case TYPE_INCDEC:
6388       if (operands[2] == const1_rtx)
6389         return "inc{b}\t%h0";
6390       else
6391         {
6392           gcc_assert (operands[2] == constm1_rtx
6393                       || (GET_CODE (operands[2]) == CONST_INT
6394                           && INTVAL (operands[2]) == 255));
6395           return "dec{b}\t%h0";
6396         }
6397
6398     default:
6399       return "add{b}\t{%2, %h0|%h0, %2}";
6400     }
6401 }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set_attr "mode" "QI")])
6407
6408 (define_insn "*addqi_ext_1_rex64"
6409   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6410                          (const_int 8)
6411                          (const_int 8))
6412         (plus:SI
6413           (zero_extract:SI
6414             (match_operand 1 "ext_register_operand" "0")
6415             (const_int 8)
6416             (const_int 8))
6417           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6418    (clobber (reg:CC FLAGS_REG))]
6419   "TARGET_64BIT"
6420 {
6421   switch (get_attr_type (insn))
6422     {
6423     case TYPE_INCDEC:
6424       if (operands[2] == const1_rtx)
6425         return "inc{b}\t%h0";
6426       else
6427         {
6428           gcc_assert (operands[2] == constm1_rtx
6429                       || (GET_CODE (operands[2]) == CONST_INT
6430                           && INTVAL (operands[2]) == 255));
6431           return "dec{b}\t%h0";
6432         }
6433
6434     default:
6435       return "add{b}\t{%2, %h0|%h0, %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")])
6443
6444 (define_insn "*addqi_ext_2"
6445   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6446                          (const_int 8)
6447                          (const_int 8))
6448         (plus:SI
6449           (zero_extract:SI
6450             (match_operand 1 "ext_register_operand" "%0")
6451             (const_int 8)
6452             (const_int 8))
6453           (zero_extract:SI
6454             (match_operand 2 "ext_register_operand" "Q")
6455             (const_int 8)
6456             (const_int 8))))
6457    (clobber (reg:CC FLAGS_REG))]
6458   ""
6459   "add{b}\t{%h2, %h0|%h0, %h2}"
6460   [(set_attr "type" "alu")
6461    (set_attr "mode" "QI")])
6462
6463 ;; The patterns that match these are at the end of this file.
6464
6465 (define_expand "addxf3"
6466   [(set (match_operand:XF 0 "register_operand" "")
6467         (plus:XF (match_operand:XF 1 "register_operand" "")
6468                  (match_operand:XF 2 "register_operand" "")))]
6469   "TARGET_80387"
6470   "")
6471
6472 (define_expand "adddf3"
6473   [(set (match_operand:DF 0 "register_operand" "")
6474         (plus:DF (match_operand:DF 1 "register_operand" "")
6475                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6476   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6477   "")
6478
6479 (define_expand "addsf3"
6480   [(set (match_operand:SF 0 "register_operand" "")
6481         (plus:SF (match_operand:SF 1 "register_operand" "")
6482                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6483   "TARGET_80387 || TARGET_SSE_MATH"
6484   "")
6485 \f
6486 ;; Subtract instructions
6487
6488 ;; %%% splits for subditi3
6489
6490 (define_expand "subti3"
6491   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493                              (match_operand:TI 2 "x86_64_general_operand" "")))
6494               (clobber (reg:CC FLAGS_REG))])]
6495   "TARGET_64BIT"
6496   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6497
6498 (define_insn "*subti3_1"
6499   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6500         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6501                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6504   "#")
6505
6506 (define_split
6507   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6508         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6509                   (match_operand:TI 2 "general_operand" "")))
6510    (clobber (reg:CC FLAGS_REG))]
6511   "TARGET_64BIT && reload_completed"
6512   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6513               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6514    (parallel [(set (match_dup 3)
6515                    (minus:DI (match_dup 4)
6516                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6517                                       (match_dup 5))))
6518               (clobber (reg:CC FLAGS_REG))])]
6519   "split_ti (operands+0, 1, operands+0, operands+3);
6520    split_ti (operands+1, 1, operands+1, operands+4);
6521    split_ti (operands+2, 1, operands+2, operands+5);")
6522
6523 ;; %%% splits for subsidi3
6524
6525 (define_expand "subdi3"
6526   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528                              (match_operand:DI 2 "x86_64_general_operand" "")))
6529               (clobber (reg:CC FLAGS_REG))])]
6530   ""
6531   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6532
6533 (define_insn "*subdi3_1"
6534   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6535         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6539   "#")
6540
6541 (define_split
6542   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6543         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6544                   (match_operand:DI 2 "general_operand" "")))
6545    (clobber (reg:CC FLAGS_REG))]
6546   "!TARGET_64BIT && reload_completed"
6547   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6548               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6549    (parallel [(set (match_dup 3)
6550                    (minus:SI (match_dup 4)
6551                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6552                                       (match_dup 5))))
6553               (clobber (reg:CC FLAGS_REG))])]
6554   "split_di (operands+0, 1, operands+0, operands+3);
6555    split_di (operands+1, 1, operands+1, operands+4);
6556    split_di (operands+2, 1, operands+2, operands+5);")
6557
6558 (define_insn "subdi3_carry_rex64"
6559   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6560           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6565   "sbb{q}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "DI")])
6569
6570 (define_insn "*subdi_1_rex64"
6571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576   "sub{q}\t{%2, %0|%0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "DI")])
6579
6580 (define_insn "*subdi_2_rex64"
6581   [(set (reg FLAGS_REG)
6582         (compare
6583           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6585           (const_int 0)))
6586    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6587         (minus:DI (match_dup 1) (match_dup 2)))]
6588   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6589    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590   "sub{q}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "mode" "DI")])
6593
6594 (define_insn "*subdi_3_rex63"
6595   [(set (reg FLAGS_REG)
6596         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6597                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6598    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599         (minus:DI (match_dup 1) (match_dup 2)))]
6600   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6601    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sub{q}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "mode" "DI")])
6605
6606 (define_insn "subqi3_carry"
6607   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6608           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6609             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6610                (match_operand:QI 2 "general_operand" "qi,qm"))))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6613   "sbb{b}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "pent_pair" "pu")
6616    (set_attr "mode" "QI")])
6617
6618 (define_insn "subhi3_carry"
6619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6620           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6621             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6622                (match_operand:HI 2 "general_operand" "ri,rm"))))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6625   "sbb{w}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "pent_pair" "pu")
6628    (set_attr "mode" "HI")])
6629
6630 (define_insn "subsi3_carry"
6631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6632           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6633             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6634                (match_operand:SI 2 "general_operand" "ri,rm"))))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6637   "sbb{l}\t{%2, %0|%0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "pent_pair" "pu")
6640    (set_attr "mode" "SI")])
6641
6642 (define_insn "subsi3_carry_zext"
6643   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6644           (zero_extend:DI
6645             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6646               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6647                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sbb{l}\t{%2, %k0|%k0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "SI")])
6654
6655 (define_expand "subsi3"
6656   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6657                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6658                              (match_operand:SI 2 "general_operand" "")))
6659               (clobber (reg:CC FLAGS_REG))])]
6660   ""
6661   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6662
6663 (define_insn "*subsi_1"
6664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6665         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6666                   (match_operand:SI 2 "general_operand" "ri,rm")))
6667    (clobber (reg:CC FLAGS_REG))]
6668   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6669   "sub{l}\t{%2, %0|%0, %2}"
6670   [(set_attr "type" "alu")
6671    (set_attr "mode" "SI")])
6672
6673 (define_insn "*subsi_1_zext"
6674   [(set (match_operand:DI 0 "register_operand" "=r")
6675         (zero_extend:DI
6676           (minus:SI (match_operand:SI 1 "register_operand" "0")
6677                     (match_operand:SI 2 "general_operand" "rim"))))
6678    (clobber (reg:CC FLAGS_REG))]
6679   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6680   "sub{l}\t{%2, %k0|%k0, %2}"
6681   [(set_attr "type" "alu")
6682    (set_attr "mode" "SI")])
6683
6684 (define_insn "*subsi_2"
6685   [(set (reg FLAGS_REG)
6686         (compare
6687           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688                     (match_operand:SI 2 "general_operand" "ri,rm"))
6689           (const_int 0)))
6690    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6691         (minus:SI (match_dup 1) (match_dup 2)))]
6692   "ix86_match_ccmode (insn, CCGOCmode)
6693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6697
6698 (define_insn "*subsi_2_zext"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (minus:SI (match_operand:SI 1 "register_operand" "0")
6702                     (match_operand:SI 2 "general_operand" "rim"))
6703           (const_int 0)))
6704    (set (match_operand:DI 0 "register_operand" "=r")
6705         (zero_extend:DI
6706           (minus:SI (match_dup 1)
6707                     (match_dup 2))))]
6708   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710   "sub{l}\t{%2, %k0|%k0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "SI")])
6713
6714 (define_insn "*subsi_3"
6715   [(set (reg FLAGS_REG)
6716         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6717                  (match_operand:SI 2 "general_operand" "ri,rm")))
6718    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6719         (minus:SI (match_dup 1) (match_dup 2)))]
6720   "ix86_match_ccmode (insn, CCmode)
6721    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722   "sub{l}\t{%2, %0|%0, %2}"
6723   [(set_attr "type" "alu")
6724    (set_attr "mode" "SI")])
6725
6726 (define_insn "*subsi_3_zext"
6727   [(set (reg FLAGS_REG)
6728         (compare (match_operand:SI 1 "register_operand" "0")
6729                  (match_operand:SI 2 "general_operand" "rim")))
6730    (set (match_operand:DI 0 "register_operand" "=r")
6731         (zero_extend:DI
6732           (minus:SI (match_dup 1)
6733                     (match_dup 2))))]
6734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6735    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736   "sub{l}\t{%2, %1|%1, %2}"
6737   [(set_attr "type" "alu")
6738    (set_attr "mode" "DI")])
6739
6740 (define_expand "subhi3"
6741   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6742                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6743                              (match_operand:HI 2 "general_operand" "")))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   "TARGET_HIMODE_MATH"
6746   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6747
6748 (define_insn "*subhi_1"
6749   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6751                   (match_operand:HI 2 "general_operand" "ri,rm")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6754   "sub{w}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "HI")])
6757
6758 (define_insn "*subhi_2"
6759   [(set (reg FLAGS_REG)
6760         (compare
6761           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6762                     (match_operand:HI 2 "general_operand" "ri,rm"))
6763           (const_int 0)))
6764    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6765         (minus:HI (match_dup 1) (match_dup 2)))]
6766   "ix86_match_ccmode (insn, CCGOCmode)
6767    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6768   "sub{w}\t{%2, %0|%0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "mode" "HI")])
6771
6772 (define_insn "*subhi_3"
6773   [(set (reg FLAGS_REG)
6774         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6775                  (match_operand:HI 2 "general_operand" "ri,rm")))
6776    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6777         (minus:HI (match_dup 1) (match_dup 2)))]
6778   "ix86_match_ccmode (insn, CCmode)
6779    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6780   "sub{w}\t{%2, %0|%0, %2}"
6781   [(set_attr "type" "alu")
6782    (set_attr "mode" "HI")])
6783
6784 (define_expand "subqi3"
6785   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6786                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6787                              (match_operand:QI 2 "general_operand" "")))
6788               (clobber (reg:CC FLAGS_REG))])]
6789   "TARGET_QIMODE_MATH"
6790   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6791
6792 (define_insn "*subqi_1"
6793   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6794         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6795                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6796    (clobber (reg:CC FLAGS_REG))]
6797   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6798   "sub{b}\t{%2, %0|%0, %2}"
6799   [(set_attr "type" "alu")
6800    (set_attr "mode" "QI")])
6801
6802 (define_insn "*subqi_1_slp"
6803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804         (minus:QI (match_dup 0)
6805                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6809   "sub{b}\t{%1, %0|%0, %1}"
6810   [(set_attr "type" "alu1")
6811    (set_attr "mode" "QI")])
6812
6813 (define_insn "*subqi_2"
6814   [(set (reg FLAGS_REG)
6815         (compare
6816           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817                     (match_operand:QI 2 "general_operand" "qi,qm"))
6818           (const_int 0)))
6819    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6820         (minus:HI (match_dup 1) (match_dup 2)))]
6821   "ix86_match_ccmode (insn, CCGOCmode)
6822    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6823   "sub{b}\t{%2, %0|%0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "mode" "QI")])
6826
6827 (define_insn "*subqi_3"
6828   [(set (reg FLAGS_REG)
6829         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6830                  (match_operand:QI 2 "general_operand" "qi,qm")))
6831    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6832         (minus:HI (match_dup 1) (match_dup 2)))]
6833   "ix86_match_ccmode (insn, CCmode)
6834    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6835   "sub{b}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "QI")])
6838
6839 ;; The patterns that match these are at the end of this file.
6840
6841 (define_expand "subxf3"
6842   [(set (match_operand:XF 0 "register_operand" "")
6843         (minus:XF (match_operand:XF 1 "register_operand" "")
6844                   (match_operand:XF 2 "register_operand" "")))]
6845   "TARGET_80387"
6846   "")
6847
6848 (define_expand "subdf3"
6849   [(set (match_operand:DF 0 "register_operand" "")
6850         (minus:DF (match_operand:DF 1 "register_operand" "")
6851                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6852   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6853   "")
6854
6855 (define_expand "subsf3"
6856   [(set (match_operand:SF 0 "register_operand" "")
6857         (minus:SF (match_operand:SF 1 "register_operand" "")
6858                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6859   "TARGET_80387 || TARGET_SSE_MATH"
6860   "")
6861 \f
6862 ;; Multiply instructions
6863
6864 (define_expand "muldi3"
6865   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6866                    (mult:DI (match_operand:DI 1 "register_operand" "")
6867                             (match_operand:DI 2 "x86_64_general_operand" "")))
6868               (clobber (reg:CC FLAGS_REG))])]
6869   "TARGET_64BIT"
6870   "")
6871
6872 (define_insn "*muldi3_1_rex64"
6873   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6874         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6875                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6876    (clobber (reg:CC FLAGS_REG))]
6877   "TARGET_64BIT
6878    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6879   "@
6880    imul{q}\t{%2, %1, %0|%0, %1, %2}
6881    imul{q}\t{%2, %1, %0|%0, %1, %2}
6882    imul{q}\t{%2, %0|%0, %2}"
6883   [(set_attr "type" "imul")
6884    (set_attr "prefix_0f" "0,0,1")
6885    (set (attr "athlon_decode")
6886         (cond [(eq_attr "cpu" "athlon")
6887                   (const_string "vector")
6888                (eq_attr "alternative" "1")
6889                   (const_string "vector")
6890                (and (eq_attr "alternative" "2")
6891                     (match_operand 1 "memory_operand" ""))
6892                   (const_string "vector")]
6893               (const_string "direct")))
6894    (set_attr "mode" "DI")])
6895
6896 (define_expand "mulsi3"
6897   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6898                    (mult:SI (match_operand:SI 1 "register_operand" "")
6899                             (match_operand:SI 2 "general_operand" "")))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   ""
6902   "")
6903
6904 (define_insn "*mulsi3_1"
6905   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6906         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6907                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6910   "@
6911    imul{l}\t{%2, %1, %0|%0, %1, %2}
6912    imul{l}\t{%2, %1, %0|%0, %1, %2}
6913    imul{l}\t{%2, %0|%0, %2}"
6914   [(set_attr "type" "imul")
6915    (set_attr "prefix_0f" "0,0,1")
6916    (set (attr "athlon_decode")
6917         (cond [(eq_attr "cpu" "athlon")
6918                   (const_string "vector")
6919                (eq_attr "alternative" "1")
6920                   (const_string "vector")
6921                (and (eq_attr "alternative" "2")
6922                     (match_operand 1 "memory_operand" ""))
6923                   (const_string "vector")]
6924               (const_string "direct")))
6925    (set_attr "mode" "SI")])
6926
6927 (define_insn "*mulsi3_1_zext"
6928   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6929         (zero_extend:DI
6930           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6931                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "TARGET_64BIT
6934    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935   "@
6936    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6937    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6938    imul{l}\t{%2, %k0|%k0, %2}"
6939   [(set_attr "type" "imul")
6940    (set_attr "prefix_0f" "0,0,1")
6941    (set (attr "athlon_decode")
6942         (cond [(eq_attr "cpu" "athlon")
6943                   (const_string "vector")
6944                (eq_attr "alternative" "1")
6945                   (const_string "vector")
6946                (and (eq_attr "alternative" "2")
6947                     (match_operand 1 "memory_operand" ""))
6948                   (const_string "vector")]
6949               (const_string "direct")))
6950    (set_attr "mode" "SI")])
6951
6952 (define_expand "mulhi3"
6953   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6954                    (mult:HI (match_operand:HI 1 "register_operand" "")
6955                             (match_operand:HI 2 "general_operand" "")))
6956               (clobber (reg:CC FLAGS_REG))])]
6957   "TARGET_HIMODE_MATH"
6958   "")
6959
6960 (define_insn "*mulhi3_1"
6961   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6962         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6963                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6966   "@
6967    imul{w}\t{%2, %1, %0|%0, %1, %2}
6968    imul{w}\t{%2, %1, %0|%0, %1, %2}
6969    imul{w}\t{%2, %0|%0, %2}"
6970   [(set_attr "type" "imul")
6971    (set_attr "prefix_0f" "0,0,1")
6972    (set (attr "athlon_decode")
6973         (cond [(eq_attr "cpu" "athlon")
6974                   (const_string "vector")
6975                (eq_attr "alternative" "1,2")
6976                   (const_string "vector")]
6977               (const_string "direct")))
6978    (set_attr "mode" "HI")])
6979
6980 (define_expand "mulqi3"
6981   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6982                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6983                             (match_operand:QI 2 "register_operand" "")))
6984               (clobber (reg:CC FLAGS_REG))])]
6985   "TARGET_QIMODE_MATH"
6986   "")
6987
6988 (define_insn "*mulqi3_1"
6989   [(set (match_operand:QI 0 "register_operand" "=a")
6990         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6991                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6992    (clobber (reg:CC FLAGS_REG))]
6993   "TARGET_QIMODE_MATH
6994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995   "mul{b}\t%2"
6996   [(set_attr "type" "imul")
6997    (set_attr "length_immediate" "0")
6998    (set (attr "athlon_decode")
6999      (if_then_else (eq_attr "cpu" "athlon")
7000         (const_string "vector")
7001         (const_string "direct")))
7002    (set_attr "mode" "QI")])
7003
7004 (define_expand "umulqihi3"
7005   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7006                    (mult:HI (zero_extend:HI
7007                               (match_operand:QI 1 "nonimmediate_operand" ""))
7008                             (zero_extend:HI
7009                               (match_operand:QI 2 "register_operand" ""))))
7010               (clobber (reg:CC FLAGS_REG))])]
7011   "TARGET_QIMODE_MATH"
7012   "")
7013
7014 (define_insn "*umulqihi3_1"
7015   [(set (match_operand:HI 0 "register_operand" "=a")
7016         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7017                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7018    (clobber (reg:CC FLAGS_REG))]
7019   "TARGET_QIMODE_MATH
7020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021   "mul{b}\t%2"
7022   [(set_attr "type" "imul")
7023    (set_attr "length_immediate" "0")
7024    (set (attr "athlon_decode")
7025      (if_then_else (eq_attr "cpu" "athlon")
7026         (const_string "vector")
7027         (const_string "direct")))
7028    (set_attr "mode" "QI")])
7029
7030 (define_expand "mulqihi3"
7031   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7032                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7033                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7034               (clobber (reg:CC FLAGS_REG))])]
7035   "TARGET_QIMODE_MATH"
7036   "")
7037
7038 (define_insn "*mulqihi3_insn"
7039   [(set (match_operand:HI 0 "register_operand" "=a")
7040         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7041                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7042    (clobber (reg:CC FLAGS_REG))]
7043   "TARGET_QIMODE_MATH
7044    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7045   "imul{b}\t%2"
7046   [(set_attr "type" "imul")
7047    (set_attr "length_immediate" "0")
7048    (set (attr "athlon_decode")
7049      (if_then_else (eq_attr "cpu" "athlon")
7050         (const_string "vector")
7051         (const_string "direct")))
7052    (set_attr "mode" "QI")])
7053
7054 (define_expand "umulditi3"
7055   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7056                    (mult:TI (zero_extend:TI
7057                               (match_operand:DI 1 "nonimmediate_operand" ""))
7058                             (zero_extend:TI
7059                               (match_operand:DI 2 "register_operand" ""))))
7060               (clobber (reg:CC FLAGS_REG))])]
7061   "TARGET_64BIT"
7062   "")
7063
7064 (define_insn "*umulditi3_insn"
7065   [(set (match_operand:TI 0 "register_operand" "=A")
7066         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7067                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "TARGET_64BIT
7070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071   "mul{q}\t%2"
7072   [(set_attr "type" "imul")
7073    (set_attr "length_immediate" "0")
7074    (set (attr "athlon_decode")
7075      (if_then_else (eq_attr "cpu" "athlon")
7076         (const_string "vector")
7077         (const_string "double")))
7078    (set_attr "mode" "DI")])
7079
7080 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7081 (define_expand "umulsidi3"
7082   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7083                    (mult:DI (zero_extend:DI
7084                               (match_operand:SI 1 "nonimmediate_operand" ""))
7085                             (zero_extend:DI
7086                               (match_operand:SI 2 "register_operand" ""))))
7087               (clobber (reg:CC FLAGS_REG))])]
7088   "!TARGET_64BIT"
7089   "")
7090
7091 (define_insn "*umulsidi3_insn"
7092   [(set (match_operand:DI 0 "register_operand" "=A")
7093         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7094                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7095    (clobber (reg:CC FLAGS_REG))]
7096   "!TARGET_64BIT
7097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7098   "mul{l}\t%2"
7099   [(set_attr "type" "imul")
7100    (set_attr "length_immediate" "0")
7101    (set (attr "athlon_decode")
7102      (if_then_else (eq_attr "cpu" "athlon")
7103         (const_string "vector")
7104         (const_string "double")))
7105    (set_attr "mode" "SI")])
7106
7107 (define_expand "mulditi3"
7108   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109                    (mult:TI (sign_extend:TI
7110                               (match_operand:DI 1 "nonimmediate_operand" ""))
7111                             (sign_extend:TI
7112                               (match_operand:DI 2 "register_operand" ""))))
7113               (clobber (reg:CC FLAGS_REG))])]
7114   "TARGET_64BIT"
7115   "")
7116
7117 (define_insn "*mulditi3_insn"
7118   [(set (match_operand:TI 0 "register_operand" "=A")
7119         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "TARGET_64BIT
7123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7124   "imul{q}\t%2"
7125   [(set_attr "type" "imul")
7126    (set_attr "length_immediate" "0")
7127    (set (attr "athlon_decode")
7128      (if_then_else (eq_attr "cpu" "athlon")
7129         (const_string "vector")
7130         (const_string "double")))
7131    (set_attr "mode" "DI")])
7132
7133 (define_expand "mulsidi3"
7134   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7135                    (mult:DI (sign_extend:DI
7136                               (match_operand:SI 1 "nonimmediate_operand" ""))
7137                             (sign_extend:DI
7138                               (match_operand:SI 2 "register_operand" ""))))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   "!TARGET_64BIT"
7141   "")
7142
7143 (define_insn "*mulsidi3_insn"
7144   [(set (match_operand:DI 0 "register_operand" "=A")
7145         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7146                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7147    (clobber (reg:CC FLAGS_REG))]
7148   "!TARGET_64BIT
7149    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7150   "imul{l}\t%2"
7151   [(set_attr "type" "imul")
7152    (set_attr "length_immediate" "0")
7153    (set (attr "athlon_decode")
7154      (if_then_else (eq_attr "cpu" "athlon")
7155         (const_string "vector")
7156         (const_string "double")))
7157    (set_attr "mode" "SI")])
7158
7159 (define_expand "umuldi3_highpart"
7160   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7161                    (truncate:DI
7162                      (lshiftrt:TI
7163                        (mult:TI (zero_extend:TI
7164                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7165                                 (zero_extend:TI
7166                                   (match_operand:DI 2 "register_operand" "")))
7167                        (const_int 64))))
7168               (clobber (match_scratch:DI 3 ""))
7169               (clobber (reg:CC FLAGS_REG))])]
7170   "TARGET_64BIT"
7171   "")
7172
7173 (define_insn "*umuldi3_highpart_rex64"
7174   [(set (match_operand:DI 0 "register_operand" "=d")
7175         (truncate:DI
7176           (lshiftrt:TI
7177             (mult:TI (zero_extend:TI
7178                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7179                      (zero_extend:TI
7180                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7181             (const_int 64))))
7182    (clobber (match_scratch:DI 3 "=1"))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "TARGET_64BIT
7185    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186   "mul{q}\t%2"
7187   [(set_attr "type" "imul")
7188    (set_attr "length_immediate" "0")
7189    (set (attr "athlon_decode")
7190      (if_then_else (eq_attr "cpu" "athlon")
7191         (const_string "vector")
7192         (const_string "double")))
7193    (set_attr "mode" "DI")])
7194
7195 (define_expand "umulsi3_highpart"
7196   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7197                    (truncate:SI
7198                      (lshiftrt:DI
7199                        (mult:DI (zero_extend:DI
7200                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7201                                 (zero_extend:DI
7202                                   (match_operand:SI 2 "register_operand" "")))
7203                        (const_int 32))))
7204               (clobber (match_scratch:SI 3 ""))
7205               (clobber (reg:CC FLAGS_REG))])]
7206   ""
7207   "")
7208
7209 (define_insn "*umulsi3_highpart_insn"
7210   [(set (match_operand:SI 0 "register_operand" "=d")
7211         (truncate:SI
7212           (lshiftrt:DI
7213             (mult:DI (zero_extend:DI
7214                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7215                      (zero_extend:DI
7216                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7217             (const_int 32))))
7218    (clobber (match_scratch:SI 3 "=1"))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7221   "mul{l}\t%2"
7222   [(set_attr "type" "imul")
7223    (set_attr "length_immediate" "0")
7224    (set (attr "athlon_decode")
7225      (if_then_else (eq_attr "cpu" "athlon")
7226         (const_string "vector")
7227         (const_string "double")))
7228    (set_attr "mode" "SI")])
7229
7230 (define_insn "*umulsi3_highpart_zext"
7231   [(set (match_operand:DI 0 "register_operand" "=d")
7232         (zero_extend:DI (truncate:SI
7233           (lshiftrt:DI
7234             (mult:DI (zero_extend:DI
7235                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7236                      (zero_extend:DI
7237                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7238             (const_int 32)))))
7239    (clobber (match_scratch:SI 3 "=1"))
7240    (clobber (reg:CC FLAGS_REG))]
7241   "TARGET_64BIT
7242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7243   "mul{l}\t%2"
7244   [(set_attr "type" "imul")
7245    (set_attr "length_immediate" "0")
7246    (set (attr "athlon_decode")
7247      (if_then_else (eq_attr "cpu" "athlon")
7248         (const_string "vector")
7249         (const_string "double")))
7250    (set_attr "mode" "SI")])
7251
7252 (define_expand "smuldi3_highpart"
7253   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7254                    (truncate:DI
7255                      (lshiftrt:TI
7256                        (mult:TI (sign_extend:TI
7257                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7258                                 (sign_extend:TI
7259                                   (match_operand:DI 2 "register_operand" "")))
7260                        (const_int 64))))
7261               (clobber (match_scratch:DI 3 ""))
7262               (clobber (reg:CC FLAGS_REG))])]
7263   "TARGET_64BIT"
7264   "")
7265
7266 (define_insn "*smuldi3_highpart_rex64"
7267   [(set (match_operand:DI 0 "register_operand" "=d")
7268         (truncate:DI
7269           (lshiftrt:TI
7270             (mult:TI (sign_extend:TI
7271                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7272                      (sign_extend:TI
7273                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7274             (const_int 64))))
7275    (clobber (match_scratch:DI 3 "=1"))
7276    (clobber (reg:CC FLAGS_REG))]
7277   "TARGET_64BIT
7278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7279   "imul{q}\t%2"
7280   [(set_attr "type" "imul")
7281    (set (attr "athlon_decode")
7282      (if_then_else (eq_attr "cpu" "athlon")
7283         (const_string "vector")
7284         (const_string "double")))
7285    (set_attr "mode" "DI")])
7286
7287 (define_expand "smulsi3_highpart"
7288   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7289                    (truncate:SI
7290                      (lshiftrt:DI
7291                        (mult:DI (sign_extend:DI
7292                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7293                                 (sign_extend:DI
7294                                   (match_operand:SI 2 "register_operand" "")))
7295                        (const_int 32))))
7296               (clobber (match_scratch:SI 3 ""))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   ""
7299   "")
7300
7301 (define_insn "*smulsi3_highpart_insn"
7302   [(set (match_operand:SI 0 "register_operand" "=d")
7303         (truncate:SI
7304           (lshiftrt:DI
7305             (mult:DI (sign_extend:DI
7306                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7307                      (sign_extend:DI
7308                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7309             (const_int 32))))
7310    (clobber (match_scratch:SI 3 "=1"))
7311    (clobber (reg:CC FLAGS_REG))]
7312   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7313   "imul{l}\t%2"
7314   [(set_attr "type" "imul")
7315    (set (attr "athlon_decode")
7316      (if_then_else (eq_attr "cpu" "athlon")
7317         (const_string "vector")
7318         (const_string "double")))
7319    (set_attr "mode" "SI")])
7320
7321 (define_insn "*smulsi3_highpart_zext"
7322   [(set (match_operand:DI 0 "register_operand" "=d")
7323         (zero_extend:DI (truncate:SI
7324           (lshiftrt:DI
7325             (mult:DI (sign_extend:DI
7326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7327                      (sign_extend:DI
7328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7329             (const_int 32)))))
7330    (clobber (match_scratch:SI 3 "=1"))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_64BIT
7333    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7334   "imul{l}\t%2"
7335   [(set_attr "type" "imul")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7341
7342 ;; The patterns that match these are at the end of this file.
7343
7344 (define_expand "mulxf3"
7345   [(set (match_operand:XF 0 "register_operand" "")
7346         (mult:XF (match_operand:XF 1 "register_operand" "")
7347                  (match_operand:XF 2 "register_operand" "")))]
7348   "TARGET_80387"
7349   "")
7350
7351 (define_expand "muldf3"
7352   [(set (match_operand:DF 0 "register_operand" "")
7353         (mult:DF (match_operand:DF 1 "register_operand" "")
7354                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7355   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7356   "")
7357
7358 (define_expand "mulsf3"
7359   [(set (match_operand:SF 0 "register_operand" "")
7360         (mult:SF (match_operand:SF 1 "register_operand" "")
7361                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7362   "TARGET_80387 || TARGET_SSE_MATH"
7363   "")
7364 \f
7365 ;; Divide instructions
7366
7367 (define_insn "divqi3"
7368   [(set (match_operand:QI 0 "register_operand" "=a")
7369         (div:QI (match_operand:HI 1 "register_operand" "0")
7370                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "TARGET_QIMODE_MATH"
7373   "idiv{b}\t%2"
7374   [(set_attr "type" "idiv")
7375    (set_attr "mode" "QI")])
7376
7377 (define_insn "udivqi3"
7378   [(set (match_operand:QI 0 "register_operand" "=a")
7379         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7380                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "TARGET_QIMODE_MATH"
7383   "div{b}\t%2"
7384   [(set_attr "type" "idiv")
7385    (set_attr "mode" "QI")])
7386
7387 ;; The patterns that match these are at the end of this file.
7388
7389 (define_expand "divxf3"
7390   [(set (match_operand:XF 0 "register_operand" "")
7391         (div:XF (match_operand:XF 1 "register_operand" "")
7392                 (match_operand:XF 2 "register_operand" "")))]
7393   "TARGET_80387"
7394   "")
7395
7396 (define_expand "divdf3"
7397   [(set (match_operand:DF 0 "register_operand" "")
7398         (div:DF (match_operand:DF 1 "register_operand" "")
7399                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7400    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7401    "")
7402  
7403 (define_expand "divsf3"
7404   [(set (match_operand:SF 0 "register_operand" "")
7405         (div:SF (match_operand:SF 1 "register_operand" "")
7406                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7407   "TARGET_80387 || TARGET_SSE_MATH"
7408   "")
7409 \f
7410 ;; Remainder instructions.
7411
7412 (define_expand "divmoddi4"
7413   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7414                    (div:DI (match_operand:DI 1 "register_operand" "")
7415                            (match_operand:DI 2 "nonimmediate_operand" "")))
7416               (set (match_operand:DI 3 "register_operand" "")
7417                    (mod:DI (match_dup 1) (match_dup 2)))
7418               (clobber (reg:CC FLAGS_REG))])]
7419   "TARGET_64BIT"
7420   "")
7421
7422 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7423 ;; Penalize eax case slightly because it results in worse scheduling
7424 ;; of code.
7425 (define_insn "*divmoddi4_nocltd_rex64"
7426   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7427         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7428                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7429    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7430         (mod:DI (match_dup 2) (match_dup 3)))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7433   "#"
7434   [(set_attr "type" "multi")])
7435
7436 (define_insn "*divmoddi4_cltd_rex64"
7437   [(set (match_operand:DI 0 "register_operand" "=a")
7438         (div:DI (match_operand:DI 2 "register_operand" "a")
7439                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7440    (set (match_operand:DI 1 "register_operand" "=&d")
7441         (mod:DI (match_dup 2) (match_dup 3)))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7444   "#"
7445   [(set_attr "type" "multi")])
7446
7447 (define_insn "*divmoddi_noext_rex64"
7448   [(set (match_operand:DI 0 "register_operand" "=a")
7449         (div:DI (match_operand:DI 1 "register_operand" "0")
7450                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7451    (set (match_operand:DI 3 "register_operand" "=d")
7452         (mod:DI (match_dup 1) (match_dup 2)))
7453    (use (match_operand:DI 4 "register_operand" "3"))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_64BIT"
7456   "idiv{q}\t%2"
7457   [(set_attr "type" "idiv")
7458    (set_attr "mode" "DI")])
7459
7460 (define_split
7461   [(set (match_operand:DI 0 "register_operand" "")
7462         (div:DI (match_operand:DI 1 "register_operand" "")
7463                 (match_operand:DI 2 "nonimmediate_operand" "")))
7464    (set (match_operand:DI 3 "register_operand" "")
7465         (mod:DI (match_dup 1) (match_dup 2)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "TARGET_64BIT && reload_completed"
7468   [(parallel [(set (match_dup 3)
7469                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7470               (clobber (reg:CC FLAGS_REG))])
7471    (parallel [(set (match_dup 0)
7472                    (div:DI (reg:DI 0) (match_dup 2)))
7473               (set (match_dup 3)
7474                    (mod:DI (reg:DI 0) (match_dup 2)))
7475               (use (match_dup 3))
7476               (clobber (reg:CC FLAGS_REG))])]
7477 {
7478   /* Avoid use of cltd in favor of a mov+shift.  */
7479   if (!TARGET_USE_CLTD && !optimize_size)
7480     {
7481       if (true_regnum (operands[1]))
7482         emit_move_insn (operands[0], operands[1]);
7483       else
7484         emit_move_insn (operands[3], operands[1]);
7485       operands[4] = operands[3];
7486     }
7487   else
7488     {
7489       gcc_assert (!true_regnum (operands[1]));
7490       operands[4] = operands[1];
7491     }
7492 })
7493
7494
7495 (define_expand "divmodsi4"
7496   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7497                    (div:SI (match_operand:SI 1 "register_operand" "")
7498                            (match_operand:SI 2 "nonimmediate_operand" "")))
7499               (set (match_operand:SI 3 "register_operand" "")
7500                    (mod:SI (match_dup 1) (match_dup 2)))
7501               (clobber (reg:CC FLAGS_REG))])]
7502   ""
7503   "")
7504
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmodsi4_nocltd"
7509   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7510         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7511                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7512    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7513         (mod:SI (match_dup 2) (match_dup 3)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "!optimize_size && !TARGET_USE_CLTD"
7516   "#"
7517   [(set_attr "type" "multi")])
7518
7519 (define_insn "*divmodsi4_cltd"
7520   [(set (match_operand:SI 0 "register_operand" "=a")
7521         (div:SI (match_operand:SI 2 "register_operand" "a")
7522                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7523    (set (match_operand:SI 1 "register_operand" "=&d")
7524         (mod:SI (match_dup 2) (match_dup 3)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "optimize_size || TARGET_USE_CLTD"
7527   "#"
7528   [(set_attr "type" "multi")])
7529
7530 (define_insn "*divmodsi_noext"
7531   [(set (match_operand:SI 0 "register_operand" "=a")
7532         (div:SI (match_operand:SI 1 "register_operand" "0")
7533                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:SI 3 "register_operand" "=d")
7535         (mod:SI (match_dup 1) (match_dup 2)))
7536    (use (match_operand:SI 4 "register_operand" "3"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   ""
7539   "idiv{l}\t%2"
7540   [(set_attr "type" "idiv")
7541    (set_attr "mode" "SI")])
7542
7543 (define_split
7544   [(set (match_operand:SI 0 "register_operand" "")
7545         (div:SI (match_operand:SI 1 "register_operand" "")
7546                 (match_operand:SI 2 "nonimmediate_operand" "")))
7547    (set (match_operand:SI 3 "register_operand" "")
7548         (mod:SI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "reload_completed"
7551   [(parallel [(set (match_dup 3)
7552                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7553               (clobber (reg:CC FLAGS_REG))])
7554    (parallel [(set (match_dup 0)
7555                    (div:SI (reg:SI 0) (match_dup 2)))
7556               (set (match_dup 3)
7557                    (mod:SI (reg:SI 0) (match_dup 2)))
7558               (use (match_dup 3))
7559               (clobber (reg:CC FLAGS_REG))])]
7560 {
7561   /* Avoid use of cltd in favor of a mov+shift.  */
7562   if (!TARGET_USE_CLTD && !optimize_size)
7563     {
7564       if (true_regnum (operands[1]))
7565         emit_move_insn (operands[0], operands[1]);
7566       else
7567         emit_move_insn (operands[3], operands[1]);
7568       operands[4] = operands[3];
7569     }
7570   else
7571     {
7572       gcc_assert (!true_regnum (operands[1]));
7573       operands[4] = operands[1];
7574     }
7575 })
7576 ;; %%% Split me.
7577 (define_insn "divmodhi4"
7578   [(set (match_operand:HI 0 "register_operand" "=a")
7579         (div:HI (match_operand:HI 1 "register_operand" "0")
7580                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7581    (set (match_operand:HI 3 "register_operand" "=&d")
7582         (mod:HI (match_dup 1) (match_dup 2)))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "TARGET_HIMODE_MATH"
7585   "cwtd\;idiv{w}\t%2"
7586   [(set_attr "type" "multi")
7587    (set_attr "length_immediate" "0")
7588    (set_attr "mode" "SI")])
7589
7590 (define_insn "udivmoddi4"
7591   [(set (match_operand:DI 0 "register_operand" "=a")
7592         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7593                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7594    (set (match_operand:DI 3 "register_operand" "=&d")
7595         (umod:DI (match_dup 1) (match_dup 2)))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "TARGET_64BIT"
7598   "xor{q}\t%3, %3\;div{q}\t%2"
7599   [(set_attr "type" "multi")
7600    (set_attr "length_immediate" "0")
7601    (set_attr "mode" "DI")])
7602
7603 (define_insn "*udivmoddi4_noext"
7604   [(set (match_operand:DI 0 "register_operand" "=a")
7605         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7606                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7607    (set (match_operand:DI 3 "register_operand" "=d")
7608         (umod:DI (match_dup 1) (match_dup 2)))
7609    (use (match_dup 3))
7610    (clobber (reg:CC FLAGS_REG))]
7611   "TARGET_64BIT"
7612   "div{q}\t%2"
7613   [(set_attr "type" "idiv")
7614    (set_attr "mode" "DI")])
7615
7616 (define_split
7617   [(set (match_operand:DI 0 "register_operand" "")
7618         (udiv:DI (match_operand:DI 1 "register_operand" "")
7619                  (match_operand:DI 2 "nonimmediate_operand" "")))
7620    (set (match_operand:DI 3 "register_operand" "")
7621         (umod:DI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_64BIT && reload_completed"
7624   [(set (match_dup 3) (const_int 0))
7625    (parallel [(set (match_dup 0)
7626                    (udiv:DI (match_dup 1) (match_dup 2)))
7627               (set (match_dup 3)
7628                    (umod:DI (match_dup 1) (match_dup 2)))
7629               (use (match_dup 3))
7630               (clobber (reg:CC FLAGS_REG))])]
7631   "")
7632
7633 (define_insn "udivmodsi4"
7634   [(set (match_operand:SI 0 "register_operand" "=a")
7635         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7636                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637    (set (match_operand:SI 3 "register_operand" "=&d")
7638         (umod:SI (match_dup 1) (match_dup 2)))
7639    (clobber (reg:CC FLAGS_REG))]
7640   ""
7641   "xor{l}\t%3, %3\;div{l}\t%2"
7642   [(set_attr "type" "multi")
7643    (set_attr "length_immediate" "0")
7644    (set_attr "mode" "SI")])
7645
7646 (define_insn "*udivmodsi4_noext"
7647   [(set (match_operand:SI 0 "register_operand" "=a")
7648         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7649                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7650    (set (match_operand:SI 3 "register_operand" "=d")
7651         (umod:SI (match_dup 1) (match_dup 2)))
7652    (use (match_dup 3))
7653    (clobber (reg:CC FLAGS_REG))]
7654   ""
7655   "div{l}\t%2"
7656   [(set_attr "type" "idiv")
7657    (set_attr "mode" "SI")])
7658
7659 (define_split
7660   [(set (match_operand:SI 0 "register_operand" "")
7661         (udiv:SI (match_operand:SI 1 "register_operand" "")
7662                  (match_operand:SI 2 "nonimmediate_operand" "")))
7663    (set (match_operand:SI 3 "register_operand" "")
7664         (umod:SI (match_dup 1) (match_dup 2)))
7665    (clobber (reg:CC FLAGS_REG))]
7666   "reload_completed"
7667   [(set (match_dup 3) (const_int 0))
7668    (parallel [(set (match_dup 0)
7669                    (udiv:SI (match_dup 1) (match_dup 2)))
7670               (set (match_dup 3)
7671                    (umod:SI (match_dup 1) (match_dup 2)))
7672               (use (match_dup 3))
7673               (clobber (reg:CC FLAGS_REG))])]
7674   "")
7675
7676 (define_expand "udivmodhi4"
7677   [(set (match_dup 4) (const_int 0))
7678    (parallel [(set (match_operand:HI 0 "register_operand" "")
7679                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7680                             (match_operand:HI 2 "nonimmediate_operand" "")))
7681               (set (match_operand:HI 3 "register_operand" "")
7682                    (umod:HI (match_dup 1) (match_dup 2)))
7683               (use (match_dup 4))
7684               (clobber (reg:CC FLAGS_REG))])]
7685   "TARGET_HIMODE_MATH"
7686   "operands[4] = gen_reg_rtx (HImode);")
7687
7688 (define_insn "*udivmodhi_noext"
7689   [(set (match_operand:HI 0 "register_operand" "=a")
7690         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7691                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7692    (set (match_operand:HI 3 "register_operand" "=d")
7693         (umod:HI (match_dup 1) (match_dup 2)))
7694    (use (match_operand:HI 4 "register_operand" "3"))
7695    (clobber (reg:CC FLAGS_REG))]
7696   ""
7697   "div{w}\t%2"
7698   [(set_attr "type" "idiv")
7699    (set_attr "mode" "HI")])
7700
7701 ;; We cannot use div/idiv for double division, because it causes
7702 ;; "division by zero" on the overflow and that's not what we expect
7703 ;; from truncate.  Because true (non truncating) double division is
7704 ;; never generated, we can't create this insn anyway.
7705 ;
7706 ;(define_insn ""
7707 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7708 ;       (truncate:SI
7709 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7710 ;                  (zero_extend:DI
7711 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7712 ;   (set (match_operand:SI 3 "register_operand" "=d")
7713 ;       (truncate:SI
7714 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7715 ;   (clobber (reg:CC FLAGS_REG))]
7716 ;  ""
7717 ;  "div{l}\t{%2, %0|%0, %2}"
7718 ;  [(set_attr "type" "idiv")])
7719 \f
7720 ;;- Logical AND instructions
7721
7722 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7723 ;; Note that this excludes ah.
7724
7725 (define_insn "*testdi_1_rex64"
7726   [(set (reg FLAGS_REG)
7727         (compare
7728           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7729                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7730           (const_int 0)))]
7731   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7732    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7733   "@
7734    test{l}\t{%k1, %k0|%k0, %k1}
7735    test{l}\t{%k1, %k0|%k0, %k1}
7736    test{q}\t{%1, %0|%0, %1}
7737    test{q}\t{%1, %0|%0, %1}
7738    test{q}\t{%1, %0|%0, %1}"
7739   [(set_attr "type" "test")
7740    (set_attr "modrm" "0,1,0,1,1")
7741    (set_attr "mode" "SI,SI,DI,DI,DI")
7742    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7743
7744 (define_insn "testsi_1"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7748                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7749           (const_int 0)))]
7750   "ix86_match_ccmode (insn, CCNOmode)
7751    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7752   "test{l}\t{%1, %0|%0, %1}"
7753   [(set_attr "type" "test")
7754    (set_attr "modrm" "0,1,1")
7755    (set_attr "mode" "SI")
7756    (set_attr "pent_pair" "uv,np,uv")])
7757
7758 (define_expand "testsi_ccno_1"
7759   [(set (reg:CCNO FLAGS_REG)
7760         (compare:CCNO
7761           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7762                   (match_operand:SI 1 "nonmemory_operand" ""))
7763           (const_int 0)))]
7764   ""
7765   "")
7766
7767 (define_insn "*testhi_1"
7768   [(set (reg FLAGS_REG)
7769         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7770                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7771                  (const_int 0)))]
7772   "ix86_match_ccmode (insn, CCNOmode)
7773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774   "test{w}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "HI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testqi_ccz_1"
7781   [(set (reg:CCZ FLAGS_REG)
7782         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7783                              (match_operand:QI 1 "nonmemory_operand" ""))
7784                  (const_int 0)))]
7785   ""
7786   "")
7787
7788 (define_insn "*testqi_1_maybe_si"
7789   [(set (reg FLAGS_REG)
7790         (compare
7791           (and:QI
7792             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7793             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7794           (const_int 0)))]
7795    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7796     && ix86_match_ccmode (insn,
7797                          GET_CODE (operands[1]) == CONST_INT
7798                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7799 {
7800   if (which_alternative == 3)
7801     {
7802       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7803         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7804       return "test{l}\t{%1, %k0|%k0, %1}";
7805     }
7806   return "test{b}\t{%1, %0|%0, %1}";
7807 }
7808   [(set_attr "type" "test")
7809    (set_attr "modrm" "0,1,1,1")
7810    (set_attr "mode" "QI,QI,QI,SI")
7811    (set_attr "pent_pair" "uv,np,uv,np")])
7812
7813 (define_insn "*testqi_1"
7814   [(set (reg FLAGS_REG)
7815         (compare
7816           (and:QI
7817             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7818             (match_operand:QI 1 "general_operand" "n,n,qn"))
7819           (const_int 0)))]
7820   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821    && ix86_match_ccmode (insn, CCNOmode)"
7822   "test{b}\t{%1, %0|%0, %1}"
7823   [(set_attr "type" "test")
7824    (set_attr "modrm" "0,1,1")
7825    (set_attr "mode" "QI")
7826    (set_attr "pent_pair" "uv,np,uv")])
7827
7828 (define_expand "testqi_ext_ccno_0"
7829   [(set (reg:CCNO FLAGS_REG)
7830         (compare:CCNO
7831           (and:SI
7832             (zero_extract:SI
7833               (match_operand 0 "ext_register_operand" "")
7834               (const_int 8)
7835               (const_int 8))
7836             (match_operand 1 "const_int_operand" ""))
7837           (const_int 0)))]
7838   ""
7839   "")
7840
7841 (define_insn "*testqi_ext_0"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (match_operand 1 "const_int_operand" "n"))
7850           (const_int 0)))]
7851   "ix86_match_ccmode (insn, CCNOmode)"
7852   "test{b}\t{%1, %h0|%h0, %1}"
7853   [(set_attr "type" "test")
7854    (set_attr "mode" "QI")
7855    (set_attr "length_immediate" "1")
7856    (set_attr "pent_pair" "np")])
7857
7858 (define_insn "*testqi_ext_1"
7859   [(set (reg FLAGS_REG)
7860         (compare
7861           (and:SI
7862             (zero_extract:SI
7863               (match_operand 0 "ext_register_operand" "Q")
7864               (const_int 8)
7865               (const_int 8))
7866             (zero_extend:SI
7867               (match_operand:QI 1 "general_operand" "Qm")))
7868           (const_int 0)))]
7869   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871   "test{b}\t{%1, %h0|%h0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "mode" "QI")])
7874
7875 (define_insn "*testqi_ext_1_rex64"
7876   [(set (reg FLAGS_REG)
7877         (compare
7878           (and:SI
7879             (zero_extract:SI
7880               (match_operand 0 "ext_register_operand" "Q")
7881               (const_int 8)
7882               (const_int 8))
7883             (zero_extend:SI
7884               (match_operand:QI 1 "register_operand" "Q")))
7885           (const_int 0)))]
7886   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7887   "test{b}\t{%1, %h0|%h0, %1}"
7888   [(set_attr "type" "test")
7889    (set_attr "mode" "QI")])
7890
7891 (define_insn "*testqi_ext_2"
7892   [(set (reg FLAGS_REG)
7893         (compare
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "Q")
7897               (const_int 8)
7898               (const_int 8))
7899             (zero_extract:SI
7900               (match_operand 1 "ext_register_operand" "Q")
7901               (const_int 8)
7902               (const_int 8)))
7903           (const_int 0)))]
7904   "ix86_match_ccmode (insn, CCNOmode)"
7905   "test{b}\t{%h1, %h0|%h0, %h1}"
7906   [(set_attr "type" "test")
7907    (set_attr "mode" "QI")])
7908
7909 ;; Combine likes to form bit extractions for some tests.  Humor it.
7910 (define_insn "*testqi_ext_3"
7911   [(set (reg FLAGS_REG)
7912         (compare (zero_extract:SI
7913                    (match_operand 0 "nonimmediate_operand" "rm")
7914                    (match_operand:SI 1 "const_int_operand" "")
7915                    (match_operand:SI 2 "const_int_operand" ""))
7916                  (const_int 0)))]
7917   "ix86_match_ccmode (insn, CCNOmode)
7918    && INTVAL (operands[1]) > 0
7919    && INTVAL (operands[2]) >= 0
7920    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7921    && (GET_MODE (operands[0]) == SImode
7922        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7923        || GET_MODE (operands[0]) == HImode
7924        || GET_MODE (operands[0]) == QImode)"
7925   "#")
7926
7927 (define_insn "*testqi_ext_3_rex64"
7928   [(set (reg FLAGS_REG)
7929         (compare (zero_extract:DI
7930                    (match_operand 0 "nonimmediate_operand" "rm")
7931                    (match_operand:DI 1 "const_int_operand" "")
7932                    (match_operand:DI 2 "const_int_operand" ""))
7933                  (const_int 0)))]
7934   "TARGET_64BIT
7935    && ix86_match_ccmode (insn, CCNOmode)
7936    && INTVAL (operands[1]) > 0
7937    && INTVAL (operands[2]) >= 0
7938    /* Ensure that resulting mask is zero or sign extended operand.  */
7939    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7940        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7941            && INTVAL (operands[1]) > 32))
7942    && (GET_MODE (operands[0]) == SImode
7943        || GET_MODE (operands[0]) == DImode
7944        || GET_MODE (operands[0]) == HImode
7945        || GET_MODE (operands[0]) == QImode)"
7946   "#")
7947
7948 (define_split
7949   [(set (match_operand 0 "flags_reg_operand" "")
7950         (match_operator 1 "compare_operator"
7951           [(zero_extract
7952              (match_operand 2 "nonimmediate_operand" "")
7953              (match_operand 3 "const_int_operand" "")
7954              (match_operand 4 "const_int_operand" ""))
7955            (const_int 0)]))]
7956   "ix86_match_ccmode (insn, CCNOmode)"
7957   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7958 {
7959   rtx val = operands[2];
7960   HOST_WIDE_INT len = INTVAL (operands[3]);
7961   HOST_WIDE_INT pos = INTVAL (operands[4]);
7962   HOST_WIDE_INT mask;
7963   enum machine_mode mode, submode;
7964
7965   mode = GET_MODE (val);
7966   if (GET_CODE (val) == MEM)
7967     {
7968       /* ??? Combine likes to put non-volatile mem extractions in QImode
7969          no matter the size of the test.  So find a mode that works.  */
7970       if (! MEM_VOLATILE_P (val))
7971         {
7972           mode = smallest_mode_for_size (pos + len, MODE_INT);
7973           val = adjust_address (val, mode, 0);
7974         }
7975     }
7976   else if (GET_CODE (val) == SUBREG
7977            && (submode = GET_MODE (SUBREG_REG (val)),
7978                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7979            && pos + len <= GET_MODE_BITSIZE (submode))
7980     {
7981       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7982       mode = submode;
7983       val = SUBREG_REG (val);
7984     }
7985   else if (mode == HImode && pos + len <= 8)
7986     {
7987       /* Small HImode tests can be converted to QImode.  */
7988       mode = QImode;
7989       val = gen_lowpart (QImode, val);
7990     }
7991
7992   if (len == HOST_BITS_PER_WIDE_INT)
7993     mask = -1;
7994   else
7995     mask = ((HOST_WIDE_INT)1 << len) - 1;
7996   mask <<= pos;
7997
7998   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7999 })
8000
8001 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8002 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8003 ;; this is relatively important trick.
8004 ;; Do the conversion only post-reload to avoid limiting of the register class
8005 ;; to QI regs.
8006 (define_split
8007   [(set (match_operand 0 "flags_reg_operand" "")
8008         (match_operator 1 "compare_operator"
8009           [(and (match_operand 2 "register_operand" "")
8010                 (match_operand 3 "const_int_operand" ""))
8011            (const_int 0)]))]
8012    "reload_completed
8013     && QI_REG_P (operands[2])
8014     && GET_MODE (operands[2]) != QImode
8015     && ((ix86_match_ccmode (insn, CCZmode)
8016          && !(INTVAL (operands[3]) & ~(255 << 8)))
8017         || (ix86_match_ccmode (insn, CCNOmode)
8018             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8019   [(set (match_dup 0)
8020         (match_op_dup 1
8021           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8022                    (match_dup 3))
8023            (const_int 0)]))]
8024   "operands[2] = gen_lowpart (SImode, operands[2]);
8025    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8026
8027 (define_split
8028   [(set (match_operand 0 "flags_reg_operand" "")
8029         (match_operator 1 "compare_operator"
8030           [(and (match_operand 2 "nonimmediate_operand" "")
8031                 (match_operand 3 "const_int_operand" ""))
8032            (const_int 0)]))]
8033    "reload_completed
8034     && GET_MODE (operands[2]) != QImode
8035     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036     && ((ix86_match_ccmode (insn, CCZmode)
8037          && !(INTVAL (operands[3]) & ~255))
8038         || (ix86_match_ccmode (insn, CCNOmode)
8039             && !(INTVAL (operands[3]) & ~127)))"
8040   [(set (match_dup 0)
8041         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8042                          (const_int 0)]))]
8043   "operands[2] = gen_lowpart (QImode, operands[2]);
8044    operands[3] = gen_lowpart (QImode, operands[3]);")
8045
8046
8047 ;; %%% This used to optimize known byte-wide and operations to memory,
8048 ;; and sometimes to QImode registers.  If this is considered useful,
8049 ;; it should be done with splitters.
8050
8051 (define_expand "anddi3"
8052   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8053         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8054                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_64BIT"
8057   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8058
8059 (define_insn "*anddi_1_rex64"
8060   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8061         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8062                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8065 {
8066   switch (get_attr_type (insn))
8067     {
8068     case TYPE_IMOVX:
8069       {
8070         enum machine_mode mode;
8071
8072         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8073         if (INTVAL (operands[2]) == 0xff)
8074           mode = QImode;
8075         else
8076           {
8077             gcc_assert (INTVAL (operands[2]) == 0xffff);
8078             mode = HImode;
8079           }
8080         
8081         operands[1] = gen_lowpart (mode, operands[1]);
8082         if (mode == QImode)
8083           return "movz{bq|x}\t{%1,%0|%0, %1}";
8084         else
8085           return "movz{wq|x}\t{%1,%0|%0, %1}";
8086       }
8087
8088     default:
8089       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8090       if (get_attr_mode (insn) == MODE_SI)
8091         return "and{l}\t{%k2, %k0|%k0, %k2}";
8092       else
8093         return "and{q}\t{%2, %0|%0, %2}";
8094     }
8095 }
8096   [(set_attr "type" "alu,alu,alu,imovx")
8097    (set_attr "length_immediate" "*,*,*,0")
8098    (set_attr "mode" "SI,DI,DI,DI")])
8099
8100 (define_insn "*anddi_2"
8101   [(set (reg FLAGS_REG)
8102         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8103                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8104                  (const_int 0)))
8105    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8106         (and:DI (match_dup 1) (match_dup 2)))]
8107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8108    && ix86_binary_operator_ok (AND, DImode, operands)"
8109   "@
8110    and{l}\t{%k2, %k0|%k0, %k2}
8111    and{q}\t{%2, %0|%0, %2}
8112    and{q}\t{%2, %0|%0, %2}"
8113   [(set_attr "type" "alu")
8114    (set_attr "mode" "SI,DI,DI")])
8115
8116 (define_expand "andsi3"
8117   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8118         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8119                 (match_operand:SI 2 "general_operand" "")))
8120    (clobber (reg:CC FLAGS_REG))]
8121   ""
8122   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8123
8124 (define_insn "*andsi_1"
8125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8126         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8127                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "ix86_binary_operator_ok (AND, SImode, operands)"
8130 {
8131   switch (get_attr_type (insn))
8132     {
8133     case TYPE_IMOVX:
8134       {
8135         enum machine_mode mode;
8136
8137         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8138         if (INTVAL (operands[2]) == 0xff)
8139           mode = QImode;
8140         else
8141           {
8142             gcc_assert (INTVAL (operands[2]) == 0xffff);
8143             mode = HImode;
8144           }
8145         
8146         operands[1] = gen_lowpart (mode, operands[1]);
8147         if (mode == QImode)
8148           return "movz{bl|x}\t{%1,%0|%0, %1}";
8149         else
8150           return "movz{wl|x}\t{%1,%0|%0, %1}";
8151       }
8152
8153     default:
8154       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8155       return "and{l}\t{%2, %0|%0, %2}";
8156     }
8157 }
8158   [(set_attr "type" "alu,alu,imovx")
8159    (set_attr "length_immediate" "*,*,0")
8160    (set_attr "mode" "SI")])
8161
8162 (define_split
8163   [(set (match_operand 0 "register_operand" "")
8164         (and (match_dup 0)
8165              (const_int -65536)))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8168   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169   "operands[1] = gen_lowpart (HImode, operands[0]);")
8170
8171 (define_split
8172   [(set (match_operand 0 "ext_register_operand" "")
8173         (and (match_dup 0)
8174              (const_int -256)))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8178   "operands[1] = gen_lowpart (QImode, operands[0]);")
8179
8180 (define_split
8181   [(set (match_operand 0 "ext_register_operand" "")
8182         (and (match_dup 0)
8183              (const_int -65281)))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8186   [(parallel [(set (zero_extract:SI (match_dup 0)
8187                                     (const_int 8)
8188                                     (const_int 8))
8189                    (xor:SI 
8190                      (zero_extract:SI (match_dup 0)
8191                                       (const_int 8)
8192                                       (const_int 8))
8193                      (zero_extract:SI (match_dup 0)
8194                                       (const_int 8)
8195                                       (const_int 8))))
8196               (clobber (reg:CC FLAGS_REG))])]
8197   "operands[0] = gen_lowpart (SImode, operands[0]);")
8198
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*andsi_1_zext"
8201   [(set (match_operand:DI 0 "register_operand" "=r")
8202         (zero_extend:DI
8203           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204                   (match_operand:SI 2 "general_operand" "rim"))))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8207   "and{l}\t{%2, %k0|%k0, %2}"
8208   [(set_attr "type" "alu")
8209    (set_attr "mode" "SI")])
8210
8211 (define_insn "*andsi_2"
8212   [(set (reg FLAGS_REG)
8213         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8214                          (match_operand:SI 2 "general_operand" "rim,ri"))
8215                  (const_int 0)))
8216    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8217         (and:SI (match_dup 1) (match_dup 2)))]
8218   "ix86_match_ccmode (insn, CCNOmode)
8219    && ix86_binary_operator_ok (AND, SImode, operands)"
8220   "and{l}\t{%2, %0|%0, %2}"
8221   [(set_attr "type" "alu")
8222    (set_attr "mode" "SI")])
8223
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_2_zext"
8226   [(set (reg FLAGS_REG)
8227         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8228                          (match_operand:SI 2 "general_operand" "rim"))
8229                  (const_int 0)))
8230    (set (match_operand:DI 0 "register_operand" "=r")
8231         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8232   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233    && ix86_binary_operator_ok (AND, SImode, operands)"
8234   "and{l}\t{%2, %k0|%k0, %2}"
8235   [(set_attr "type" "alu")
8236    (set_attr "mode" "SI")])
8237
8238 (define_expand "andhi3"
8239   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8240         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8241                 (match_operand:HI 2 "general_operand" "")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "TARGET_HIMODE_MATH"
8244   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8245
8246 (define_insn "*andhi_1"
8247   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8248         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8249                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "ix86_binary_operator_ok (AND, HImode, operands)"
8252 {
8253   switch (get_attr_type (insn))
8254     {
8255     case TYPE_IMOVX:
8256       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8257       gcc_assert (INTVAL (operands[2]) == 0xff);
8258       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8259
8260     default:
8261       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8262
8263       return "and{w}\t{%2, %0|%0, %2}";
8264     }
8265 }
8266   [(set_attr "type" "alu,alu,imovx")
8267    (set_attr "length_immediate" "*,*,0")
8268    (set_attr "mode" "HI,HI,SI")])
8269
8270 (define_insn "*andhi_2"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8273                          (match_operand:HI 2 "general_operand" "rim,ri"))
8274                  (const_int 0)))
8275    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8276         (and:HI (match_dup 1) (match_dup 2)))]
8277   "ix86_match_ccmode (insn, CCNOmode)
8278    && ix86_binary_operator_ok (AND, HImode, operands)"
8279   "and{w}\t{%2, %0|%0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "HI")])
8282
8283 (define_expand "andqi3"
8284   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8285         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8286                 (match_operand:QI 2 "general_operand" "")))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_QIMODE_MATH"
8289   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8290
8291 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8292 (define_insn "*andqi_1"
8293   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8294         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8295                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "ix86_binary_operator_ok (AND, QImode, operands)"
8298   "@
8299    and{b}\t{%2, %0|%0, %2}
8300    and{b}\t{%2, %0|%0, %2}
8301    and{l}\t{%k2, %k0|%k0, %k2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "QI,QI,SI")])
8304
8305 (define_insn "*andqi_1_slp"
8306   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8307         (and:QI (match_dup 0)
8308                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8309    (clobber (reg:CC FLAGS_REG))]
8310   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8311    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8312   "and{b}\t{%1, %0|%0, %1}"
8313   [(set_attr "type" "alu1")
8314    (set_attr "mode" "QI")])
8315
8316 (define_insn "*andqi_2_maybe_si"
8317   [(set (reg FLAGS_REG)
8318         (compare (and:QI
8319                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8321                  (const_int 0)))
8322    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8323         (and:QI (match_dup 1) (match_dup 2)))]
8324   "ix86_binary_operator_ok (AND, QImode, operands)
8325    && ix86_match_ccmode (insn,
8326                          GET_CODE (operands[2]) == CONST_INT
8327                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8328 {
8329   if (which_alternative == 2)
8330     {
8331       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8332         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8333       return "and{l}\t{%2, %k0|%k0, %2}";
8334     }
8335   return "and{b}\t{%2, %0|%0, %2}";
8336 }
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "QI,QI,SI")])
8339
8340 (define_insn "*andqi_2"
8341   [(set (reg FLAGS_REG)
8342         (compare (and:QI
8343                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8344                    (match_operand:QI 2 "general_operand" "qim,qi"))
8345                  (const_int 0)))
8346    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8347         (and:QI (match_dup 1) (match_dup 2)))]
8348   "ix86_match_ccmode (insn, CCNOmode)
8349    && ix86_binary_operator_ok (AND, QImode, operands)"
8350   "and{b}\t{%2, %0|%0, %2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "QI")])
8353
8354 (define_insn "*andqi_2_slp"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:QI
8357                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8358                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8359                  (const_int 0)))
8360    (set (strict_low_part (match_dup 0))
8361         (and:QI (match_dup 0) (match_dup 1)))]
8362   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8363    && ix86_match_ccmode (insn, CCNOmode)
8364    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8365   "and{b}\t{%1, %0|%0, %1}"
8366   [(set_attr "type" "alu1")
8367    (set_attr "mode" "QI")])
8368
8369 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8370 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8371 ;; for a QImode operand, which of course failed.
8372
8373 (define_insn "andqi_ext_0"
8374   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8375                          (const_int 8)
8376                          (const_int 8))
8377         (and:SI 
8378           (zero_extract:SI
8379             (match_operand 1 "ext_register_operand" "0")
8380             (const_int 8)
8381             (const_int 8))
8382           (match_operand 2 "const_int_operand" "n")))
8383    (clobber (reg:CC FLAGS_REG))]
8384   ""
8385   "and{b}\t{%2, %h0|%h0, %2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "length_immediate" "1")
8388    (set_attr "mode" "QI")])
8389
8390 ;; Generated by peephole translating test to and.  This shows up
8391 ;; often in fp comparisons.
8392
8393 (define_insn "*andqi_ext_0_cc"
8394   [(set (reg FLAGS_REG)
8395         (compare
8396           (and:SI
8397             (zero_extract:SI
8398               (match_operand 1 "ext_register_operand" "0")
8399               (const_int 8)
8400               (const_int 8))
8401             (match_operand 2 "const_int_operand" "n"))
8402           (const_int 0)))
8403    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404                          (const_int 8)
8405                          (const_int 8))
8406         (and:SI 
8407           (zero_extract:SI
8408             (match_dup 1)
8409             (const_int 8)
8410             (const_int 8))
8411           (match_dup 2)))]
8412   "ix86_match_ccmode (insn, CCNOmode)"
8413   "and{b}\t{%2, %h0|%h0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "length_immediate" "1")
8416    (set_attr "mode" "QI")])
8417
8418 (define_insn "*andqi_ext_1"
8419   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420                          (const_int 8)
8421                          (const_int 8))
8422         (and:SI 
8423           (zero_extract:SI
8424             (match_operand 1 "ext_register_operand" "0")
8425             (const_int 8)
8426             (const_int 8))
8427           (zero_extend:SI
8428             (match_operand:QI 2 "general_operand" "Qm"))))
8429    (clobber (reg:CC FLAGS_REG))]
8430   "!TARGET_64BIT"
8431   "and{b}\t{%2, %h0|%h0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "length_immediate" "0")
8434    (set_attr "mode" "QI")])
8435
8436 (define_insn "*andqi_ext_1_rex64"
8437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438                          (const_int 8)
8439                          (const_int 8))
8440         (and:SI 
8441           (zero_extract:SI
8442             (match_operand 1 "ext_register_operand" "0")
8443             (const_int 8)
8444             (const_int 8))
8445           (zero_extend:SI
8446             (match_operand 2 "ext_register_operand" "Q"))))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "TARGET_64BIT"
8449   "and{b}\t{%2, %h0|%h0, %2}"
8450   [(set_attr "type" "alu")
8451    (set_attr "length_immediate" "0")
8452    (set_attr "mode" "QI")])
8453
8454 (define_insn "*andqi_ext_2"
8455   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456                          (const_int 8)
8457                          (const_int 8))
8458         (and:SI
8459           (zero_extract:SI
8460             (match_operand 1 "ext_register_operand" "%0")
8461             (const_int 8)
8462             (const_int 8))
8463           (zero_extract:SI
8464             (match_operand 2 "ext_register_operand" "Q")
8465             (const_int 8)
8466             (const_int 8))))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "and{b}\t{%h2, %h0|%h0, %h2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "QI")])
8473
8474 ;; Convert wide AND instructions with immediate operand to shorter QImode
8475 ;; equivalents when possible.
8476 ;; Don't do the splitting with memory operands, since it introduces risk
8477 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8478 ;; for size, but that can (should?) be handled by generic code instead.
8479 (define_split
8480   [(set (match_operand 0 "register_operand" "")
8481         (and (match_operand 1 "register_operand" "")
8482              (match_operand 2 "const_int_operand" "")))
8483    (clobber (reg:CC FLAGS_REG))]
8484    "reload_completed
8485     && QI_REG_P (operands[0])
8486     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8487     && !(~INTVAL (operands[2]) & ~(255 << 8))
8488     && GET_MODE (operands[0]) != QImode"
8489   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8490                    (and:SI (zero_extract:SI (match_dup 1)
8491                                             (const_int 8) (const_int 8))
8492                            (match_dup 2)))
8493               (clobber (reg:CC FLAGS_REG))])]
8494   "operands[0] = gen_lowpart (SImode, operands[0]);
8495    operands[1] = gen_lowpart (SImode, operands[1]);
8496    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8497
8498 ;; Since AND can be encoded with sign extended immediate, this is only
8499 ;; profitable when 7th bit is not set.
8500 (define_split
8501   [(set (match_operand 0 "register_operand" "")
8502         (and (match_operand 1 "general_operand" "")
8503              (match_operand 2 "const_int_operand" "")))
8504    (clobber (reg:CC FLAGS_REG))]
8505    "reload_completed
8506     && ANY_QI_REG_P (operands[0])
8507     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8508     && !(~INTVAL (operands[2]) & ~255)
8509     && !(INTVAL (operands[2]) & 128)
8510     && GET_MODE (operands[0]) != QImode"
8511   [(parallel [(set (strict_low_part (match_dup 0))
8512                    (and:QI (match_dup 1)
8513                            (match_dup 2)))
8514               (clobber (reg:CC FLAGS_REG))])]
8515   "operands[0] = gen_lowpart (QImode, operands[0]);
8516    operands[1] = gen_lowpart (QImode, operands[1]);
8517    operands[2] = gen_lowpart (QImode, operands[2]);")
8518 \f
8519 ;; Logical inclusive OR instructions
8520
8521 ;; %%% This used to optimize known byte-wide and operations to memory.
8522 ;; If this is considered useful, it should be done with splitters.
8523
8524 (define_expand "iordi3"
8525   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8526         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8527                 (match_operand:DI 2 "x86_64_general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_64BIT"
8530   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8531
8532 (define_insn "*iordi_1_rex64"
8533   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8534         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_64BIT
8538    && ix86_binary_operator_ok (IOR, DImode, operands)"
8539   "or{q}\t{%2, %0|%0, %2}"
8540   [(set_attr "type" "alu")
8541    (set_attr "mode" "DI")])
8542
8543 (define_insn "*iordi_2_rex64"
8544   [(set (reg FLAGS_REG)
8545         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8546                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8547                  (const_int 0)))
8548    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8549         (ior:DI (match_dup 1) (match_dup 2)))]
8550   "TARGET_64BIT
8551    && ix86_match_ccmode (insn, CCNOmode)
8552    && ix86_binary_operator_ok (IOR, DImode, operands)"
8553   "or{q}\t{%2, %0|%0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "DI")])
8556
8557 (define_insn "*iordi_3_rex64"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8560                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8561                  (const_int 0)))
8562    (clobber (match_scratch:DI 0 "=r"))]
8563   "TARGET_64BIT
8564    && ix86_match_ccmode (insn, CCNOmode)
8565    && ix86_binary_operator_ok (IOR, DImode, operands)"
8566   "or{q}\t{%2, %0|%0, %2}"
8567   [(set_attr "type" "alu")
8568    (set_attr "mode" "DI")])
8569
8570
8571 (define_expand "iorsi3"
8572   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8573         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8574                 (match_operand:SI 2 "general_operand" "")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   ""
8577   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8578
8579 (define_insn "*iorsi_1"
8580   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8581         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8582                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8583    (clobber (reg:CC FLAGS_REG))]
8584   "ix86_binary_operator_ok (IOR, SImode, operands)"
8585   "or{l}\t{%2, %0|%0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8588
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*iorsi_1_zext"
8591   [(set (match_operand:DI 0 "register_operand" "=rm")
8592         (zero_extend:DI
8593           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594                   (match_operand:SI 2 "general_operand" "rim"))))
8595    (clobber (reg:CC FLAGS_REG))]
8596   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8597   "or{l}\t{%2, %k0|%k0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "SI")])
8600
8601 (define_insn "*iorsi_1_zext_imm"
8602   [(set (match_operand:DI 0 "register_operand" "=rm")
8603         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8604                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8605    (clobber (reg:CC FLAGS_REG))]
8606   "TARGET_64BIT"
8607   "or{l}\t{%2, %k0|%k0, %2}"
8608   [(set_attr "type" "alu")
8609    (set_attr "mode" "SI")])
8610
8611 (define_insn "*iorsi_2"
8612   [(set (reg FLAGS_REG)
8613         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8614                          (match_operand:SI 2 "general_operand" "rim,ri"))
8615                  (const_int 0)))
8616    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8617         (ior:SI (match_dup 1) (match_dup 2)))]
8618   "ix86_match_ccmode (insn, CCNOmode)
8619    && ix86_binary_operator_ok (IOR, SImode, operands)"
8620   "or{l}\t{%2, %0|%0, %2}"
8621   [(set_attr "type" "alu")
8622    (set_attr "mode" "SI")])
8623
8624 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8625 ;; ??? Special case for immediate operand is missing - it is tricky.
8626 (define_insn "*iorsi_2_zext"
8627   [(set (reg FLAGS_REG)
8628         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8629                          (match_operand:SI 2 "general_operand" "rim"))
8630                  (const_int 0)))
8631    (set (match_operand:DI 0 "register_operand" "=r")
8632         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8633   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8634    && ix86_binary_operator_ok (IOR, SImode, operands)"
8635   "or{l}\t{%2, %k0|%k0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "SI")])
8638
8639 (define_insn "*iorsi_2_zext_imm"
8640   [(set (reg FLAGS_REG)
8641         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8643                  (const_int 0)))
8644    (set (match_operand:DI 0 "register_operand" "=r")
8645         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8646   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8647    && ix86_binary_operator_ok (IOR, SImode, operands)"
8648   "or{l}\t{%2, %k0|%k0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "SI")])
8651
8652 (define_insn "*iorsi_3"
8653   [(set (reg FLAGS_REG)
8654         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8655                          (match_operand:SI 2 "general_operand" "rim"))
8656                  (const_int 0)))
8657    (clobber (match_scratch:SI 0 "=r"))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 (define_expand "iorhi3"
8665   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8666         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8667                 (match_operand:HI 2 "general_operand" "")))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "TARGET_HIMODE_MATH"
8670   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8671
8672 (define_insn "*iorhi_1"
8673   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8674         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "ix86_binary_operator_ok (IOR, HImode, operands)"
8678   "or{w}\t{%2, %0|%0, %2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "HI")])
8681
8682 (define_insn "*iorhi_2"
8683   [(set (reg FLAGS_REG)
8684         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8685                          (match_operand:HI 2 "general_operand" "rim,ri"))
8686                  (const_int 0)))
8687    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8688         (ior:HI (match_dup 1) (match_dup 2)))]
8689   "ix86_match_ccmode (insn, CCNOmode)
8690    && ix86_binary_operator_ok (IOR, HImode, operands)"
8691   "or{w}\t{%2, %0|%0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "HI")])
8694
8695 (define_insn "*iorhi_3"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8698                          (match_operand:HI 2 "general_operand" "rim"))
8699                  (const_int 0)))
8700    (clobber (match_scratch:HI 0 "=r"))]
8701   "ix86_match_ccmode (insn, CCNOmode)
8702    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8703   "or{w}\t{%2, %0|%0, %2}"
8704   [(set_attr "type" "alu")
8705    (set_attr "mode" "HI")])
8706
8707 (define_expand "iorqi3"
8708   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8709         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8710                 (match_operand:QI 2 "general_operand" "")))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "TARGET_QIMODE_MATH"
8713   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8714
8715 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8716 (define_insn "*iorqi_1"
8717   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8718         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8719                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "ix86_binary_operator_ok (IOR, QImode, operands)"
8722   "@
8723    or{b}\t{%2, %0|%0, %2}
8724    or{b}\t{%2, %0|%0, %2}
8725    or{l}\t{%k2, %k0|%k0, %k2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "QI,QI,SI")])
8728
8729 (define_insn "*iorqi_1_slp"
8730   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8731         (ior:QI (match_dup 0)
8732                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8736   "or{b}\t{%1, %0|%0, %1}"
8737   [(set_attr "type" "alu1")
8738    (set_attr "mode" "QI")])
8739
8740 (define_insn "*iorqi_2"
8741   [(set (reg FLAGS_REG)
8742         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8743                          (match_operand:QI 2 "general_operand" "qim,qi"))
8744                  (const_int 0)))
8745    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8746         (ior:QI (match_dup 1) (match_dup 2)))]
8747   "ix86_match_ccmode (insn, CCNOmode)
8748    && ix86_binary_operator_ok (IOR, QImode, operands)"
8749   "or{b}\t{%2, %0|%0, %2}"
8750   [(set_attr "type" "alu")
8751    (set_attr "mode" "QI")])
8752
8753 (define_insn "*iorqi_2_slp"
8754   [(set (reg FLAGS_REG)
8755         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8756                          (match_operand:QI 1 "general_operand" "qim,qi"))
8757                  (const_int 0)))
8758    (set (strict_low_part (match_dup 0))
8759         (ior:QI (match_dup 0) (match_dup 1)))]
8760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8761    && ix86_match_ccmode (insn, CCNOmode)
8762    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8763   "or{b}\t{%1, %0|%0, %1}"
8764   [(set_attr "type" "alu1")
8765    (set_attr "mode" "QI")])
8766
8767 (define_insn "*iorqi_3"
8768   [(set (reg FLAGS_REG)
8769         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8770                          (match_operand:QI 2 "general_operand" "qim"))
8771                  (const_int 0)))
8772    (clobber (match_scratch:QI 0 "=q"))]
8773   "ix86_match_ccmode (insn, CCNOmode)
8774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8775   "or{b}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "QI")])
8778
8779 (define_insn "iorqi_ext_0"
8780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781                          (const_int 8)
8782                          (const_int 8))
8783         (ior:SI 
8784           (zero_extract:SI
8785             (match_operand 1 "ext_register_operand" "0")
8786             (const_int 8)
8787             (const_int 8))
8788           (match_operand 2 "const_int_operand" "n")))
8789    (clobber (reg:CC FLAGS_REG))]
8790   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791   "or{b}\t{%2, %h0|%h0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "length_immediate" "1")
8794    (set_attr "mode" "QI")])
8795
8796 (define_insn "*iorqi_ext_1"
8797   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8798                          (const_int 8)
8799                          (const_int 8))
8800         (ior:SI 
8801           (zero_extract:SI
8802             (match_operand 1 "ext_register_operand" "0")
8803             (const_int 8)
8804             (const_int 8))
8805           (zero_extend:SI
8806             (match_operand:QI 2 "general_operand" "Qm"))))
8807    (clobber (reg:CC FLAGS_REG))]
8808   "!TARGET_64BIT
8809    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8810   "or{b}\t{%2, %h0|%h0, %2}"
8811   [(set_attr "type" "alu")
8812    (set_attr "length_immediate" "0")
8813    (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_ext_1_rex64"
8816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8817                          (const_int 8)
8818                          (const_int 8))
8819         (ior:SI 
8820           (zero_extract:SI
8821             (match_operand 1 "ext_register_operand" "0")
8822             (const_int 8)
8823             (const_int 8))
8824           (zero_extend:SI
8825             (match_operand 2 "ext_register_operand" "Q"))))
8826    (clobber (reg:CC FLAGS_REG))]
8827   "TARGET_64BIT
8828    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829   "or{b}\t{%2, %h0|%h0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "0")
8832    (set_attr "mode" "QI")])
8833
8834 (define_insn "*iorqi_ext_2"
8835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836                          (const_int 8)
8837                          (const_int 8))
8838         (ior:SI 
8839           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8840                            (const_int 8)
8841                            (const_int 8))
8842           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8843                            (const_int 8)
8844                            (const_int 8))))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8847   "ior{b}\t{%h2, %h0|%h0, %h2}"
8848   [(set_attr "type" "alu")
8849    (set_attr "length_immediate" "0")
8850    (set_attr "mode" "QI")])
8851
8852 (define_split
8853   [(set (match_operand 0 "register_operand" "")
8854         (ior (match_operand 1 "register_operand" "")
8855              (match_operand 2 "const_int_operand" "")))
8856    (clobber (reg:CC FLAGS_REG))]
8857    "reload_completed
8858     && QI_REG_P (operands[0])
8859     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8860     && !(INTVAL (operands[2]) & ~(255 << 8))
8861     && GET_MODE (operands[0]) != QImode"
8862   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8863                    (ior:SI (zero_extract:SI (match_dup 1)
8864                                             (const_int 8) (const_int 8))
8865                            (match_dup 2)))
8866               (clobber (reg:CC FLAGS_REG))])]
8867   "operands[0] = gen_lowpart (SImode, operands[0]);
8868    operands[1] = gen_lowpart (SImode, operands[1]);
8869    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8870
8871 ;; Since OR can be encoded with sign extended immediate, this is only
8872 ;; profitable when 7th bit is set.
8873 (define_split
8874   [(set (match_operand 0 "register_operand" "")
8875         (ior (match_operand 1 "general_operand" "")
8876              (match_operand 2 "const_int_operand" "")))
8877    (clobber (reg:CC FLAGS_REG))]
8878    "reload_completed
8879     && ANY_QI_REG_P (operands[0])
8880     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8881     && !(INTVAL (operands[2]) & ~255)
8882     && (INTVAL (operands[2]) & 128)
8883     && GET_MODE (operands[0]) != QImode"
8884   [(parallel [(set (strict_low_part (match_dup 0))
8885                    (ior:QI (match_dup 1)
8886                            (match_dup 2)))
8887               (clobber (reg:CC FLAGS_REG))])]
8888   "operands[0] = gen_lowpart (QImode, operands[0]);
8889    operands[1] = gen_lowpart (QImode, operands[1]);
8890    operands[2] = gen_lowpart (QImode, operands[2]);")
8891 \f
8892 ;; Logical XOR instructions
8893
8894 ;; %%% This used to optimize known byte-wide and operations to memory.
8895 ;; If this is considered useful, it should be done with splitters.
8896
8897 (define_expand "xordi3"
8898   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900                 (match_operand:DI 2 "x86_64_general_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT"
8903   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8904
8905 (define_insn "*xordi_1_rex64"
8906   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8907         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8908                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "TARGET_64BIT
8911    && ix86_binary_operator_ok (XOR, DImode, operands)"
8912   "@
8913    xor{q}\t{%2, %0|%0, %2}
8914    xor{q}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "DI,DI")])
8917
8918 (define_insn "*xordi_2_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8921                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8924         (xor:DI (match_dup 1) (match_dup 2)))]
8925   "TARGET_64BIT
8926    && ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, DImode, operands)"
8928   "@
8929    xor{q}\t{%2, %0|%0, %2}
8930    xor{q}\t{%2, %0|%0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "DI,DI")])
8933
8934 (define_insn "*xordi_3_rex64"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8937                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8938                  (const_int 0)))
8939    (clobber (match_scratch:DI 0 "=r"))]
8940   "TARGET_64BIT
8941    && ix86_match_ccmode (insn, CCNOmode)
8942    && ix86_binary_operator_ok (XOR, DImode, operands)"
8943   "xor{q}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "DI")])
8946
8947 (define_expand "xorsi3"
8948   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950                 (match_operand:SI 2 "general_operand" "")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   ""
8953   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8954
8955 (define_insn "*xorsi_1"
8956   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8957         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8958                 (match_operand:SI 2 "general_operand" "ri,rm")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "ix86_binary_operator_ok (XOR, SImode, operands)"
8961   "xor{l}\t{%2, %0|%0, %2}"
8962   [(set_attr "type" "alu")
8963    (set_attr "mode" "SI")])
8964
8965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8966 ;; Add speccase for immediates
8967 (define_insn "*xorsi_1_zext"
8968   [(set (match_operand:DI 0 "register_operand" "=r")
8969         (zero_extend:DI
8970           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971                   (match_operand:SI 2 "general_operand" "rim"))))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8974   "xor{l}\t{%2, %k0|%k0, %2}"
8975   [(set_attr "type" "alu")
8976    (set_attr "mode" "SI")])
8977
8978 (define_insn "*xorsi_1_zext_imm"
8979   [(set (match_operand:DI 0 "register_operand" "=r")
8980         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8981                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8984   "xor{l}\t{%2, %k0|%k0, %2}"
8985   [(set_attr "type" "alu")
8986    (set_attr "mode" "SI")])
8987
8988 (define_insn "*xorsi_2"
8989   [(set (reg FLAGS_REG)
8990         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8991                          (match_operand:SI 2 "general_operand" "rim,ri"))
8992                  (const_int 0)))
8993    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8994         (xor:SI (match_dup 1) (match_dup 2)))]
8995   "ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (XOR, SImode, operands)"
8997   "xor{l}\t{%2, %0|%0, %2}"
8998   [(set_attr "type" "alu")
8999    (set_attr "mode" "SI")])
9000
9001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9002 ;; ??? Special case for immediate operand is missing - it is tricky.
9003 (define_insn "*xorsi_2_zext"
9004   [(set (reg FLAGS_REG)
9005         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9006                          (match_operand:SI 2 "general_operand" "rim"))
9007                  (const_int 0)))
9008    (set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9010   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %k0|%k0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9015
9016 (define_insn "*xorsi_2_zext_imm"
9017   [(set (reg FLAGS_REG)
9018         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9020                  (const_int 0)))
9021    (set (match_operand:DI 0 "register_operand" "=r")
9022         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9023   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9024    && ix86_binary_operator_ok (XOR, SImode, operands)"
9025   "xor{l}\t{%2, %k0|%k0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "SI")])
9028
9029 (define_insn "*xorsi_3"
9030   [(set (reg FLAGS_REG)
9031         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032                          (match_operand:SI 2 "general_operand" "rim"))
9033                  (const_int 0)))
9034    (clobber (match_scratch:SI 0 "=r"))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 (define_expand "xorhi3"
9042   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9043         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9044                 (match_operand:HI 2 "general_operand" "")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "TARGET_HIMODE_MATH"
9047   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9048
9049 (define_insn "*xorhi_1"
9050   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9051         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9052                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "ix86_binary_operator_ok (XOR, HImode, operands)"
9055   "xor{w}\t{%2, %0|%0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "HI")])
9058
9059 (define_insn "*xorhi_2"
9060   [(set (reg FLAGS_REG)
9061         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9062                          (match_operand:HI 2 "general_operand" "rim,ri"))
9063                  (const_int 0)))
9064    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9065         (xor:HI (match_dup 1) (match_dup 2)))]
9066   "ix86_match_ccmode (insn, CCNOmode)
9067    && ix86_binary_operator_ok (XOR, HImode, operands)"
9068   "xor{w}\t{%2, %0|%0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "HI")])
9071
9072 (define_insn "*xorhi_3"
9073   [(set (reg FLAGS_REG)
9074         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9075                          (match_operand:HI 2 "general_operand" "rim"))
9076                  (const_int 0)))
9077    (clobber (match_scratch:HI 0 "=r"))]
9078   "ix86_match_ccmode (insn, CCNOmode)
9079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9080   "xor{w}\t{%2, %0|%0, %2}"
9081   [(set_attr "type" "alu")
9082    (set_attr "mode" "HI")])
9083
9084 (define_expand "xorqi3"
9085   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9086         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9087                 (match_operand:QI 2 "general_operand" "")))
9088    (clobber (reg:CC FLAGS_REG))]
9089   "TARGET_QIMODE_MATH"
9090   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9091
9092 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9093 (define_insn "*xorqi_1"
9094   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9095         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9096                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9097    (clobber (reg:CC FLAGS_REG))]
9098   "ix86_binary_operator_ok (XOR, QImode, operands)"
9099   "@
9100    xor{b}\t{%2, %0|%0, %2}
9101    xor{b}\t{%2, %0|%0, %2}
9102    xor{l}\t{%k2, %k0|%k0, %k2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "mode" "QI,QI,SI")])
9105
9106 (define_insn "*xorqi_1_slp"
9107   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9108         (xor:QI (match_dup 0)
9109                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9112    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9113   "xor{b}\t{%1, %0|%0, %1}"
9114   [(set_attr "type" "alu1")
9115    (set_attr "mode" "QI")])
9116
9117 (define_insn "xorqi_ext_0"
9118   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119                          (const_int 8)
9120                          (const_int 8))
9121         (xor:SI 
9122           (zero_extract:SI
9123             (match_operand 1 "ext_register_operand" "0")
9124             (const_int 8)
9125             (const_int 8))
9126           (match_operand 2 "const_int_operand" "n")))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129   "xor{b}\t{%2, %h0|%h0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "length_immediate" "1")
9132    (set_attr "mode" "QI")])
9133
9134 (define_insn "*xorqi_ext_1"
9135   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9136                          (const_int 8)
9137                          (const_int 8))
9138         (xor:SI 
9139           (zero_extract:SI
9140             (match_operand 1 "ext_register_operand" "0")
9141             (const_int 8)
9142             (const_int 8))
9143           (zero_extend:SI
9144             (match_operand:QI 2 "general_operand" "Qm"))))
9145    (clobber (reg:CC FLAGS_REG))]
9146   "!TARGET_64BIT
9147    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148   "xor{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "length_immediate" "0")
9151    (set_attr "mode" "QI")])
9152
9153 (define_insn "*xorqi_ext_1_rex64"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (xor:SI 
9158           (zero_extract:SI
9159             (match_operand 1 "ext_register_operand" "0")
9160             (const_int 8)
9161             (const_int 8))
9162           (zero_extend:SI
9163             (match_operand 2 "ext_register_operand" "Q"))))
9164    (clobber (reg:CC FLAGS_REG))]
9165   "TARGET_64BIT
9166    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "xor{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "0")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*xorqi_ext_2"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (xor:SI 
9177           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9178                            (const_int 8)
9179                            (const_int 8))
9180           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9181                            (const_int 8)
9182                            (const_int 8))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9185   "xor{b}\t{%h2, %h0|%h0, %h2}"
9186   [(set_attr "type" "alu")
9187    (set_attr "length_immediate" "0")
9188    (set_attr "mode" "QI")])
9189
9190 (define_insn "*xorqi_cc_1"
9191   [(set (reg FLAGS_REG)
9192         (compare
9193           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9194                   (match_operand:QI 2 "general_operand" "qim,qi"))
9195           (const_int 0)))
9196    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9197         (xor:QI (match_dup 1) (match_dup 2)))]
9198   "ix86_match_ccmode (insn, CCNOmode)
9199    && ix86_binary_operator_ok (XOR, QImode, operands)"
9200   "xor{b}\t{%2, %0|%0, %2}"
9201   [(set_attr "type" "alu")
9202    (set_attr "mode" "QI")])
9203
9204 (define_insn "*xorqi_2_slp"
9205   [(set (reg FLAGS_REG)
9206         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207                          (match_operand:QI 1 "general_operand" "qim,qi"))
9208                  (const_int 0)))
9209    (set (strict_low_part (match_dup 0))
9210         (xor:QI (match_dup 0) (match_dup 1)))]
9211   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212    && ix86_match_ccmode (insn, CCNOmode)
9213    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9214   "xor{b}\t{%1, %0|%0, %1}"
9215   [(set_attr "type" "alu1")
9216    (set_attr "mode" "QI")])
9217
9218 (define_insn "*xorqi_cc_2"
9219   [(set (reg FLAGS_REG)
9220         (compare
9221           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9222                   (match_operand:QI 2 "general_operand" "qim"))
9223           (const_int 0)))
9224    (clobber (match_scratch:QI 0 "=q"))]
9225   "ix86_match_ccmode (insn, CCNOmode)
9226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9227   "xor{b}\t{%2, %0|%0, %2}"
9228   [(set_attr "type" "alu")
9229    (set_attr "mode" "QI")])
9230
9231 (define_insn "*xorqi_cc_ext_1"
9232   [(set (reg FLAGS_REG)
9233         (compare
9234           (xor:SI
9235             (zero_extract:SI
9236               (match_operand 1 "ext_register_operand" "0")
9237               (const_int 8)
9238               (const_int 8))
9239             (match_operand:QI 2 "general_operand" "qmn"))
9240           (const_int 0)))
9241    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9242                          (const_int 8)
9243                          (const_int 8))
9244         (xor:SI 
9245           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9246           (match_dup 2)))]
9247   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9248   "xor{b}\t{%2, %h0|%h0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "QI")])
9251
9252 (define_insn "*xorqi_cc_ext_1_rex64"
9253   [(set (reg FLAGS_REG)
9254         (compare
9255           (xor:SI
9256             (zero_extract:SI
9257               (match_operand 1 "ext_register_operand" "0")
9258               (const_int 8)
9259               (const_int 8))
9260             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9261           (const_int 0)))
9262    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9263                          (const_int 8)
9264                          (const_int 8))
9265         (xor:SI 
9266           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9267           (match_dup 2)))]
9268   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9269   "xor{b}\t{%2, %h0|%h0, %2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "mode" "QI")])
9272
9273 (define_expand "xorqi_cc_ext_1"
9274   [(parallel [
9275      (set (reg:CCNO FLAGS_REG)
9276           (compare:CCNO
9277             (xor:SI
9278               (zero_extract:SI
9279                 (match_operand 1 "ext_register_operand" "")
9280                 (const_int 8)
9281                 (const_int 8))
9282               (match_operand:QI 2 "general_operand" ""))
9283             (const_int 0)))
9284      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9285                            (const_int 8)
9286                            (const_int 8))
9287           (xor:SI 
9288             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9289             (match_dup 2)))])]
9290   ""
9291   "")
9292
9293 (define_split
9294   [(set (match_operand 0 "register_operand" "")
9295         (xor (match_operand 1 "register_operand" "")
9296              (match_operand 2 "const_int_operand" "")))
9297    (clobber (reg:CC FLAGS_REG))]
9298    "reload_completed
9299     && QI_REG_P (operands[0])
9300     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301     && !(INTVAL (operands[2]) & ~(255 << 8))
9302     && GET_MODE (operands[0]) != QImode"
9303   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304                    (xor:SI (zero_extract:SI (match_dup 1)
9305                                             (const_int 8) (const_int 8))
9306                            (match_dup 2)))
9307               (clobber (reg:CC FLAGS_REG))])]
9308   "operands[0] = gen_lowpart (SImode, operands[0]);
9309    operands[1] = gen_lowpart (SImode, operands[1]);
9310    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9311
9312 ;; Since XOR can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is set.
9314 (define_split
9315   [(set (match_operand 0 "register_operand" "")
9316         (xor (match_operand 1 "general_operand" "")
9317              (match_operand 2 "const_int_operand" "")))
9318    (clobber (reg:CC FLAGS_REG))]
9319    "reload_completed
9320     && ANY_QI_REG_P (operands[0])
9321     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322     && !(INTVAL (operands[2]) & ~255)
9323     && (INTVAL (operands[2]) & 128)
9324     && GET_MODE (operands[0]) != QImode"
9325   [(parallel [(set (strict_low_part (match_dup 0))
9326                    (xor:QI (match_dup 1)
9327                            (match_dup 2)))
9328               (clobber (reg:CC FLAGS_REG))])]
9329   "operands[0] = gen_lowpart (QImode, operands[0]);
9330    operands[1] = gen_lowpart (QImode, operands[1]);
9331    operands[2] = gen_lowpart (QImode, operands[2]);")
9332 \f
9333 ;; Negation instructions
9334
9335 (define_expand "negti2"
9336   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338               (clobber (reg:CC FLAGS_REG))])]
9339   "TARGET_64BIT"
9340   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9341
9342 (define_insn "*negti2_1"
9343   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9344         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "TARGET_64BIT
9347    && ix86_unary_operator_ok (NEG, TImode, operands)"
9348   "#")
9349
9350 (define_split
9351   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9352         (neg:TI (match_operand:TI 1 "general_operand" "")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "TARGET_64BIT && reload_completed"
9355   [(parallel
9356     [(set (reg:CCZ FLAGS_REG)
9357           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9358      (set (match_dup 0) (neg:DI (match_dup 2)))])
9359    (parallel
9360     [(set (match_dup 1)
9361           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9362                             (match_dup 3))
9363                    (const_int 0)))
9364      (clobber (reg:CC FLAGS_REG))])
9365    (parallel
9366     [(set (match_dup 1)
9367           (neg:DI (match_dup 1)))
9368      (clobber (reg:CC FLAGS_REG))])]
9369   "split_ti (operands+1, 1, operands+2, operands+3);
9370    split_ti (operands+0, 1, operands+0, operands+1);")
9371
9372 (define_expand "negdi2"
9373   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9375               (clobber (reg:CC FLAGS_REG))])]
9376   ""
9377   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9378
9379 (define_insn "*negdi2_1"
9380   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9381         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "!TARGET_64BIT
9384    && ix86_unary_operator_ok (NEG, DImode, operands)"
9385   "#")
9386
9387 (define_split
9388   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9389         (neg:DI (match_operand:DI 1 "general_operand" "")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "!TARGET_64BIT && reload_completed"
9392   [(parallel
9393     [(set (reg:CCZ FLAGS_REG)
9394           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9395      (set (match_dup 0) (neg:SI (match_dup 2)))])
9396    (parallel
9397     [(set (match_dup 1)
9398           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9399                             (match_dup 3))
9400                    (const_int 0)))
9401      (clobber (reg:CC FLAGS_REG))])
9402    (parallel
9403     [(set (match_dup 1)
9404           (neg:SI (match_dup 1)))
9405      (clobber (reg:CC FLAGS_REG))])]
9406   "split_di (operands+1, 1, operands+2, operands+3);
9407    split_di (operands+0, 1, operands+0, operands+1);")
9408
9409 (define_insn "*negdi2_1_rex64"
9410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414   "neg{q}\t%0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "DI")])
9417
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9421
9422 (define_insn "*negdi2_cmpz_rex64"
9423   [(set (reg:CCZ FLAGS_REG)
9424         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9425                      (const_int 0)))
9426    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427         (neg:DI (match_dup 1)))]
9428   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9429   "neg{q}\t%0"
9430   [(set_attr "type" "negnot")
9431    (set_attr "mode" "DI")])
9432
9433
9434 (define_expand "negsi2"
9435   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9437               (clobber (reg:CC FLAGS_REG))])]
9438   ""
9439   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9440
9441 (define_insn "*negsi2_1"
9442   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9443         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9444    (clobber (reg:CC FLAGS_REG))]
9445   "ix86_unary_operator_ok (NEG, SImode, operands)"
9446   "neg{l}\t%0"
9447   [(set_attr "type" "negnot")
9448    (set_attr "mode" "SI")])
9449
9450 ;; Combine is quite creative about this pattern.
9451 (define_insn "*negsi2_1_zext"
9452   [(set (match_operand:DI 0 "register_operand" "=r")
9453         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9454                                         (const_int 32)))
9455                      (const_int 32)))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%k0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 ;; The problem with neg is that it does not perform (compare x 0),
9463 ;; it really performs (compare 0 x), which leaves us with the zero
9464 ;; flag being the only useful item.
9465
9466 (define_insn "*negsi2_cmpz"
9467   [(set (reg:CCZ FLAGS_REG)
9468         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9469                      (const_int 0)))
9470    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9471         (neg:SI (match_dup 1)))]
9472   "ix86_unary_operator_ok (NEG, SImode, operands)"
9473   "neg{l}\t%0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9476
9477 (define_insn "*negsi2_cmpz_zext"
9478   [(set (reg:CCZ FLAGS_REG)
9479         (compare:CCZ (lshiftrt:DI
9480                        (neg:DI (ashift:DI
9481                                  (match_operand:DI 1 "register_operand" "0")
9482                                  (const_int 32)))
9483                        (const_int 32))
9484                      (const_int 0)))
9485    (set (match_operand:DI 0 "register_operand" "=r")
9486         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9487                                         (const_int 32)))
9488                      (const_int 32)))]
9489   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490   "neg{l}\t%k0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "SI")])
9493
9494 (define_expand "neghi2"
9495   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9497               (clobber (reg:CC FLAGS_REG))])]
9498   "TARGET_HIMODE_MATH"
9499   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9500
9501 (define_insn "*neghi2_1"
9502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9504    (clobber (reg:CC FLAGS_REG))]
9505   "ix86_unary_operator_ok (NEG, HImode, operands)"
9506   "neg{w}\t%0"
9507   [(set_attr "type" "negnot")
9508    (set_attr "mode" "HI")])
9509
9510 (define_insn "*neghi2_cmpz"
9511   [(set (reg:CCZ FLAGS_REG)
9512         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9513                      (const_int 0)))
9514    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515         (neg:HI (match_dup 1)))]
9516   "ix86_unary_operator_ok (NEG, HImode, operands)"
9517   "neg{w}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "HI")])
9520
9521 (define_expand "negqi2"
9522   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9523                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9524               (clobber (reg:CC FLAGS_REG))])]
9525   "TARGET_QIMODE_MATH"
9526   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9527
9528 (define_insn "*negqi2_1"
9529   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9530         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "ix86_unary_operator_ok (NEG, QImode, operands)"
9533   "neg{b}\t%0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "QI")])
9536
9537 (define_insn "*negqi2_cmpz"
9538   [(set (reg:CCZ FLAGS_REG)
9539         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9540                      (const_int 0)))
9541    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542         (neg:QI (match_dup 1)))]
9543   "ix86_unary_operator_ok (NEG, QImode, operands)"
9544   "neg{b}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "QI")])
9547
9548 ;; Changing of sign for FP values is doable using integer unit too.
9549
9550 (define_expand "negsf2"
9551   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9552         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9553   "TARGET_80387 || TARGET_SSE_MATH"
9554   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9555
9556 (define_expand "abssf2"
9557   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9558         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9559   "TARGET_80387 || TARGET_SSE_MATH"
9560   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9561
9562 (define_insn "*absnegsf2_mixed"
9563   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9564         (match_operator:SF 3 "absneg_operator"
9565           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9566    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9569    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9570   "#")
9571
9572 (define_insn "*absnegsf2_sse"
9573   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9574         (match_operator:SF 3 "absneg_operator"
9575           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9576    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9577    (clobber (reg:CC FLAGS_REG))]
9578   "TARGET_SSE_MATH
9579    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9580   "#")
9581
9582 (define_insn "*absnegsf2_i387"
9583   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9584         (match_operator:SF 3 "absneg_operator"
9585           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9586    (use (match_operand 2 "" ""))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "TARGET_80387 && !TARGET_SSE_MATH
9589    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9590   "#")
9591
9592 (define_expand "copysignsf3"
9593   [(match_operand:SF 0 "register_operand" "")
9594    (match_operand:SF 1 "nonmemory_operand" "")
9595    (match_operand:SF 2 "register_operand" "")]
9596   "TARGET_SSE_MATH"
9597 {
9598   ix86_expand_copysign (operands);
9599   DONE;
9600 })
9601
9602 (define_insn_and_split "copysignsf3_const"
9603   [(set (match_operand:SF 0 "register_operand"          "=x")
9604         (unspec:SF
9605           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9606            (match_operand:SF 2 "register_operand"       "0")
9607            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9608           UNSPEC_COPYSIGN))]
9609   "TARGET_SSE_MATH"
9610   "#"
9611   "&& reload_completed"
9612   [(const_int 0)]
9613 {
9614   ix86_split_copysign_const (operands);
9615   DONE;
9616 })
9617
9618 (define_insn "copysignsf3_var"
9619   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9620         (unspec:SF
9621           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9622            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9623            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9624            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9625           UNSPEC_COPYSIGN))
9626    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9627   "TARGET_SSE_MATH"
9628   "#")
9629
9630 (define_split
9631   [(set (match_operand:SF 0 "register_operand" "")
9632         (unspec:SF
9633           [(match_operand:SF 2 "register_operand" "")
9634            (match_operand:SF 3 "register_operand" "")
9635            (match_operand:V4SF 4 "" "")
9636            (match_operand:V4SF 5 "" "")]
9637           UNSPEC_COPYSIGN))
9638    (clobber (match_scratch:V4SF 1 ""))]
9639   "TARGET_SSE_MATH && reload_completed"
9640   [(const_int 0)]
9641 {
9642   ix86_split_copysign_var (operands);
9643   DONE;
9644 })
9645
9646 (define_expand "negdf2"
9647   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9648         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9649   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9650   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9651
9652 (define_expand "absdf2"
9653   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9654         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9655   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9656   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9657
9658 (define_insn "*absnegdf2_mixed"
9659   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9660         (match_operator:DF 3 "absneg_operator"
9661           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9662    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9665    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9666   "#")
9667
9668 (define_insn "*absnegdf2_sse"
9669   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9670         (match_operator:DF 3 "absneg_operator"
9671           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9672    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "TARGET_SSE2 && TARGET_SSE_MATH
9675    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9676   "#")
9677
9678 (define_insn "*absnegdf2_i387"
9679   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9680         (match_operator:DF 3 "absneg_operator"
9681           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9682    (use (match_operand 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9685    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9686   "#")
9687
9688 (define_expand "copysigndf3"
9689   [(match_operand:DF 0 "register_operand" "")
9690    (match_operand:DF 1 "nonmemory_operand" "")
9691    (match_operand:DF 2 "register_operand" "")]
9692   "TARGET_SSE2 && TARGET_SSE_MATH"
9693 {
9694   ix86_expand_copysign (operands);
9695   DONE;
9696 })
9697
9698 (define_insn_and_split "copysigndf3_const"
9699   [(set (match_operand:DF 0 "register_operand"          "=x")
9700         (unspec:DF
9701           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9702            (match_operand:DF 2 "register_operand"       "0")
9703            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9704           UNSPEC_COPYSIGN))]
9705   "TARGET_SSE2 && TARGET_SSE_MATH"
9706   "#"
9707   "&& reload_completed"
9708   [(const_int 0)]
9709 {
9710   ix86_split_copysign_const (operands);
9711   DONE;
9712 })
9713
9714 (define_insn "copysigndf3_var"
9715   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9716         (unspec:DF
9717           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9718            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9719            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9720            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9721           UNSPEC_COPYSIGN))
9722    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9723   "TARGET_SSE2 && TARGET_SSE_MATH"
9724   "#")
9725
9726 (define_split
9727   [(set (match_operand:DF 0 "register_operand" "")
9728         (unspec:DF
9729           [(match_operand:DF 2 "register_operand" "")
9730            (match_operand:DF 3 "register_operand" "")
9731            (match_operand:V2DF 4 "" "")
9732            (match_operand:V2DF 5 "" "")]
9733           UNSPEC_COPYSIGN))
9734    (clobber (match_scratch:V2DF 1 ""))]
9735   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9736   [(const_int 0)]
9737 {
9738   ix86_split_copysign_var (operands);
9739   DONE;
9740 })
9741
9742 (define_expand "negxf2"
9743   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9744         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9745   "TARGET_80387"
9746   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9747
9748 (define_expand "absxf2"
9749   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9750         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9751   "TARGET_80387"
9752   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9753
9754 (define_insn "*absnegxf2_i387"
9755   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9756         (match_operator:XF 3 "absneg_operator"
9757           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9758    (use (match_operand 2 "" ""))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "TARGET_80387
9761    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9762   "#")
9763
9764 ;; Splitters for fp abs and neg.
9765
9766 (define_split
9767   [(set (match_operand 0 "fp_register_operand" "")
9768         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9769    (use (match_operand 2 "" ""))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "reload_completed"
9772   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9773
9774 (define_split
9775   [(set (match_operand 0 "register_operand" "")
9776         (match_operator 3 "absneg_operator"
9777           [(match_operand 1 "register_operand" "")]))
9778    (use (match_operand 2 "nonimmediate_operand" ""))
9779    (clobber (reg:CC FLAGS_REG))]
9780   "reload_completed && SSE_REG_P (operands[0])"
9781   [(set (match_dup 0) (match_dup 3))]
9782 {
9783   enum machine_mode mode = GET_MODE (operands[0]);
9784   enum machine_mode vmode = GET_MODE (operands[2]);
9785   rtx tmp;
9786   
9787   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9788   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9789   if (operands_match_p (operands[0], operands[2]))
9790     {
9791       tmp = operands[1];
9792       operands[1] = operands[2];
9793       operands[2] = tmp;
9794     }
9795   if (GET_CODE (operands[3]) == ABS)
9796     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9797   else
9798     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9799   operands[3] = tmp;
9800 })
9801
9802 (define_split
9803   [(set (match_operand:SF 0 "register_operand" "")
9804         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9805    (use (match_operand:V4SF 2 "" ""))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "reload_completed"
9808   [(parallel [(set (match_dup 0) (match_dup 1))
9809               (clobber (reg:CC FLAGS_REG))])]
9810
9811   rtx tmp;
9812   operands[0] = gen_lowpart (SImode, operands[0]);
9813   if (GET_CODE (operands[1]) == ABS)
9814     {
9815       tmp = gen_int_mode (0x7fffffff, SImode);
9816       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9817     }
9818   else
9819     {
9820       tmp = gen_int_mode (0x80000000, SImode);
9821       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9822     }
9823   operands[1] = tmp;
9824 })
9825
9826 (define_split
9827   [(set (match_operand:DF 0 "register_operand" "")
9828         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9829    (use (match_operand 2 "" ""))
9830    (clobber (reg:CC FLAGS_REG))]
9831   "reload_completed"
9832   [(parallel [(set (match_dup 0) (match_dup 1))
9833               (clobber (reg:CC FLAGS_REG))])]
9834 {
9835   rtx tmp;
9836   if (TARGET_64BIT)
9837     {
9838       tmp = gen_lowpart (DImode, operands[0]);
9839       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9840       operands[0] = tmp;
9841
9842       if (GET_CODE (operands[1]) == ABS)
9843         tmp = const0_rtx;
9844       else
9845         tmp = gen_rtx_NOT (DImode, tmp);
9846     }
9847   else
9848     {
9849       operands[0] = gen_highpart (SImode, operands[0]);
9850       if (GET_CODE (operands[1]) == ABS)
9851         {
9852           tmp = gen_int_mode (0x7fffffff, SImode);
9853           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9854         }
9855       else
9856         {
9857           tmp = gen_int_mode (0x80000000, SImode);
9858           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9859         }
9860     }
9861   operands[1] = tmp;
9862 })
9863
9864 (define_split
9865   [(set (match_operand:XF 0 "register_operand" "")
9866         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9867    (use (match_operand 2 "" ""))
9868    (clobber (reg:CC FLAGS_REG))]
9869   "reload_completed"
9870   [(parallel [(set (match_dup 0) (match_dup 1))
9871               (clobber (reg:CC FLAGS_REG))])]
9872 {
9873   rtx tmp;
9874   operands[0] = gen_rtx_REG (SImode,
9875                              true_regnum (operands[0])
9876                              + (TARGET_64BIT ? 1 : 2));
9877   if (GET_CODE (operands[1]) == ABS)
9878     {
9879       tmp = GEN_INT (0x7fff);
9880       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9881     }
9882   else
9883     {
9884       tmp = GEN_INT (0x8000);
9885       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9886     }
9887   operands[1] = tmp;
9888 })
9889
9890 (define_split
9891   [(set (match_operand 0 "memory_operand" "")
9892         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9893    (use (match_operand 2 "" ""))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "reload_completed"
9896   [(parallel [(set (match_dup 0) (match_dup 1))
9897               (clobber (reg:CC FLAGS_REG))])]
9898 {
9899   enum machine_mode mode = GET_MODE (operands[0]);
9900   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9901   rtx tmp;
9902
9903   operands[0] = adjust_address (operands[0], QImode, size - 1);
9904   if (GET_CODE (operands[1]) == ABS)
9905     {
9906       tmp = gen_int_mode (0x7f, QImode);
9907       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9908     }
9909   else
9910     {
9911       tmp = gen_int_mode (0x80, QImode);
9912       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9913     }
9914   operands[1] = tmp;
9915 })
9916
9917 ;; Conditionalize these after reload. If they match before reload, we 
9918 ;; lose the clobber and ability to use integer instructions.
9919
9920 (define_insn "*negsf2_1"
9921   [(set (match_operand:SF 0 "register_operand" "=f")
9922         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9923   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "SF")])
9927
9928 (define_insn "*negdf2_1"
9929   [(set (match_operand:DF 0 "register_operand" "=f")
9930         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9931   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "DF")])
9935
9936 (define_insn "*negxf2_1"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9939   "TARGET_80387"
9940   "fchs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "XF")])
9943
9944 (define_insn "*abssf2_1"
9945   [(set (match_operand:SF 0 "register_operand" "=f")
9946         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9947   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "SF")])
9951
9952 (define_insn "*absdf2_1"
9953   [(set (match_operand:DF 0 "register_operand" "=f")
9954         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9955   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9956   "fabs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9959
9960 (define_insn "*absxf2_1"
9961   [(set (match_operand:XF 0 "register_operand" "=f")
9962         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "DF")])
9967
9968 (define_insn "*negextendsfdf2"
9969   [(set (match_operand:DF 0 "register_operand" "=f")
9970         (neg:DF (float_extend:DF
9971                   (match_operand:SF 1 "register_operand" "0"))))]
9972   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9973   "fchs"
9974   [(set_attr "type" "fsgn")
9975    (set_attr "mode" "DF")])
9976
9977 (define_insn "*negextenddfxf2"
9978   [(set (match_operand:XF 0 "register_operand" "=f")
9979         (neg:XF (float_extend:XF
9980                   (match_operand:DF 1 "register_operand" "0"))))]
9981   "TARGET_80387"
9982   "fchs"
9983   [(set_attr "type" "fsgn")
9984    (set_attr "mode" "XF")])
9985
9986 (define_insn "*negextendsfxf2"
9987   [(set (match_operand:XF 0 "register_operand" "=f")
9988         (neg:XF (float_extend:XF
9989                   (match_operand:SF 1 "register_operand" "0"))))]
9990   "TARGET_80387"
9991   "fchs"
9992   [(set_attr "type" "fsgn")
9993    (set_attr "mode" "XF")])
9994
9995 (define_insn "*absextendsfdf2"
9996   [(set (match_operand:DF 0 "register_operand" "=f")
9997         (abs:DF (float_extend:DF
9998                   (match_operand:SF 1 "register_operand" "0"))))]
9999   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10000   "fabs"
10001   [(set_attr "type" "fsgn")
10002    (set_attr "mode" "DF")])
10003
10004 (define_insn "*absextenddfxf2"
10005   [(set (match_operand:XF 0 "register_operand" "=f")
10006         (abs:XF (float_extend:XF
10007           (match_operand:DF 1 "register_operand" "0"))))]
10008   "TARGET_80387"
10009   "fabs"
10010   [(set_attr "type" "fsgn")
10011    (set_attr "mode" "XF")])
10012
10013 (define_insn "*absextendsfxf2"
10014   [(set (match_operand:XF 0 "register_operand" "=f")
10015         (abs:XF (float_extend:XF
10016           (match_operand:SF 1 "register_operand" "0"))))]
10017   "TARGET_80387"
10018   "fabs"
10019   [(set_attr "type" "fsgn")
10020    (set_attr "mode" "XF")])
10021 \f
10022 ;; One complement instructions
10023
10024 (define_expand "one_cmpldi2"
10025   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10026         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10027   "TARGET_64BIT"
10028   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10029
10030 (define_insn "*one_cmpldi2_1_rex64"
10031   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10032         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10033   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10034   "not{q}\t%0"
10035   [(set_attr "type" "negnot")
10036    (set_attr "mode" "DI")])
10037
10038 (define_insn "*one_cmpldi2_2_rex64"
10039   [(set (reg FLAGS_REG)
10040         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10041                  (const_int 0)))
10042    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10043         (not:DI (match_dup 1)))]
10044   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10045    && ix86_unary_operator_ok (NOT, DImode, operands)"
10046   "#"
10047   [(set_attr "type" "alu1")
10048    (set_attr "mode" "DI")])
10049
10050 (define_split
10051   [(set (match_operand 0 "flags_reg_operand" "")
10052         (match_operator 2 "compare_operator"
10053           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10054            (const_int 0)]))
10055    (set (match_operand:DI 1 "nonimmediate_operand" "")
10056         (not:DI (match_dup 3)))]
10057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10058   [(parallel [(set (match_dup 0)
10059                    (match_op_dup 2
10060                      [(xor:DI (match_dup 3) (const_int -1))
10061                       (const_int 0)]))
10062               (set (match_dup 1)
10063                    (xor:DI (match_dup 3) (const_int -1)))])]
10064   "")
10065
10066 (define_expand "one_cmplsi2"
10067   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10068         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10069   ""
10070   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10071
10072 (define_insn "*one_cmplsi2_1"
10073   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10074         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10075   "ix86_unary_operator_ok (NOT, SImode, operands)"
10076   "not{l}\t%0"
10077   [(set_attr "type" "negnot")
10078    (set_attr "mode" "SI")])
10079
10080 ;; ??? Currently never generated - xor is used instead.
10081 (define_insn "*one_cmplsi2_1_zext"
10082   [(set (match_operand:DI 0 "register_operand" "=r")
10083         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10084   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10085   "not{l}\t%k0"
10086   [(set_attr "type" "negnot")
10087    (set_attr "mode" "SI")])
10088
10089 (define_insn "*one_cmplsi2_2"
10090   [(set (reg FLAGS_REG)
10091         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10092                  (const_int 0)))
10093    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094         (not:SI (match_dup 1)))]
10095   "ix86_match_ccmode (insn, CCNOmode)
10096    && ix86_unary_operator_ok (NOT, SImode, operands)"
10097   "#"
10098   [(set_attr "type" "alu1")
10099    (set_attr "mode" "SI")])
10100
10101 (define_split
10102   [(set (match_operand 0 "flags_reg_operand" "")
10103         (match_operator 2 "compare_operator"
10104           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10105            (const_int 0)]))
10106    (set (match_operand:SI 1 "nonimmediate_operand" "")
10107         (not:SI (match_dup 3)))]
10108   "ix86_match_ccmode (insn, CCNOmode)"
10109   [(parallel [(set (match_dup 0)
10110                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10111                                     (const_int 0)]))
10112               (set (match_dup 1)
10113                    (xor:SI (match_dup 3) (const_int -1)))])]
10114   "")
10115
10116 ;; ??? Currently never generated - xor is used instead.
10117 (define_insn "*one_cmplsi2_2_zext"
10118   [(set (reg FLAGS_REG)
10119         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10120                  (const_int 0)))
10121    (set (match_operand:DI 0 "register_operand" "=r")
10122         (zero_extend:DI (not:SI (match_dup 1))))]
10123   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10124    && ix86_unary_operator_ok (NOT, SImode, operands)"
10125   "#"
10126   [(set_attr "type" "alu1")
10127    (set_attr "mode" "SI")])
10128
10129 (define_split
10130   [(set (match_operand 0 "flags_reg_operand" "")
10131         (match_operator 2 "compare_operator"
10132           [(not:SI (match_operand:SI 3 "register_operand" ""))
10133            (const_int 0)]))
10134    (set (match_operand:DI 1 "register_operand" "")
10135         (zero_extend:DI (not:SI (match_dup 3))))]
10136   "ix86_match_ccmode (insn, CCNOmode)"
10137   [(parallel [(set (match_dup 0)
10138                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10139                                     (const_int 0)]))
10140               (set (match_dup 1)
10141                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10142   "")
10143
10144 (define_expand "one_cmplhi2"
10145   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10146         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10147   "TARGET_HIMODE_MATH"
10148   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10149
10150 (define_insn "*one_cmplhi2_1"
10151   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10152         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10153   "ix86_unary_operator_ok (NOT, HImode, operands)"
10154   "not{w}\t%0"
10155   [(set_attr "type" "negnot")
10156    (set_attr "mode" "HI")])
10157
10158 (define_insn "*one_cmplhi2_2"
10159   [(set (reg FLAGS_REG)
10160         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10161                  (const_int 0)))
10162    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10163         (not:HI (match_dup 1)))]
10164   "ix86_match_ccmode (insn, CCNOmode)
10165    && ix86_unary_operator_ok (NEG, HImode, operands)"
10166   "#"
10167   [(set_attr "type" "alu1")
10168    (set_attr "mode" "HI")])
10169
10170 (define_split
10171   [(set (match_operand 0 "flags_reg_operand" "")
10172         (match_operator 2 "compare_operator"
10173           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10174            (const_int 0)]))
10175    (set (match_operand:HI 1 "nonimmediate_operand" "")
10176         (not:HI (match_dup 3)))]
10177   "ix86_match_ccmode (insn, CCNOmode)"
10178   [(parallel [(set (match_dup 0)
10179                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10180                                     (const_int 0)]))
10181               (set (match_dup 1)
10182                    (xor:HI (match_dup 3) (const_int -1)))])]
10183   "")
10184
10185 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10186 (define_expand "one_cmplqi2"
10187   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10188         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10189   "TARGET_QIMODE_MATH"
10190   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10191
10192 (define_insn "*one_cmplqi2_1"
10193   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10194         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10195   "ix86_unary_operator_ok (NOT, QImode, operands)"
10196   "@
10197    not{b}\t%0
10198    not{l}\t%k0"
10199   [(set_attr "type" "negnot")
10200    (set_attr "mode" "QI,SI")])
10201
10202 (define_insn "*one_cmplqi2_2"
10203   [(set (reg FLAGS_REG)
10204         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10205                  (const_int 0)))
10206    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207         (not:QI (match_dup 1)))]
10208   "ix86_match_ccmode (insn, CCNOmode)
10209    && ix86_unary_operator_ok (NOT, QImode, operands)"
10210   "#"
10211   [(set_attr "type" "alu1")
10212    (set_attr "mode" "QI")])
10213
10214 (define_split
10215   [(set (match_operand 0 "flags_reg_operand" "")
10216         (match_operator 2 "compare_operator"
10217           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10218            (const_int 0)]))
10219    (set (match_operand:QI 1 "nonimmediate_operand" "")
10220         (not:QI (match_dup 3)))]
10221   "ix86_match_ccmode (insn, CCNOmode)"
10222   [(parallel [(set (match_dup 0)
10223                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10224                                     (const_int 0)]))
10225               (set (match_dup 1)
10226                    (xor:QI (match_dup 3) (const_int -1)))])]
10227   "")
10228 \f
10229 ;; Arithmetic shift instructions
10230
10231 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10232 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10233 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10234 ;; from the assembler input.
10235 ;;
10236 ;; This instruction shifts the target reg/mem as usual, but instead of
10237 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10238 ;; is a left shift double, bits are taken from the high order bits of
10239 ;; reg, else if the insn is a shift right double, bits are taken from the
10240 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10241 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10242 ;;
10243 ;; Since sh[lr]d does not change the `reg' operand, that is done
10244 ;; separately, making all shifts emit pairs of shift double and normal
10245 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10246 ;; support a 63 bit shift, each shift where the count is in a reg expands
10247 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10248 ;;
10249 ;; If the shift count is a constant, we need never emit more than one
10250 ;; shift pair, instead using moves and sign extension for counts greater
10251 ;; than 31.
10252
10253 (define_expand "ashlti3"
10254   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10255                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10256                               (match_operand:QI 2 "nonmemory_operand" "")))
10257               (clobber (reg:CC FLAGS_REG))])]
10258   "TARGET_64BIT"
10259 {
10260   if (! immediate_operand (operands[2], QImode))
10261     {
10262       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10263       DONE;
10264     }
10265   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10266   DONE;
10267 })
10268
10269 (define_insn "ashlti3_1"
10270   [(set (match_operand:TI 0 "register_operand" "=r")
10271         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10272                    (match_operand:QI 2 "register_operand" "c")))
10273    (clobber (match_scratch:DI 3 "=&r"))
10274    (clobber (reg:CC FLAGS_REG))]
10275   "TARGET_64BIT"
10276   "#"
10277   [(set_attr "type" "multi")])
10278
10279 (define_insn "*ashlti3_2"
10280   [(set (match_operand:TI 0 "register_operand" "=r")
10281         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10282                    (match_operand:QI 2 "immediate_operand" "O")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "TARGET_64BIT"
10285   "#"
10286   [(set_attr "type" "multi")])
10287
10288 (define_split
10289   [(set (match_operand:TI 0 "register_operand" "")
10290         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10291                    (match_operand:QI 2 "register_operand" "")))
10292    (clobber (match_scratch:DI 3 ""))
10293    (clobber (reg:CC FLAGS_REG))]
10294   "TARGET_64BIT && reload_completed"
10295   [(const_int 0)]
10296   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10297
10298 (define_split
10299   [(set (match_operand:TI 0 "register_operand" "")
10300         (ashift:TI (match_operand:TI 1 "register_operand" "")
10301                    (match_operand:QI 2 "immediate_operand" "")))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "TARGET_64BIT && reload_completed"
10304   [(const_int 0)]
10305   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10306
10307 (define_insn "x86_64_shld"
10308   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10309         (ior:DI (ashift:DI (match_dup 0)
10310                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10311                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10312                   (minus:QI (const_int 64) (match_dup 2)))))
10313    (clobber (reg:CC FLAGS_REG))]
10314   "TARGET_64BIT"
10315   "@
10316    shld{q}\t{%2, %1, %0|%0, %1, %2}
10317    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10318   [(set_attr "type" "ishift")
10319    (set_attr "prefix_0f" "1")
10320    (set_attr "mode" "DI")
10321    (set_attr "athlon_decode" "vector")])
10322
10323 (define_expand "x86_64_shift_adj"
10324   [(set (reg:CCZ FLAGS_REG)
10325         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10326                              (const_int 64))
10327                      (const_int 0)))
10328    (set (match_operand:DI 0 "register_operand" "")
10329         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10330                          (match_operand:DI 1 "register_operand" "")
10331                          (match_dup 0)))
10332    (set (match_dup 1)
10333         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334                          (match_operand:DI 3 "register_operand" "r")
10335                          (match_dup 1)))]
10336   "TARGET_64BIT"
10337   "")
10338
10339 (define_expand "ashldi3"
10340   [(set (match_operand:DI 0 "shiftdi_operand" "")
10341         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10342                    (match_operand:QI 2 "nonmemory_operand" "")))]
10343   ""
10344   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10345
10346 (define_insn "*ashldi3_1_rex64"
10347   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10348         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10349                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10352 {
10353   switch (get_attr_type (insn))
10354     {
10355     case TYPE_ALU:
10356       gcc_assert (operands[2] == const1_rtx);
10357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10358       return "add{q}\t{%0, %0|%0, %0}";
10359
10360     case TYPE_LEA:
10361       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10362       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10363       operands[1] = gen_rtx_MULT (DImode, operands[1],
10364                                   GEN_INT (1 << INTVAL (operands[2])));
10365       return "lea{q}\t{%a1, %0|%0, %a1}";
10366
10367     default:
10368       if (REG_P (operands[2]))
10369         return "sal{q}\t{%b2, %0|%0, %b2}";
10370       else if (operands[2] == const1_rtx
10371                && (TARGET_SHIFT1 || optimize_size))
10372         return "sal{q}\t%0";
10373       else
10374         return "sal{q}\t{%2, %0|%0, %2}";
10375     }
10376 }
10377   [(set (attr "type")
10378      (cond [(eq_attr "alternative" "1")
10379               (const_string "lea")
10380             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10381                           (const_int 0))
10382                       (match_operand 0 "register_operand" ""))
10383                  (match_operand 2 "const1_operand" ""))
10384               (const_string "alu")
10385            ]
10386            (const_string "ishift")))
10387    (set_attr "mode" "DI")])
10388
10389 ;; Convert lea to the lea pattern to avoid flags dependency.
10390 (define_split
10391   [(set (match_operand:DI 0 "register_operand" "")
10392         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10393                    (match_operand:QI 2 "immediate_operand" "")))
10394    (clobber (reg:CC FLAGS_REG))]
10395   "TARGET_64BIT && reload_completed
10396    && true_regnum (operands[0]) != true_regnum (operands[1])"
10397   [(set (match_dup 0)
10398         (mult:DI (match_dup 1)
10399                  (match_dup 2)))]
10400   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10401
10402 ;; This pattern can't accept a variable shift count, since shifts by
10403 ;; zero don't affect the flags.  We assume that shifts by constant
10404 ;; zero are optimized away.
10405 (define_insn "*ashldi3_cmp_rex64"
10406   [(set (reg FLAGS_REG)
10407         (compare
10408           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10409                      (match_operand:QI 2 "immediate_operand" "e"))
10410           (const_int 0)))
10411    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412         (ashift:DI (match_dup 1) (match_dup 2)))]
10413   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10414    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10415    && (optimize_size
10416        || !TARGET_PARTIAL_FLAG_REG_STALL
10417        || (operands[2] == const1_rtx
10418            && (TARGET_SHIFT1
10419                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10420 {
10421   switch (get_attr_type (insn))
10422     {
10423     case TYPE_ALU:
10424       gcc_assert (operands[2] == const1_rtx);
10425       return "add{q}\t{%0, %0|%0, %0}";
10426
10427     default:
10428       if (REG_P (operands[2]))
10429         return "sal{q}\t{%b2, %0|%0, %b2}";
10430       else if (operands[2] == const1_rtx
10431                && (TARGET_SHIFT1 || optimize_size))
10432         return "sal{q}\t%0";
10433       else
10434         return "sal{q}\t{%2, %0|%0, %2}";
10435     }
10436 }
10437   [(set (attr "type")
10438      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10439                           (const_int 0))
10440                       (match_operand 0 "register_operand" ""))
10441                  (match_operand 2 "const1_operand" ""))
10442               (const_string "alu")
10443            ]
10444            (const_string "ishift")))
10445    (set_attr "mode" "DI")])
10446
10447 (define_insn "*ashldi3_cconly_rex64"
10448   [(set (reg FLAGS_REG)
10449         (compare
10450           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451                      (match_operand:QI 2 "immediate_operand" "e"))
10452           (const_int 0)))
10453    (clobber (match_scratch:DI 0 "=r"))]
10454   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10456    && (optimize_size
10457        || !TARGET_PARTIAL_FLAG_REG_STALL
10458        || (operands[2] == const1_rtx
10459            && (TARGET_SHIFT1
10460                || TARGET_DOUBLE_WITH_ADD)))"
10461 {
10462   switch (get_attr_type (insn))
10463     {
10464     case TYPE_ALU:
10465       gcc_assert (operands[2] == const1_rtx);
10466       return "add{q}\t{%0, %0|%0, %0}";
10467
10468     default:
10469       if (REG_P (operands[2]))
10470         return "sal{q}\t{%b2, %0|%0, %b2}";
10471       else if (operands[2] == const1_rtx
10472                && (TARGET_SHIFT1 || optimize_size))
10473         return "sal{q}\t%0";
10474       else
10475         return "sal{q}\t{%2, %0|%0, %2}";
10476     }
10477 }
10478   [(set (attr "type")
10479      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10480                           (const_int 0))
10481                       (match_operand 0 "register_operand" ""))
10482                  (match_operand 2 "const1_operand" ""))
10483               (const_string "alu")
10484            ]
10485            (const_string "ishift")))
10486    (set_attr "mode" "DI")])
10487
10488 (define_insn "*ashldi3_1"
10489   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10490         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10491                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10492    (clobber (reg:CC FLAGS_REG))]
10493   "!TARGET_64BIT"
10494   "#"
10495   [(set_attr "type" "multi")])
10496
10497 ;; By default we don't ask for a scratch register, because when DImode
10498 ;; values are manipulated, registers are already at a premium.  But if
10499 ;; we have one handy, we won't turn it away.
10500 (define_peephole2
10501   [(match_scratch:SI 3 "r")
10502    (parallel [(set (match_operand:DI 0 "register_operand" "")
10503                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10504                               (match_operand:QI 2 "nonmemory_operand" "")))
10505               (clobber (reg:CC FLAGS_REG))])
10506    (match_dup 3)]
10507   "!TARGET_64BIT && TARGET_CMOVE"
10508   [(const_int 0)]
10509   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10510
10511 (define_split
10512   [(set (match_operand:DI 0 "register_operand" "")
10513         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10514                    (match_operand:QI 2 "nonmemory_operand" "")))
10515    (clobber (reg:CC FLAGS_REG))]
10516   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10517                      ? flow2_completed : reload_completed)"
10518   [(const_int 0)]
10519   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10520
10521 (define_insn "x86_shld_1"
10522   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10523         (ior:SI (ashift:SI (match_dup 0)
10524                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10525                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10526                   (minus:QI (const_int 32) (match_dup 2)))))
10527    (clobber (reg:CC FLAGS_REG))]
10528   ""
10529   "@
10530    shld{l}\t{%2, %1, %0|%0, %1, %2}
10531    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10532   [(set_attr "type" "ishift")
10533    (set_attr "prefix_0f" "1")
10534    (set_attr "mode" "SI")
10535    (set_attr "pent_pair" "np")
10536    (set_attr "athlon_decode" "vector")])
10537
10538 (define_expand "x86_shift_adj_1"
10539   [(set (reg:CCZ FLAGS_REG)
10540         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10541                              (const_int 32))
10542                      (const_int 0)))
10543    (set (match_operand:SI 0 "register_operand" "")
10544         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10545                          (match_operand:SI 1 "register_operand" "")
10546                          (match_dup 0)))
10547    (set (match_dup 1)
10548         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10549                          (match_operand:SI 3 "register_operand" "r")
10550                          (match_dup 1)))]
10551   "TARGET_CMOVE"
10552   "")
10553
10554 (define_expand "x86_shift_adj_2"
10555   [(use (match_operand:SI 0 "register_operand" ""))
10556    (use (match_operand:SI 1 "register_operand" ""))
10557    (use (match_operand:QI 2 "register_operand" ""))]
10558   ""
10559 {
10560   rtx label = gen_label_rtx ();
10561   rtx tmp;
10562
10563   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10564
10565   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10566   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10567   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10568                               gen_rtx_LABEL_REF (VOIDmode, label),
10569                               pc_rtx);
10570   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10571   JUMP_LABEL (tmp) = label;
10572
10573   emit_move_insn (operands[0], operands[1]);
10574   ix86_expand_clear (operands[1]);
10575
10576   emit_label (label);
10577   LABEL_NUSES (label) = 1;
10578
10579   DONE;
10580 })
10581
10582 (define_expand "ashlsi3"
10583   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10584         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10585                    (match_operand:QI 2 "nonmemory_operand" "")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   ""
10588   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10589
10590 (define_insn "*ashlsi3_1"
10591   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10592         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10593                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10594    (clobber (reg:CC FLAGS_REG))]
10595   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10596 {
10597   switch (get_attr_type (insn))
10598     {
10599     case TYPE_ALU:
10600       gcc_assert (operands[2] == const1_rtx);
10601       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10602       return "add{l}\t{%0, %0|%0, %0}";
10603
10604     case TYPE_LEA:
10605       return "#";
10606
10607     default:
10608       if (REG_P (operands[2]))
10609         return "sal{l}\t{%b2, %0|%0, %b2}";
10610       else if (operands[2] == const1_rtx
10611                && (TARGET_SHIFT1 || optimize_size))
10612         return "sal{l}\t%0";
10613       else
10614         return "sal{l}\t{%2, %0|%0, %2}";
10615     }
10616 }
10617   [(set (attr "type")
10618      (cond [(eq_attr "alternative" "1")
10619               (const_string "lea")
10620             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621                           (const_int 0))
10622                       (match_operand 0 "register_operand" ""))
10623                  (match_operand 2 "const1_operand" ""))
10624               (const_string "alu")
10625            ]
10626            (const_string "ishift")))
10627    (set_attr "mode" "SI")])
10628
10629 ;; Convert lea to the lea pattern to avoid flags dependency.
10630 (define_split
10631   [(set (match_operand 0 "register_operand" "")
10632         (ashift (match_operand 1 "index_register_operand" "")
10633                 (match_operand:QI 2 "const_int_operand" "")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "reload_completed
10636    && true_regnum (operands[0]) != true_regnum (operands[1])
10637    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10638   [(const_int 0)]
10639 {
10640   rtx pat;
10641   enum machine_mode mode = GET_MODE (operands[0]);
10642
10643   if (GET_MODE_SIZE (mode) < 4)
10644     operands[0] = gen_lowpart (SImode, operands[0]);
10645   if (mode != Pmode)
10646     operands[1] = gen_lowpart (Pmode, operands[1]);
10647   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10648
10649   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10650   if (Pmode != SImode)
10651     pat = gen_rtx_SUBREG (SImode, pat, 0);
10652   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10653   DONE;
10654 })
10655
10656 ;; Rare case of shifting RSP is handled by generating move and shift
10657 (define_split
10658   [(set (match_operand 0 "register_operand" "")
10659         (ashift (match_operand 1 "register_operand" "")
10660                 (match_operand:QI 2 "const_int_operand" "")))
10661    (clobber (reg:CC FLAGS_REG))]
10662   "reload_completed
10663    && true_regnum (operands[0]) != true_regnum (operands[1])"
10664   [(const_int 0)]
10665 {
10666   rtx pat, clob;
10667   emit_move_insn (operands[0], operands[1]);
10668   pat = gen_rtx_SET (VOIDmode, operands[0],
10669                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10670                                      operands[0], operands[2]));
10671   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10672   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10673   DONE;
10674 })
10675
10676 (define_insn "*ashlsi3_1_zext"
10677   [(set (match_operand:DI 0 "register_operand" "=r,r")
10678         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10679                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       return "add{l}\t{%k0, %k0|%k0, %k0}";
10688
10689     case TYPE_LEA:
10690       return "#";
10691
10692     default:
10693       if (REG_P (operands[2]))
10694         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695       else if (operands[2] == const1_rtx
10696                && (TARGET_SHIFT1 || optimize_size))
10697         return "sal{l}\t%k0";
10698       else
10699         return "sal{l}\t{%2, %k0|%k0, %2}";
10700     }
10701 }
10702   [(set (attr "type")
10703      (cond [(eq_attr "alternative" "1")
10704               (const_string "lea")
10705             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706                      (const_int 0))
10707                  (match_operand 2 "const1_operand" ""))
10708               (const_string "alu")
10709            ]
10710            (const_string "ishift")))
10711    (set_attr "mode" "SI")])
10712
10713 ;; Convert lea to the lea pattern to avoid flags dependency.
10714 (define_split
10715   [(set (match_operand:DI 0 "register_operand" "")
10716         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10717                                 (match_operand:QI 2 "const_int_operand" ""))))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "TARGET_64BIT && reload_completed
10720    && true_regnum (operands[0]) != true_regnum (operands[1])"
10721   [(set (match_dup 0) (zero_extend:DI
10722                         (subreg:SI (mult:SI (match_dup 1)
10723                                             (match_dup 2)) 0)))]
10724 {
10725   operands[1] = gen_lowpart (Pmode, operands[1]);
10726   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10727 })
10728
10729 ;; This pattern can't accept a variable shift count, since shifts by
10730 ;; zero don't affect the flags.  We assume that shifts by constant
10731 ;; zero are optimized away.
10732 (define_insn "*ashlsi3_cmp"
10733   [(set (reg FLAGS_REG)
10734         (compare
10735           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10736                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10737           (const_int 0)))
10738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10739         (ashift:SI (match_dup 1) (match_dup 2)))]
10740   "ix86_match_ccmode (insn, CCGOCmode)
10741    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10742    && (optimize_size
10743        || !TARGET_PARTIAL_FLAG_REG_STALL
10744        || (operands[2] == const1_rtx
10745            && (TARGET_SHIFT1
10746                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10747 {
10748   switch (get_attr_type (insn))
10749     {
10750     case TYPE_ALU:
10751       gcc_assert (operands[2] == const1_rtx);
10752       return "add{l}\t{%0, %0|%0, %0}";
10753
10754     default:
10755       if (REG_P (operands[2]))
10756         return "sal{l}\t{%b2, %0|%0, %b2}";
10757       else if (operands[2] == const1_rtx
10758                && (TARGET_SHIFT1 || optimize_size))
10759         return "sal{l}\t%0";
10760       else
10761         return "sal{l}\t{%2, %0|%0, %2}";
10762     }
10763 }
10764   [(set (attr "type")
10765      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766                           (const_int 0))
10767                       (match_operand 0 "register_operand" ""))
10768                  (match_operand 2 "const1_operand" ""))
10769               (const_string "alu")
10770            ]
10771            (const_string "ishift")))
10772    (set_attr "mode" "SI")])
10773
10774 (define_insn "*ashlsi3_cconly"
10775   [(set (reg FLAGS_REG)
10776         (compare
10777           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10778                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10779           (const_int 0)))
10780    (clobber (match_scratch:SI 0 "=r"))]
10781   "ix86_match_ccmode (insn, CCGOCmode)
10782    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10783    && (optimize_size
10784        || !TARGET_PARTIAL_FLAG_REG_STALL
10785        || (operands[2] == const1_rtx
10786            && (TARGET_SHIFT1
10787                || TARGET_DOUBLE_WITH_ADD)))"
10788 {
10789   switch (get_attr_type (insn))
10790     {
10791     case TYPE_ALU:
10792       gcc_assert (operands[2] == const1_rtx);
10793       return "add{l}\t{%0, %0|%0, %0}";
10794
10795     default:
10796       if (REG_P (operands[2]))
10797         return "sal{l}\t{%b2, %0|%0, %b2}";
10798       else if (operands[2] == const1_rtx
10799                && (TARGET_SHIFT1 || optimize_size))
10800         return "sal{l}\t%0";
10801       else
10802         return "sal{l}\t{%2, %0|%0, %2}";
10803     }
10804 }
10805   [(set (attr "type")
10806      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807                           (const_int 0))
10808                       (match_operand 0 "register_operand" ""))
10809                  (match_operand 2 "const1_operand" ""))
10810               (const_string "alu")
10811            ]
10812            (const_string "ishift")))
10813    (set_attr "mode" "SI")])
10814
10815 (define_insn "*ashlsi3_cmp_zext"
10816   [(set (reg FLAGS_REG)
10817         (compare
10818           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10819                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10820           (const_int 0)))
10821    (set (match_operand:DI 0 "register_operand" "=r")
10822         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10823   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10824    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10825    && (optimize_size
10826        || !TARGET_PARTIAL_FLAG_REG_STALL
10827        || (operands[2] == const1_rtx
10828            && (TARGET_SHIFT1
10829                || TARGET_DOUBLE_WITH_ADD)))"
10830 {
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       gcc_assert (operands[2] == const1_rtx);
10835       return "add{l}\t{%k0, %k0|%k0, %k0}";
10836
10837     default:
10838       if (REG_P (operands[2]))
10839         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10840       else if (operands[2] == const1_rtx
10841                && (TARGET_SHIFT1 || optimize_size))
10842         return "sal{l}\t%k0";
10843       else
10844         return "sal{l}\t{%2, %k0|%k0, %2}";
10845     }
10846 }
10847   [(set (attr "type")
10848      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10849                      (const_int 0))
10850                  (match_operand 2 "const1_operand" ""))
10851               (const_string "alu")
10852            ]
10853            (const_string "ishift")))
10854    (set_attr "mode" "SI")])
10855
10856 (define_expand "ashlhi3"
10857   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10858         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10859                    (match_operand:QI 2 "nonmemory_operand" "")))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "TARGET_HIMODE_MATH"
10862   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10863
10864 (define_insn "*ashlhi3_1_lea"
10865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10866         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10867                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "!TARGET_PARTIAL_REG_STALL
10870    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10871 {
10872   switch (get_attr_type (insn))
10873     {
10874     case TYPE_LEA:
10875       return "#";
10876     case TYPE_ALU:
10877       gcc_assert (operands[2] == const1_rtx);
10878       return "add{w}\t{%0, %0|%0, %0}";
10879
10880     default:
10881       if (REG_P (operands[2]))
10882         return "sal{w}\t{%b2, %0|%0, %b2}";
10883       else if (operands[2] == const1_rtx
10884                && (TARGET_SHIFT1 || optimize_size))
10885         return "sal{w}\t%0";
10886       else
10887         return "sal{w}\t{%2, %0|%0, %2}";
10888     }
10889 }
10890   [(set (attr "type")
10891      (cond [(eq_attr "alternative" "1")
10892               (const_string "lea")
10893             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894                           (const_int 0))
10895                       (match_operand 0 "register_operand" ""))
10896                  (match_operand 2 "const1_operand" ""))
10897               (const_string "alu")
10898            ]
10899            (const_string "ishift")))
10900    (set_attr "mode" "HI,SI")])
10901
10902 (define_insn "*ashlhi3_1"
10903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10904         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10905                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "TARGET_PARTIAL_REG_STALL
10908    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10909 {
10910   switch (get_attr_type (insn))
10911     {
10912     case TYPE_ALU:
10913       gcc_assert (operands[2] == const1_rtx);
10914       return "add{w}\t{%0, %0|%0, %0}";
10915
10916     default:
10917       if (REG_P (operands[2]))
10918         return "sal{w}\t{%b2, %0|%0, %b2}";
10919       else if (operands[2] == const1_rtx
10920                && (TARGET_SHIFT1 || optimize_size))
10921         return "sal{w}\t%0";
10922       else
10923         return "sal{w}\t{%2, %0|%0, %2}";
10924     }
10925 }
10926   [(set (attr "type")
10927      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10928                           (const_int 0))
10929                       (match_operand 0 "register_operand" ""))
10930                  (match_operand 2 "const1_operand" ""))
10931               (const_string "alu")
10932            ]
10933            (const_string "ishift")))
10934    (set_attr "mode" "HI")])
10935
10936 ;; This pattern can't accept a variable shift count, since shifts by
10937 ;; zero don't affect the flags.  We assume that shifts by constant
10938 ;; zero are optimized away.
10939 (define_insn "*ashlhi3_cmp"
10940   [(set (reg FLAGS_REG)
10941         (compare
10942           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10944           (const_int 0)))
10945    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10946         (ashift:HI (match_dup 1) (match_dup 2)))]
10947   "ix86_match_ccmode (insn, CCGOCmode)
10948    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10949    && (optimize_size
10950        || !TARGET_PARTIAL_FLAG_REG_STALL
10951        || (operands[2] == const1_rtx
10952            && (TARGET_SHIFT1
10953                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10954 {
10955   switch (get_attr_type (insn))
10956     {
10957     case TYPE_ALU:
10958       gcc_assert (operands[2] == const1_rtx);
10959       return "add{w}\t{%0, %0|%0, %0}";
10960
10961     default:
10962       if (REG_P (operands[2]))
10963         return "sal{w}\t{%b2, %0|%0, %b2}";
10964       else if (operands[2] == const1_rtx
10965                && (TARGET_SHIFT1 || optimize_size))
10966         return "sal{w}\t%0";
10967       else
10968         return "sal{w}\t{%2, %0|%0, %2}";
10969     }
10970 }
10971   [(set (attr "type")
10972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973                           (const_int 0))
10974                       (match_operand 0 "register_operand" ""))
10975                  (match_operand 2 "const1_operand" ""))
10976               (const_string "alu")
10977            ]
10978            (const_string "ishift")))
10979    (set_attr "mode" "HI")])
10980
10981 (define_insn "*ashlhi3_cconly"
10982   [(set (reg FLAGS_REG)
10983         (compare
10984           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10986           (const_int 0)))
10987    (clobber (match_scratch:HI 0 "=r"))]
10988   "ix86_match_ccmode (insn, CCGOCmode)
10989    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10990    && (optimize_size
10991        || !TARGET_PARTIAL_FLAG_REG_STALL
10992        || (operands[2] == const1_rtx
10993            && (TARGET_SHIFT1
10994                || TARGET_DOUBLE_WITH_ADD)))"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{w}\t{%0, %0|%0, %0}";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{w}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{w}\t%0";
11008       else
11009         return "sal{w}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "HI")])
11021
11022 (define_expand "ashlqi3"
11023   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11024         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11025                    (match_operand:QI 2 "nonmemory_operand" "")))
11026    (clobber (reg:CC FLAGS_REG))]
11027   "TARGET_QIMODE_MATH"
11028   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11029
11030 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11031
11032 (define_insn "*ashlqi3_1_lea"
11033   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11034         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11035                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11036    (clobber (reg:CC FLAGS_REG))]
11037   "!TARGET_PARTIAL_REG_STALL
11038    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11039 {
11040   switch (get_attr_type (insn))
11041     {
11042     case TYPE_LEA:
11043       return "#";
11044     case TYPE_ALU:
11045       gcc_assert (operands[2] == const1_rtx);
11046       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11047         return "add{l}\t{%k0, %k0|%k0, %k0}";
11048       else
11049         return "add{b}\t{%0, %0|%0, %0}";
11050
11051     default:
11052       if (REG_P (operands[2]))
11053         {
11054           if (get_attr_mode (insn) == MODE_SI)
11055             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11056           else
11057             return "sal{b}\t{%b2, %0|%0, %b2}";
11058         }
11059       else if (operands[2] == const1_rtx
11060                && (TARGET_SHIFT1 || optimize_size))
11061         {
11062           if (get_attr_mode (insn) == MODE_SI)
11063             return "sal{l}\t%0";
11064           else
11065             return "sal{b}\t%0";
11066         }
11067       else
11068         {
11069           if (get_attr_mode (insn) == MODE_SI)
11070             return "sal{l}\t{%2, %k0|%k0, %2}";
11071           else
11072             return "sal{b}\t{%2, %0|%0, %2}";
11073         }
11074     }
11075 }
11076   [(set (attr "type")
11077      (cond [(eq_attr "alternative" "2")
11078               (const_string "lea")
11079             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11080                           (const_int 0))
11081                       (match_operand 0 "register_operand" ""))
11082                  (match_operand 2 "const1_operand" ""))
11083               (const_string "alu")
11084            ]
11085            (const_string "ishift")))
11086    (set_attr "mode" "QI,SI,SI")])
11087
11088 (define_insn "*ashlqi3_1"
11089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11090         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11091                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11092    (clobber (reg:CC FLAGS_REG))]
11093   "TARGET_PARTIAL_REG_STALL
11094    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11095 {
11096   switch (get_attr_type (insn))
11097     {
11098     case TYPE_ALU:
11099       gcc_assert (operands[2] == const1_rtx);
11100       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11101         return "add{l}\t{%k0, %k0|%k0, %k0}";
11102       else
11103         return "add{b}\t{%0, %0|%0, %0}";
11104
11105     default:
11106       if (REG_P (operands[2]))
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11110           else
11111             return "sal{b}\t{%b2, %0|%0, %b2}";
11112         }
11113       else if (operands[2] == const1_rtx
11114                && (TARGET_SHIFT1 || optimize_size))
11115         {
11116           if (get_attr_mode (insn) == MODE_SI)
11117             return "sal{l}\t%0";
11118           else
11119             return "sal{b}\t%0";
11120         }
11121       else
11122         {
11123           if (get_attr_mode (insn) == MODE_SI)
11124             return "sal{l}\t{%2, %k0|%k0, %2}";
11125           else
11126             return "sal{b}\t{%2, %0|%0, %2}";
11127         }
11128     }
11129 }
11130   [(set (attr "type")
11131      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132                           (const_int 0))
11133                       (match_operand 0 "register_operand" ""))
11134                  (match_operand 2 "const1_operand" ""))
11135               (const_string "alu")
11136            ]
11137            (const_string "ishift")))
11138    (set_attr "mode" "QI,SI")])
11139
11140 ;; This pattern can't accept a variable shift count, since shifts by
11141 ;; zero don't affect the flags.  We assume that shifts by constant
11142 ;; zero are optimized away.
11143 (define_insn "*ashlqi3_cmp"
11144   [(set (reg FLAGS_REG)
11145         (compare
11146           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11147                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11148           (const_int 0)))
11149    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11150         (ashift:QI (match_dup 1) (match_dup 2)))]
11151   "ix86_match_ccmode (insn, CCGOCmode)
11152    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11153    && (optimize_size
11154        || !TARGET_PARTIAL_FLAG_REG_STALL
11155        || (operands[2] == const1_rtx
11156            && (TARGET_SHIFT1
11157                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11158 {
11159   switch (get_attr_type (insn))
11160     {
11161     case TYPE_ALU:
11162       gcc_assert (operands[2] == const1_rtx);
11163       return "add{b}\t{%0, %0|%0, %0}";
11164
11165     default:
11166       if (REG_P (operands[2]))
11167         return "sal{b}\t{%b2, %0|%0, %b2}";
11168       else if (operands[2] == const1_rtx
11169                && (TARGET_SHIFT1 || optimize_size))
11170         return "sal{b}\t%0";
11171       else
11172         return "sal{b}\t{%2, %0|%0, %2}";
11173     }
11174 }
11175   [(set (attr "type")
11176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11177                           (const_int 0))
11178                       (match_operand 0 "register_operand" ""))
11179                  (match_operand 2 "const1_operand" ""))
11180               (const_string "alu")
11181            ]
11182            (const_string "ishift")))
11183    (set_attr "mode" "QI")])
11184
11185 (define_insn "*ashlqi3_cconly"
11186   [(set (reg FLAGS_REG)
11187         (compare
11188           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11189                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11190           (const_int 0)))
11191    (clobber (match_scratch:QI 0 "=q"))]
11192   "ix86_match_ccmode (insn, CCGOCmode)
11193    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11194    && (optimize_size
11195        || !TARGET_PARTIAL_FLAG_REG_STALL
11196        || (operands[2] == const1_rtx
11197            && (TARGET_SHIFT1
11198                || TARGET_DOUBLE_WITH_ADD)))"
11199 {
11200   switch (get_attr_type (insn))
11201     {
11202     case TYPE_ALU:
11203       gcc_assert (operands[2] == const1_rtx);
11204       return "add{b}\t{%0, %0|%0, %0}";
11205
11206     default:
11207       if (REG_P (operands[2]))
11208         return "sal{b}\t{%b2, %0|%0, %b2}";
11209       else if (operands[2] == const1_rtx
11210                && (TARGET_SHIFT1 || optimize_size))
11211         return "sal{b}\t%0";
11212       else
11213         return "sal{b}\t{%2, %0|%0, %2}";
11214     }
11215 }
11216   [(set (attr "type")
11217      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218                           (const_int 0))
11219                       (match_operand 0 "register_operand" ""))
11220                  (match_operand 2 "const1_operand" ""))
11221               (const_string "alu")
11222            ]
11223            (const_string "ishift")))
11224    (set_attr "mode" "QI")])
11225
11226 ;; See comment above `ashldi3' about how this works.
11227
11228 (define_expand "ashrti3"
11229   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11230                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11231                                 (match_operand:QI 2 "nonmemory_operand" "")))
11232               (clobber (reg:CC FLAGS_REG))])]
11233   "TARGET_64BIT"
11234 {
11235   if (! immediate_operand (operands[2], QImode))
11236     {
11237       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11238       DONE;
11239     }
11240   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11241   DONE;
11242 })
11243
11244 (define_insn "ashrti3_1"
11245   [(set (match_operand:TI 0 "register_operand" "=r")
11246         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11247                      (match_operand:QI 2 "register_operand" "c")))
11248    (clobber (match_scratch:DI 3 "=&r"))
11249    (clobber (reg:CC FLAGS_REG))]
11250   "TARGET_64BIT"
11251   "#"
11252   [(set_attr "type" "multi")])
11253
11254 (define_insn "*ashrti3_2"
11255   [(set (match_operand:TI 0 "register_operand" "=r")
11256         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11257                      (match_operand:QI 2 "immediate_operand" "O")))
11258    (clobber (reg:CC FLAGS_REG))]
11259   "TARGET_64BIT"
11260   "#"
11261   [(set_attr "type" "multi")])
11262
11263 (define_split
11264   [(set (match_operand:TI 0 "register_operand" "")
11265         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11266                      (match_operand:QI 2 "register_operand" "")))
11267    (clobber (match_scratch:DI 3 ""))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_64BIT && reload_completed"
11270   [(const_int 0)]
11271   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11272
11273 (define_split
11274   [(set (match_operand:TI 0 "register_operand" "")
11275         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11276                      (match_operand:QI 2 "immediate_operand" "")))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && reload_completed"
11279   [(const_int 0)]
11280   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11281
11282 (define_insn "x86_64_shrd"
11283   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11284         (ior:DI (ashiftrt:DI (match_dup 0)
11285                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11286                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11287                   (minus:QI (const_int 64) (match_dup 2)))))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "TARGET_64BIT"
11290   "@
11291    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11292    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "prefix_0f" "1")
11295    (set_attr "mode" "DI")
11296    (set_attr "athlon_decode" "vector")])
11297
11298 (define_expand "ashrdi3"
11299   [(set (match_operand:DI 0 "shiftdi_operand" "")
11300         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11301                      (match_operand:QI 2 "nonmemory_operand" "")))]
11302   ""
11303   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11304
11305 (define_insn "*ashrdi3_63_rex64"
11306   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11307         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11308                      (match_operand:DI 2 "const_int_operand" "i,i")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "TARGET_64BIT && INTVAL (operands[2]) == 63
11311    && (TARGET_USE_CLTD || optimize_size)
11312    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11313   "@
11314    {cqto|cqo}
11315    sar{q}\t{%2, %0|%0, %2}"
11316   [(set_attr "type" "imovx,ishift")
11317    (set_attr "prefix_0f" "0,*")
11318    (set_attr "length_immediate" "0,*")
11319    (set_attr "modrm" "0,1")
11320    (set_attr "mode" "DI")])
11321
11322 (define_insn "*ashrdi3_1_one_bit_rex64"
11323   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11324         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11325                      (match_operand:QI 2 "const1_operand" "")))
11326    (clobber (reg:CC FLAGS_REG))]
11327   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11328    && (TARGET_SHIFT1 || optimize_size)"
11329   "sar{q}\t%0"
11330   [(set_attr "type" "ishift")
11331    (set (attr "length") 
11332      (if_then_else (match_operand:DI 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11335
11336 (define_insn "*ashrdi3_1_rex64"
11337   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11338         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11339                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11340    (clobber (reg:CC FLAGS_REG))]
11341   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11342   "@
11343    sar{q}\t{%2, %0|%0, %2}
11344    sar{q}\t{%b2, %0|%0, %b2}"
11345   [(set_attr "type" "ishift")
11346    (set_attr "mode" "DI")])
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11355                        (match_operand:QI 2 "const1_operand" ""))
11356           (const_int 0)))
11357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11360    && (TARGET_SHIFT1 || optimize_size)
11361    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11362   "sar{q}\t%0"
11363   [(set_attr "type" "ishift")
11364    (set (attr "length") 
11365      (if_then_else (match_operand:DI 0 "register_operand" "") 
11366         (const_string "2")
11367         (const_string "*")))])
11368
11369 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11370   [(set (reg FLAGS_REG)
11371         (compare
11372           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11373                        (match_operand:QI 2 "const1_operand" ""))
11374           (const_int 0)))
11375    (clobber (match_scratch:DI 0 "=r"))]
11376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11377    && (TARGET_SHIFT1 || optimize_size)
11378    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11379   "sar{q}\t%0"
11380   [(set_attr "type" "ishift")
11381    (set_attr "length" "2")])
11382
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags.  We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_cmp_rex64"
11387   [(set (reg FLAGS_REG)
11388         (compare
11389           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390                        (match_operand:QI 2 "const_int_operand" "n"))
11391           (const_int 0)))
11392    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11396    && (optimize_size
11397        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398   "sar{q}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "DI")])
11401
11402 (define_insn "*ashrdi3_cconly_rex64"
11403   [(set (reg FLAGS_REG)
11404         (compare
11405           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11406                        (match_operand:QI 2 "const_int_operand" "n"))
11407           (const_int 0)))
11408    (clobber (match_scratch:DI 0 "=r"))]
11409   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11411    && (optimize_size
11412        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11413   "sar{q}\t{%2, %0|%0, %2}"
11414   [(set_attr "type" "ishift")
11415    (set_attr "mode" "DI")])
11416
11417 (define_insn "*ashrdi3_1"
11418   [(set (match_operand:DI 0 "register_operand" "=r")
11419         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11420                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11421    (clobber (reg:CC FLAGS_REG))]
11422   "!TARGET_64BIT"
11423   "#"
11424   [(set_attr "type" "multi")])
11425
11426 ;; By default we don't ask for a scratch register, because when DImode
11427 ;; values are manipulated, registers are already at a premium.  But if
11428 ;; we have one handy, we won't turn it away.
11429 (define_peephole2
11430   [(match_scratch:SI 3 "r")
11431    (parallel [(set (match_operand:DI 0 "register_operand" "")
11432                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11433                                 (match_operand:QI 2 "nonmemory_operand" "")))
11434               (clobber (reg:CC FLAGS_REG))])
11435    (match_dup 3)]
11436   "!TARGET_64BIT && TARGET_CMOVE"
11437   [(const_int 0)]
11438   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11439
11440 (define_split
11441   [(set (match_operand:DI 0 "register_operand" "")
11442         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11443                      (match_operand:QI 2 "nonmemory_operand" "")))
11444    (clobber (reg:CC FLAGS_REG))]
11445   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11446                      ? flow2_completed : reload_completed)"
11447   [(const_int 0)]
11448   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11449
11450 (define_insn "x86_shrd_1"
11451   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11452         (ior:SI (ashiftrt:SI (match_dup 0)
11453                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11454                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11455                   (minus:QI (const_int 32) (match_dup 2)))))
11456    (clobber (reg:CC FLAGS_REG))]
11457   ""
11458   "@
11459    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11460    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11461   [(set_attr "type" "ishift")
11462    (set_attr "prefix_0f" "1")
11463    (set_attr "pent_pair" "np")
11464    (set_attr "mode" "SI")])
11465
11466 (define_expand "x86_shift_adj_3"
11467   [(use (match_operand:SI 0 "register_operand" ""))
11468    (use (match_operand:SI 1 "register_operand" ""))
11469    (use (match_operand:QI 2 "register_operand" ""))]
11470   ""
11471 {
11472   rtx label = gen_label_rtx ();
11473   rtx tmp;
11474
11475   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11476
11477   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11478   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11479   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11480                               gen_rtx_LABEL_REF (VOIDmode, label),
11481                               pc_rtx);
11482   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11483   JUMP_LABEL (tmp) = label;
11484
11485   emit_move_insn (operands[0], operands[1]);
11486   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11487
11488   emit_label (label);
11489   LABEL_NUSES (label) = 1;
11490
11491   DONE;
11492 })
11493
11494 (define_insn "ashrsi3_31"
11495   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11496         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11497                      (match_operand:SI 2 "const_int_operand" "i,i")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11500    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11501   "@
11502    {cltd|cdq}
11503    sar{l}\t{%2, %0|%0, %2}"
11504   [(set_attr "type" "imovx,ishift")
11505    (set_attr "prefix_0f" "0,*")
11506    (set_attr "length_immediate" "0,*")
11507    (set_attr "modrm" "0,1")
11508    (set_attr "mode" "SI")])
11509
11510 (define_insn "*ashrsi3_31_zext"
11511   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11512         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11513                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11514    (clobber (reg:CC FLAGS_REG))]
11515   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11516    && INTVAL (operands[2]) == 31
11517    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11518   "@
11519    {cltd|cdq}
11520    sar{l}\t{%2, %k0|%k0, %2}"
11521   [(set_attr "type" "imovx,ishift")
11522    (set_attr "prefix_0f" "0,*")
11523    (set_attr "length_immediate" "0,*")
11524    (set_attr "modrm" "0,1")
11525    (set_attr "mode" "SI")])
11526
11527 (define_expand "ashrsi3"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11530                      (match_operand:QI 2 "nonmemory_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   ""
11533   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11534
11535 (define_insn "*ashrsi3_1_one_bit"
11536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11537         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11538                      (match_operand:QI 2 "const1_operand" "")))
11539    (clobber (reg:CC FLAGS_REG))]
11540   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11541    && (TARGET_SHIFT1 || optimize_size)"
11542   "sar{l}\t%0"
11543   [(set_attr "type" "ishift")
11544    (set (attr "length") 
11545      (if_then_else (match_operand:SI 0 "register_operand" "") 
11546         (const_string "2")
11547         (const_string "*")))])
11548
11549 (define_insn "*ashrsi3_1_one_bit_zext"
11550   [(set (match_operand:DI 0 "register_operand" "=r")
11551         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11552                                      (match_operand:QI 2 "const1_operand" ""))))
11553    (clobber (reg:CC FLAGS_REG))]
11554   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11555    && (TARGET_SHIFT1 || optimize_size)"
11556   "sar{l}\t%k0"
11557   [(set_attr "type" "ishift")
11558    (set_attr "length" "2")])
11559
11560 (define_insn "*ashrsi3_1"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11563                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11566   "@
11567    sar{l}\t{%2, %0|%0, %2}
11568    sar{l}\t{%b2, %0|%0, %b2}"
11569   [(set_attr "type" "ishift")
11570    (set_attr "mode" "SI")])
11571
11572 (define_insn "*ashrsi3_1_zext"
11573   [(set (match_operand:DI 0 "register_operand" "=r,r")
11574         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11575                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578   "@
11579    sar{l}\t{%2, %k0|%k0, %2}
11580    sar{l}\t{%b2, %k0|%k0, %b2}"
11581   [(set_attr "type" "ishift")
11582    (set_attr "mode" "SI")])
11583
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags.  We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrsi3_one_bit_cmp"
11588   [(set (reg FLAGS_REG)
11589         (compare
11590           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11591                        (match_operand:QI 2 "const1_operand" ""))
11592           (const_int 0)))
11593    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11595   "ix86_match_ccmode (insn, CCGOCmode)
11596    && (TARGET_SHIFT1 || optimize_size)
11597    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11598   "sar{l}\t%0"
11599   [(set_attr "type" "ishift")
11600    (set (attr "length") 
11601      (if_then_else (match_operand:SI 0 "register_operand" "") 
11602         (const_string "2")
11603         (const_string "*")))])
11604
11605 (define_insn "*ashrsi3_one_bit_cconly"
11606   [(set (reg FLAGS_REG)
11607         (compare
11608           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11609                        (match_operand:QI 2 "const1_operand" ""))
11610           (const_int 0)))
11611    (clobber (match_scratch:SI 0 "=r"))]
11612   "ix86_match_ccmode (insn, CCGOCmode)
11613    && (TARGET_SHIFT1 || optimize_size)
11614    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11615   "sar{l}\t%0"
11616   [(set_attr "type" "ishift")
11617    (set_attr "length" "2")])
11618
11619 (define_insn "*ashrsi3_one_bit_cmp_zext"
11620   [(set (reg FLAGS_REG)
11621         (compare
11622           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11623                        (match_operand:QI 2 "const1_operand" ""))
11624           (const_int 0)))
11625    (set (match_operand:DI 0 "register_operand" "=r")
11626         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11627   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11628    && (TARGET_SHIFT1 || optimize_size)
11629    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11630   "sar{l}\t%k0"
11631   [(set_attr "type" "ishift")
11632    (set_attr "length" "2")])
11633
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags.  We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrsi3_cmp"
11638   [(set (reg FLAGS_REG)
11639         (compare
11640           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642           (const_int 0)))
11643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11644         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11645   "ix86_match_ccmode (insn, CCGOCmode)
11646    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11647    && (optimize_size
11648        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649   "sar{l}\t{%2, %0|%0, %2}"
11650   [(set_attr "type" "ishift")
11651    (set_attr "mode" "SI")])
11652
11653 (define_insn "*ashrsi3_cconly"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11658           (const_int 0)))
11659    (clobber (match_scratch:SI 0 "=r"))]
11660   "ix86_match_ccmode (insn, CCGOCmode)
11661    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11662    && (optimize_size
11663        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11664   "sar{l}\t{%2, %0|%0, %2}"
11665   [(set_attr "type" "ishift")
11666    (set_attr "mode" "SI")])
11667
11668 (define_insn "*ashrsi3_cmp_zext"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11672                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673           (const_int 0)))
11674    (set (match_operand:DI 0 "register_operand" "=r")
11675         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11678    && (optimize_size
11679        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11680   "sar{l}\t{%2, %k0|%k0, %2}"
11681   [(set_attr "type" "ishift")
11682    (set_attr "mode" "SI")])
11683
11684 (define_expand "ashrhi3"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687                      (match_operand:QI 2 "nonmemory_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_HIMODE_MATH"
11690   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11691
11692 (define_insn "*ashrhi3_1_one_bit"
11693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const1_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698    && (TARGET_SHIFT1 || optimize_size)"
11699   "sar{w}\t%0"
11700   [(set_attr "type" "ishift")
11701    (set (attr "length") 
11702      (if_then_else (match_operand 0 "register_operand" "") 
11703         (const_string "2")
11704         (const_string "*")))])
11705
11706 (define_insn "*ashrhi3_1"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11712   "@
11713    sar{w}\t{%2, %0|%0, %2}
11714    sar{w}\t{%b2, %0|%0, %b2}"
11715   [(set_attr "type" "ishift")
11716    (set_attr "mode" "HI")])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*ashrhi3_one_bit_cmp"
11722   [(set (reg FLAGS_REG)
11723         (compare
11724           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11732   "sar{w}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 (define_insn "*ashrhi3_one_bit_cconly"
11740   [(set (reg FLAGS_REG)
11741         (compare
11742           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11743                        (match_operand:QI 2 "const1_operand" ""))
11744           (const_int 0)))
11745    (clobber (match_scratch:HI 0 "=r"))]
11746   "ix86_match_ccmode (insn, CCGOCmode)
11747    && (TARGET_SHIFT1 || optimize_size)
11748    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11749   "sar{w}\t%0"
11750   [(set_attr "type" "ishift")
11751    (set_attr "length" "2")])
11752
11753 ;; This pattern can't accept a variable shift count, since shifts by
11754 ;; zero don't affect the flags.  We assume that shifts by constant
11755 ;; zero are optimized away.
11756 (define_insn "*ashrhi3_cmp"
11757   [(set (reg FLAGS_REG)
11758         (compare
11759           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11760                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761           (const_int 0)))
11762    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11763         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11764   "ix86_match_ccmode (insn, CCGOCmode)
11765    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11766    && (optimize_size
11767        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768   "sar{w}\t{%2, %0|%0, %2}"
11769   [(set_attr "type" "ishift")
11770    (set_attr "mode" "HI")])
11771
11772 (define_insn "*ashrhi3_cconly"
11773   [(set (reg FLAGS_REG)
11774         (compare
11775           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11776                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11777           (const_int 0)))
11778    (clobber (match_scratch:HI 0 "=r"))]
11779   "ix86_match_ccmode (insn, CCGOCmode)
11780    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11781    && (optimize_size
11782        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11783   "sar{w}\t{%2, %0|%0, %2}"
11784   [(set_attr "type" "ishift")
11785    (set_attr "mode" "HI")])
11786
11787 (define_expand "ashrqi3"
11788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11789         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11790                      (match_operand:QI 2 "nonmemory_operand" "")))
11791    (clobber (reg:CC FLAGS_REG))]
11792   "TARGET_QIMODE_MATH"
11793   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11794
11795 (define_insn "*ashrqi3_1_one_bit"
11796   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11797         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11798                      (match_operand:QI 2 "const1_operand" "")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11801    && (TARGET_SHIFT1 || optimize_size)"
11802   "sar{b}\t%0"
11803   [(set_attr "type" "ishift")
11804    (set (attr "length") 
11805      (if_then_else (match_operand 0 "register_operand" "") 
11806         (const_string "2")
11807         (const_string "*")))])
11808
11809 (define_insn "*ashrqi3_1_one_bit_slp"
11810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11811         (ashiftrt:QI (match_dup 0)
11812                      (match_operand:QI 1 "const1_operand" "")))
11813    (clobber (reg:CC FLAGS_REG))]
11814   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11815    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11816    && (TARGET_SHIFT1 || optimize_size)"
11817   "sar{b}\t%0"
11818   [(set_attr "type" "ishift1")
11819    (set (attr "length") 
11820      (if_then_else (match_operand 0 "register_operand" "") 
11821         (const_string "2")
11822         (const_string "*")))])
11823
11824 (define_insn "*ashrqi3_1"
11825   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11826         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11827                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11830   "@
11831    sar{b}\t{%2, %0|%0, %2}
11832    sar{b}\t{%b2, %0|%0, %b2}"
11833   [(set_attr "type" "ishift")
11834    (set_attr "mode" "QI")])
11835
11836 (define_insn "*ashrqi3_1_slp"
11837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838         (ashiftrt:QI (match_dup 0)
11839                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11843   "@
11844    sar{b}\t{%1, %0|%0, %1}
11845    sar{b}\t{%b1, %0|%0, %b1}"
11846   [(set_attr "type" "ishift1")
11847    (set_attr "mode" "QI")])
11848
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags.  We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*ashrqi3_one_bit_cmp"
11853   [(set (reg FLAGS_REG)
11854         (compare
11855           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856                        (match_operand:QI 2 "const1_operand" "I"))
11857           (const_int 0)))
11858    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11859         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11860   "ix86_match_ccmode (insn, CCGOCmode)
11861    && (TARGET_SHIFT1 || optimize_size)
11862    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11863   "sar{b}\t%0"
11864   [(set_attr "type" "ishift")
11865    (set (attr "length") 
11866      (if_then_else (match_operand 0 "register_operand" "") 
11867         (const_string "2")
11868         (const_string "*")))])
11869
11870 (define_insn "*ashrqi3_one_bit_cconly"
11871   [(set (reg FLAGS_REG)
11872         (compare
11873           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const1_operand" "I"))
11875           (const_int 0)))
11876    (clobber (match_scratch:QI 0 "=q"))]
11877   "ix86_match_ccmode (insn, CCGOCmode)
11878    && (TARGET_SHIFT1 || optimize_size)
11879    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11880   "sar{b}\t%0"
11881   [(set_attr "type" "ishift")
11882    (set_attr "length" "2")])
11883
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags.  We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*ashrqi3_cmp"
11888   [(set (reg FLAGS_REG)
11889         (compare
11890           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11891                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11892           (const_int 0)))
11893    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11894         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11895   "ix86_match_ccmode (insn, CCGOCmode)
11896    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11897    && (optimize_size
11898        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899   "sar{b}\t{%2, %0|%0, %2}"
11900   [(set_attr "type" "ishift")
11901    (set_attr "mode" "QI")])
11902
11903 (define_insn "*ashrqi3_cconly"
11904   [(set (reg FLAGS_REG)
11905         (compare
11906           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11907                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908           (const_int 0)))
11909    (clobber (match_scratch:QI 0 "=q"))]
11910   "ix86_match_ccmode (insn, CCGOCmode)
11911    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11912    && (optimize_size
11913        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11914   "sar{b}\t{%2, %0|%0, %2}"
11915   [(set_attr "type" "ishift")
11916    (set_attr "mode" "QI")])
11917
11918 \f
11919 ;; Logical shift instructions
11920
11921 ;; See comment above `ashldi3' about how this works.
11922
11923 (define_expand "lshrti3"
11924   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11925                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11926                                 (match_operand:QI 2 "nonmemory_operand" "")))
11927               (clobber (reg:CC FLAGS_REG))])]
11928   "TARGET_64BIT"
11929 {
11930   if (! immediate_operand (operands[2], QImode))
11931     {
11932       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11933       DONE;
11934     }
11935   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11936   DONE;
11937 })
11938
11939 (define_insn "lshrti3_1"
11940   [(set (match_operand:TI 0 "register_operand" "=r")
11941         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11942                      (match_operand:QI 2 "register_operand" "c")))
11943    (clobber (match_scratch:DI 3 "=&r"))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "TARGET_64BIT"
11946   "#"
11947   [(set_attr "type" "multi")])
11948
11949 (define_insn "*lshrti3_2"
11950   [(set (match_operand:TI 0 "register_operand" "=r")
11951         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11952                      (match_operand:QI 2 "immediate_operand" "O")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "TARGET_64BIT"
11955   "#"
11956   [(set_attr "type" "multi")])
11957
11958 (define_split 
11959   [(set (match_operand:TI 0 "register_operand" "")
11960         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11961                      (match_operand:QI 2 "register_operand" "")))
11962    (clobber (match_scratch:DI 3 ""))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "TARGET_64BIT && reload_completed"
11965   [(const_int 0)]
11966   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11967
11968 (define_split 
11969   [(set (match_operand:TI 0 "register_operand" "")
11970         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11971                      (match_operand:QI 2 "immediate_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "TARGET_64BIT && reload_completed"
11974   [(const_int 0)]
11975   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11976
11977 (define_expand "lshrdi3"
11978   [(set (match_operand:DI 0 "shiftdi_operand" "")
11979         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11980                      (match_operand:QI 2 "nonmemory_operand" "")))]
11981   ""
11982   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11983
11984 (define_insn "*lshrdi3_1_one_bit_rex64"
11985   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11987                      (match_operand:QI 2 "const1_operand" "")))
11988    (clobber (reg:CC FLAGS_REG))]
11989   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11990    && (TARGET_SHIFT1 || optimize_size)"
11991   "shr{q}\t%0"
11992   [(set_attr "type" "ishift")
11993    (set (attr "length") 
11994      (if_then_else (match_operand:DI 0 "register_operand" "") 
11995         (const_string "2")
11996         (const_string "*")))])
11997
11998 (define_insn "*lshrdi3_1_rex64"
11999   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12000         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12001                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004   "@
12005    shr{q}\t{%2, %0|%0, %2}
12006    shr{q}\t{%b2, %0|%0, %b2}"
12007   [(set_attr "type" "ishift")
12008    (set_attr "mode" "DI")])
12009
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags.  We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const1_operand" ""))
12018           (const_int 0)))
12019    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12021   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12022    && (TARGET_SHIFT1 || optimize_size)
12023    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12024   "shr{q}\t%0"
12025   [(set_attr "type" "ishift")
12026    (set (attr "length") 
12027      (if_then_else (match_operand:DI 0 "register_operand" "") 
12028         (const_string "2")
12029         (const_string "*")))])
12030
12031 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const1_operand" ""))
12036           (const_int 0)))
12037    (clobber (match_scratch:DI 0 "=r"))]
12038   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12039    && (TARGET_SHIFT1 || optimize_size)
12040    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12041   "shr{q}\t%0"
12042   [(set_attr "type" "ishift")
12043    (set_attr "length" "2")])
12044
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags.  We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrdi3_cmp_rex64"
12049   [(set (reg FLAGS_REG)
12050         (compare
12051           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052                        (match_operand:QI 2 "const_int_operand" "e"))
12053           (const_int 0)))
12054    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12055         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12056   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12058    && (optimize_size
12059        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060   "shr{q}\t{%2, %0|%0, %2}"
12061   [(set_attr "type" "ishift")
12062    (set_attr "mode" "DI")])
12063
12064 (define_insn "*lshrdi3_cconly_rex64"
12065   [(set (reg FLAGS_REG)
12066         (compare
12067           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12068                        (match_operand:QI 2 "const_int_operand" "e"))
12069           (const_int 0)))
12070    (clobber (match_scratch:DI 0 "=r"))]
12071   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12073    && (optimize_size
12074        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12075   "shr{q}\t{%2, %0|%0, %2}"
12076   [(set_attr "type" "ishift")
12077    (set_attr "mode" "DI")])
12078
12079 (define_insn "*lshrdi3_1"
12080   [(set (match_operand:DI 0 "register_operand" "=r")
12081         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12082                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "!TARGET_64BIT"
12085   "#"
12086   [(set_attr "type" "multi")])
12087
12088 ;; By default we don't ask for a scratch register, because when DImode
12089 ;; values are manipulated, registers are already at a premium.  But if
12090 ;; we have one handy, we won't turn it away.
12091 (define_peephole2
12092   [(match_scratch:SI 3 "r")
12093    (parallel [(set (match_operand:DI 0 "register_operand" "")
12094                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12095                                 (match_operand:QI 2 "nonmemory_operand" "")))
12096               (clobber (reg:CC FLAGS_REG))])
12097    (match_dup 3)]
12098   "!TARGET_64BIT && TARGET_CMOVE"
12099   [(const_int 0)]
12100   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12101
12102 (define_split 
12103   [(set (match_operand:DI 0 "register_operand" "")
12104         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12105                      (match_operand:QI 2 "nonmemory_operand" "")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12108                      ? flow2_completed : reload_completed)"
12109   [(const_int 0)]
12110   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12111
12112 (define_expand "lshrsi3"
12113   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12114         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12115                      (match_operand:QI 2 "nonmemory_operand" "")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   ""
12118   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12119
12120 (define_insn "*lshrsi3_1_one_bit"
12121   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12122         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12123                      (match_operand:QI 2 "const1_operand" "")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126    && (TARGET_SHIFT1 || optimize_size)"
12127   "shr{l}\t%0"
12128   [(set_attr "type" "ishift")
12129    (set (attr "length") 
12130      (if_then_else (match_operand:SI 0 "register_operand" "") 
12131         (const_string "2")
12132         (const_string "*")))])
12133
12134 (define_insn "*lshrsi3_1_one_bit_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=r")
12136         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12137                      (match_operand:QI 2 "const1_operand" "")))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12140    && (TARGET_SHIFT1 || optimize_size)"
12141   "shr{l}\t%k0"
12142   [(set_attr "type" "ishift")
12143    (set_attr "length" "2")])
12144
12145 (define_insn "*lshrsi3_1"
12146   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12147         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12148                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151   "@
12152    shr{l}\t{%2, %0|%0, %2}
12153    shr{l}\t{%b2, %0|%0, %b2}"
12154   [(set_attr "type" "ishift")
12155    (set_attr "mode" "SI")])
12156
12157 (define_insn "*lshrsi3_1_zext"
12158   [(set (match_operand:DI 0 "register_operand" "=r,r")
12159         (zero_extend:DI
12160           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12161                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12164   "@
12165    shr{l}\t{%2, %k0|%k0, %2}
12166    shr{l}\t{%b2, %k0|%k0, %b2}"
12167   [(set_attr "type" "ishift")
12168    (set_attr "mode" "SI")])
12169
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags.  We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrsi3_one_bit_cmp"
12174   [(set (reg FLAGS_REG)
12175         (compare
12176           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12177                        (match_operand:QI 2 "const1_operand" ""))
12178           (const_int 0)))
12179    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12180         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12181   "ix86_match_ccmode (insn, CCGOCmode)
12182    && (TARGET_SHIFT1 || optimize_size)
12183    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12184   "shr{l}\t%0"
12185   [(set_attr "type" "ishift")
12186    (set (attr "length") 
12187      (if_then_else (match_operand:SI 0 "register_operand" "") 
12188         (const_string "2")
12189         (const_string "*")))])
12190
12191 (define_insn "*lshrsi3_one_bit_cconly"
12192   [(set (reg FLAGS_REG)
12193         (compare
12194           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195                        (match_operand:QI 2 "const1_operand" ""))
12196           (const_int 0)))
12197    (clobber (match_scratch:SI 0 "=r"))]
12198   "ix86_match_ccmode (insn, CCGOCmode)
12199    && (TARGET_SHIFT1 || optimize_size)
12200    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201   "shr{l}\t%0"
12202   [(set_attr "type" "ishift")
12203    (set_attr "length" "2")])
12204
12205 (define_insn "*lshrsi3_cmp_one_bit_zext"
12206   [(set (reg FLAGS_REG)
12207         (compare
12208           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209                        (match_operand:QI 2 "const1_operand" ""))
12210           (const_int 0)))
12211    (set (match_operand:DI 0 "register_operand" "=r")
12212         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12213   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12214    && (TARGET_SHIFT1 || optimize_size)
12215    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216   "shr{l}\t%k0"
12217   [(set_attr "type" "ishift")
12218    (set_attr "length" "2")])
12219
12220 ;; This pattern can't accept a variable shift count, since shifts by
12221 ;; zero don't affect the flags.  We assume that shifts by constant
12222 ;; zero are optimized away.
12223 (define_insn "*lshrsi3_cmp"
12224   [(set (reg FLAGS_REG)
12225         (compare
12226           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12228           (const_int 0)))
12229    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12230         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12231   "ix86_match_ccmode (insn, CCGOCmode)
12232    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12233    && (optimize_size
12234        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235   "shr{l}\t{%2, %0|%0, %2}"
12236   [(set_attr "type" "ishift")
12237    (set_attr "mode" "SI")])
12238
12239 (define_insn "*lshrsi3_cconly"
12240   [(set (reg FLAGS_REG)
12241       (compare
12242         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244         (const_int 0)))
12245    (clobber (match_scratch:SI 0 "=r"))]
12246   "ix86_match_ccmode (insn, CCGOCmode)
12247    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12248    && (optimize_size
12249        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12250   "shr{l}\t{%2, %0|%0, %2}"
12251   [(set_attr "type" "ishift")
12252    (set_attr "mode" "SI")])
12253
12254 (define_insn "*lshrsi3_cmp_zext"
12255   [(set (reg FLAGS_REG)
12256         (compare
12257           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12258                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12259           (const_int 0)))
12260    (set (match_operand:DI 0 "register_operand" "=r")
12261         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12262   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12263    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12264    && (optimize_size
12265        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12266   "shr{l}\t{%2, %k0|%k0, %2}"
12267   [(set_attr "type" "ishift")
12268    (set_attr "mode" "SI")])
12269
12270 (define_expand "lshrhi3"
12271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12272         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12273                      (match_operand:QI 2 "nonmemory_operand" "")))
12274    (clobber (reg:CC FLAGS_REG))]
12275   "TARGET_HIMODE_MATH"
12276   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12277
12278 (define_insn "*lshrhi3_1_one_bit"
12279   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12280         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281                      (match_operand:QI 2 "const1_operand" "")))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12284    && (TARGET_SHIFT1 || optimize_size)"
12285   "shr{w}\t%0"
12286   [(set_attr "type" "ishift")
12287    (set (attr "length") 
12288      (if_then_else (match_operand 0 "register_operand" "") 
12289         (const_string "2")
12290         (const_string "*")))])
12291
12292 (define_insn "*lshrhi3_1"
12293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12294         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12295                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12298   "@
12299    shr{w}\t{%2, %0|%0, %2}
12300    shr{w}\t{%b2, %0|%0, %b2}"
12301   [(set_attr "type" "ishift")
12302    (set_attr "mode" "HI")])
12303
12304 ;; This pattern can't accept a variable shift count, since shifts by
12305 ;; zero don't affect the flags.  We assume that shifts by constant
12306 ;; zero are optimized away.
12307 (define_insn "*lshrhi3_one_bit_cmp"
12308   [(set (reg FLAGS_REG)
12309         (compare
12310           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311                        (match_operand:QI 2 "const1_operand" ""))
12312           (const_int 0)))
12313    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12314         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12315   "ix86_match_ccmode (insn, CCGOCmode)
12316    && (TARGET_SHIFT1 || optimize_size)
12317    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12318   "shr{w}\t%0"
12319   [(set_attr "type" "ishift")
12320    (set (attr "length") 
12321      (if_then_else (match_operand:SI 0 "register_operand" "") 
12322         (const_string "2")
12323         (const_string "*")))])
12324
12325 (define_insn "*lshrhi3_one_bit_cconly"
12326   [(set (reg FLAGS_REG)
12327         (compare
12328           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329                        (match_operand:QI 2 "const1_operand" ""))
12330           (const_int 0)))
12331    (clobber (match_scratch:HI 0 "=r"))]
12332   "ix86_match_ccmode (insn, CCGOCmode)
12333    && (TARGET_SHIFT1 || optimize_size)
12334    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12335   "shr{w}\t%0"
12336   [(set_attr "type" "ishift")
12337    (set_attr "length" "2")])
12338
12339 ;; This pattern can't accept a variable shift count, since shifts by
12340 ;; zero don't affect the flags.  We assume that shifts by constant
12341 ;; zero are optimized away.
12342 (define_insn "*lshrhi3_cmp"
12343   [(set (reg FLAGS_REG)
12344         (compare
12345           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12346                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347           (const_int 0)))
12348    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12349         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12350   "ix86_match_ccmode (insn, CCGOCmode)
12351    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352    && (optimize_size
12353        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354   "shr{w}\t{%2, %0|%0, %2}"
12355   [(set_attr "type" "ishift")
12356    (set_attr "mode" "HI")])
12357
12358 (define_insn "*lshrhi3_cconly"
12359   [(set (reg FLAGS_REG)
12360         (compare
12361           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12363           (const_int 0)))
12364    (clobber (match_scratch:HI 0 "=r"))]
12365   "ix86_match_ccmode (insn, CCGOCmode)
12366    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12367    && (optimize_size
12368        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12369   "shr{w}\t{%2, %0|%0, %2}"
12370   [(set_attr "type" "ishift")
12371    (set_attr "mode" "HI")])
12372
12373 (define_expand "lshrqi3"
12374   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12375         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12376                      (match_operand:QI 2 "nonmemory_operand" "")))
12377    (clobber (reg:CC FLAGS_REG))]
12378   "TARGET_QIMODE_MATH"
12379   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12380
12381 (define_insn "*lshrqi3_1_one_bit"
12382   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12383         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12384                      (match_operand:QI 2 "const1_operand" "")))
12385    (clobber (reg:CC FLAGS_REG))]
12386   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12387    && (TARGET_SHIFT1 || optimize_size)"
12388   "shr{b}\t%0"
12389   [(set_attr "type" "ishift")
12390    (set (attr "length") 
12391      (if_then_else (match_operand 0 "register_operand" "") 
12392         (const_string "2")
12393         (const_string "*")))])
12394
12395 (define_insn "*lshrqi3_1_one_bit_slp"
12396   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12397         (lshiftrt:QI (match_dup 0)
12398                      (match_operand:QI 1 "const1_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12401    && (TARGET_SHIFT1 || optimize_size)"
12402   "shr{b}\t%0"
12403   [(set_attr "type" "ishift1")
12404    (set (attr "length") 
12405      (if_then_else (match_operand 0 "register_operand" "") 
12406         (const_string "2")
12407         (const_string "*")))])
12408
12409 (define_insn "*lshrqi3_1"
12410   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12411         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12412                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12413    (clobber (reg:CC FLAGS_REG))]
12414   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12415   "@
12416    shr{b}\t{%2, %0|%0, %2}
12417    shr{b}\t{%b2, %0|%0, %b2}"
12418   [(set_attr "type" "ishift")
12419    (set_attr "mode" "QI")])
12420
12421 (define_insn "*lshrqi3_1_slp"
12422   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12423         (lshiftrt:QI (match_dup 0)
12424                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12427    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12428   "@
12429    shr{b}\t{%1, %0|%0, %1}
12430    shr{b}\t{%b1, %0|%0, %b1}"
12431   [(set_attr "type" "ishift1")
12432    (set_attr "mode" "QI")])
12433
12434 ;; This pattern can't accept a variable shift count, since shifts by
12435 ;; zero don't affect the flags.  We assume that shifts by constant
12436 ;; zero are optimized away.
12437 (define_insn "*lshrqi2_one_bit_cmp"
12438   [(set (reg FLAGS_REG)
12439         (compare
12440           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441                        (match_operand:QI 2 "const1_operand" ""))
12442           (const_int 0)))
12443    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12445   "ix86_match_ccmode (insn, CCGOCmode)
12446    && (TARGET_SHIFT1 || optimize_size)
12447    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12448   "shr{b}\t%0"
12449   [(set_attr "type" "ishift")
12450    (set (attr "length") 
12451      (if_then_else (match_operand:SI 0 "register_operand" "") 
12452         (const_string "2")
12453         (const_string "*")))])
12454
12455 (define_insn "*lshrqi2_one_bit_cconly"
12456   [(set (reg FLAGS_REG)
12457         (compare
12458           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459                        (match_operand:QI 2 "const1_operand" ""))
12460           (const_int 0)))
12461    (clobber (match_scratch:QI 0 "=q"))]
12462   "ix86_match_ccmode (insn, CCGOCmode)
12463    && (TARGET_SHIFT1 || optimize_size)
12464    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12465   "shr{b}\t%0"
12466   [(set_attr "type" "ishift")
12467    (set_attr "length" "2")])
12468
12469 ;; This pattern can't accept a variable shift count, since shifts by
12470 ;; zero don't affect the flags.  We assume that shifts by constant
12471 ;; zero are optimized away.
12472 (define_insn "*lshrqi2_cmp"
12473   [(set (reg FLAGS_REG)
12474         (compare
12475           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12477           (const_int 0)))
12478    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12479         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12480   "ix86_match_ccmode (insn, CCGOCmode)
12481    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12482    && (optimize_size
12483        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484   "shr{b}\t{%2, %0|%0, %2}"
12485   [(set_attr "type" "ishift")
12486    (set_attr "mode" "QI")])
12487
12488 (define_insn "*lshrqi2_cconly"
12489   [(set (reg FLAGS_REG)
12490         (compare
12491           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12492                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12493           (const_int 0)))
12494    (clobber (match_scratch:QI 0 "=q"))]
12495   "ix86_match_ccmode (insn, CCGOCmode)
12496    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12497    && (optimize_size
12498        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12499   "shr{b}\t{%2, %0|%0, %2}"
12500   [(set_attr "type" "ishift")
12501    (set_attr "mode" "QI")])
12502 \f
12503 ;; Rotate instructions
12504
12505 (define_expand "rotldi3"
12506   [(set (match_operand:DI 0 "shiftdi_operand" "")
12507         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12508                    (match_operand:QI 2 "nonmemory_operand" "")))
12509    (clobber (reg:CC FLAGS_REG))]
12510  ""
12511 {
12512   if (TARGET_64BIT)
12513     {
12514       ix86_expand_binary_operator (ROTATE, DImode, operands);
12515       DONE;
12516     }
12517   if (!const_1_to_31_operand (operands[2], VOIDmode))
12518     FAIL;
12519   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12520   DONE;
12521 })
12522
12523 ;; Implement rotation using two double-precision shift instructions
12524 ;; and a scratch register.   
12525 (define_insn_and_split "ix86_rotldi3"
12526  [(set (match_operand:DI 0 "register_operand" "=r")
12527        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12528                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12529   (clobber (reg:CC FLAGS_REG))
12530   (clobber (match_scratch:SI 3 "=&r"))]
12531  "!TARGET_64BIT"
12532  "" 
12533  "&& reload_completed"
12534  [(set (match_dup 3) (match_dup 4))
12535   (parallel
12536    [(set (match_dup 4)
12537          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12538                  (lshiftrt:SI (match_dup 5)
12539                               (minus:QI (const_int 32) (match_dup 2)))))
12540     (clobber (reg:CC FLAGS_REG))])
12541   (parallel
12542    [(set (match_dup 5)
12543          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12544                  (lshiftrt:SI (match_dup 3)
12545                               (minus:QI (const_int 32) (match_dup 2)))))
12546     (clobber (reg:CC FLAGS_REG))])]
12547  "split_di (operands, 1, operands + 4, operands + 5);")
12548  
12549 (define_insn "*rotlsi3_1_one_bit_rex64"
12550   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12551         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12552                    (match_operand:QI 2 "const1_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12555    && (TARGET_SHIFT1 || optimize_size)"
12556   "rol{q}\t%0"
12557   [(set_attr "type" "rotate")
12558    (set (attr "length") 
12559      (if_then_else (match_operand:DI 0 "register_operand" "") 
12560         (const_string "2")
12561         (const_string "*")))])
12562
12563 (define_insn "*rotldi3_1_rex64"
12564   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12565         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12566                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12569   "@
12570    rol{q}\t{%2, %0|%0, %2}
12571    rol{q}\t{%b2, %0|%0, %b2}"
12572   [(set_attr "type" "rotate")
12573    (set_attr "mode" "DI")])
12574
12575 (define_expand "rotlsi3"
12576   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12577         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12578                    (match_operand:QI 2 "nonmemory_operand" "")))
12579    (clobber (reg:CC FLAGS_REG))]
12580   ""
12581   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12582
12583 (define_insn "*rotlsi3_1_one_bit"
12584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12585         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586                    (match_operand:QI 2 "const1_operand" "")))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12589    && (TARGET_SHIFT1 || optimize_size)"
12590   "rol{l}\t%0"
12591   [(set_attr "type" "rotate")
12592    (set (attr "length") 
12593      (if_then_else (match_operand:SI 0 "register_operand" "") 
12594         (const_string "2")
12595         (const_string "*")))])
12596
12597 (define_insn "*rotlsi3_1_one_bit_zext"
12598   [(set (match_operand:DI 0 "register_operand" "=r")
12599         (zero_extend:DI
12600           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12601                      (match_operand:QI 2 "const1_operand" ""))))
12602    (clobber (reg:CC FLAGS_REG))]
12603   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12604    && (TARGET_SHIFT1 || optimize_size)"
12605   "rol{l}\t%k0"
12606   [(set_attr "type" "rotate")
12607    (set_attr "length" "2")])
12608
12609 (define_insn "*rotlsi3_1"
12610   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12611         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12612                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12613    (clobber (reg:CC FLAGS_REG))]
12614   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12615   "@
12616    rol{l}\t{%2, %0|%0, %2}
12617    rol{l}\t{%b2, %0|%0, %b2}"
12618   [(set_attr "type" "rotate")
12619    (set_attr "mode" "SI")])
12620
12621 (define_insn "*rotlsi3_1_zext"
12622   [(set (match_operand:DI 0 "register_operand" "=r,r")
12623         (zero_extend:DI
12624           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12625                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12626    (clobber (reg:CC FLAGS_REG))]
12627   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12628   "@
12629    rol{l}\t{%2, %k0|%k0, %2}
12630    rol{l}\t{%b2, %k0|%k0, %b2}"
12631   [(set_attr "type" "rotate")
12632    (set_attr "mode" "SI")])
12633
12634 (define_expand "rotlhi3"
12635   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12636         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12637                    (match_operand:QI 2 "nonmemory_operand" "")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "TARGET_HIMODE_MATH"
12640   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12641
12642 (define_insn "*rotlhi3_1_one_bit"
12643   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645                    (match_operand:QI 2 "const1_operand" "")))
12646    (clobber (reg:CC FLAGS_REG))]
12647   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12648    && (TARGET_SHIFT1 || optimize_size)"
12649   "rol{w}\t%0"
12650   [(set_attr "type" "rotate")
12651    (set (attr "length") 
12652      (if_then_else (match_operand 0 "register_operand" "") 
12653         (const_string "2")
12654         (const_string "*")))])
12655
12656 (define_insn "*rotlhi3_1"
12657   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12658         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12659                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12660    (clobber (reg:CC FLAGS_REG))]
12661   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12662   "@
12663    rol{w}\t{%2, %0|%0, %2}
12664    rol{w}\t{%b2, %0|%0, %b2}"
12665   [(set_attr "type" "rotate")
12666    (set_attr "mode" "HI")])
12667
12668 (define_expand "rotlqi3"
12669   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12670         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12671                    (match_operand:QI 2 "nonmemory_operand" "")))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "TARGET_QIMODE_MATH"
12674   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12675
12676 (define_insn "*rotlqi3_1_one_bit_slp"
12677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12678         (rotate:QI (match_dup 0)
12679                    (match_operand:QI 1 "const1_operand" "")))
12680    (clobber (reg:CC FLAGS_REG))]
12681   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12682    && (TARGET_SHIFT1 || optimize_size)"
12683   "rol{b}\t%0"
12684   [(set_attr "type" "rotate1")
12685    (set (attr "length") 
12686      (if_then_else (match_operand 0 "register_operand" "") 
12687         (const_string "2")
12688         (const_string "*")))])
12689
12690 (define_insn "*rotlqi3_1_one_bit"
12691   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12692         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12693                    (match_operand:QI 2 "const1_operand" "")))
12694    (clobber (reg:CC FLAGS_REG))]
12695   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12696    && (TARGET_SHIFT1 || optimize_size)"
12697   "rol{b}\t%0"
12698   [(set_attr "type" "rotate")
12699    (set (attr "length") 
12700      (if_then_else (match_operand 0 "register_operand" "") 
12701         (const_string "2")
12702         (const_string "*")))])
12703
12704 (define_insn "*rotlqi3_1_slp"
12705   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12706         (rotate:QI (match_dup 0)
12707                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12710    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12711   "@
12712    rol{b}\t{%1, %0|%0, %1}
12713    rol{b}\t{%b1, %0|%0, %b1}"
12714   [(set_attr "type" "rotate1")
12715    (set_attr "mode" "QI")])
12716
12717 (define_insn "*rotlqi3_1"
12718   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12719         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12720                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721    (clobber (reg:CC FLAGS_REG))]
12722   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12723   "@
12724    rol{b}\t{%2, %0|%0, %2}
12725    rol{b}\t{%b2, %0|%0, %b2}"
12726   [(set_attr "type" "rotate")
12727    (set_attr "mode" "QI")])
12728
12729 (define_expand "rotrdi3"
12730   [(set (match_operand:DI 0 "shiftdi_operand" "")
12731         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12732                    (match_operand:QI 2 "nonmemory_operand" "")))
12733    (clobber (reg:CC FLAGS_REG))]
12734  ""
12735 {
12736   if (TARGET_64BIT)
12737     {
12738       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12739       DONE;
12740     }
12741   if (!const_1_to_31_operand (operands[2], VOIDmode))
12742     FAIL;
12743   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12744   DONE;
12745 })
12746   
12747 ;; Implement rotation using two double-precision shift instructions
12748 ;; and a scratch register.   
12749 (define_insn_and_split "ix86_rotrdi3"
12750  [(set (match_operand:DI 0 "register_operand" "=r")
12751        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12752                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12753   (clobber (reg:CC FLAGS_REG))
12754   (clobber (match_scratch:SI 3 "=&r"))]
12755  "!TARGET_64BIT"
12756  ""
12757  "&& reload_completed"
12758  [(set (match_dup 3) (match_dup 4))
12759   (parallel
12760    [(set (match_dup 4)
12761          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12762                  (ashift:SI (match_dup 5)
12763                             (minus:QI (const_int 32) (match_dup 2)))))
12764     (clobber (reg:CC FLAGS_REG))])
12765   (parallel
12766    [(set (match_dup 5)
12767          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12768                  (ashift:SI (match_dup 3)
12769                             (minus:QI (const_int 32) (match_dup 2)))))
12770     (clobber (reg:CC FLAGS_REG))])]
12771  "split_di (operands, 1, operands + 4, operands + 5);")
12772
12773 (define_insn "*rotrdi3_1_one_bit_rex64"
12774   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12775         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12776                      (match_operand:QI 2 "const1_operand" "")))
12777    (clobber (reg:CC FLAGS_REG))]
12778   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12779    && (TARGET_SHIFT1 || optimize_size)"
12780   "ror{q}\t%0"
12781   [(set_attr "type" "rotate")
12782    (set (attr "length") 
12783      (if_then_else (match_operand:DI 0 "register_operand" "") 
12784         (const_string "2")
12785         (const_string "*")))])
12786
12787 (define_insn "*rotrdi3_1_rex64"
12788   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12789         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12790                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12791    (clobber (reg:CC FLAGS_REG))]
12792   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12793   "@
12794    ror{q}\t{%2, %0|%0, %2}
12795    ror{q}\t{%b2, %0|%0, %b2}"
12796   [(set_attr "type" "rotate")
12797    (set_attr "mode" "DI")])
12798
12799 (define_expand "rotrsi3"
12800   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12801         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12802                      (match_operand:QI 2 "nonmemory_operand" "")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   ""
12805   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12806
12807 (define_insn "*rotrsi3_1_one_bit"
12808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12809         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12810                      (match_operand:QI 2 "const1_operand" "")))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813    && (TARGET_SHIFT1 || optimize_size)"
12814   "ror{l}\t%0"
12815   [(set_attr "type" "rotate")
12816    (set (attr "length") 
12817      (if_then_else (match_operand:SI 0 "register_operand" "") 
12818         (const_string "2")
12819         (const_string "*")))])
12820
12821 (define_insn "*rotrsi3_1_one_bit_zext"
12822   [(set (match_operand:DI 0 "register_operand" "=r")
12823         (zero_extend:DI
12824           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12825                        (match_operand:QI 2 "const1_operand" ""))))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12828    && (TARGET_SHIFT1 || optimize_size)"
12829   "ror{l}\t%k0"
12830   [(set_attr "type" "rotate")
12831    (set (attr "length") 
12832      (if_then_else (match_operand:SI 0 "register_operand" "") 
12833         (const_string "2")
12834         (const_string "*")))])
12835
12836 (define_insn "*rotrsi3_1"
12837   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12838         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12839                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12842   "@
12843    ror{l}\t{%2, %0|%0, %2}
12844    ror{l}\t{%b2, %0|%0, %b2}"
12845   [(set_attr "type" "rotate")
12846    (set_attr "mode" "SI")])
12847
12848 (define_insn "*rotrsi3_1_zext"
12849   [(set (match_operand:DI 0 "register_operand" "=r,r")
12850         (zero_extend:DI
12851           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12852                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12853    (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12855   "@
12856    ror{l}\t{%2, %k0|%k0, %2}
12857    ror{l}\t{%b2, %k0|%k0, %b2}"
12858   [(set_attr "type" "rotate")
12859    (set_attr "mode" "SI")])
12860
12861 (define_expand "rotrhi3"
12862   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12863         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12864                      (match_operand:QI 2 "nonmemory_operand" "")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "TARGET_HIMODE_MATH"
12867   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12868
12869 (define_insn "*rotrhi3_one_bit"
12870   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12871         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12872                      (match_operand:QI 2 "const1_operand" "")))
12873    (clobber (reg:CC FLAGS_REG))]
12874   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12875    && (TARGET_SHIFT1 || optimize_size)"
12876   "ror{w}\t%0"
12877   [(set_attr "type" "rotate")
12878    (set (attr "length") 
12879      (if_then_else (match_operand 0 "register_operand" "") 
12880         (const_string "2")
12881         (const_string "*")))])
12882
12883 (define_insn "*rotrhi3"
12884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12885         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12886                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12887    (clobber (reg:CC FLAGS_REG))]
12888   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12889   "@
12890    ror{w}\t{%2, %0|%0, %2}
12891    ror{w}\t{%b2, %0|%0, %b2}"
12892   [(set_attr "type" "rotate")
12893    (set_attr "mode" "HI")])
12894
12895 (define_expand "rotrqi3"
12896   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12897         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12898                      (match_operand:QI 2 "nonmemory_operand" "")))
12899    (clobber (reg:CC FLAGS_REG))]
12900   "TARGET_QIMODE_MATH"
12901   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12902
12903 (define_insn "*rotrqi3_1_one_bit"
12904   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12905         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12906                      (match_operand:QI 2 "const1_operand" "")))
12907    (clobber (reg:CC FLAGS_REG))]
12908   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12909    && (TARGET_SHIFT1 || optimize_size)"
12910   "ror{b}\t%0"
12911   [(set_attr "type" "rotate")
12912    (set (attr "length") 
12913      (if_then_else (match_operand 0 "register_operand" "") 
12914         (const_string "2")
12915         (const_string "*")))])
12916
12917 (define_insn "*rotrqi3_1_one_bit_slp"
12918   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12919         (rotatert:QI (match_dup 0)
12920                      (match_operand:QI 1 "const1_operand" "")))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12923    && (TARGET_SHIFT1 || optimize_size)"
12924   "ror{b}\t%0"
12925   [(set_attr "type" "rotate1")
12926    (set (attr "length") 
12927      (if_then_else (match_operand 0 "register_operand" "") 
12928         (const_string "2")
12929         (const_string "*")))])
12930
12931 (define_insn "*rotrqi3_1"
12932   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12933         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12934                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12937   "@
12938    ror{b}\t{%2, %0|%0, %2}
12939    ror{b}\t{%b2, %0|%0, %b2}"
12940   [(set_attr "type" "rotate")
12941    (set_attr "mode" "QI")])
12942
12943 (define_insn "*rotrqi3_1_slp"
12944   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12945         (rotatert:QI (match_dup 0)
12946                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12949    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12950   "@
12951    ror{b}\t{%1, %0|%0, %1}
12952    ror{b}\t{%b1, %0|%0, %b1}"
12953   [(set_attr "type" "rotate1")
12954    (set_attr "mode" "QI")])
12955 \f
12956 ;; Bit set / bit test instructions
12957
12958 (define_expand "extv"
12959   [(set (match_operand:SI 0 "register_operand" "")
12960         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12961                          (match_operand:SI 2 "const8_operand" "")
12962                          (match_operand:SI 3 "const8_operand" "")))]
12963   ""
12964 {
12965   /* Handle extractions from %ah et al.  */
12966   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12967     FAIL;
12968
12969   /* From mips.md: extract_bit_field doesn't verify that our source
12970      matches the predicate, so check it again here.  */
12971   if (! ext_register_operand (operands[1], VOIDmode))
12972     FAIL;
12973 })
12974
12975 (define_expand "extzv"
12976   [(set (match_operand:SI 0 "register_operand" "")
12977         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12978                          (match_operand:SI 2 "const8_operand" "")
12979                          (match_operand:SI 3 "const8_operand" "")))]
12980   ""
12981 {
12982   /* Handle extractions from %ah et al.  */
12983   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12984     FAIL;
12985
12986   /* From mips.md: extract_bit_field doesn't verify that our source
12987      matches the predicate, so check it again here.  */
12988   if (! ext_register_operand (operands[1], VOIDmode))
12989     FAIL;
12990 })
12991
12992 (define_expand "insv"
12993   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12994                       (match_operand 1 "const8_operand" "")
12995                       (match_operand 2 "const8_operand" ""))
12996         (match_operand 3 "register_operand" ""))]
12997   ""
12998 {
12999   /* Handle insertions to %ah et al.  */
13000   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13001     FAIL;
13002
13003   /* From mips.md: insert_bit_field doesn't verify that our source
13004      matches the predicate, so check it again here.  */
13005   if (! ext_register_operand (operands[0], VOIDmode))
13006     FAIL;
13007
13008   if (TARGET_64BIT)
13009     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13010   else
13011     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13012
13013   DONE;
13014 })
13015
13016 ;; %%% bts, btr, btc, bt.
13017 ;; In general these instructions are *slow* when applied to memory,
13018 ;; since they enforce atomic operation.  When applied to registers,
13019 ;; it depends on the cpu implementation.  They're never faster than
13020 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13021 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13022 ;; within the instruction itself, so operating on bits in the high
13023 ;; 32-bits of a register becomes easier.
13024 ;;
13025 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13026 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13027 ;; negdf respectively, so they can never be disabled entirely.
13028
13029 (define_insn "*btsq"
13030   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13031                          (const_int 1)
13032                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13033         (const_int 1))
13034    (clobber (reg:CC FLAGS_REG))]
13035   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13036   "bts{q} %1,%0"
13037   [(set_attr "type" "alu1")])
13038
13039 (define_insn "*btrq"
13040   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13041                          (const_int 1)
13042                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13043         (const_int 0))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13046   "btr{q} %1,%0"
13047   [(set_attr "type" "alu1")])
13048
13049 (define_insn "*btcq"
13050   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13051                          (const_int 1)
13052                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13053         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13056   "btc{q} %1,%0"
13057   [(set_attr "type" "alu1")])
13058
13059 ;; Allow Nocona to avoid these instructions if a register is available.
13060
13061 (define_peephole2
13062   [(match_scratch:DI 2 "r")
13063    (parallel [(set (zero_extract:DI
13064                      (match_operand:DI 0 "register_operand" "")
13065                      (const_int 1)
13066                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13067                    (const_int 1))
13068               (clobber (reg:CC FLAGS_REG))])]
13069   "TARGET_64BIT && !TARGET_USE_BT"
13070   [(const_int 0)]
13071 {
13072   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13073   rtx op1;
13074
13075   if (HOST_BITS_PER_WIDE_INT >= 64)
13076     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13077   else if (i < HOST_BITS_PER_WIDE_INT)
13078     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13079   else
13080     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13081
13082   op1 = immed_double_const (lo, hi, DImode);
13083   if (i >= 31)
13084     {
13085       emit_move_insn (operands[2], op1);
13086       op1 = operands[2];
13087     }
13088
13089   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13090   DONE;
13091 })
13092
13093 (define_peephole2
13094   [(match_scratch:DI 2 "r")
13095    (parallel [(set (zero_extract:DI
13096                      (match_operand:DI 0 "register_operand" "")
13097                      (const_int 1)
13098                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13099                    (const_int 0))
13100               (clobber (reg:CC FLAGS_REG))])]
13101   "TARGET_64BIT && !TARGET_USE_BT"
13102   [(const_int 0)]
13103 {
13104   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13105   rtx op1;
13106
13107   if (HOST_BITS_PER_WIDE_INT >= 64)
13108     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13109   else if (i < HOST_BITS_PER_WIDE_INT)
13110     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13111   else
13112     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13113
13114   op1 = immed_double_const (~lo, ~hi, DImode);
13115   if (i >= 32)
13116     {
13117       emit_move_insn (operands[2], op1);
13118       op1 = operands[2];
13119     }
13120
13121   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13122   DONE;
13123 })
13124
13125 (define_peephole2
13126   [(match_scratch:DI 2 "r")
13127    (parallel [(set (zero_extract:DI
13128                      (match_operand:DI 0 "register_operand" "")
13129                      (const_int 1)
13130                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13131               (not:DI (zero_extract:DI
13132                         (match_dup 0) (const_int 1) (match_dup 1))))
13133               (clobber (reg:CC FLAGS_REG))])]
13134   "TARGET_64BIT && !TARGET_USE_BT"
13135   [(const_int 0)]
13136 {
13137   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13138   rtx op1;
13139
13140   if (HOST_BITS_PER_WIDE_INT >= 64)
13141     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13142   else if (i < HOST_BITS_PER_WIDE_INT)
13143     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13144   else
13145     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13146
13147   op1 = immed_double_const (lo, hi, DImode);
13148   if (i >= 31)
13149     {
13150       emit_move_insn (operands[2], op1);
13151       op1 = operands[2];
13152     }
13153
13154   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13155   DONE;
13156 })
13157 \f
13158 ;; Store-flag instructions.
13159
13160 ;; For all sCOND expanders, also expand the compare or test insn that
13161 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13162
13163 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13164 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13165 ;; way, which can later delete the movzx if only QImode is needed.
13166
13167 (define_expand "seq"
13168   [(set (match_operand:QI 0 "register_operand" "")
13169         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13170   ""
13171   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13172
13173 (define_expand "sne"
13174   [(set (match_operand:QI 0 "register_operand" "")
13175         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13176   ""
13177   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13178
13179 (define_expand "sgt"
13180   [(set (match_operand:QI 0 "register_operand" "")
13181         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13182   ""
13183   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13184
13185 (define_expand "sgtu"
13186   [(set (match_operand:QI 0 "register_operand" "")
13187         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13188   ""
13189   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13190
13191 (define_expand "slt"
13192   [(set (match_operand:QI 0 "register_operand" "")
13193         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13194   ""
13195   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13196
13197 (define_expand "sltu"
13198   [(set (match_operand:QI 0 "register_operand" "")
13199         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13200   ""
13201   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13202
13203 (define_expand "sge"
13204   [(set (match_operand:QI 0 "register_operand" "")
13205         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13206   ""
13207   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13208
13209 (define_expand "sgeu"
13210   [(set (match_operand:QI 0 "register_operand" "")
13211         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13212   ""
13213   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13214
13215 (define_expand "sle"
13216   [(set (match_operand:QI 0 "register_operand" "")
13217         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13218   ""
13219   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13220
13221 (define_expand "sleu"
13222   [(set (match_operand:QI 0 "register_operand" "")
13223         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13224   ""
13225   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13226
13227 (define_expand "sunordered"
13228   [(set (match_operand:QI 0 "register_operand" "")
13229         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13230   "TARGET_80387 || TARGET_SSE"
13231   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13232
13233 (define_expand "sordered"
13234   [(set (match_operand:QI 0 "register_operand" "")
13235         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13236   "TARGET_80387"
13237   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13238
13239 (define_expand "suneq"
13240   [(set (match_operand:QI 0 "register_operand" "")
13241         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13242   "TARGET_80387 || TARGET_SSE"
13243   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13244
13245 (define_expand "sunge"
13246   [(set (match_operand:QI 0 "register_operand" "")
13247         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13248   "TARGET_80387 || TARGET_SSE"
13249   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13250
13251 (define_expand "sungt"
13252   [(set (match_operand:QI 0 "register_operand" "")
13253         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13254   "TARGET_80387 || TARGET_SSE"
13255   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13256
13257 (define_expand "sunle"
13258   [(set (match_operand:QI 0 "register_operand" "")
13259         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13260   "TARGET_80387 || TARGET_SSE"
13261   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13262
13263 (define_expand "sunlt"
13264   [(set (match_operand:QI 0 "register_operand" "")
13265         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13266   "TARGET_80387 || TARGET_SSE"
13267   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13268
13269 (define_expand "sltgt"
13270   [(set (match_operand:QI 0 "register_operand" "")
13271         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13272   "TARGET_80387 || TARGET_SSE"
13273   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13274
13275 (define_insn "*setcc_1"
13276   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13277         (match_operator:QI 1 "ix86_comparison_operator"
13278           [(reg FLAGS_REG) (const_int 0)]))]
13279   ""
13280   "set%C1\t%0"
13281   [(set_attr "type" "setcc")
13282    (set_attr "mode" "QI")])
13283
13284 (define_insn "*setcc_2"
13285   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286         (match_operator:QI 1 "ix86_comparison_operator"
13287           [(reg FLAGS_REG) (const_int 0)]))]
13288   ""
13289   "set%C1\t%0"
13290   [(set_attr "type" "setcc")
13291    (set_attr "mode" "QI")])
13292
13293 ;; In general it is not safe to assume too much about CCmode registers,
13294 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13295 ;; conditions this is safe on x86, so help combine not create
13296 ;;
13297 ;;      seta    %al
13298 ;;      testb   %al, %al
13299 ;;      sete    %al
13300
13301 (define_split 
13302   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13303         (ne:QI (match_operator 1 "ix86_comparison_operator"
13304                  [(reg FLAGS_REG) (const_int 0)])
13305             (const_int 0)))]
13306   ""
13307   [(set (match_dup 0) (match_dup 1))]
13308 {
13309   PUT_MODE (operands[1], QImode);
13310 })
13311
13312 (define_split 
13313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13314         (ne:QI (match_operator 1 "ix86_comparison_operator"
13315                  [(reg FLAGS_REG) (const_int 0)])
13316             (const_int 0)))]
13317   ""
13318   [(set (match_dup 0) (match_dup 1))]
13319 {
13320   PUT_MODE (operands[1], QImode);
13321 })
13322
13323 (define_split 
13324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325         (eq:QI (match_operator 1 "ix86_comparison_operator"
13326                  [(reg FLAGS_REG) (const_int 0)])
13327             (const_int 0)))]
13328   ""
13329   [(set (match_dup 0) (match_dup 1))]
13330 {
13331   rtx new_op1 = copy_rtx (operands[1]);
13332   operands[1] = new_op1;
13333   PUT_MODE (new_op1, QImode);
13334   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13335                                              GET_MODE (XEXP (new_op1, 0))));
13336
13337   /* Make sure that (a) the CCmode we have for the flags is strong
13338      enough for the reversed compare or (b) we have a valid FP compare.  */
13339   if (! ix86_comparison_operator (new_op1, VOIDmode))
13340     FAIL;
13341 })
13342
13343 (define_split 
13344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13345         (eq:QI (match_operator 1 "ix86_comparison_operator"
13346                  [(reg FLAGS_REG) (const_int 0)])
13347             (const_int 0)))]
13348   ""
13349   [(set (match_dup 0) (match_dup 1))]
13350 {
13351   rtx new_op1 = copy_rtx (operands[1]);
13352   operands[1] = new_op1;
13353   PUT_MODE (new_op1, QImode);
13354   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13355                                              GET_MODE (XEXP (new_op1, 0))));
13356
13357   /* Make sure that (a) the CCmode we have for the flags is strong
13358      enough for the reversed compare or (b) we have a valid FP compare.  */
13359   if (! ix86_comparison_operator (new_op1, VOIDmode))
13360     FAIL;
13361 })
13362
13363 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13364 ;; subsequent logical operations are used to imitate conditional moves.
13365 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13366 ;; it directly.
13367
13368 (define_insn "*sse_setccsf"
13369   [(set (match_operand:SF 0 "register_operand" "=x")
13370         (match_operator:SF 1 "sse_comparison_operator"
13371           [(match_operand:SF 2 "register_operand" "0")
13372            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13373   "TARGET_SSE"
13374   "cmp%D1ss\t{%3, %0|%0, %3}"
13375   [(set_attr "type" "ssecmp")
13376    (set_attr "mode" "SF")])
13377
13378 (define_insn "*sse_setccdf"
13379   [(set (match_operand:DF 0 "register_operand" "=Y")
13380         (match_operator:DF 1 "sse_comparison_operator"
13381           [(match_operand:DF 2 "register_operand" "0")
13382            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13383   "TARGET_SSE2"
13384   "cmp%D1sd\t{%3, %0|%0, %3}"
13385   [(set_attr "type" "ssecmp")
13386    (set_attr "mode" "DF")])
13387 \f
13388 ;; Basic conditional jump instructions.
13389 ;; We ignore the overflow flag for signed branch instructions.
13390
13391 ;; For all bCOND expanders, also expand the compare or test insn that
13392 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13393
13394 (define_expand "beq"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   ""
13400   "ix86_expand_branch (EQ, operands[0]); DONE;")
13401
13402 (define_expand "bne"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   ""
13408   "ix86_expand_branch (NE, operands[0]); DONE;")
13409
13410 (define_expand "bgt"
13411   [(set (pc)
13412         (if_then_else (match_dup 1)
13413                       (label_ref (match_operand 0 "" ""))
13414                       (pc)))]
13415   ""
13416   "ix86_expand_branch (GT, operands[0]); DONE;")
13417
13418 (define_expand "bgtu"
13419   [(set (pc)
13420         (if_then_else (match_dup 1)
13421                       (label_ref (match_operand 0 "" ""))
13422                       (pc)))]
13423   ""
13424   "ix86_expand_branch (GTU, operands[0]); DONE;")
13425
13426 (define_expand "blt"
13427   [(set (pc)
13428         (if_then_else (match_dup 1)
13429                       (label_ref (match_operand 0 "" ""))
13430                       (pc)))]
13431   ""
13432   "ix86_expand_branch (LT, operands[0]); DONE;")
13433
13434 (define_expand "bltu"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (LTU, operands[0]); DONE;")
13441
13442 (define_expand "bge"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (GE, operands[0]); DONE;")
13449
13450 (define_expand "bgeu"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (GEU, operands[0]); DONE;")
13457
13458 (define_expand "ble"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (LE, operands[0]); DONE;")
13465
13466 (define_expand "bleu"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (LEU, operands[0]); DONE;")
13473
13474 (define_expand "bunordered"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   "TARGET_80387 || TARGET_SSE_MATH"
13480   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13481
13482 (define_expand "bordered"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   "TARGET_80387 || TARGET_SSE_MATH"
13488   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13489
13490 (define_expand "buneq"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   "TARGET_80387 || TARGET_SSE_MATH"
13496   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13497
13498 (define_expand "bunge"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   "TARGET_80387 || TARGET_SSE_MATH"
13504   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13505
13506 (define_expand "bungt"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   "TARGET_80387 || TARGET_SSE_MATH"
13512   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13513
13514 (define_expand "bunle"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13521
13522 (define_expand "bunlt"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13529
13530 (define_expand "bltgt"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   "TARGET_80387 || TARGET_SSE_MATH"
13536   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13537
13538 (define_insn "*jcc_1"
13539   [(set (pc)
13540         (if_then_else (match_operator 1 "ix86_comparison_operator"
13541                                       [(reg FLAGS_REG) (const_int 0)])
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   ""
13545   "%+j%C1\t%l0"
13546   [(set_attr "type" "ibr")
13547    (set_attr "modrm" "0")
13548    (set (attr "length")
13549            (if_then_else (and (ge (minus (match_dup 0) (pc))
13550                                   (const_int -126))
13551                               (lt (minus (match_dup 0) (pc))
13552                                   (const_int 128)))
13553              (const_int 2)
13554              (const_int 6)))])
13555
13556 (define_insn "*jcc_2"
13557   [(set (pc)
13558         (if_then_else (match_operator 1 "ix86_comparison_operator"
13559                                       [(reg FLAGS_REG) (const_int 0)])
13560                       (pc)
13561                       (label_ref (match_operand 0 "" ""))))]
13562   ""
13563   "%+j%c1\t%l0"
13564   [(set_attr "type" "ibr")
13565    (set_attr "modrm" "0")
13566    (set (attr "length")
13567            (if_then_else (and (ge (minus (match_dup 0) (pc))
13568                                   (const_int -126))
13569                               (lt (minus (match_dup 0) (pc))
13570                                   (const_int 128)))
13571              (const_int 2)
13572              (const_int 6)))])
13573
13574 ;; In general it is not safe to assume too much about CCmode registers,
13575 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13576 ;; conditions this is safe on x86, so help combine not create
13577 ;;
13578 ;;      seta    %al
13579 ;;      testb   %al, %al
13580 ;;      je      Lfoo
13581
13582 (define_split 
13583   [(set (pc)
13584         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13585                                       [(reg FLAGS_REG) (const_int 0)])
13586                           (const_int 0))
13587                       (label_ref (match_operand 1 "" ""))
13588                       (pc)))]
13589   ""
13590   [(set (pc)
13591         (if_then_else (match_dup 0)
13592                       (label_ref (match_dup 1))
13593                       (pc)))]
13594 {
13595   PUT_MODE (operands[0], VOIDmode);
13596 })
13597   
13598 (define_split 
13599   [(set (pc)
13600         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13601                                       [(reg FLAGS_REG) (const_int 0)])
13602                           (const_int 0))
13603                       (label_ref (match_operand 1 "" ""))
13604                       (pc)))]
13605   ""
13606   [(set (pc)
13607         (if_then_else (match_dup 0)
13608                       (label_ref (match_dup 1))
13609                       (pc)))]
13610 {
13611   rtx new_op0 = copy_rtx (operands[0]);
13612   operands[0] = new_op0;
13613   PUT_MODE (new_op0, VOIDmode);
13614   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13615                                              GET_MODE (XEXP (new_op0, 0))));
13616
13617   /* Make sure that (a) the CCmode we have for the flags is strong
13618      enough for the reversed compare or (b) we have a valid FP compare.  */
13619   if (! ix86_comparison_operator (new_op0, VOIDmode))
13620     FAIL;
13621 })
13622
13623 ;; Define combination compare-and-branch fp compare instructions to use
13624 ;; during early optimization.  Splitting the operation apart early makes
13625 ;; for bad code when we want to reverse the operation.
13626
13627 (define_insn "*fp_jcc_1_mixed"
13628   [(set (pc)
13629         (if_then_else (match_operator 0 "comparison_operator"
13630                         [(match_operand 1 "register_operand" "f,x")
13631                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13632           (label_ref (match_operand 3 "" ""))
13633           (pc)))
13634    (clobber (reg:CCFP FPSR_REG))
13635    (clobber (reg:CCFP FLAGS_REG))]
13636   "TARGET_MIX_SSE_I387
13637    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640   "#")
13641
13642 (define_insn "*fp_jcc_1_sse"
13643   [(set (pc)
13644         (if_then_else (match_operator 0 "comparison_operator"
13645                         [(match_operand 1 "register_operand" "x")
13646                          (match_operand 2 "nonimmediate_operand" "xm")])
13647           (label_ref (match_operand 3 "" ""))
13648           (pc)))
13649    (clobber (reg:CCFP FPSR_REG))
13650    (clobber (reg:CCFP FLAGS_REG))]
13651   "TARGET_SSE_MATH
13652    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13653    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13655   "#")
13656
13657 (define_insn "*fp_jcc_1_387"
13658   [(set (pc)
13659         (if_then_else (match_operator 0 "comparison_operator"
13660                         [(match_operand 1 "register_operand" "f")
13661                          (match_operand 2 "register_operand" "f")])
13662           (label_ref (match_operand 3 "" ""))
13663           (pc)))
13664    (clobber (reg:CCFP FPSR_REG))
13665    (clobber (reg:CCFP FLAGS_REG))]
13666   "TARGET_CMOVE && TARGET_80387
13667    && FLOAT_MODE_P (GET_MODE (operands[1]))
13668    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670   "#")
13671
13672 (define_insn "*fp_jcc_2_mixed"
13673   [(set (pc)
13674         (if_then_else (match_operator 0 "comparison_operator"
13675                         [(match_operand 1 "register_operand" "f,x")
13676                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13677           (pc)
13678           (label_ref (match_operand 3 "" ""))))
13679    (clobber (reg:CCFP FPSR_REG))
13680    (clobber (reg:CCFP FLAGS_REG))]
13681   "TARGET_MIX_SSE_I387
13682    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13685   "#")
13686
13687 (define_insn "*fp_jcc_2_sse"
13688   [(set (pc)
13689         (if_then_else (match_operator 0 "comparison_operator"
13690                         [(match_operand 1 "register_operand" "x")
13691                          (match_operand 2 "nonimmediate_operand" "xm")])
13692           (pc)
13693           (label_ref (match_operand 3 "" ""))))
13694    (clobber (reg:CCFP FPSR_REG))
13695    (clobber (reg:CCFP FLAGS_REG))]
13696   "TARGET_SSE_MATH
13697    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13698    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13700   "#")
13701
13702 (define_insn "*fp_jcc_2_387"
13703   [(set (pc)
13704         (if_then_else (match_operator 0 "comparison_operator"
13705                         [(match_operand 1 "register_operand" "f")
13706                          (match_operand 2 "register_operand" "f")])
13707           (pc)
13708           (label_ref (match_operand 3 "" ""))))
13709    (clobber (reg:CCFP FPSR_REG))
13710    (clobber (reg:CCFP FLAGS_REG))]
13711   "TARGET_CMOVE && TARGET_80387
13712    && FLOAT_MODE_P (GET_MODE (operands[1]))
13713    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13714    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13715   "#")
13716
13717 (define_insn "*fp_jcc_3_387"
13718   [(set (pc)
13719         (if_then_else (match_operator 0 "comparison_operator"
13720                         [(match_operand 1 "register_operand" "f")
13721                          (match_operand 2 "nonimmediate_operand" "fm")])
13722           (label_ref (match_operand 3 "" ""))
13723           (pc)))
13724    (clobber (reg:CCFP FPSR_REG))
13725    (clobber (reg:CCFP FLAGS_REG))
13726    (clobber (match_scratch:HI 4 "=a"))]
13727   "TARGET_80387
13728    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13729    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13730    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13731    && SELECT_CC_MODE (GET_CODE (operands[0]),
13732                       operands[1], operands[2]) == CCFPmode
13733    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13734   "#")
13735
13736 (define_insn "*fp_jcc_4_387"
13737   [(set (pc)
13738         (if_then_else (match_operator 0 "comparison_operator"
13739                         [(match_operand 1 "register_operand" "f")
13740                          (match_operand 2 "nonimmediate_operand" "fm")])
13741           (pc)
13742           (label_ref (match_operand 3 "" ""))))
13743    (clobber (reg:CCFP FPSR_REG))
13744    (clobber (reg:CCFP FLAGS_REG))
13745    (clobber (match_scratch:HI 4 "=a"))]
13746   "TARGET_80387
13747    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13748    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13749    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13750    && SELECT_CC_MODE (GET_CODE (operands[0]),
13751                       operands[1], operands[2]) == CCFPmode
13752    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753   "#")
13754
13755 (define_insn "*fp_jcc_5_387"
13756   [(set (pc)
13757         (if_then_else (match_operator 0 "comparison_operator"
13758                         [(match_operand 1 "register_operand" "f")
13759                          (match_operand 2 "register_operand" "f")])
13760           (label_ref (match_operand 3 "" ""))
13761           (pc)))
13762    (clobber (reg:CCFP FPSR_REG))
13763    (clobber (reg:CCFP FLAGS_REG))
13764    (clobber (match_scratch:HI 4 "=a"))]
13765   "TARGET_80387
13766    && FLOAT_MODE_P (GET_MODE (operands[1]))
13767    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13769   "#")
13770
13771 (define_insn "*fp_jcc_6_387"
13772   [(set (pc)
13773         (if_then_else (match_operator 0 "comparison_operator"
13774                         [(match_operand 1 "register_operand" "f")
13775                          (match_operand 2 "register_operand" "f")])
13776           (pc)
13777           (label_ref (match_operand 3 "" ""))))
13778    (clobber (reg:CCFP FPSR_REG))
13779    (clobber (reg:CCFP FLAGS_REG))
13780    (clobber (match_scratch:HI 4 "=a"))]
13781   "TARGET_80387
13782    && FLOAT_MODE_P (GET_MODE (operands[1]))
13783    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13784    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13785   "#")
13786
13787 (define_insn "*fp_jcc_7_387"
13788   [(set (pc)
13789         (if_then_else (match_operator 0 "comparison_operator"
13790                         [(match_operand 1 "register_operand" "f")
13791                          (match_operand 2 "const0_operand" "X")])
13792           (label_ref (match_operand 3 "" ""))
13793           (pc)))
13794    (clobber (reg:CCFP FPSR_REG))
13795    (clobber (reg:CCFP FLAGS_REG))
13796    (clobber (match_scratch:HI 4 "=a"))]
13797   "TARGET_80387
13798    && FLOAT_MODE_P (GET_MODE (operands[1]))
13799    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13801    && SELECT_CC_MODE (GET_CODE (operands[0]),
13802                       operands[1], operands[2]) == CCFPmode
13803    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13804   "#")
13805
13806 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13807 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13808 ;; with a precedence over other operators and is always put in the first
13809 ;; place. Swap condition and operands to match ficom instruction.
13810
13811 (define_insn "*fp_jcc_8<mode>_387"
13812   [(set (pc)
13813         (if_then_else (match_operator 0 "comparison_operator"
13814                         [(match_operator 1 "float_operator"
13815                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13816                            (match_operand 3 "register_operand" "f,f")])
13817           (label_ref (match_operand 4 "" ""))
13818           (pc)))
13819    (clobber (reg:CCFP FPSR_REG))
13820    (clobber (reg:CCFP FLAGS_REG))
13821    (clobber (match_scratch:HI 5 "=a,a"))]
13822   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13823    && FLOAT_MODE_P (GET_MODE (operands[3]))
13824    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13825    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13826    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13827    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13828   "#")
13829
13830 (define_split
13831   [(set (pc)
13832         (if_then_else (match_operator 0 "comparison_operator"
13833                         [(match_operand 1 "register_operand" "")
13834                          (match_operand 2 "nonimmediate_operand" "")])
13835           (match_operand 3 "" "")
13836           (match_operand 4 "" "")))
13837    (clobber (reg:CCFP FPSR_REG))
13838    (clobber (reg:CCFP FLAGS_REG))]
13839   "reload_completed"
13840   [(const_int 0)]
13841 {
13842   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13843                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13844   DONE;
13845 })
13846
13847 (define_split
13848   [(set (pc)
13849         (if_then_else (match_operator 0 "comparison_operator"
13850                         [(match_operand 1 "register_operand" "")
13851                          (match_operand 2 "general_operand" "")])
13852           (match_operand 3 "" "")
13853           (match_operand 4 "" "")))
13854    (clobber (reg:CCFP FPSR_REG))
13855    (clobber (reg:CCFP FLAGS_REG))
13856    (clobber (match_scratch:HI 5 "=a"))]
13857   "reload_completed"
13858   [(const_int 0)]
13859 {
13860   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13861                         operands[3], operands[4], operands[5], NULL_RTX);
13862   DONE;
13863 })
13864
13865 (define_split
13866   [(set (pc)
13867         (if_then_else (match_operator 0 "comparison_operator"
13868                         [(match_operator 1 "float_operator"
13869                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13870                            (match_operand 3 "register_operand" "")])
13871           (match_operand 4 "" "")
13872           (match_operand 5 "" "")))
13873    (clobber (reg:CCFP FPSR_REG))
13874    (clobber (reg:CCFP FLAGS_REG))
13875    (clobber (match_scratch:HI 6 "=a"))]
13876   "reload_completed"
13877   [(const_int 0)]
13878 {
13879   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13880   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13881                         operands[3], operands[7],
13882                         operands[4], operands[5], operands[6], NULL_RTX);
13883   DONE;
13884 })
13885
13886 ;; %%% Kill this when reload knows how to do it.
13887 (define_split
13888   [(set (pc)
13889         (if_then_else (match_operator 0 "comparison_operator"
13890                         [(match_operator 1 "float_operator"
13891                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13892                            (match_operand 3 "register_operand" "")])
13893           (match_operand 4 "" "")
13894           (match_operand 5 "" "")))
13895    (clobber (reg:CCFP FPSR_REG))
13896    (clobber (reg:CCFP FLAGS_REG))
13897    (clobber (match_scratch:HI 6 "=a"))]
13898   "reload_completed"
13899   [(const_int 0)]
13900 {
13901   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13902   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13903   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13904                         operands[3], operands[7],
13905                         operands[4], operands[5], operands[6], operands[2]);
13906   DONE;
13907 })
13908 \f
13909 ;; Unconditional and other jump instructions
13910
13911 (define_insn "jump"
13912   [(set (pc)
13913         (label_ref (match_operand 0 "" "")))]
13914   ""
13915   "jmp\t%l0"
13916   [(set_attr "type" "ibr")
13917    (set (attr "length")
13918            (if_then_else (and (ge (minus (match_dup 0) (pc))
13919                                   (const_int -126))
13920                               (lt (minus (match_dup 0) (pc))
13921                                   (const_int 128)))
13922              (const_int 2)
13923              (const_int 5)))
13924    (set_attr "modrm" "0")])
13925
13926 (define_expand "indirect_jump"
13927   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13928   ""
13929   "")
13930
13931 (define_insn "*indirect_jump"
13932   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13933   "!TARGET_64BIT"
13934   "jmp\t%A0"
13935   [(set_attr "type" "ibr")
13936    (set_attr "length_immediate" "0")])
13937
13938 (define_insn "*indirect_jump_rtx64"
13939   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13940   "TARGET_64BIT"
13941   "jmp\t%A0"
13942   [(set_attr "type" "ibr")
13943    (set_attr "length_immediate" "0")])
13944
13945 (define_expand "tablejump"
13946   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13947               (use (label_ref (match_operand 1 "" "")))])]
13948   ""
13949 {
13950   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13951      relative.  Convert the relative address to an absolute address.  */
13952   if (flag_pic)
13953     {
13954       rtx op0, op1;
13955       enum rtx_code code;
13956
13957       if (TARGET_64BIT)
13958         {
13959           code = PLUS;
13960           op0 = operands[0];
13961           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13962         }
13963       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13964         {
13965           code = PLUS;
13966           op0 = operands[0];
13967           op1 = pic_offset_table_rtx;
13968         }
13969       else
13970         {
13971           code = MINUS;
13972           op0 = pic_offset_table_rtx;
13973           op1 = operands[0];
13974         }
13975
13976       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13977                                          OPTAB_DIRECT);
13978     }
13979 })
13980
13981 (define_insn "*tablejump_1"
13982   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13983    (use (label_ref (match_operand 1 "" "")))]
13984   "!TARGET_64BIT"
13985   "jmp\t%A0"
13986   [(set_attr "type" "ibr")
13987    (set_attr "length_immediate" "0")])
13988
13989 (define_insn "*tablejump_1_rtx64"
13990   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13991    (use (label_ref (match_operand 1 "" "")))]
13992   "TARGET_64BIT"
13993   "jmp\t%A0"
13994   [(set_attr "type" "ibr")
13995    (set_attr "length_immediate" "0")])
13996 \f
13997 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13998
13999 (define_peephole2
14000   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14001    (set (match_operand:QI 1 "register_operand" "")
14002         (match_operator:QI 2 "ix86_comparison_operator"
14003           [(reg FLAGS_REG) (const_int 0)]))
14004    (set (match_operand 3 "q_regs_operand" "")
14005         (zero_extend (match_dup 1)))]
14006   "(peep2_reg_dead_p (3, operands[1])
14007     || operands_match_p (operands[1], operands[3]))
14008    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14009   [(set (match_dup 4) (match_dup 0))
14010    (set (strict_low_part (match_dup 5))
14011         (match_dup 2))]
14012 {
14013   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14014   operands[5] = gen_lowpart (QImode, operands[3]);
14015   ix86_expand_clear (operands[3]);
14016 })
14017
14018 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14019
14020 (define_peephole2
14021   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14022    (set (match_operand:QI 1 "register_operand" "")
14023         (match_operator:QI 2 "ix86_comparison_operator"
14024           [(reg FLAGS_REG) (const_int 0)]))
14025    (parallel [(set (match_operand 3 "q_regs_operand" "")
14026                    (zero_extend (match_dup 1)))
14027               (clobber (reg:CC FLAGS_REG))])]
14028   "(peep2_reg_dead_p (3, operands[1])
14029     || operands_match_p (operands[1], operands[3]))
14030    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14031   [(set (match_dup 4) (match_dup 0))
14032    (set (strict_low_part (match_dup 5))
14033         (match_dup 2))]
14034 {
14035   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14036   operands[5] = gen_lowpart (QImode, operands[3]);
14037   ix86_expand_clear (operands[3]);
14038 })
14039 \f
14040 ;; Call instructions.
14041
14042 ;; The predicates normally associated with named expanders are not properly
14043 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14044 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14045
14046 ;; Call subroutine returning no value.
14047
14048 (define_expand "call_pop"
14049   [(parallel [(call (match_operand:QI 0 "" "")
14050                     (match_operand:SI 1 "" ""))
14051               (set (reg:SI SP_REG)
14052                    (plus:SI (reg:SI SP_REG)
14053                             (match_operand:SI 3 "" "")))])]
14054   "!TARGET_64BIT"
14055 {
14056   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14057   DONE;
14058 })
14059
14060 (define_insn "*call_pop_0"
14061   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14062          (match_operand:SI 1 "" ""))
14063    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14064                             (match_operand:SI 2 "immediate_operand" "")))]
14065   "!TARGET_64BIT"
14066 {
14067   if (SIBLING_CALL_P (insn))
14068     return "jmp\t%P0";
14069   else
14070     return "call\t%P0";
14071 }
14072   [(set_attr "type" "call")])
14073   
14074 (define_insn "*call_pop_1"
14075   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14076          (match_operand:SI 1 "" ""))
14077    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14078                             (match_operand:SI 2 "immediate_operand" "i")))]
14079   "!TARGET_64BIT"
14080 {
14081   if (constant_call_address_operand (operands[0], Pmode))
14082     {
14083       if (SIBLING_CALL_P (insn))
14084         return "jmp\t%P0";
14085       else
14086         return "call\t%P0";
14087     }
14088   if (SIBLING_CALL_P (insn))
14089     return "jmp\t%A0";
14090   else
14091     return "call\t%A0";
14092 }
14093   [(set_attr "type" "call")])
14094
14095 (define_expand "call"
14096   [(call (match_operand:QI 0 "" "")
14097          (match_operand 1 "" ""))
14098    (use (match_operand 2 "" ""))]
14099   ""
14100 {
14101   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14102   DONE;
14103 })
14104
14105 (define_expand "sibcall"
14106   [(call (match_operand:QI 0 "" "")
14107          (match_operand 1 "" ""))
14108    (use (match_operand 2 "" ""))]
14109   ""
14110 {
14111   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14112   DONE;
14113 })
14114
14115 (define_insn "*call_0"
14116   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14117          (match_operand 1 "" ""))]
14118   ""
14119 {
14120   if (SIBLING_CALL_P (insn))
14121     return "jmp\t%P0";
14122   else
14123     return "call\t%P0";
14124 }
14125   [(set_attr "type" "call")])
14126
14127 (define_insn "*call_1"
14128   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14129          (match_operand 1 "" ""))]
14130   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14131 {
14132   if (constant_call_address_operand (operands[0], Pmode))
14133     return "call\t%P0";
14134   return "call\t%A0";
14135 }
14136   [(set_attr "type" "call")])
14137
14138 (define_insn "*sibcall_1"
14139   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14140          (match_operand 1 "" ""))]
14141   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14142 {
14143   if (constant_call_address_operand (operands[0], Pmode))
14144     return "jmp\t%P0";
14145   return "jmp\t%A0";
14146 }
14147   [(set_attr "type" "call")])
14148
14149 (define_insn "*call_1_rex64"
14150   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14151          (match_operand 1 "" ""))]
14152   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14153 {
14154   if (constant_call_address_operand (operands[0], Pmode))
14155     return "call\t%P0";
14156   return "call\t%A0";
14157 }
14158   [(set_attr "type" "call")])
14159
14160 (define_insn "*sibcall_1_rex64"
14161   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14162          (match_operand 1 "" ""))]
14163   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14164   "jmp\t%P0"
14165   [(set_attr "type" "call")])
14166
14167 (define_insn "*sibcall_1_rex64_v"
14168   [(call (mem:QI (reg:DI R11_REG))
14169          (match_operand 0 "" ""))]
14170   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14171   "jmp\t*%%r11"
14172   [(set_attr "type" "call")])
14173
14174
14175 ;; Call subroutine, returning value in operand 0
14176
14177 (define_expand "call_value_pop"
14178   [(parallel [(set (match_operand 0 "" "")
14179                    (call (match_operand:QI 1 "" "")
14180                          (match_operand:SI 2 "" "")))
14181               (set (reg:SI SP_REG)
14182                    (plus:SI (reg:SI SP_REG)
14183                             (match_operand:SI 4 "" "")))])]
14184   "!TARGET_64BIT"
14185 {
14186   ix86_expand_call (operands[0], operands[1], operands[2],
14187                     operands[3], operands[4], 0);
14188   DONE;
14189 })
14190
14191 (define_expand "call_value"
14192   [(set (match_operand 0 "" "")
14193         (call (match_operand:QI 1 "" "")
14194               (match_operand:SI 2 "" "")))
14195    (use (match_operand:SI 3 "" ""))]
14196   ;; Operand 2 not used on the i386.
14197   ""
14198 {
14199   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14200   DONE;
14201 })
14202
14203 (define_expand "sibcall_value"
14204   [(set (match_operand 0 "" "")
14205         (call (match_operand:QI 1 "" "")
14206               (match_operand:SI 2 "" "")))
14207    (use (match_operand:SI 3 "" ""))]
14208   ;; Operand 2 not used on the i386.
14209   ""
14210 {
14211   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14212   DONE;
14213 })
14214
14215 ;; Call subroutine returning any type.
14216
14217 (define_expand "untyped_call"
14218   [(parallel [(call (match_operand 0 "" "")
14219                     (const_int 0))
14220               (match_operand 1 "" "")
14221               (match_operand 2 "" "")])]
14222   ""
14223 {
14224   int i;
14225
14226   /* In order to give reg-stack an easier job in validating two
14227      coprocessor registers as containing a possible return value,
14228      simply pretend the untyped call returns a complex long double
14229      value.  */
14230
14231   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14232                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14233                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14234                     NULL, 0);
14235
14236   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14237     {
14238       rtx set = XVECEXP (operands[2], 0, i);
14239       emit_move_insn (SET_DEST (set), SET_SRC (set));
14240     }
14241
14242   /* The optimizer does not know that the call sets the function value
14243      registers we stored in the result block.  We avoid problems by
14244      claiming that all hard registers are used and clobbered at this
14245      point.  */
14246   emit_insn (gen_blockage (const0_rtx));
14247
14248   DONE;
14249 })
14250 \f
14251 ;; Prologue and epilogue instructions
14252
14253 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14254 ;; all of memory.  This blocks insns from being moved across this point.
14255
14256 (define_insn "blockage"
14257   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14258   ""
14259   ""
14260   [(set_attr "length" "0")])
14261
14262 ;; Insn emitted into the body of a function to return from a function.
14263 ;; This is only done if the function's epilogue is known to be simple.
14264 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14265
14266 (define_expand "return"
14267   [(return)]
14268   "ix86_can_use_return_insn_p ()"
14269 {
14270   if (current_function_pops_args)
14271     {
14272       rtx popc = GEN_INT (current_function_pops_args);
14273       emit_jump_insn (gen_return_pop_internal (popc));
14274       DONE;
14275     }
14276 })
14277
14278 (define_insn "return_internal"
14279   [(return)]
14280   "reload_completed"
14281   "ret"
14282   [(set_attr "length" "1")
14283    (set_attr "length_immediate" "0")
14284    (set_attr "modrm" "0")])
14285
14286 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14287 ;; instruction Athlon and K8 have.
14288
14289 (define_insn "return_internal_long"
14290   [(return)
14291    (unspec [(const_int 0)] UNSPEC_REP)]
14292   "reload_completed"
14293   "rep {;} ret"
14294   [(set_attr "length" "1")
14295    (set_attr "length_immediate" "0")
14296    (set_attr "prefix_rep" "1")
14297    (set_attr "modrm" "0")])
14298
14299 (define_insn "return_pop_internal"
14300   [(return)
14301    (use (match_operand:SI 0 "const_int_operand" ""))]
14302   "reload_completed"
14303   "ret\t%0"
14304   [(set_attr "length" "3")
14305    (set_attr "length_immediate" "2")
14306    (set_attr "modrm" "0")])
14307
14308 (define_insn "return_indirect_internal"
14309   [(return)
14310    (use (match_operand:SI 0 "register_operand" "r"))]
14311   "reload_completed"
14312   "jmp\t%A0"
14313   [(set_attr "type" "ibr")
14314    (set_attr "length_immediate" "0")])
14315
14316 (define_insn "nop"
14317   [(const_int 0)]
14318   ""
14319   "nop"
14320   [(set_attr "length" "1")
14321    (set_attr "length_immediate" "0")
14322    (set_attr "modrm" "0")])
14323
14324 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14325 ;; branch prediction penalty for the third jump in a 16-byte
14326 ;; block on K8.
14327
14328 (define_insn "align"
14329   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14330   ""
14331 {
14332 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14333   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14334 #else
14335   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14336      The align insn is used to avoid 3 jump instructions in the row to improve
14337      branch prediction and the benefits hardly outweigh the cost of extra 8
14338      nops on the average inserted by full alignment pseudo operation.  */
14339 #endif
14340   return "";
14341 }
14342   [(set_attr "length" "16")])
14343
14344 (define_expand "prologue"
14345   [(const_int 1)]
14346   ""
14347   "ix86_expand_prologue (); DONE;")
14348
14349 (define_insn "set_got"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "!TARGET_64BIT"
14354   { return output_set_got (operands[0], NULL_RTX); }
14355   [(set_attr "type" "multi")
14356    (set_attr "length" "12")])
14357
14358 (define_insn "set_got_labelled"
14359   [(set (match_operand:SI 0 "register_operand" "=r")
14360         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14361          UNSPEC_SET_GOT))
14362    (clobber (reg:CC FLAGS_REG))]
14363   "!TARGET_64BIT"
14364   { return output_set_got (operands[0], operands[1]); }
14365   [(set_attr "type" "multi")
14366    (set_attr "length" "12")])
14367
14368 (define_insn "set_got_rex64"
14369   [(set (match_operand:DI 0 "register_operand" "=r")
14370         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14371   "TARGET_64BIT"
14372   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14373   [(set_attr "type" "lea")
14374    (set_attr "length" "6")])
14375
14376 (define_expand "epilogue"
14377   [(const_int 1)]
14378   ""
14379   "ix86_expand_epilogue (1); DONE;")
14380
14381 (define_expand "sibcall_epilogue"
14382   [(const_int 1)]
14383   ""
14384   "ix86_expand_epilogue (0); DONE;")
14385
14386 (define_expand "eh_return"
14387   [(use (match_operand 0 "register_operand" ""))]
14388   ""
14389 {
14390   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14391
14392   /* Tricky bit: we write the address of the handler to which we will
14393      be returning into someone else's stack frame, one word below the
14394      stack address we wish to restore.  */
14395   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14396   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14397   tmp = gen_rtx_MEM (Pmode, tmp);
14398   emit_move_insn (tmp, ra);
14399
14400   if (Pmode == SImode)
14401     emit_jump_insn (gen_eh_return_si (sa));
14402   else
14403     emit_jump_insn (gen_eh_return_di (sa));
14404   emit_barrier ();
14405   DONE;
14406 })
14407
14408 (define_insn_and_split "eh_return_si"
14409   [(set (pc) 
14410         (unspec [(match_operand:SI 0 "register_operand" "c")]
14411                  UNSPEC_EH_RETURN))]
14412   "!TARGET_64BIT"
14413   "#"
14414   "reload_completed"
14415   [(const_int 1)]
14416   "ix86_expand_epilogue (2); DONE;")
14417
14418 (define_insn_and_split "eh_return_di"
14419   [(set (pc) 
14420         (unspec [(match_operand:DI 0 "register_operand" "c")]
14421                  UNSPEC_EH_RETURN))]
14422   "TARGET_64BIT"
14423   "#"
14424   "reload_completed"
14425   [(const_int 1)]
14426   "ix86_expand_epilogue (2); DONE;")
14427
14428 (define_insn "leave"
14429   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14430    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14431    (clobber (mem:BLK (scratch)))]
14432   "!TARGET_64BIT"
14433   "leave"
14434   [(set_attr "type" "leave")])
14435
14436 (define_insn "leave_rex64"
14437   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14438    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14439    (clobber (mem:BLK (scratch)))]
14440   "TARGET_64BIT"
14441   "leave"
14442   [(set_attr "type" "leave")])
14443 \f
14444 (define_expand "ffssi2"
14445   [(parallel
14446      [(set (match_operand:SI 0 "register_operand" "") 
14447            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14448       (clobber (match_scratch:SI 2 ""))
14449       (clobber (reg:CC FLAGS_REG))])]
14450   ""
14451   "")
14452
14453 (define_insn_and_split "*ffs_cmove"
14454   [(set (match_operand:SI 0 "register_operand" "=r") 
14455         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14456    (clobber (match_scratch:SI 2 "=&r"))
14457    (clobber (reg:CC FLAGS_REG))]
14458   "TARGET_CMOVE"
14459   "#"
14460   "&& reload_completed"
14461   [(set (match_dup 2) (const_int -1))
14462    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14463               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14464    (set (match_dup 0) (if_then_else:SI
14465                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14466                         (match_dup 2)
14467                         (match_dup 0)))
14468    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14469               (clobber (reg:CC FLAGS_REG))])]
14470   "")
14471
14472 (define_insn_and_split "*ffs_no_cmove"
14473   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14474         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14475    (clobber (match_scratch:SI 2 "=&q"))
14476    (clobber (reg:CC FLAGS_REG))]
14477   ""
14478   "#"
14479   "reload_completed"
14480   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14481               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14482    (set (strict_low_part (match_dup 3))
14483         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14484    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14485               (clobber (reg:CC FLAGS_REG))])
14486    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14487               (clobber (reg:CC FLAGS_REG))])
14488    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14489               (clobber (reg:CC FLAGS_REG))])]
14490 {
14491   operands[3] = gen_lowpart (QImode, operands[2]);
14492   ix86_expand_clear (operands[2]);
14493 })
14494
14495 (define_insn "*ffssi_1"
14496   [(set (reg:CCZ FLAGS_REG)
14497         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14498                      (const_int 0)))
14499    (set (match_operand:SI 0 "register_operand" "=r")
14500         (ctz:SI (match_dup 1)))]
14501   ""
14502   "bsf{l}\t{%1, %0|%0, %1}"
14503   [(set_attr "prefix_0f" "1")])
14504
14505 (define_expand "ffsdi2"
14506   [(parallel
14507      [(set (match_operand:DI 0 "register_operand" "") 
14508            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14509       (clobber (match_scratch:DI 2 ""))
14510       (clobber (reg:CC FLAGS_REG))])]
14511   "TARGET_64BIT && TARGET_CMOVE"
14512   "")
14513
14514 (define_insn_and_split "*ffs_rex64"
14515   [(set (match_operand:DI 0 "register_operand" "=r") 
14516         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14517    (clobber (match_scratch:DI 2 "=&r"))
14518    (clobber (reg:CC FLAGS_REG))]
14519   "TARGET_64BIT && TARGET_CMOVE"
14520   "#"
14521   "&& reload_completed"
14522   [(set (match_dup 2) (const_int -1))
14523    (parallel [(set (reg:CCZ FLAGS_REG)
14524                    (compare:CCZ (match_dup 1) (const_int 0)))
14525               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14526    (set (match_dup 0) (if_then_else:DI
14527                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14528                         (match_dup 2)
14529                         (match_dup 0)))
14530    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14531               (clobber (reg:CC FLAGS_REG))])]
14532   "")
14533
14534 (define_insn "*ffsdi_1"
14535   [(set (reg:CCZ FLAGS_REG)
14536         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14537                      (const_int 0)))
14538    (set (match_operand:DI 0 "register_operand" "=r")
14539         (ctz:DI (match_dup 1)))]
14540   "TARGET_64BIT"
14541   "bsf{q}\t{%1, %0|%0, %1}"
14542   [(set_attr "prefix_0f" "1")])
14543
14544 (define_insn "ctzsi2"
14545   [(set (match_operand:SI 0 "register_operand" "=r")
14546         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14547    (clobber (reg:CC FLAGS_REG))]
14548   ""
14549   "bsf{l}\t{%1, %0|%0, %1}"
14550   [(set_attr "prefix_0f" "1")])
14551
14552 (define_insn "ctzdi2"
14553   [(set (match_operand:DI 0 "register_operand" "=r")
14554         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555    (clobber (reg:CC FLAGS_REG))]
14556   "TARGET_64BIT"
14557   "bsf{q}\t{%1, %0|%0, %1}"
14558   [(set_attr "prefix_0f" "1")])
14559
14560 (define_expand "clzsi2"
14561   [(parallel
14562      [(set (match_operand:SI 0 "register_operand" "")
14563            (minus:SI (const_int 31)
14564                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14565       (clobber (reg:CC FLAGS_REG))])
14566    (parallel
14567      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14568       (clobber (reg:CC FLAGS_REG))])]
14569   ""
14570   "")
14571
14572 (define_insn "*bsr"
14573   [(set (match_operand:SI 0 "register_operand" "=r")
14574         (minus:SI (const_int 31)
14575                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14576    (clobber (reg:CC FLAGS_REG))]
14577   ""
14578   "bsr{l}\t{%1, %0|%0, %1}"
14579   [(set_attr "prefix_0f" "1")])
14580
14581 (define_expand "clzdi2"
14582   [(parallel
14583      [(set (match_operand:DI 0 "register_operand" "")
14584            (minus:DI (const_int 63)
14585                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14586       (clobber (reg:CC FLAGS_REG))])
14587    (parallel
14588      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14589       (clobber (reg:CC FLAGS_REG))])]
14590   "TARGET_64BIT"
14591   "")
14592
14593 (define_insn "*bsr_rex64"
14594   [(set (match_operand:DI 0 "register_operand" "=r")
14595         (minus:DI (const_int 63)
14596                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14597    (clobber (reg:CC FLAGS_REG))]
14598   "TARGET_64BIT"
14599   "bsr{q}\t{%1, %0|%0, %1}"
14600   [(set_attr "prefix_0f" "1")])
14601 \f
14602 ;; Thread-local storage patterns for ELF.
14603 ;;
14604 ;; Note that these code sequences must appear exactly as shown
14605 ;; in order to allow linker relaxation.
14606
14607 (define_insn "*tls_global_dynamic_32_gnu"
14608   [(set (match_operand:SI 0 "register_operand" "=a")
14609         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14610                     (match_operand:SI 2 "tls_symbolic_operand" "")
14611                     (match_operand:SI 3 "call_insn_operand" "")]
14612                     UNSPEC_TLS_GD))
14613    (clobber (match_scratch:SI 4 "=d"))
14614    (clobber (match_scratch:SI 5 "=c"))
14615    (clobber (reg:CC FLAGS_REG))]
14616   "!TARGET_64BIT && TARGET_GNU_TLS"
14617   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14618   [(set_attr "type" "multi")
14619    (set_attr "length" "12")])
14620
14621 (define_insn "*tls_global_dynamic_32_sun"
14622   [(set (match_operand:SI 0 "register_operand" "=a")
14623         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14624                     (match_operand:SI 2 "tls_symbolic_operand" "")
14625                     (match_operand:SI 3 "call_insn_operand" "")]
14626                     UNSPEC_TLS_GD))
14627    (clobber (match_scratch:SI 4 "=d"))
14628    (clobber (match_scratch:SI 5 "=c"))
14629    (clobber (reg:CC FLAGS_REG))]
14630   "!TARGET_64BIT && TARGET_SUN_TLS"
14631   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14632         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14633   [(set_attr "type" "multi")
14634    (set_attr "length" "14")])
14635
14636 (define_expand "tls_global_dynamic_32"
14637   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14638                    (unspec:SI
14639                     [(match_dup 2)
14640                      (match_operand:SI 1 "tls_symbolic_operand" "")
14641                      (match_dup 3)]
14642                     UNSPEC_TLS_GD))
14643               (clobber (match_scratch:SI 4 ""))
14644               (clobber (match_scratch:SI 5 ""))
14645               (clobber (reg:CC FLAGS_REG))])]
14646   ""
14647 {
14648   if (flag_pic)
14649     operands[2] = pic_offset_table_rtx;
14650   else
14651     {
14652       operands[2] = gen_reg_rtx (Pmode);
14653       emit_insn (gen_set_got (operands[2]));
14654     }
14655   if (TARGET_GNU2_TLS)
14656     {
14657        emit_insn (gen_tls_dynamic_gnu2_32
14658                   (operands[0], operands[1], operands[2]));
14659        DONE;
14660     }
14661   operands[3] = ix86_tls_get_addr ();
14662 })
14663
14664 (define_insn "*tls_global_dynamic_64"
14665   [(set (match_operand:DI 0 "register_operand" "=a")
14666         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14667                  (match_operand:DI 3 "" "")))
14668    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14669               UNSPEC_TLS_GD)]
14670   "TARGET_64BIT"
14671   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14672   [(set_attr "type" "multi")
14673    (set_attr "length" "16")])
14674
14675 (define_expand "tls_global_dynamic_64"
14676   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14677                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14678               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14679                          UNSPEC_TLS_GD)])]
14680   ""
14681 {
14682   if (TARGET_GNU2_TLS)
14683     {
14684        emit_insn (gen_tls_dynamic_gnu2_64
14685                   (operands[0], operands[1]));
14686        DONE;
14687     }
14688   operands[2] = ix86_tls_get_addr ();
14689 })
14690
14691 (define_insn "*tls_local_dynamic_base_32_gnu"
14692   [(set (match_operand:SI 0 "register_operand" "=a")
14693         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14694                     (match_operand:SI 2 "call_insn_operand" "")]
14695                    UNSPEC_TLS_LD_BASE))
14696    (clobber (match_scratch:SI 3 "=d"))
14697    (clobber (match_scratch:SI 4 "=c"))
14698    (clobber (reg:CC FLAGS_REG))]
14699   "!TARGET_64BIT && TARGET_GNU_TLS"
14700   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14701   [(set_attr "type" "multi")
14702    (set_attr "length" "11")])
14703
14704 (define_insn "*tls_local_dynamic_base_32_sun"
14705   [(set (match_operand:SI 0 "register_operand" "=a")
14706         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14707                     (match_operand:SI 2 "call_insn_operand" "")]
14708                    UNSPEC_TLS_LD_BASE))
14709    (clobber (match_scratch:SI 3 "=d"))
14710    (clobber (match_scratch:SI 4 "=c"))
14711    (clobber (reg:CC FLAGS_REG))]
14712   "!TARGET_64BIT && TARGET_SUN_TLS"
14713   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14714         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14715   [(set_attr "type" "multi")
14716    (set_attr "length" "13")])
14717
14718 (define_expand "tls_local_dynamic_base_32"
14719   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14720                    (unspec:SI [(match_dup 1) (match_dup 2)]
14721                               UNSPEC_TLS_LD_BASE))
14722               (clobber (match_scratch:SI 3 ""))
14723               (clobber (match_scratch:SI 4 ""))
14724               (clobber (reg:CC FLAGS_REG))])]
14725   ""
14726 {
14727   if (flag_pic)
14728     operands[1] = pic_offset_table_rtx;
14729   else
14730     {
14731       operands[1] = gen_reg_rtx (Pmode);
14732       emit_insn (gen_set_got (operands[1]));
14733     }
14734   if (TARGET_GNU2_TLS)
14735     {
14736        emit_insn (gen_tls_dynamic_gnu2_32
14737                   (operands[0], ix86_tls_module_base (), operands[1]));
14738        DONE;
14739     }
14740   operands[2] = ix86_tls_get_addr ();
14741 })
14742
14743 (define_insn "*tls_local_dynamic_base_64"
14744   [(set (match_operand:DI 0 "register_operand" "=a")
14745         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14746                  (match_operand:DI 2 "" "")))
14747    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14748   "TARGET_64BIT"
14749   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14750   [(set_attr "type" "multi")
14751    (set_attr "length" "12")])
14752
14753 (define_expand "tls_local_dynamic_base_64"
14754   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14755                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14756               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14757   ""
14758 {
14759   if (TARGET_GNU2_TLS)
14760     {
14761        emit_insn (gen_tls_dynamic_gnu2_64
14762                   (operands[0], ix86_tls_module_base ()));
14763        DONE;
14764     }
14765   operands[1] = ix86_tls_get_addr ();
14766 })
14767
14768 ;; Local dynamic of a single variable is a lose.  Show combine how
14769 ;; to convert that back to global dynamic.
14770
14771 (define_insn_and_split "*tls_local_dynamic_32_once"
14772   [(set (match_operand:SI 0 "register_operand" "=a")
14773         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14774                              (match_operand:SI 2 "call_insn_operand" "")]
14775                             UNSPEC_TLS_LD_BASE)
14776                  (const:SI (unspec:SI
14777                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14778                             UNSPEC_DTPOFF))))
14779    (clobber (match_scratch:SI 4 "=d"))
14780    (clobber (match_scratch:SI 5 "=c"))
14781    (clobber (reg:CC FLAGS_REG))]
14782   ""
14783   "#"
14784   ""
14785   [(parallel [(set (match_dup 0)
14786                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14787                               UNSPEC_TLS_GD))
14788               (clobber (match_dup 4))
14789               (clobber (match_dup 5))
14790               (clobber (reg:CC FLAGS_REG))])]
14791   "")
14792
14793 ;; Load and add the thread base pointer from %gs:0.
14794
14795 (define_insn "*load_tp_si"
14796   [(set (match_operand:SI 0 "register_operand" "=r")
14797         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14798   "!TARGET_64BIT"
14799   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14800   [(set_attr "type" "imov")
14801    (set_attr "modrm" "0")
14802    (set_attr "length" "7")
14803    (set_attr "memory" "load")
14804    (set_attr "imm_disp" "false")])
14805
14806 (define_insn "*add_tp_si"
14807   [(set (match_operand:SI 0 "register_operand" "=r")
14808         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14809                  (match_operand:SI 1 "register_operand" "0")))
14810    (clobber (reg:CC FLAGS_REG))]
14811   "!TARGET_64BIT"
14812   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14813   [(set_attr "type" "alu")
14814    (set_attr "modrm" "0")
14815    (set_attr "length" "7")
14816    (set_attr "memory" "load")
14817    (set_attr "imm_disp" "false")])
14818
14819 (define_insn "*load_tp_di"
14820   [(set (match_operand:DI 0 "register_operand" "=r")
14821         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14822   "TARGET_64BIT"
14823   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14824   [(set_attr "type" "imov")
14825    (set_attr "modrm" "0")
14826    (set_attr "length" "7")
14827    (set_attr "memory" "load")
14828    (set_attr "imm_disp" "false")])
14829
14830 (define_insn "*add_tp_di"
14831   [(set (match_operand:DI 0 "register_operand" "=r")
14832         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14833                  (match_operand:DI 1 "register_operand" "0")))
14834    (clobber (reg:CC FLAGS_REG))]
14835   "TARGET_64BIT"
14836   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14837   [(set_attr "type" "alu")
14838    (set_attr "modrm" "0")
14839    (set_attr "length" "7")
14840    (set_attr "memory" "load")
14841    (set_attr "imm_disp" "false")])
14842
14843 ;; GNU2 TLS patterns can be split.
14844
14845 (define_expand "tls_dynamic_gnu2_32"
14846   [(set (match_dup 3)
14847         (plus:SI (match_operand:SI 2 "register_operand" "")
14848                  (const:SI
14849                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14850                              UNSPEC_TLSDESC))))
14851    (parallel
14852     [(set (match_operand:SI 0 "register_operand" "")
14853           (unspec:SI [(match_dup 1) (match_dup 3)
14854                       (match_dup 2) (reg:SI SP_REG)]
14855                       UNSPEC_TLSDESC))
14856      (clobber (reg:CC FLAGS_REG))])]
14857   "!TARGET_64BIT && TARGET_GNU2_TLS"
14858 {
14859   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14860   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14861 })
14862
14863 (define_insn "*tls_dynamic_lea_32"
14864   [(set (match_operand:SI 0 "register_operand" "=r")
14865         (plus:SI (match_operand:SI 1 "register_operand" "b")
14866                  (const:SI
14867                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14868                               UNSPEC_TLSDESC))))]
14869   "!TARGET_64BIT && TARGET_GNU2_TLS"
14870   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14871   [(set_attr "type" "lea")
14872    (set_attr "mode" "SI")
14873    (set_attr "length" "6")
14874    (set_attr "length_address" "4")])
14875
14876 (define_insn "*tls_dynamic_call_32"
14877   [(set (match_operand:SI 0 "register_operand" "=a")
14878         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14879                     (match_operand:SI 2 "register_operand" "0")
14880                     ;; we have to make sure %ebx still points to the GOT
14881                     (match_operand:SI 3 "register_operand" "b")
14882                     (reg:SI SP_REG)]
14883                    UNSPEC_TLSDESC))
14884    (clobber (reg:CC FLAGS_REG))]
14885   "!TARGET_64BIT && TARGET_GNU2_TLS"
14886   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14887   [(set_attr "type" "call")
14888    (set_attr "length" "2")
14889    (set_attr "length_address" "0")])
14890
14891 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14892   [(set (match_operand:SI 0 "register_operand" "=&a")
14893         (plus:SI
14894          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14895                      (match_operand:SI 4 "" "")
14896                      (match_operand:SI 2 "register_operand" "b")
14897                      (reg:SI SP_REG)]
14898                     UNSPEC_TLSDESC)
14899          (const:SI (unspec:SI
14900                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14901                     UNSPEC_DTPOFF))))
14902    (clobber (reg:CC FLAGS_REG))]
14903   "!TARGET_64BIT && TARGET_GNU2_TLS"
14904   "#"
14905   ""
14906   [(set (match_dup 0) (match_dup 5))]
14907 {
14908   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14910 })
14911
14912 (define_expand "tls_dynamic_gnu2_64"
14913   [(set (match_dup 2)
14914         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14915                    UNSPEC_TLSDESC))
14916    (parallel
14917     [(set (match_operand:DI 0 "register_operand" "")
14918           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14919                      UNSPEC_TLSDESC))
14920      (clobber (reg:CC FLAGS_REG))])]
14921   "TARGET_64BIT && TARGET_GNU2_TLS"
14922 {
14923   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14924   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14925 })
14926
14927 (define_insn "*tls_dynamic_lea_64"
14928   [(set (match_operand:DI 0 "register_operand" "=r")
14929         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14930                    UNSPEC_TLSDESC))]
14931   "TARGET_64BIT && TARGET_GNU2_TLS"
14932   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14933   [(set_attr "type" "lea")
14934    (set_attr "mode" "DI")
14935    (set_attr "length" "7")
14936    (set_attr "length_address" "4")])
14937
14938 (define_insn "*tls_dynamic_call_64"
14939   [(set (match_operand:DI 0 "register_operand" "=a")
14940         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14941                     (match_operand:DI 2 "register_operand" "0")
14942                     (reg:DI SP_REG)]
14943                    UNSPEC_TLSDESC))
14944    (clobber (reg:CC FLAGS_REG))]
14945   "TARGET_64BIT && TARGET_GNU2_TLS"
14946   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14947   [(set_attr "type" "call")
14948    (set_attr "length" "2")
14949    (set_attr "length_address" "0")])
14950
14951 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14952   [(set (match_operand:DI 0 "register_operand" "=&a")
14953         (plus:DI
14954          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14955                      (match_operand:DI 3 "" "")
14956                      (reg:DI SP_REG)]
14957                     UNSPEC_TLSDESC)
14958          (const:DI (unspec:DI
14959                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14960                     UNSPEC_DTPOFF))))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_64BIT && TARGET_GNU2_TLS"
14963   "#"
14964   ""
14965   [(set (match_dup 0) (match_dup 4))]
14966 {
14967   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14969 })
14970
14971 ;;
14972 \f
14973 ;; These patterns match the binary 387 instructions for addM3, subM3,
14974 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14975 ;; SFmode.  The first is the normal insn, the second the same insn but
14976 ;; with one operand a conversion, and the third the same insn but with
14977 ;; the other operand a conversion.  The conversion may be SFmode or
14978 ;; SImode if the target mode DFmode, but only SImode if the target mode
14979 ;; is SFmode.
14980
14981 ;; Gcc is slightly more smart about handling normal two address instructions
14982 ;; so use special patterns for add and mull.
14983
14984 (define_insn "*fop_sf_comm_mixed"
14985   [(set (match_operand:SF 0 "register_operand" "=f,x")
14986         (match_operator:SF 3 "binary_fp_operator"
14987                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14988                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14989   "TARGET_MIX_SSE_I387
14990    && COMMUTATIVE_ARITH_P (operands[3])
14991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14992   "* return output_387_binary_op (insn, operands);"
14993   [(set (attr "type") 
14994         (if_then_else (eq_attr "alternative" "1")
14995            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14996               (const_string "ssemul")
14997               (const_string "sseadd"))
14998            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14999               (const_string "fmul")
15000               (const_string "fop"))))
15001    (set_attr "mode" "SF")])
15002
15003 (define_insn "*fop_sf_comm_sse"
15004   [(set (match_operand:SF 0 "register_operand" "=x")
15005         (match_operator:SF 3 "binary_fp_operator"
15006                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15008   "TARGET_SSE_MATH
15009    && COMMUTATIVE_ARITH_P (operands[3])
15010    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011   "* return output_387_binary_op (insn, operands);"
15012   [(set (attr "type") 
15013         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15014            (const_string "ssemul")
15015            (const_string "sseadd")))
15016    (set_attr "mode" "SF")])
15017
15018 (define_insn "*fop_sf_comm_i387"
15019   [(set (match_operand:SF 0 "register_operand" "=f")
15020         (match_operator:SF 3 "binary_fp_operator"
15021                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15022                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15023   "TARGET_80387
15024    && COMMUTATIVE_ARITH_P (operands[3])
15025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026   "* return output_387_binary_op (insn, operands);"
15027   [(set (attr "type") 
15028         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15029            (const_string "fmul")
15030            (const_string "fop")))
15031    (set_attr "mode" "SF")])
15032
15033 (define_insn "*fop_sf_1_mixed"
15034   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15035         (match_operator:SF 3 "binary_fp_operator"
15036                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15037                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15038   "TARGET_MIX_SSE_I387
15039    && !COMMUTATIVE_ARITH_P (operands[3])
15040    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15041   "* return output_387_binary_op (insn, operands);"
15042   [(set (attr "type") 
15043         (cond [(and (eq_attr "alternative" "2")
15044                     (match_operand:SF 3 "mult_operator" ""))
15045                  (const_string "ssemul")
15046                (and (eq_attr "alternative" "2")
15047                     (match_operand:SF 3 "div_operator" ""))
15048                  (const_string "ssediv")
15049                (eq_attr "alternative" "2")
15050                  (const_string "sseadd")
15051                (match_operand:SF 3 "mult_operator" "") 
15052                  (const_string "fmul")
15053                (match_operand:SF 3 "div_operator" "") 
15054                  (const_string "fdiv")
15055               ]
15056               (const_string "fop")))
15057    (set_attr "mode" "SF")])
15058
15059 (define_insn "*fop_sf_1_sse"
15060   [(set (match_operand:SF 0 "register_operand" "=x")
15061         (match_operator:SF 3 "binary_fp_operator"
15062                         [(match_operand:SF 1 "register_operand" "0")
15063                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15064   "TARGET_SSE_MATH
15065    && !COMMUTATIVE_ARITH_P (operands[3])"
15066   "* return output_387_binary_op (insn, operands);"
15067   [(set (attr "type") 
15068         (cond [(match_operand:SF 3 "mult_operator" "")
15069                  (const_string "ssemul")
15070                (match_operand:SF 3 "div_operator" "")
15071                  (const_string "ssediv")
15072               ]
15073               (const_string "sseadd")))
15074    (set_attr "mode" "SF")])
15075
15076 ;; This pattern is not fully shadowed by the pattern above.
15077 (define_insn "*fop_sf_1_i387"
15078   [(set (match_operand:SF 0 "register_operand" "=f,f")
15079         (match_operator:SF 3 "binary_fp_operator"
15080                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15081                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15082   "TARGET_80387 && !TARGET_SSE_MATH
15083    && !COMMUTATIVE_ARITH_P (operands[3])
15084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15085   "* return output_387_binary_op (insn, operands);"
15086   [(set (attr "type") 
15087         (cond [(match_operand:SF 3 "mult_operator" "") 
15088                  (const_string "fmul")
15089                (match_operand:SF 3 "div_operator" "") 
15090                  (const_string "fdiv")
15091               ]
15092               (const_string "fop")))
15093    (set_attr "mode" "SF")])
15094
15095 ;; ??? Add SSE splitters for these!
15096 (define_insn "*fop_sf_2<mode>_i387"
15097   [(set (match_operand:SF 0 "register_operand" "=f,f")
15098         (match_operator:SF 3 "binary_fp_operator"
15099           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15100            (match_operand:SF 2 "register_operand" "0,0")]))]
15101   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15102   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15103   [(set (attr "type") 
15104         (cond [(match_operand:SF 3 "mult_operator" "") 
15105                  (const_string "fmul")
15106                (match_operand:SF 3 "div_operator" "") 
15107                  (const_string "fdiv")
15108               ]
15109               (const_string "fop")))
15110    (set_attr "fp_int_src" "true")
15111    (set_attr "mode" "<MODE>")])
15112
15113 (define_insn "*fop_sf_3<mode>_i387"
15114   [(set (match_operand:SF 0 "register_operand" "=f,f")
15115         (match_operator:SF 3 "binary_fp_operator"
15116           [(match_operand:SF 1 "register_operand" "0,0")
15117            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15118   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15119   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15120   [(set (attr "type") 
15121         (cond [(match_operand:SF 3 "mult_operator" "") 
15122                  (const_string "fmul")
15123                (match_operand:SF 3 "div_operator" "") 
15124                  (const_string "fdiv")
15125               ]
15126               (const_string "fop")))
15127    (set_attr "fp_int_src" "true")
15128    (set_attr "mode" "<MODE>")])
15129
15130 (define_insn "*fop_df_comm_mixed"
15131   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15132         (match_operator:DF 3 "binary_fp_operator"
15133                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15134                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15135   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15136    && COMMUTATIVE_ARITH_P (operands[3])
15137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15138   "* return output_387_binary_op (insn, operands);"
15139   [(set (attr "type") 
15140         (if_then_else (eq_attr "alternative" "1")
15141            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15142               (const_string "ssemul")
15143               (const_string "sseadd"))
15144            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15145               (const_string "fmul")
15146               (const_string "fop"))))
15147    (set_attr "mode" "DF")])
15148
15149 (define_insn "*fop_df_comm_sse"
15150   [(set (match_operand:DF 0 "register_operand" "=Y")
15151         (match_operator:DF 3 "binary_fp_operator"
15152                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15154   "TARGET_SSE2 && TARGET_SSE_MATH
15155    && COMMUTATIVE_ARITH_P (operands[3])
15156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157   "* return output_387_binary_op (insn, operands);"
15158   [(set (attr "type") 
15159         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15160            (const_string "ssemul")
15161            (const_string "sseadd")))
15162    (set_attr "mode" "DF")])
15163
15164 (define_insn "*fop_df_comm_i387"
15165   [(set (match_operand:DF 0 "register_operand" "=f")
15166         (match_operator:DF 3 "binary_fp_operator"
15167                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15168                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15169   "TARGET_80387
15170    && COMMUTATIVE_ARITH_P (operands[3])
15171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172   "* return output_387_binary_op (insn, operands);"
15173   [(set (attr "type") 
15174         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15175            (const_string "fmul")
15176            (const_string "fop")))
15177    (set_attr "mode" "DF")])
15178
15179 (define_insn "*fop_df_1_mixed"
15180   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15181         (match_operator:DF 3 "binary_fp_operator"
15182                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15183                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15184   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15185    && !COMMUTATIVE_ARITH_P (operands[3])
15186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15187   "* return output_387_binary_op (insn, operands);"
15188   [(set (attr "type") 
15189         (cond [(and (eq_attr "alternative" "2")
15190                     (match_operand:DF 3 "mult_operator" ""))
15191                  (const_string "ssemul")
15192                (and (eq_attr "alternative" "2")
15193                     (match_operand:DF 3 "div_operator" ""))
15194                  (const_string "ssediv")
15195                (eq_attr "alternative" "2")
15196                  (const_string "sseadd")
15197                (match_operand:DF 3 "mult_operator" "") 
15198                  (const_string "fmul")
15199                (match_operand:DF 3 "div_operator" "") 
15200                  (const_string "fdiv")
15201               ]
15202               (const_string "fop")))
15203    (set_attr "mode" "DF")])
15204
15205 (define_insn "*fop_df_1_sse"
15206   [(set (match_operand:DF 0 "register_operand" "=Y")
15207         (match_operator:DF 3 "binary_fp_operator"
15208                         [(match_operand:DF 1 "register_operand" "0")
15209                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210   "TARGET_SSE2 && TARGET_SSE_MATH
15211    && !COMMUTATIVE_ARITH_P (operands[3])"
15212   "* return output_387_binary_op (insn, operands);"
15213   [(set_attr "mode" "DF")
15214    (set (attr "type") 
15215         (cond [(match_operand:DF 3 "mult_operator" "")
15216                  (const_string "ssemul")
15217                (match_operand:DF 3 "div_operator" "")
15218                  (const_string "ssediv")
15219               ]
15220               (const_string "sseadd")))])
15221
15222 ;; This pattern is not fully shadowed by the pattern above.
15223 (define_insn "*fop_df_1_i387"
15224   [(set (match_operand:DF 0 "register_operand" "=f,f")
15225         (match_operator:DF 3 "binary_fp_operator"
15226                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15227                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15228   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15229    && !COMMUTATIVE_ARITH_P (operands[3])
15230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15231   "* return output_387_binary_op (insn, operands);"
15232   [(set (attr "type") 
15233         (cond [(match_operand:DF 3 "mult_operator" "") 
15234                  (const_string "fmul")
15235                (match_operand:DF 3 "div_operator" "")
15236                  (const_string "fdiv")
15237               ]
15238               (const_string "fop")))
15239    (set_attr "mode" "DF")])
15240
15241 ;; ??? Add SSE splitters for these!
15242 (define_insn "*fop_df_2<mode>_i387"
15243   [(set (match_operand:DF 0 "register_operand" "=f,f")
15244         (match_operator:DF 3 "binary_fp_operator"
15245            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15246             (match_operand:DF 2 "register_operand" "0,0")]))]
15247   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15248    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15249   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15250   [(set (attr "type") 
15251         (cond [(match_operand:DF 3 "mult_operator" "") 
15252                  (const_string "fmul")
15253                (match_operand:DF 3 "div_operator" "") 
15254                  (const_string "fdiv")
15255               ]
15256               (const_string "fop")))
15257    (set_attr "fp_int_src" "true")
15258    (set_attr "mode" "<MODE>")])
15259
15260 (define_insn "*fop_df_3<mode>_i387"
15261   [(set (match_operand:DF 0 "register_operand" "=f,f")
15262         (match_operator:DF 3 "binary_fp_operator"
15263            [(match_operand:DF 1 "register_operand" "0,0")
15264             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15265   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15266    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15267   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15268   [(set (attr "type") 
15269         (cond [(match_operand:DF 3 "mult_operator" "") 
15270                  (const_string "fmul")
15271                (match_operand:DF 3 "div_operator" "") 
15272                  (const_string "fdiv")
15273               ]
15274               (const_string "fop")))
15275    (set_attr "fp_int_src" "true")
15276    (set_attr "mode" "<MODE>")])
15277
15278 (define_insn "*fop_df_4_i387"
15279   [(set (match_operand:DF 0 "register_operand" "=f,f")
15280         (match_operator:DF 3 "binary_fp_operator"
15281            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15282             (match_operand:DF 2 "register_operand" "0,f")]))]
15283   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285   "* return output_387_binary_op (insn, operands);"
15286   [(set (attr "type") 
15287         (cond [(match_operand:DF 3 "mult_operator" "") 
15288                  (const_string "fmul")
15289                (match_operand:DF 3 "div_operator" "") 
15290                  (const_string "fdiv")
15291               ]
15292               (const_string "fop")))
15293    (set_attr "mode" "SF")])
15294
15295 (define_insn "*fop_df_5_i387"
15296   [(set (match_operand:DF 0 "register_operand" "=f,f")
15297         (match_operator:DF 3 "binary_fp_operator"
15298           [(match_operand:DF 1 "register_operand" "0,f")
15299            (float_extend:DF
15300             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15301   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15302   "* return output_387_binary_op (insn, operands);"
15303   [(set (attr "type") 
15304         (cond [(match_operand:DF 3 "mult_operator" "") 
15305                  (const_string "fmul")
15306                (match_operand:DF 3 "div_operator" "") 
15307                  (const_string "fdiv")
15308               ]
15309               (const_string "fop")))
15310    (set_attr "mode" "SF")])
15311
15312 (define_insn "*fop_df_6_i387"
15313   [(set (match_operand:DF 0 "register_operand" "=f,f")
15314         (match_operator:DF 3 "binary_fp_operator"
15315           [(float_extend:DF
15316             (match_operand:SF 1 "register_operand" "0,f"))
15317            (float_extend:DF
15318             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15319   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15320   "* return output_387_binary_op (insn, operands);"
15321   [(set (attr "type") 
15322         (cond [(match_operand:DF 3 "mult_operator" "") 
15323                  (const_string "fmul")
15324                (match_operand:DF 3 "div_operator" "") 
15325                  (const_string "fdiv")
15326               ]
15327               (const_string "fop")))
15328    (set_attr "mode" "SF")])
15329
15330 (define_insn "*fop_xf_comm_i387"
15331   [(set (match_operand:XF 0 "register_operand" "=f")
15332         (match_operator:XF 3 "binary_fp_operator"
15333                         [(match_operand:XF 1 "register_operand" "%0")
15334                          (match_operand:XF 2 "register_operand" "f")]))]
15335   "TARGET_80387
15336    && COMMUTATIVE_ARITH_P (operands[3])"
15337   "* return output_387_binary_op (insn, operands);"
15338   [(set (attr "type") 
15339         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15340            (const_string "fmul")
15341            (const_string "fop")))
15342    (set_attr "mode" "XF")])
15343
15344 (define_insn "*fop_xf_1_i387"
15345   [(set (match_operand:XF 0 "register_operand" "=f,f")
15346         (match_operator:XF 3 "binary_fp_operator"
15347                         [(match_operand:XF 1 "register_operand" "0,f")
15348                          (match_operand:XF 2 "register_operand" "f,0")]))]
15349   "TARGET_80387
15350    && !COMMUTATIVE_ARITH_P (operands[3])"
15351   "* return output_387_binary_op (insn, operands);"
15352   [(set (attr "type") 
15353         (cond [(match_operand:XF 3 "mult_operator" "") 
15354                  (const_string "fmul")
15355                (match_operand:XF 3 "div_operator" "") 
15356                  (const_string "fdiv")
15357               ]
15358               (const_string "fop")))
15359    (set_attr "mode" "XF")])
15360
15361 (define_insn "*fop_xf_2<mode>_i387"
15362   [(set (match_operand:XF 0 "register_operand" "=f,f")
15363         (match_operator:XF 3 "binary_fp_operator"
15364            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15365             (match_operand:XF 2 "register_operand" "0,0")]))]
15366   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15367   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15368   [(set (attr "type") 
15369         (cond [(match_operand:XF 3 "mult_operator" "") 
15370                  (const_string "fmul")
15371                (match_operand:XF 3 "div_operator" "") 
15372                  (const_string "fdiv")
15373               ]
15374               (const_string "fop")))
15375    (set_attr "fp_int_src" "true")
15376    (set_attr "mode" "<MODE>")])
15377
15378 (define_insn "*fop_xf_3<mode>_i387"
15379   [(set (match_operand:XF 0 "register_operand" "=f,f")
15380         (match_operator:XF 3 "binary_fp_operator"
15381           [(match_operand:XF 1 "register_operand" "0,0")
15382            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15383   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15384   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15385   [(set (attr "type") 
15386         (cond [(match_operand:XF 3 "mult_operator" "") 
15387                  (const_string "fmul")
15388                (match_operand:XF 3 "div_operator" "") 
15389                  (const_string "fdiv")
15390               ]
15391               (const_string "fop")))
15392    (set_attr "fp_int_src" "true")
15393    (set_attr "mode" "<MODE>")])
15394
15395 (define_insn "*fop_xf_4_i387"
15396   [(set (match_operand:XF 0 "register_operand" "=f,f")
15397         (match_operator:XF 3 "binary_fp_operator"
15398            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15399             (match_operand:XF 2 "register_operand" "0,f")]))]
15400   "TARGET_80387"
15401   "* return output_387_binary_op (insn, operands);"
15402   [(set (attr "type") 
15403         (cond [(match_operand:XF 3 "mult_operator" "") 
15404                  (const_string "fmul")
15405                (match_operand:XF 3 "div_operator" "") 
15406                  (const_string "fdiv")
15407               ]
15408               (const_string "fop")))
15409    (set_attr "mode" "SF")])
15410
15411 (define_insn "*fop_xf_5_i387"
15412   [(set (match_operand:XF 0 "register_operand" "=f,f")
15413         (match_operator:XF 3 "binary_fp_operator"
15414           [(match_operand:XF 1 "register_operand" "0,f")
15415            (float_extend:XF
15416             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15417   "TARGET_80387"
15418   "* return output_387_binary_op (insn, operands);"
15419   [(set (attr "type") 
15420         (cond [(match_operand:XF 3 "mult_operator" "") 
15421                  (const_string "fmul")
15422                (match_operand:XF 3 "div_operator" "") 
15423                  (const_string "fdiv")
15424               ]
15425               (const_string "fop")))
15426    (set_attr "mode" "SF")])
15427
15428 (define_insn "*fop_xf_6_i387"
15429   [(set (match_operand:XF 0 "register_operand" "=f,f")
15430         (match_operator:XF 3 "binary_fp_operator"
15431           [(float_extend:XF
15432             (match_operand 1 "register_operand" "0,f"))
15433            (float_extend:XF
15434             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15435   "TARGET_80387"
15436   "* return output_387_binary_op (insn, operands);"
15437   [(set (attr "type") 
15438         (cond [(match_operand:XF 3 "mult_operator" "") 
15439                  (const_string "fmul")
15440                (match_operand:XF 3 "div_operator" "") 
15441                  (const_string "fdiv")
15442               ]
15443               (const_string "fop")))
15444    (set_attr "mode" "SF")])
15445
15446 (define_split
15447   [(set (match_operand 0 "register_operand" "")
15448         (match_operator 3 "binary_fp_operator"
15449            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15450             (match_operand 2 "register_operand" "")]))]
15451   "TARGET_80387 && reload_completed
15452    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15453   [(const_int 0)]
15454
15455   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15456   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15457   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15458                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15459                                           GET_MODE (operands[3]),
15460                                           operands[4],
15461                                           operands[2])));
15462   ix86_free_from_memory (GET_MODE (operands[1]));
15463   DONE;
15464 })
15465
15466 (define_split
15467   [(set (match_operand 0 "register_operand" "")
15468         (match_operator 3 "binary_fp_operator"
15469            [(match_operand 1 "register_operand" "")
15470             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15471   "TARGET_80387 && reload_completed
15472    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15473   [(const_int 0)]
15474 {
15475   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15476   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15477   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15478                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15479                                           GET_MODE (operands[3]),
15480                                           operands[1],
15481                                           operands[4])));
15482   ix86_free_from_memory (GET_MODE (operands[2]));
15483   DONE;
15484 })
15485 \f
15486 ;; FPU special functions.
15487
15488 (define_expand "sqrtsf2"
15489   [(set (match_operand:SF 0 "register_operand" "")
15490         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15491   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15492 {
15493   if (!TARGET_SSE_MATH)
15494     operands[1] = force_reg (SFmode, operands[1]);
15495 })
15496
15497 (define_insn "*sqrtsf2_mixed"
15498   [(set (match_operand:SF 0 "register_operand" "=f,x")
15499         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15500   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15501   "@
15502    fsqrt
15503    sqrtss\t{%1, %0|%0, %1}"
15504   [(set_attr "type" "fpspc,sse")
15505    (set_attr "mode" "SF,SF")
15506    (set_attr "athlon_decode" "direct,*")])
15507
15508 (define_insn "*sqrtsf2_sse"
15509   [(set (match_operand:SF 0 "register_operand" "=x")
15510         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15511   "TARGET_SSE_MATH"
15512   "sqrtss\t{%1, %0|%0, %1}"
15513   [(set_attr "type" "sse")
15514    (set_attr "mode" "SF")
15515    (set_attr "athlon_decode" "*")])
15516
15517 (define_insn "*sqrtsf2_i387"
15518   [(set (match_operand:SF 0 "register_operand" "=f")
15519         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15520   "TARGET_USE_FANCY_MATH_387"
15521   "fsqrt"
15522   [(set_attr "type" "fpspc")
15523    (set_attr "mode" "SF")
15524    (set_attr "athlon_decode" "direct")])
15525
15526 (define_expand "sqrtdf2"
15527   [(set (match_operand:DF 0 "register_operand" "")
15528         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15529   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15530 {
15531   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15532     operands[1] = force_reg (DFmode, operands[1]);
15533 })
15534
15535 (define_insn "*sqrtdf2_mixed"
15536   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15537         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15538   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15539   "@
15540    fsqrt
15541    sqrtsd\t{%1, %0|%0, %1}"
15542   [(set_attr "type" "fpspc,sse")
15543    (set_attr "mode" "DF,DF")
15544    (set_attr "athlon_decode" "direct,*")])
15545
15546 (define_insn "*sqrtdf2_sse"
15547   [(set (match_operand:DF 0 "register_operand" "=Y")
15548         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15549   "TARGET_SSE2 && TARGET_SSE_MATH"
15550   "sqrtsd\t{%1, %0|%0, %1}"
15551   [(set_attr "type" "sse")
15552    (set_attr "mode" "DF")
15553    (set_attr "athlon_decode" "*")])
15554
15555 (define_insn "*sqrtdf2_i387"
15556   [(set (match_operand:DF 0 "register_operand" "=f")
15557         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15558   "TARGET_USE_FANCY_MATH_387"
15559   "fsqrt"
15560   [(set_attr "type" "fpspc")
15561    (set_attr "mode" "DF")
15562    (set_attr "athlon_decode" "direct")])
15563
15564 (define_insn "*sqrtextendsfdf2_i387"
15565   [(set (match_operand:DF 0 "register_operand" "=f")
15566         (sqrt:DF (float_extend:DF
15567                   (match_operand:SF 1 "register_operand" "0"))))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15570   "fsqrt"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "DF")
15573    (set_attr "athlon_decode" "direct")])
15574
15575 (define_insn "sqrtxf2"
15576   [(set (match_operand:XF 0 "register_operand" "=f")
15577         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578   "TARGET_USE_FANCY_MATH_387"
15579   "fsqrt"
15580   [(set_attr "type" "fpspc")
15581    (set_attr "mode" "XF")
15582    (set_attr "athlon_decode" "direct")])
15583
15584 (define_insn "*sqrtextendsfxf2_i387"
15585   [(set (match_operand:XF 0 "register_operand" "=f")
15586         (sqrt:XF (float_extend:XF
15587                   (match_operand:SF 1 "register_operand" "0"))))]
15588   "TARGET_USE_FANCY_MATH_387"
15589   "fsqrt"
15590   [(set_attr "type" "fpspc")
15591    (set_attr "mode" "XF")
15592    (set_attr "athlon_decode" "direct")])
15593
15594 (define_insn "*sqrtextenddfxf2_i387"
15595   [(set (match_operand:XF 0 "register_operand" "=f")
15596         (sqrt:XF (float_extend:XF
15597                   (match_operand:DF 1 "register_operand" "0"))))]
15598   "TARGET_USE_FANCY_MATH_387"
15599   "fsqrt"
15600   [(set_attr "type" "fpspc")
15601    (set_attr "mode" "XF")
15602    (set_attr "athlon_decode" "direct")])
15603
15604 (define_insn "fpremxf4"
15605   [(set (match_operand:XF 0 "register_operand" "=f")
15606         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15607                     (match_operand:XF 3 "register_operand" "1")]
15608                    UNSPEC_FPREM_F))
15609    (set (match_operand:XF 1 "register_operand" "=u")
15610         (unspec:XF [(match_dup 2) (match_dup 3)]
15611                    UNSPEC_FPREM_U))
15612    (set (reg:CCFP FPSR_REG)
15613         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15614   "TARGET_USE_FANCY_MATH_387"
15615   "fprem"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "XF")])
15618
15619 (define_expand "fmodsf3"
15620   [(use (match_operand:SF 0 "register_operand" ""))
15621    (use (match_operand:SF 1 "register_operand" ""))
15622    (use (match_operand:SF 2 "register_operand" ""))]
15623   "TARGET_USE_FANCY_MATH_387
15624    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15625 {
15626   rtx label = gen_label_rtx ();
15627
15628   rtx op1 = gen_reg_rtx (XFmode);
15629   rtx op2 = gen_reg_rtx (XFmode);
15630
15631   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15632   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15633
15634   emit_label (label);
15635
15636   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15637   ix86_emit_fp_unordered_jump (label);
15638
15639   emit_insn (gen_truncxfsf2 (operands[0], op1));
15640   DONE;
15641 })
15642
15643 (define_expand "fmoddf3"
15644   [(use (match_operand:DF 0 "register_operand" ""))
15645    (use (match_operand:DF 1 "register_operand" ""))
15646    (use (match_operand:DF 2 "register_operand" ""))]
15647   "TARGET_USE_FANCY_MATH_387
15648    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15649 {
15650   rtx label = gen_label_rtx ();
15651
15652   rtx op1 = gen_reg_rtx (XFmode);
15653   rtx op2 = gen_reg_rtx (XFmode);
15654
15655   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15656   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15657
15658   emit_label (label);
15659
15660   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15661   ix86_emit_fp_unordered_jump (label);
15662
15663   emit_insn (gen_truncxfdf2 (operands[0], op1));
15664   DONE;
15665 })
15666
15667 (define_expand "fmodxf3"
15668   [(use (match_operand:XF 0 "register_operand" ""))
15669    (use (match_operand:XF 1 "register_operand" ""))
15670    (use (match_operand:XF 2 "register_operand" ""))]
15671   "TARGET_USE_FANCY_MATH_387"
15672 {
15673   rtx label = gen_label_rtx ();
15674
15675   emit_label (label);
15676
15677   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15678                            operands[1], operands[2]));
15679   ix86_emit_fp_unordered_jump (label);
15680
15681   emit_move_insn (operands[0], operands[1]);
15682   DONE;
15683 })
15684
15685 (define_insn "fprem1xf4"
15686   [(set (match_operand:XF 0 "register_operand" "=f")
15687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15688                     (match_operand:XF 3 "register_operand" "1")]
15689                    UNSPEC_FPREM1_F))
15690    (set (match_operand:XF 1 "register_operand" "=u")
15691         (unspec:XF [(match_dup 2) (match_dup 3)]
15692                    UNSPEC_FPREM1_U))
15693    (set (reg:CCFP FPSR_REG)
15694         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15695   "TARGET_USE_FANCY_MATH_387"
15696   "fprem1"
15697   [(set_attr "type" "fpspc")
15698    (set_attr "mode" "XF")])
15699
15700 (define_expand "remaindersf3"
15701   [(use (match_operand:SF 0 "register_operand" ""))
15702    (use (match_operand:SF 1 "register_operand" ""))
15703    (use (match_operand:SF 2 "register_operand" ""))]
15704   "TARGET_USE_FANCY_MATH_387
15705    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15706 {
15707   rtx label = gen_label_rtx ();
15708
15709   rtx op1 = gen_reg_rtx (XFmode);
15710   rtx op2 = gen_reg_rtx (XFmode);
15711
15712   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15713   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15714
15715   emit_label (label);
15716
15717   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15718   ix86_emit_fp_unordered_jump (label);
15719
15720   emit_insn (gen_truncxfsf2 (operands[0], op1));
15721   DONE;
15722 })
15723
15724 (define_expand "remainderdf3"
15725   [(use (match_operand:DF 0 "register_operand" ""))
15726    (use (match_operand:DF 1 "register_operand" ""))
15727    (use (match_operand:DF 2 "register_operand" ""))]
15728   "TARGET_USE_FANCY_MATH_387
15729    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15730 {
15731   rtx label = gen_label_rtx ();
15732
15733   rtx op1 = gen_reg_rtx (XFmode);
15734   rtx op2 = gen_reg_rtx (XFmode);
15735
15736   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15737   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15738
15739   emit_label (label);
15740
15741   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15742   ix86_emit_fp_unordered_jump (label);
15743
15744   emit_insn (gen_truncxfdf2 (operands[0], op1));
15745   DONE;
15746 })
15747
15748 (define_expand "remainderxf3"
15749   [(use (match_operand:XF 0 "register_operand" ""))
15750    (use (match_operand:XF 1 "register_operand" ""))
15751    (use (match_operand:XF 2 "register_operand" ""))]
15752   "TARGET_USE_FANCY_MATH_387"
15753 {
15754   rtx label = gen_label_rtx ();
15755
15756   emit_label (label);
15757
15758   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759                             operands[1], operands[2]));
15760   ix86_emit_fp_unordered_jump (label);
15761
15762   emit_move_insn (operands[0], operands[1]);
15763   DONE;
15764 })
15765
15766 (define_insn "*sindf2"
15767   [(set (match_operand:DF 0 "register_operand" "=f")
15768         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771    && flag_unsafe_math_optimizations"
15772   "fsin"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "DF")])
15775
15776 (define_insn "*sinsf2"
15777   [(set (match_operand:SF 0 "register_operand" "=f")
15778         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782   "fsin"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "SF")])
15785
15786 (define_insn "*sinextendsfdf2"
15787   [(set (match_operand:DF 0 "register_operand" "=f")
15788         (unspec:DF [(float_extend:DF
15789                      (match_operand:SF 1 "register_operand" "0"))]
15790                    UNSPEC_SIN))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15794   "fsin"
15795   [(set_attr "type" "fpspc")
15796    (set_attr "mode" "DF")])
15797
15798 (define_insn "*sinxf2"
15799   [(set (match_operand:XF 0 "register_operand" "=f")
15800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && flag_unsafe_math_optimizations"
15803   "fsin"
15804   [(set_attr "type" "fpspc")
15805    (set_attr "mode" "XF")])
15806
15807 (define_insn "*cosdf2"
15808   [(set (match_operand:DF 0 "register_operand" "=f")
15809         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813   "fcos"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "DF")])
15816
15817 (define_insn "*cossf2"
15818   [(set (match_operand:SF 0 "register_operand" "=f")
15819         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820   "TARGET_USE_FANCY_MATH_387
15821    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822    && flag_unsafe_math_optimizations"
15823   "fcos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "SF")])
15826
15827 (define_insn "*cosextendsfdf2"
15828   [(set (match_operand:DF 0 "register_operand" "=f")
15829         (unspec:DF [(float_extend:DF
15830                      (match_operand:SF 1 "register_operand" "0"))]
15831                    UNSPEC_COS))]
15832   "TARGET_USE_FANCY_MATH_387
15833    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15835   "fcos"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")])
15838
15839 (define_insn "*cosxf2"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15844   "fcos"
15845   [(set_attr "type" "fpspc")
15846    (set_attr "mode" "XF")])
15847
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused. 
15850 ;; Cse pass  will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15853
15854 (define_insn "sincosdf3"
15855   [(set (match_operand:DF 0 "register_operand" "=f")
15856         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857                    UNSPEC_SINCOS_COS))
15858    (set (match_operand:DF 1 "register_operand" "=u")
15859         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862    && flag_unsafe_math_optimizations"
15863   "fsincos"
15864   [(set_attr "type" "fpspc")
15865    (set_attr "mode" "DF")])
15866
15867 (define_split
15868   [(set (match_operand:DF 0 "register_operand" "")
15869         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870                    UNSPEC_SINCOS_COS))
15871    (set (match_operand:DF 1 "register_operand" "")
15872         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874    && !reload_completed && !reload_in_progress"
15875   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15876   "")
15877
15878 (define_split
15879   [(set (match_operand:DF 0 "register_operand" "")
15880         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881                    UNSPEC_SINCOS_COS))
15882    (set (match_operand:DF 1 "register_operand" "")
15883         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885    && !reload_completed && !reload_in_progress"
15886   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15887   "")
15888
15889 (define_insn "sincossf3"
15890   [(set (match_operand:SF 0 "register_operand" "=f")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:SF 1 "register_operand" "=u")
15894         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fsincos"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "SF")])
15901
15902 (define_split
15903   [(set (match_operand:SF 0 "register_operand" "")
15904         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905                    UNSPEC_SINCOS_COS))
15906    (set (match_operand:SF 1 "register_operand" "")
15907         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909    && !reload_completed && !reload_in_progress"
15910   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15911   "")
15912
15913 (define_split
15914   [(set (match_operand:SF 0 "register_operand" "")
15915         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916                    UNSPEC_SINCOS_COS))
15917    (set (match_operand:SF 1 "register_operand" "")
15918         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920    && !reload_completed && !reload_in_progress"
15921   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15922   "")
15923
15924 (define_insn "*sincosextendsfdf3"
15925   [(set (match_operand:DF 0 "register_operand" "=f")
15926         (unspec:DF [(float_extend:DF
15927                      (match_operand:SF 2 "register_operand" "0"))]
15928                    UNSPEC_SINCOS_COS))
15929    (set (match_operand:DF 1 "register_operand" "=u")
15930         (unspec:DF [(float_extend:DF
15931                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15935   "fsincos"
15936   [(set_attr "type" "fpspc")
15937    (set_attr "mode" "DF")])
15938
15939 (define_split
15940   [(set (match_operand:DF 0 "register_operand" "")
15941         (unspec:DF [(float_extend:DF
15942                      (match_operand:SF 2 "register_operand" ""))]
15943                    UNSPEC_SINCOS_COS))
15944    (set (match_operand:DF 1 "register_operand" "")
15945         (unspec:DF [(float_extend:DF
15946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948    && !reload_completed && !reload_in_progress"
15949   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950                                    (match_dup 2))] UNSPEC_SIN))]
15951   "")
15952
15953 (define_split
15954   [(set (match_operand:DF 0 "register_operand" "")
15955         (unspec:DF [(float_extend:DF
15956                      (match_operand:SF 2 "register_operand" ""))]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:DF 1 "register_operand" "")
15959         (unspec:DF [(float_extend:DF
15960                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962    && !reload_completed && !reload_in_progress"
15963   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964                                    (match_dup 2))] UNSPEC_COS))]
15965   "")
15966
15967 (define_insn "sincosxf3"
15968   [(set (match_operand:XF 0 "register_operand" "=f")
15969         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970                    UNSPEC_SINCOS_COS))
15971    (set (match_operand:XF 1 "register_operand" "=u")
15972         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973   "TARGET_USE_FANCY_MATH_387
15974    && flag_unsafe_math_optimizations"
15975   "fsincos"
15976   [(set_attr "type" "fpspc")
15977    (set_attr "mode" "XF")])
15978
15979 (define_split
15980   [(set (match_operand:XF 0 "register_operand" "")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982                    UNSPEC_SINCOS_COS))
15983    (set (match_operand:XF 1 "register_operand" "")
15984         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986    && !reload_completed && !reload_in_progress"
15987   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15988   "")
15989
15990 (define_split
15991   [(set (match_operand:XF 0 "register_operand" "")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993                    UNSPEC_SINCOS_COS))
15994    (set (match_operand:XF 1 "register_operand" "")
15995         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997    && !reload_completed && !reload_in_progress"
15998   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15999   "")
16000
16001 (define_insn "*tandf3_1"
16002   [(set (match_operand:DF 0 "register_operand" "=f")
16003         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004                    UNSPEC_TAN_ONE))
16005    (set (match_operand:DF 1 "register_operand" "=u")
16006         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007   "TARGET_USE_FANCY_MATH_387
16008    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009    && flag_unsafe_math_optimizations"
16010   "fptan"
16011   [(set_attr "type" "fpspc")
16012    (set_attr "mode" "DF")])
16013
16014 ;; optimize sequence: fptan
16015 ;;                    fstp    %st(0)
16016 ;;                    fld1
16017 ;; into fptan insn.
16018
16019 (define_peephole2
16020   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022                              UNSPEC_TAN_ONE))
16023              (set (match_operand:DF 1 "register_operand" "")
16024                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025    (set (match_dup 0)
16026         (match_operand:DF 3 "immediate_operand" ""))]
16027   "standard_80387_constant_p (operands[3]) == 2"
16028   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16030   "")
16031
16032 (define_expand "tandf2"
16033   [(parallel [(set (match_dup 2)
16034                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035                               UNSPEC_TAN_ONE))
16036               (set (match_operand:DF 0 "register_operand" "")
16037                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16041 {
16042   operands[2] = gen_reg_rtx (DFmode);
16043 })
16044
16045 (define_insn "*tansf3_1"
16046   [(set (match_operand:SF 0 "register_operand" "=f")
16047         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048                    UNSPEC_TAN_ONE))
16049    (set (match_operand:SF 1 "register_operand" "=u")
16050         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054   "fptan"
16055   [(set_attr "type" "fpspc")
16056    (set_attr "mode" "SF")])
16057
16058 ;; optimize sequence: fptan
16059 ;;                    fstp    %st(0)
16060 ;;                    fld1
16061 ;; into fptan insn.
16062
16063 (define_peephole2
16064   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066                              UNSPEC_TAN_ONE))
16067              (set (match_operand:SF 1 "register_operand" "")
16068                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069    (set (match_dup 0)
16070         (match_operand:SF 3 "immediate_operand" ""))]
16071   "standard_80387_constant_p (operands[3]) == 2"
16072   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16074   "")
16075
16076 (define_expand "tansf2"
16077   [(parallel [(set (match_dup 2)
16078                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079                               UNSPEC_TAN_ONE))
16080               (set (match_operand:SF 0 "register_operand" "")
16081                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082   "TARGET_USE_FANCY_MATH_387
16083    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084    && flag_unsafe_math_optimizations"
16085 {
16086   operands[2] = gen_reg_rtx (SFmode);
16087 })
16088
16089 (define_insn "*tanxf3_1"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092                    UNSPEC_TAN_ONE))
16093    (set (match_operand:XF 1 "register_operand" "=u")
16094         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16097   "fptan"
16098   [(set_attr "type" "fpspc")
16099    (set_attr "mode" "XF")])
16100
16101 ;; optimize sequence: fptan
16102 ;;                    fstp    %st(0)
16103 ;;                    fld1
16104 ;; into fptan insn.
16105
16106 (define_peephole2
16107   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109                              UNSPEC_TAN_ONE))
16110              (set (match_operand:XF 1 "register_operand" "")
16111                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112    (set (match_dup 0)
16113         (match_operand:XF 3 "immediate_operand" ""))]
16114   "standard_80387_constant_p (operands[3]) == 2"
16115   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16117   "")
16118
16119 (define_expand "tanxf2"
16120   [(parallel [(set (match_dup 2)
16121                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122                               UNSPEC_TAN_ONE))
16123               (set (match_operand:XF 0 "register_operand" "")
16124                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16127 {
16128   operands[2] = gen_reg_rtx (XFmode);
16129 })
16130
16131 (define_insn "atan2df3_1"
16132   [(set (match_operand:DF 0 "register_operand" "=f")
16133         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134                     (match_operand:DF 1 "register_operand" "u")]
16135                    UNSPEC_FPATAN))
16136    (clobber (match_scratch:DF 3 "=1"))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139    && flag_unsafe_math_optimizations"
16140   "fpatan"
16141   [(set_attr "type" "fpspc")
16142    (set_attr "mode" "DF")])
16143
16144 (define_expand "atan2df3"
16145   [(use (match_operand:DF 0 "register_operand" ""))
16146    (use (match_operand:DF 2 "register_operand" ""))
16147    (use (match_operand:DF 1 "register_operand" ""))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16151 {
16152   rtx copy = gen_reg_rtx (DFmode);
16153   emit_move_insn (copy, operands[1]);
16154   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16155   DONE;
16156 })
16157
16158 (define_expand "atandf2"
16159   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160                    (unspec:DF [(match_dup 2)
16161                                (match_operand:DF 1 "register_operand" "")]
16162                     UNSPEC_FPATAN))
16163               (clobber (match_scratch:DF 3 ""))])]
16164   "TARGET_USE_FANCY_MATH_387
16165    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166    && flag_unsafe_math_optimizations"
16167 {
16168   operands[2] = gen_reg_rtx (DFmode);
16169   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16170 })
16171
16172 (define_insn "atan2sf3_1"
16173   [(set (match_operand:SF 0 "register_operand" "=f")
16174         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175                     (match_operand:SF 1 "register_operand" "u")]
16176                    UNSPEC_FPATAN))
16177    (clobber (match_scratch:SF 3 "=1"))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16181   "fpatan"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "SF")])
16184
16185 (define_expand "atan2sf3"
16186   [(use (match_operand:SF 0 "register_operand" ""))
16187    (use (match_operand:SF 2 "register_operand" ""))
16188    (use (match_operand:SF 1 "register_operand" ""))]
16189   "TARGET_USE_FANCY_MATH_387
16190    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx copy = gen_reg_rtx (SFmode);
16194   emit_move_insn (copy, operands[1]);
16195   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16196   DONE;
16197 })
16198
16199 (define_expand "atansf2"
16200   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201                    (unspec:SF [(match_dup 2)
16202                                (match_operand:SF 1 "register_operand" "")]
16203                     UNSPEC_FPATAN))
16204               (clobber (match_scratch:SF 3 ""))])]
16205   "TARGET_USE_FANCY_MATH_387
16206    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207    && flag_unsafe_math_optimizations"
16208 {
16209   operands[2] = gen_reg_rtx (SFmode);
16210   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16211 })
16212
16213 (define_insn "atan2xf3_1"
16214   [(set (match_operand:XF 0 "register_operand" "=f")
16215         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216                     (match_operand:XF 1 "register_operand" "u")]
16217                    UNSPEC_FPATAN))
16218    (clobber (match_scratch:XF 3 "=1"))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221   "fpatan"
16222   [(set_attr "type" "fpspc")
16223    (set_attr "mode" "XF")])
16224
16225 (define_expand "atan2xf3"
16226   [(use (match_operand:XF 0 "register_operand" ""))
16227    (use (match_operand:XF 2 "register_operand" ""))
16228    (use (match_operand:XF 1 "register_operand" ""))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && flag_unsafe_math_optimizations"
16231 {
16232   rtx copy = gen_reg_rtx (XFmode);
16233   emit_move_insn (copy, operands[1]);
16234   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16235   DONE;
16236 })
16237
16238 (define_expand "atanxf2"
16239   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240                    (unspec:XF [(match_dup 2)
16241                                (match_operand:XF 1 "register_operand" "")]
16242                     UNSPEC_FPATAN))
16243               (clobber (match_scratch:XF 3 ""))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   operands[2] = gen_reg_rtx (XFmode);
16248   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16249 })
16250
16251 (define_expand "asindf2"
16252   [(set (match_dup 2)
16253         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257    (parallel [(set (match_dup 7)
16258                    (unspec:XF [(match_dup 6) (match_dup 2)]
16259                               UNSPEC_FPATAN))
16260               (clobber (match_scratch:XF 8 ""))])
16261    (set (match_operand:DF 0 "register_operand" "")
16262         (float_truncate:DF (match_dup 7)))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16266 {
16267   int i;
16268
16269   for (i=2; i<8; i++)
16270     operands[i] = gen_reg_rtx (XFmode);
16271
16272   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16273 })
16274
16275 (define_expand "asinsf2"
16276   [(set (match_dup 2)
16277         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281    (parallel [(set (match_dup 7)
16282                    (unspec:XF [(match_dup 6) (match_dup 2)]
16283                               UNSPEC_FPATAN))
16284               (clobber (match_scratch:XF 8 ""))])
16285    (set (match_operand:SF 0 "register_operand" "")
16286         (float_truncate:SF (match_dup 7)))]
16287   "TARGET_USE_FANCY_MATH_387
16288    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289    && flag_unsafe_math_optimizations"
16290 {
16291   int i;
16292
16293   for (i=2; i<8; i++)
16294     operands[i] = gen_reg_rtx (XFmode);
16295
16296   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16297 })
16298
16299 (define_expand "asinxf2"
16300   [(set (match_dup 2)
16301         (mult:XF (match_operand:XF 1 "register_operand" "")
16302                  (match_dup 1)))
16303    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305    (parallel [(set (match_operand:XF 0 "register_operand" "")
16306                    (unspec:XF [(match_dup 5) (match_dup 1)]
16307                               UNSPEC_FPATAN))
16308               (clobber (match_scratch:XF 6 ""))])]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16311 {
16312   int i;
16313
16314   for (i=2; i<6; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16316
16317   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16318 })
16319
16320 (define_expand "acosdf2"
16321   [(set (match_dup 2)
16322         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326    (parallel [(set (match_dup 7)
16327                    (unspec:XF [(match_dup 2) (match_dup 6)]
16328                               UNSPEC_FPATAN))
16329               (clobber (match_scratch:XF 8 ""))])
16330    (set (match_operand:DF 0 "register_operand" "")
16331         (float_truncate:DF (match_dup 7)))]
16332   "TARGET_USE_FANCY_MATH_387
16333    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334    && flag_unsafe_math_optimizations"
16335 {
16336   int i;
16337
16338   for (i=2; i<8; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16340
16341   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16342 })
16343
16344 (define_expand "acossf2"
16345   [(set (match_dup 2)
16346         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350    (parallel [(set (match_dup 7)
16351                    (unspec:XF [(match_dup 2) (match_dup 6)]
16352                               UNSPEC_FPATAN))
16353               (clobber (match_scratch:XF 8 ""))])
16354    (set (match_operand:SF 0 "register_operand" "")
16355         (float_truncate:SF (match_dup 7)))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358    && flag_unsafe_math_optimizations"
16359 {
16360   int i;
16361
16362   for (i=2; i<8; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16364
16365   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16366 })
16367
16368 (define_expand "acosxf2"
16369   [(set (match_dup 2)
16370         (mult:XF (match_operand:XF 1 "register_operand" "")
16371                  (match_dup 1)))
16372    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374    (parallel [(set (match_operand:XF 0 "register_operand" "")
16375                    (unspec:XF [(match_dup 1) (match_dup 5)]
16376                               UNSPEC_FPATAN))
16377               (clobber (match_scratch:XF 6 ""))])]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16380 {
16381   int i;
16382
16383   for (i=2; i<6; i++)
16384     operands[i] = gen_reg_rtx (XFmode);
16385
16386   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16387 })
16388
16389 (define_insn "fyl2x_xf3"
16390   [(set (match_operand:XF 0 "register_operand" "=f")
16391         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392                     (match_operand:XF 1 "register_operand" "u")]
16393                    UNSPEC_FYL2X))
16394    (clobber (match_scratch:XF 3 "=1"))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && flag_unsafe_math_optimizations"
16397   "fyl2x"
16398   [(set_attr "type" "fpspc")
16399    (set_attr "mode" "XF")])
16400
16401 (define_expand "logsf2"
16402   [(set (match_dup 2)
16403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404    (parallel [(set (match_dup 4)
16405                    (unspec:XF [(match_dup 2)
16406                                (match_dup 3)] UNSPEC_FYL2X))
16407               (clobber (match_scratch:XF 5 ""))])
16408    (set (match_operand:SF 0 "register_operand" "")
16409         (float_truncate:SF (match_dup 4)))]
16410   "TARGET_USE_FANCY_MATH_387
16411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412    && flag_unsafe_math_optimizations"
16413 {
16414   rtx temp;
16415
16416   operands[2] = gen_reg_rtx (XFmode);
16417   operands[3] = gen_reg_rtx (XFmode);
16418   operands[4] = gen_reg_rtx (XFmode);
16419
16420   temp = standard_80387_constant_rtx (4); /* fldln2 */
16421   emit_move_insn (operands[3], temp);
16422 })
16423
16424 (define_expand "logdf2"
16425   [(set (match_dup 2)
16426         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427    (parallel [(set (match_dup 4)
16428                    (unspec:XF [(match_dup 2)
16429                                (match_dup 3)] UNSPEC_FYL2X))
16430               (clobber (match_scratch:XF 5 ""))])
16431    (set (match_operand:DF 0 "register_operand" "")
16432         (float_truncate:DF (match_dup 4)))]
16433   "TARGET_USE_FANCY_MATH_387
16434    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations"
16436 {
16437   rtx temp;
16438
16439   operands[2] = gen_reg_rtx (XFmode);
16440   operands[3] = gen_reg_rtx (XFmode);
16441   operands[4] = gen_reg_rtx (XFmode);
16442
16443   temp = standard_80387_constant_rtx (4); /* fldln2 */
16444   emit_move_insn (operands[3], temp);
16445 })
16446
16447 (define_expand "logxf2"
16448   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450                                (match_dup 2)] UNSPEC_FYL2X))
16451               (clobber (match_scratch:XF 3 ""))])]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16454 {
16455   rtx temp;
16456
16457   operands[2] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (4); /* fldln2 */
16459   emit_move_insn (operands[2], temp);
16460 })
16461
16462 (define_expand "log10sf2"
16463   [(set (match_dup 2)
16464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465    (parallel [(set (match_dup 4)
16466                    (unspec:XF [(match_dup 2)
16467                                (match_dup 3)] UNSPEC_FYL2X))
16468               (clobber (match_scratch:XF 5 ""))])
16469    (set (match_operand:SF 0 "register_operand" "")
16470         (float_truncate:SF (match_dup 4)))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473    && flag_unsafe_math_optimizations"
16474 {
16475   rtx temp;
16476
16477   operands[2] = gen_reg_rtx (XFmode);
16478   operands[3] = gen_reg_rtx (XFmode);
16479   operands[4] = gen_reg_rtx (XFmode);
16480
16481   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482   emit_move_insn (operands[3], temp);
16483 })
16484
16485 (define_expand "log10df2"
16486   [(set (match_dup 2)
16487         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488    (parallel [(set (match_dup 4)
16489                    (unspec:XF [(match_dup 2)
16490                                (match_dup 3)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 5 ""))])
16492    (set (match_operand:DF 0 "register_operand" "")
16493         (float_truncate:DF (match_dup 4)))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496    && flag_unsafe_math_optimizations"
16497 {
16498   rtx temp;
16499
16500   operands[2] = gen_reg_rtx (XFmode);
16501   operands[3] = gen_reg_rtx (XFmode);
16502   operands[4] = gen_reg_rtx (XFmode);
16503
16504   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505   emit_move_insn (operands[3], temp);
16506 })
16507
16508 (define_expand "log10xf2"
16509   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511                                (match_dup 2)] UNSPEC_FYL2X))
16512               (clobber (match_scratch:XF 3 ""))])]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16515 {
16516   rtx temp;
16517
16518   operands[2] = gen_reg_rtx (XFmode);
16519   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520   emit_move_insn (operands[2], temp);
16521 })
16522
16523 (define_expand "log2sf2"
16524   [(set (match_dup 2)
16525         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526    (parallel [(set (match_dup 4)
16527                    (unspec:XF [(match_dup 2)
16528                                (match_dup 3)] UNSPEC_FYL2X))
16529               (clobber (match_scratch:XF 5 ""))])
16530    (set (match_operand:SF 0 "register_operand" "")
16531         (float_truncate:SF (match_dup 4)))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534    && flag_unsafe_math_optimizations"
16535 {
16536   operands[2] = gen_reg_rtx (XFmode);
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16539
16540   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16541 })
16542
16543 (define_expand "log2df2"
16544   [(set (match_dup 2)
16545         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546    (parallel [(set (match_dup 4)
16547                    (unspec:XF [(match_dup 2)
16548                                (match_dup 3)] UNSPEC_FYL2X))
16549               (clobber (match_scratch:XF 5 ""))])
16550    (set (match_operand:DF 0 "register_operand" "")
16551         (float_truncate:DF (match_dup 4)))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations"
16555 {
16556   operands[2] = gen_reg_rtx (XFmode);
16557   operands[3] = gen_reg_rtx (XFmode);
16558   operands[4] = gen_reg_rtx (XFmode);
16559
16560   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16561 })
16562
16563 (define_expand "log2xf2"
16564   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566                                (match_dup 2)] UNSPEC_FYL2X))
16567               (clobber (match_scratch:XF 3 ""))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570 {
16571   operands[2] = gen_reg_rtx (XFmode);
16572   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16573 })
16574
16575 (define_insn "fyl2xp1_xf3"
16576   [(set (match_operand:XF 0 "register_operand" "=f")
16577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578                     (match_operand:XF 1 "register_operand" "u")]
16579                    UNSPEC_FYL2XP1))
16580    (clobber (match_scratch:XF 3 "=1"))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && flag_unsafe_math_optimizations"
16583   "fyl2xp1"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16586
16587 (define_expand "log1psf2"
16588   [(use (match_operand:SF 0 "register_operand" ""))
16589    (use (match_operand:SF 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592    && flag_unsafe_math_optimizations"
16593 {
16594   rtx op0 = gen_reg_rtx (XFmode);
16595   rtx op1 = gen_reg_rtx (XFmode);
16596
16597   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598   ix86_emit_i387_log1p (op0, op1);
16599   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16600   DONE;
16601 })
16602
16603 (define_expand "log1pdf2"
16604   [(use (match_operand:DF 0 "register_operand" ""))
16605    (use (match_operand:DF 1 "register_operand" ""))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608    && flag_unsafe_math_optimizations"
16609 {
16610   rtx op0 = gen_reg_rtx (XFmode);
16611   rtx op1 = gen_reg_rtx (XFmode);
16612
16613   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614   ix86_emit_i387_log1p (op0, op1);
16615   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16616   DONE;
16617 })
16618
16619 (define_expand "log1pxf2"
16620   [(use (match_operand:XF 0 "register_operand" ""))
16621    (use (match_operand:XF 1 "register_operand" ""))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624 {
16625   ix86_emit_i387_log1p (operands[0], operands[1]);
16626   DONE;
16627 })
16628
16629 (define_insn "*fxtractxf3"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632                    UNSPEC_XTRACT_FRACT))
16633    (set (match_operand:XF 1 "register_operand" "=u")
16634         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations"
16637   "fxtract"
16638   [(set_attr "type" "fpspc")
16639    (set_attr "mode" "XF")])
16640
16641 (define_expand "logbsf2"
16642   [(set (match_dup 2)
16643         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644    (parallel [(set (match_dup 3)
16645                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646               (set (match_dup 4)
16647                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648    (set (match_operand:SF 0 "register_operand" "")
16649         (float_truncate:SF (match_dup 4)))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652    && flag_unsafe_math_optimizations"
16653 {
16654   operands[2] = gen_reg_rtx (XFmode);
16655   operands[3] = gen_reg_rtx (XFmode);
16656   operands[4] = gen_reg_rtx (XFmode);
16657 })
16658
16659 (define_expand "logbdf2"
16660   [(set (match_dup 2)
16661         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662    (parallel [(set (match_dup 3)
16663                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664               (set (match_dup 4)
16665                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666    (set (match_operand:DF 0 "register_operand" "")
16667         (float_truncate:DF (match_dup 4)))]
16668   "TARGET_USE_FANCY_MATH_387
16669    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations"
16671 {
16672   operands[2] = gen_reg_rtx (XFmode);
16673   operands[3] = gen_reg_rtx (XFmode);
16674   operands[4] = gen_reg_rtx (XFmode);
16675 })
16676
16677 (define_expand "logbxf2"
16678   [(parallel [(set (match_dup 2)
16679                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680                               UNSPEC_XTRACT_FRACT))
16681               (set (match_operand:XF 0 "register_operand" "")
16682                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16685 {
16686   operands[2] = gen_reg_rtx (XFmode);
16687 })
16688
16689 (define_expand "ilogbsi2"
16690   [(parallel [(set (match_dup 2)
16691                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692                               UNSPEC_XTRACT_FRACT))
16693               (set (match_operand:XF 3 "register_operand" "")
16694                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695    (parallel [(set (match_operand:SI 0 "register_operand" "")
16696                    (fix:SI (match_dup 3)))
16697               (clobber (reg:CC FLAGS_REG))])]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16701 {
16702   operands[2] = gen_reg_rtx (XFmode);
16703   operands[3] = gen_reg_rtx (XFmode);
16704 })
16705
16706 (define_insn "*f2xm1xf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709          UNSPEC_F2XM1))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations"
16712   "f2xm1"
16713   [(set_attr "type" "fpspc")
16714    (set_attr "mode" "XF")])
16715
16716 (define_insn "*fscalexf4"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719                     (match_operand:XF 3 "register_operand" "1")]
16720                    UNSPEC_FSCALE_FRACT))
16721    (set (match_operand:XF 1 "register_operand" "=u")
16722         (unspec:XF [(match_dup 2) (match_dup 3)]
16723                    UNSPEC_FSCALE_EXP))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && flag_unsafe_math_optimizations"
16726   "fscale"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")])
16729
16730 (define_expand "expsf2"
16731   [(set (match_dup 2)
16732         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738    (parallel [(set (match_dup 10)
16739                    (unspec:XF [(match_dup 9) (match_dup 5)]
16740                               UNSPEC_FSCALE_FRACT))
16741               (set (match_dup 11)
16742                    (unspec:XF [(match_dup 9) (match_dup 5)]
16743                               UNSPEC_FSCALE_EXP))])
16744    (set (match_operand:SF 0 "register_operand" "")
16745         (float_truncate:SF (match_dup 10)))]
16746   "TARGET_USE_FANCY_MATH_387
16747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748    && flag_unsafe_math_optimizations"
16749 {
16750   rtx temp;
16751   int i;
16752
16753   for (i=2; i<12; i++)
16754     operands[i] = gen_reg_rtx (XFmode);
16755   temp = standard_80387_constant_rtx (5); /* fldl2e */
16756   emit_move_insn (operands[3], temp);
16757   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16758 })
16759
16760 (define_expand "expdf2"
16761   [(set (match_dup 2)
16762         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768    (parallel [(set (match_dup 10)
16769                    (unspec:XF [(match_dup 9) (match_dup 5)]
16770                               UNSPEC_FSCALE_FRACT))
16771               (set (match_dup 11)
16772                    (unspec:XF [(match_dup 9) (match_dup 5)]
16773                               UNSPEC_FSCALE_EXP))])
16774    (set (match_operand:DF 0 "register_operand" "")
16775         (float_truncate:DF (match_dup 10)))]
16776   "TARGET_USE_FANCY_MATH_387
16777    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations"
16779 {
16780   rtx temp;
16781   int i;
16782
16783   for (i=2; i<12; i++)
16784     operands[i] = gen_reg_rtx (XFmode);
16785   temp = standard_80387_constant_rtx (5); /* fldl2e */
16786   emit_move_insn (operands[3], temp);
16787   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16788 })
16789
16790 (define_expand "expxf2"
16791   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792                                (match_dup 2)))
16793    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797    (parallel [(set (match_operand:XF 0 "register_operand" "")
16798                    (unspec:XF [(match_dup 8) (match_dup 4)]
16799                               UNSPEC_FSCALE_FRACT))
16800               (set (match_dup 9)
16801                    (unspec:XF [(match_dup 8) (match_dup 4)]
16802                               UNSPEC_FSCALE_EXP))])]
16803   "TARGET_USE_FANCY_MATH_387
16804    && flag_unsafe_math_optimizations"
16805 {
16806   rtx temp;
16807   int i;
16808
16809   for (i=2; i<10; i++)
16810     operands[i] = gen_reg_rtx (XFmode);
16811   temp = standard_80387_constant_rtx (5); /* fldl2e */
16812   emit_move_insn (operands[2], temp);
16813   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16814 })
16815
16816 (define_expand "exp10sf2"
16817   [(set (match_dup 2)
16818         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824    (parallel [(set (match_dup 10)
16825                    (unspec:XF [(match_dup 9) (match_dup 5)]
16826                               UNSPEC_FSCALE_FRACT))
16827               (set (match_dup 11)
16828                    (unspec:XF [(match_dup 9) (match_dup 5)]
16829                               UNSPEC_FSCALE_EXP))])
16830    (set (match_operand:SF 0 "register_operand" "")
16831         (float_truncate:SF (match_dup 10)))]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16835 {
16836   rtx temp;
16837   int i;
16838
16839   for (i=2; i<12; i++)
16840     operands[i] = gen_reg_rtx (XFmode);
16841   temp = standard_80387_constant_rtx (6); /* fldl2t */
16842   emit_move_insn (operands[3], temp);
16843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16844 })
16845
16846 (define_expand "exp10df2"
16847   [(set (match_dup 2)
16848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854    (parallel [(set (match_dup 10)
16855                    (unspec:XF [(match_dup 9) (match_dup 5)]
16856                               UNSPEC_FSCALE_FRACT))
16857               (set (match_dup 11)
16858                    (unspec:XF [(match_dup 9) (match_dup 5)]
16859                               UNSPEC_FSCALE_EXP))])
16860    (set (match_operand:DF 0 "register_operand" "")
16861         (float_truncate:DF (match_dup 10)))]
16862   "TARGET_USE_FANCY_MATH_387
16863    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864    && flag_unsafe_math_optimizations"
16865 {
16866   rtx temp;
16867   int i;
16868
16869   for (i=2; i<12; i++)
16870     operands[i] = gen_reg_rtx (XFmode);
16871   temp = standard_80387_constant_rtx (6); /* fldl2t */
16872   emit_move_insn (operands[3], temp);
16873   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16874 })
16875
16876 (define_expand "exp10xf2"
16877   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878                                (match_dup 2)))
16879    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883    (parallel [(set (match_operand:XF 0 "register_operand" "")
16884                    (unspec:XF [(match_dup 8) (match_dup 4)]
16885                               UNSPEC_FSCALE_FRACT))
16886               (set (match_dup 9)
16887                    (unspec:XF [(match_dup 8) (match_dup 4)]
16888                               UNSPEC_FSCALE_EXP))])]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16891 {
16892   rtx temp;
16893   int i;
16894
16895   for (i=2; i<10; i++)
16896     operands[i] = gen_reg_rtx (XFmode);
16897   temp = standard_80387_constant_rtx (6); /* fldl2t */
16898   emit_move_insn (operands[2], temp);
16899   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16900 })
16901
16902 (define_expand "exp2sf2"
16903   [(set (match_dup 2)
16904         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909    (parallel [(set (match_dup 8)
16910                    (unspec:XF [(match_dup 7) (match_dup 3)]
16911                               UNSPEC_FSCALE_FRACT))
16912               (set (match_dup 9)
16913                    (unspec:XF [(match_dup 7) (match_dup 3)]
16914                               UNSPEC_FSCALE_EXP))])
16915    (set (match_operand:SF 0 "register_operand" "")
16916         (float_truncate:SF (match_dup 8)))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations"
16920 {
16921   int i;
16922
16923   for (i=2; i<10; i++)
16924     operands[i] = gen_reg_rtx (XFmode);
16925   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16926 })
16927
16928 (define_expand "exp2df2"
16929   [(set (match_dup 2)
16930         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935    (parallel [(set (match_dup 8)
16936                    (unspec:XF [(match_dup 7) (match_dup 3)]
16937                               UNSPEC_FSCALE_FRACT))
16938               (set (match_dup 9)
16939                    (unspec:XF [(match_dup 7) (match_dup 3)]
16940                               UNSPEC_FSCALE_EXP))])
16941    (set (match_operand:DF 0 "register_operand" "")
16942         (float_truncate:DF (match_dup 8)))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16946 {
16947   int i;
16948
16949   for (i=2; i<10; i++)
16950     operands[i] = gen_reg_rtx (XFmode);
16951   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16952 })
16953
16954 (define_expand "exp2xf2"
16955   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960    (parallel [(set (match_operand:XF 0 "register_operand" "")
16961                    (unspec:XF [(match_dup 7) (match_dup 3)]
16962                               UNSPEC_FSCALE_FRACT))
16963               (set (match_dup 8)
16964                    (unspec:XF [(match_dup 7) (match_dup 3)]
16965                               UNSPEC_FSCALE_EXP))])]
16966   "TARGET_USE_FANCY_MATH_387
16967    && flag_unsafe_math_optimizations"
16968 {
16969   int i;
16970
16971   for (i=2; i<9; i++)
16972     operands[i] = gen_reg_rtx (XFmode);
16973   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16974 })
16975
16976 (define_expand "expm1df2"
16977   [(set (match_dup 2)
16978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983    (parallel [(set (match_dup 8)
16984                    (unspec:XF [(match_dup 7) (match_dup 5)]
16985                               UNSPEC_FSCALE_FRACT))
16986                    (set (match_dup 9)
16987                    (unspec:XF [(match_dup 7) (match_dup 5)]
16988                               UNSPEC_FSCALE_EXP))])
16989    (parallel [(set (match_dup 11)
16990                    (unspec:XF [(match_dup 10) (match_dup 9)]
16991                               UNSPEC_FSCALE_FRACT))
16992               (set (match_dup 12)
16993                    (unspec:XF [(match_dup 10) (match_dup 9)]
16994                               UNSPEC_FSCALE_EXP))])
16995    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997    (set (match_operand:DF 0 "register_operand" "")
16998         (float_truncate:DF (match_dup 14)))]
16999   "TARGET_USE_FANCY_MATH_387
17000    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17002 {
17003   rtx temp;
17004   int i;
17005
17006   for (i=2; i<15; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008   temp = standard_80387_constant_rtx (5); /* fldl2e */
17009   emit_move_insn (operands[3], temp);
17010   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17011 })
17012
17013 (define_expand "expm1sf2"
17014   [(set (match_dup 2)
17015         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020    (parallel [(set (match_dup 8)
17021                    (unspec:XF [(match_dup 7) (match_dup 5)]
17022                               UNSPEC_FSCALE_FRACT))
17023                    (set (match_dup 9)
17024                    (unspec:XF [(match_dup 7) (match_dup 5)]
17025                               UNSPEC_FSCALE_EXP))])
17026    (parallel [(set (match_dup 11)
17027                    (unspec:XF [(match_dup 10) (match_dup 9)]
17028                               UNSPEC_FSCALE_FRACT))
17029               (set (match_dup 12)
17030                    (unspec:XF [(match_dup 10) (match_dup 9)]
17031                               UNSPEC_FSCALE_EXP))])
17032    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034    (set (match_operand:SF 0 "register_operand" "")
17035         (float_truncate:SF (match_dup 14)))]
17036   "TARGET_USE_FANCY_MATH_387
17037    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038    && flag_unsafe_math_optimizations"
17039 {
17040   rtx temp;
17041   int i;
17042
17043   for (i=2; i<15; i++)
17044     operands[i] = gen_reg_rtx (XFmode);
17045   temp = standard_80387_constant_rtx (5); /* fldl2e */
17046   emit_move_insn (operands[3], temp);
17047   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17048 })
17049
17050 (define_expand "expm1xf2"
17051   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052                                (match_dup 2)))
17053    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056    (parallel [(set (match_dup 7)
17057                    (unspec:XF [(match_dup 6) (match_dup 4)]
17058                               UNSPEC_FSCALE_FRACT))
17059                    (set (match_dup 8)
17060                    (unspec:XF [(match_dup 6) (match_dup 4)]
17061                               UNSPEC_FSCALE_EXP))])
17062    (parallel [(set (match_dup 10)
17063                    (unspec:XF [(match_dup 9) (match_dup 8)]
17064                               UNSPEC_FSCALE_FRACT))
17065               (set (match_dup 11)
17066                    (unspec:XF [(match_dup 9) (match_dup 8)]
17067                               UNSPEC_FSCALE_EXP))])
17068    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069    (set (match_operand:XF 0 "register_operand" "")
17070         (plus:XF (match_dup 12) (match_dup 7)))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073 {
17074   rtx temp;
17075   int i;
17076
17077   for (i=2; i<13; i++)
17078     operands[i] = gen_reg_rtx (XFmode);
17079   temp = standard_80387_constant_rtx (5); /* fldl2e */
17080   emit_move_insn (operands[2], temp);
17081   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17082 })
17083
17084 (define_expand "ldexpdf3"
17085   [(set (match_dup 3)
17086         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087    (set (match_dup 4)
17088         (float:XF (match_operand:SI 2 "register_operand" "")))
17089    (parallel [(set (match_dup 5)
17090                    (unspec:XF [(match_dup 3) (match_dup 4)]
17091                               UNSPEC_FSCALE_FRACT))
17092               (set (match_dup 6)
17093                    (unspec:XF [(match_dup 3) (match_dup 4)]
17094                               UNSPEC_FSCALE_EXP))])
17095    (set (match_operand:DF 0 "register_operand" "")
17096         (float_truncate:DF (match_dup 5)))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17100 {
17101   int i;
17102
17103   for (i=3; i<7; i++)
17104     operands[i] = gen_reg_rtx (XFmode);
17105 })
17106
17107 (define_expand "ldexpsf3"
17108   [(set (match_dup 3)
17109         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110    (set (match_dup 4)
17111         (float:XF (match_operand:SI 2 "register_operand" "")))
17112    (parallel [(set (match_dup 5)
17113                    (unspec:XF [(match_dup 3) (match_dup 4)]
17114                               UNSPEC_FSCALE_FRACT))
17115               (set (match_dup 6)
17116                    (unspec:XF [(match_dup 3) (match_dup 4)]
17117                               UNSPEC_FSCALE_EXP))])
17118    (set (match_operand:SF 0 "register_operand" "")
17119         (float_truncate:SF (match_dup 5)))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122    && flag_unsafe_math_optimizations"
17123 {
17124   int i;
17125
17126   for (i=3; i<7; i++)
17127     operands[i] = gen_reg_rtx (XFmode);
17128 })
17129
17130 (define_expand "ldexpxf3"
17131   [(set (match_dup 3)
17132         (float:XF (match_operand:SI 2 "register_operand" "")))
17133    (parallel [(set (match_operand:XF 0 " register_operand" "")
17134                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135                                (match_dup 3)]
17136                               UNSPEC_FSCALE_FRACT))
17137               (set (match_dup 4)
17138                    (unspec:XF [(match_dup 1) (match_dup 3)]
17139                               UNSPEC_FSCALE_EXP))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && flag_unsafe_math_optimizations"
17142 {
17143   int i;
17144
17145   for (i=3; i<5; i++)
17146     operands[i] = gen_reg_rtx (XFmode);
17147 })
17148 \f
17149
17150 (define_insn "frndintxf2"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153          UNSPEC_FRNDINT))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "frndint"
17157   [(set_attr "type" "fpspc")
17158    (set_attr "mode" "XF")])
17159
17160 (define_expand "rintdf2"
17161   [(use (match_operand:DF 0 "register_operand" ""))
17162    (use (match_operand:DF 1 "register_operand" ""))]
17163   "(TARGET_USE_FANCY_MATH_387
17164     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165     && flag_unsafe_math_optimizations)
17166    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17167        && !flag_trapping_math)"
17168 {
17169   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17170       && !flag_trapping_math)
17171     ix86_expand_rint (operand0, operand1);
17172   else
17173     {
17174   rtx op0 = gen_reg_rtx (XFmode);
17175   rtx op1 = gen_reg_rtx (XFmode);
17176
17177   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17178   emit_insn (gen_frndintxf2 (op0, op1));
17179
17180   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17181     }
17182   DONE;
17183 })
17184
17185 (define_expand "rintsf2"
17186   [(use (match_operand:SF 0 "register_operand" ""))
17187    (use (match_operand:SF 1 "register_operand" ""))]
17188   "(TARGET_USE_FANCY_MATH_387
17189     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17190     && flag_unsafe_math_optimizations)
17191    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17192        && !flag_trapping_math)"
17193 {
17194   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17195       && !flag_trapping_math)
17196     ix86_expand_rint (operand0, operand1);
17197   else
17198     {
17199   rtx op0 = gen_reg_rtx (XFmode);
17200   rtx op1 = gen_reg_rtx (XFmode);
17201
17202   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17203   emit_insn (gen_frndintxf2 (op0, op1));
17204
17205   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17206     }
17207   DONE;
17208 })
17209
17210 (define_expand "rintxf2"
17211   [(use (match_operand:XF 0 "register_operand" ""))
17212    (use (match_operand:XF 1 "register_operand" ""))]
17213   "TARGET_USE_FANCY_MATH_387
17214    && flag_unsafe_math_optimizations"
17215 {
17216   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17217   DONE;
17218 })
17219
17220 (define_expand "roundsf2"
17221   [(match_operand:SF 0 "register_operand" "")
17222    (match_operand:SF 1 "nonimmediate_operand" "")]
17223   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17224    && !flag_trapping_math && !flag_rounding_math
17225    && !optimize_size"
17226 {
17227   ix86_expand_round (operand0, operand1);
17228   DONE;
17229 })
17230
17231 (define_expand "rounddf2"
17232   [(match_operand:DF 0 "register_operand" "")
17233    (match_operand:DF 1 "nonimmediate_operand" "")]
17234   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17235    && !flag_trapping_math && !flag_rounding_math
17236    && !optimize_size"
17237 {
17238   if (TARGET_64BIT)
17239     ix86_expand_round (operand0, operand1);
17240   else
17241     ix86_expand_rounddf_32 (operand0, operand1);
17242   DONE;
17243 })
17244
17245 (define_insn_and_split "*fistdi2_1"
17246   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17247         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17248          UNSPEC_FIST))]
17249   "TARGET_USE_FANCY_MATH_387
17250    && !(reload_completed || reload_in_progress)"
17251   "#"
17252   "&& 1"
17253   [(const_int 0)]
17254 {
17255   if (memory_operand (operands[0], VOIDmode))
17256     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17257   else
17258     {
17259       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17260       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17261                                          operands[2]));
17262     }
17263   DONE;
17264 }
17265   [(set_attr "type" "fpspc")
17266    (set_attr "mode" "DI")])
17267
17268 (define_insn "fistdi2"
17269   [(set (match_operand:DI 0 "memory_operand" "=m")
17270         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17271          UNSPEC_FIST))
17272    (clobber (match_scratch:XF 2 "=&1f"))]
17273   "TARGET_USE_FANCY_MATH_387"
17274   "* return output_fix_trunc (insn, operands, 0);"
17275   [(set_attr "type" "fpspc")
17276    (set_attr "mode" "DI")])
17277
17278 (define_insn "fistdi2_with_temp"
17279   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17280         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17281          UNSPEC_FIST))
17282    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17283    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17284   "TARGET_USE_FANCY_MATH_387"
17285   "#"
17286   [(set_attr "type" "fpspc")
17287    (set_attr "mode" "DI")])
17288
17289 (define_split 
17290   [(set (match_operand:DI 0 "register_operand" "")
17291         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17292          UNSPEC_FIST))
17293    (clobber (match_operand:DI 2 "memory_operand" ""))
17294    (clobber (match_scratch 3 ""))]
17295   "reload_completed"
17296   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17297               (clobber (match_dup 3))])
17298    (set (match_dup 0) (match_dup 2))]
17299   "")
17300
17301 (define_split 
17302   [(set (match_operand:DI 0 "memory_operand" "")
17303         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17304          UNSPEC_FIST))
17305    (clobber (match_operand:DI 2 "memory_operand" ""))
17306    (clobber (match_scratch 3 ""))]
17307   "reload_completed"
17308   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17309               (clobber (match_dup 3))])]
17310   "")
17311
17312 (define_insn_and_split "*fist<mode>2_1"
17313   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17314         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17315          UNSPEC_FIST))]
17316   "TARGET_USE_FANCY_MATH_387
17317    && !(reload_completed || reload_in_progress)"
17318   "#"
17319   "&& 1"
17320   [(const_int 0)]
17321 {
17322   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17323   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17324                                         operands[2]));
17325   DONE;
17326 }
17327   [(set_attr "type" "fpspc")
17328    (set_attr "mode" "<MODE>")])
17329
17330 (define_insn "fist<mode>2"
17331   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17332         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17333          UNSPEC_FIST))]
17334   "TARGET_USE_FANCY_MATH_387"
17335   "* return output_fix_trunc (insn, operands, 0);"
17336   [(set_attr "type" "fpspc")
17337    (set_attr "mode" "<MODE>")])
17338
17339 (define_insn "fist<mode>2_with_temp"
17340   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17341         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17342          UNSPEC_FIST))
17343    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17344   "TARGET_USE_FANCY_MATH_387"
17345   "#"
17346   [(set_attr "type" "fpspc")
17347    (set_attr "mode" "<MODE>")])
17348
17349 (define_split 
17350   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17351         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17352          UNSPEC_FIST))
17353    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17354   "reload_completed"
17355   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17356                        UNSPEC_FIST))
17357    (set (match_dup 0) (match_dup 2))]
17358   "")
17359
17360 (define_split 
17361   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17362         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17363          UNSPEC_FIST))
17364    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17365   "reload_completed"
17366   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17367                        UNSPEC_FIST))]
17368   "")
17369
17370 (define_expand "lrintxf<mode>2"
17371   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17372      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17373       UNSPEC_FIST))]
17374   "TARGET_USE_FANCY_MATH_387"
17375   "")
17376
17377 (define_expand "lrint<mode>di2"
17378   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17379      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17380       UNSPEC_FIX_NOTRUNC))]
17381   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17382   "")
17383
17384 (define_expand "lrint<mode>si2"
17385   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17386      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17387       UNSPEC_FIX_NOTRUNC))]
17388   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17389   "")
17390
17391 (define_expand "lround<mode>di2"
17392   [(match_operand:DI 0 "nonimmediate_operand" "")
17393    (match_operand:SSEMODEF 1 "register_operand" "")]
17394   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17395    && !flag_trapping_math && !flag_rounding_math"
17396 {
17397   ix86_expand_lround (operand0, operand1);
17398   DONE;
17399 })
17400
17401 (define_expand "lround<mode>si2"
17402   [(match_operand:SI 0 "nonimmediate_operand" "")
17403    (match_operand:SSEMODEF 1 "register_operand" "")]
17404   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17405    && !flag_trapping_math && !flag_rounding_math"
17406 {
17407   ix86_expand_lround (operand0, operand1);
17408   DONE;
17409 })
17410
17411 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17412 (define_insn_and_split "frndintxf2_floor"
17413   [(set (match_operand:XF 0 "register_operand" "=f")
17414         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17415          UNSPEC_FRNDINT_FLOOR))
17416    (clobber (reg:CC FLAGS_REG))]
17417   "TARGET_USE_FANCY_MATH_387
17418    && flag_unsafe_math_optimizations
17419    && !(reload_completed || reload_in_progress)"
17420   "#"
17421   "&& 1"
17422   [(const_int 0)]
17423 {
17424   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17425
17426   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17427   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17428
17429   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17430                                         operands[2], operands[3]));
17431   DONE;
17432 }
17433   [(set_attr "type" "frndint")
17434    (set_attr "i387_cw" "floor")
17435    (set_attr "mode" "XF")])
17436
17437 (define_insn "frndintxf2_floor_i387"
17438   [(set (match_operand:XF 0 "register_operand" "=f")
17439         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17440          UNSPEC_FRNDINT_FLOOR))
17441    (use (match_operand:HI 2 "memory_operand" "m"))
17442    (use (match_operand:HI 3 "memory_operand" "m"))]
17443   "TARGET_USE_FANCY_MATH_387
17444    && flag_unsafe_math_optimizations"
17445   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17446   [(set_attr "type" "frndint")
17447    (set_attr "i387_cw" "floor")
17448    (set_attr "mode" "XF")])
17449
17450 (define_expand "floorxf2"
17451   [(use (match_operand:XF 0 "register_operand" ""))
17452    (use (match_operand:XF 1 "register_operand" ""))]
17453   "TARGET_USE_FANCY_MATH_387
17454    && flag_unsafe_math_optimizations"
17455 {
17456   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17457   DONE;
17458 })
17459
17460 (define_expand "floordf2"
17461   [(use (match_operand:DF 0 "register_operand" ""))
17462    (use (match_operand:DF 1 "register_operand" ""))]
17463   "(TARGET_USE_FANCY_MATH_387
17464     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17465     && flag_unsafe_math_optimizations)
17466    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17467        && !flag_trapping_math
17468        && !optimize_size)"
17469 {
17470   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17471       && !flag_trapping_math
17472       && !optimize_size)
17473     {
17474       if (TARGET_64BIT)
17475         ix86_expand_floorceil (operand0, operand1, true);
17476       else
17477         ix86_expand_floorceildf_32 (operand0, operand1, true);
17478     }
17479   else
17480     {
17481       rtx op0 = gen_reg_rtx (XFmode);
17482       rtx op1 = gen_reg_rtx (XFmode);
17483
17484       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17485       emit_insn (gen_frndintxf2_floor (op0, op1));
17486
17487       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17488     }
17489   DONE;
17490 })
17491
17492 (define_expand "floorsf2"
17493   [(use (match_operand:SF 0 "register_operand" ""))
17494    (use (match_operand:SF 1 "register_operand" ""))]
17495   "(TARGET_USE_FANCY_MATH_387
17496     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17497     && flag_unsafe_math_optimizations)
17498    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17499        && !flag_trapping_math
17500        && !optimize_size)"
17501 {
17502   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17503       && !flag_trapping_math
17504       && !optimize_size)
17505     ix86_expand_floorceil (operand0, operand1, true);
17506   else
17507     {
17508       rtx op0 = gen_reg_rtx (XFmode);
17509       rtx op1 = gen_reg_rtx (XFmode);
17510
17511       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17512       emit_insn (gen_frndintxf2_floor (op0, op1));
17513
17514       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17515     }
17516   DONE;
17517 })
17518
17519 (define_insn_and_split "*fist<mode>2_floor_1"
17520   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17521         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17522          UNSPEC_FIST_FLOOR))
17523    (clobber (reg:CC FLAGS_REG))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && flag_unsafe_math_optimizations
17526    && !(reload_completed || reload_in_progress)"
17527   "#"
17528   "&& 1"
17529   [(const_int 0)]
17530 {
17531   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17532
17533   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17534   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17535   if (memory_operand (operands[0], VOIDmode))
17536     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17537                                       operands[2], operands[3]));
17538   else
17539     {
17540       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17541       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17542                                                   operands[2], operands[3],
17543                                                   operands[4]));
17544     }
17545   DONE;
17546 }
17547   [(set_attr "type" "fistp")
17548    (set_attr "i387_cw" "floor")
17549    (set_attr "mode" "<MODE>")])
17550
17551 (define_insn "fistdi2_floor"
17552   [(set (match_operand:DI 0 "memory_operand" "=m")
17553         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17554          UNSPEC_FIST_FLOOR))
17555    (use (match_operand:HI 2 "memory_operand" "m"))
17556    (use (match_operand:HI 3 "memory_operand" "m"))
17557    (clobber (match_scratch:XF 4 "=&1f"))]
17558   "TARGET_USE_FANCY_MATH_387
17559    && flag_unsafe_math_optimizations"
17560   "* return output_fix_trunc (insn, operands, 0);"
17561   [(set_attr "type" "fistp")
17562    (set_attr "i387_cw" "floor")
17563    (set_attr "mode" "DI")])
17564
17565 (define_insn "fistdi2_floor_with_temp"
17566   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17567         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17568          UNSPEC_FIST_FLOOR))
17569    (use (match_operand:HI 2 "memory_operand" "m,m"))
17570    (use (match_operand:HI 3 "memory_operand" "m,m"))
17571    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17572    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17573   "TARGET_USE_FANCY_MATH_387
17574    && flag_unsafe_math_optimizations"
17575   "#"
17576   [(set_attr "type" "fistp")
17577    (set_attr "i387_cw" "floor")
17578    (set_attr "mode" "DI")])
17579
17580 (define_split 
17581   [(set (match_operand:DI 0 "register_operand" "")
17582         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17583          UNSPEC_FIST_FLOOR))
17584    (use (match_operand:HI 2 "memory_operand" ""))
17585    (use (match_operand:HI 3 "memory_operand" ""))
17586    (clobber (match_operand:DI 4 "memory_operand" ""))
17587    (clobber (match_scratch 5 ""))]
17588   "reload_completed"
17589   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17590               (use (match_dup 2))
17591               (use (match_dup 3))
17592               (clobber (match_dup 5))])
17593    (set (match_dup 0) (match_dup 4))]
17594   "")
17595
17596 (define_split 
17597   [(set (match_operand:DI 0 "memory_operand" "")
17598         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17599          UNSPEC_FIST_FLOOR))
17600    (use (match_operand:HI 2 "memory_operand" ""))
17601    (use (match_operand:HI 3 "memory_operand" ""))
17602    (clobber (match_operand:DI 4 "memory_operand" ""))
17603    (clobber (match_scratch 5 ""))]
17604   "reload_completed"
17605   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17606               (use (match_dup 2))
17607               (use (match_dup 3))
17608               (clobber (match_dup 5))])]
17609   "")
17610
17611 (define_insn "fist<mode>2_floor"
17612   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17613         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17614          UNSPEC_FIST_FLOOR))
17615    (use (match_operand:HI 2 "memory_operand" "m"))
17616    (use (match_operand:HI 3 "memory_operand" "m"))]
17617   "TARGET_USE_FANCY_MATH_387
17618    && flag_unsafe_math_optimizations"
17619   "* return output_fix_trunc (insn, operands, 0);"
17620   [(set_attr "type" "fistp")
17621    (set_attr "i387_cw" "floor")
17622    (set_attr "mode" "<MODE>")])
17623
17624 (define_insn "fist<mode>2_floor_with_temp"
17625   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17626         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17627          UNSPEC_FIST_FLOOR))
17628    (use (match_operand:HI 2 "memory_operand" "m,m"))
17629    (use (match_operand:HI 3 "memory_operand" "m,m"))
17630    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17631   "TARGET_USE_FANCY_MATH_387
17632    && flag_unsafe_math_optimizations"
17633   "#"
17634   [(set_attr "type" "fistp")
17635    (set_attr "i387_cw" "floor")
17636    (set_attr "mode" "<MODE>")])
17637
17638 (define_split 
17639   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17640         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17641          UNSPEC_FIST_FLOOR))
17642    (use (match_operand:HI 2 "memory_operand" ""))
17643    (use (match_operand:HI 3 "memory_operand" ""))
17644    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17645   "reload_completed"
17646   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17647                                   UNSPEC_FIST_FLOOR))
17648               (use (match_dup 2))
17649               (use (match_dup 3))])
17650    (set (match_dup 0) (match_dup 4))]
17651   "")
17652
17653 (define_split 
17654   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17655         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17656          UNSPEC_FIST_FLOOR))
17657    (use (match_operand:HI 2 "memory_operand" ""))
17658    (use (match_operand:HI 3 "memory_operand" ""))
17659    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17660   "reload_completed"
17661   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17662                                   UNSPEC_FIST_FLOOR))
17663               (use (match_dup 2))
17664               (use (match_dup 3))])]
17665   "")
17666
17667 (define_expand "lfloorxf<mode>2"
17668   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17669                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17670                     UNSPEC_FIST_FLOOR))
17671               (clobber (reg:CC FLAGS_REG))])]
17672   "TARGET_USE_FANCY_MATH_387
17673    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17674    && flag_unsafe_math_optimizations"
17675   "")
17676
17677 (define_expand "lfloor<mode>di2"
17678   [(match_operand:DI 0 "nonimmediate_operand" "")
17679    (match_operand:SSEMODEF 1 "register_operand" "")]
17680   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17681    && !flag_trapping_math"
17682 {
17683   ix86_expand_lfloorceil (operand0, operand1, true);
17684   DONE;
17685 })
17686
17687 (define_expand "lfloor<mode>si2"
17688   [(match_operand:SI 0 "nonimmediate_operand" "")
17689    (match_operand:SSEMODEF 1 "register_operand" "")]
17690   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17691    && !flag_trapping_math"
17692 {
17693   ix86_expand_lfloorceil (operand0, operand1, true);
17694   DONE;
17695 })
17696
17697 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17698 (define_insn_and_split "frndintxf2_ceil"
17699   [(set (match_operand:XF 0 "register_operand" "=f")
17700         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17701          UNSPEC_FRNDINT_CEIL))
17702    (clobber (reg:CC FLAGS_REG))]
17703   "TARGET_USE_FANCY_MATH_387
17704    && flag_unsafe_math_optimizations
17705    && !(reload_completed || reload_in_progress)"
17706   "#"
17707   "&& 1"
17708   [(const_int 0)]
17709 {
17710   ix86_optimize_mode_switching[I387_CEIL] = 1;
17711
17712   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17713   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17714
17715   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17716                                        operands[2], operands[3]));
17717   DONE;
17718 }
17719   [(set_attr "type" "frndint")
17720    (set_attr "i387_cw" "ceil")
17721    (set_attr "mode" "XF")])
17722
17723 (define_insn "frndintxf2_ceil_i387"
17724   [(set (match_operand:XF 0 "register_operand" "=f")
17725         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17726          UNSPEC_FRNDINT_CEIL))
17727    (use (match_operand:HI 2 "memory_operand" "m"))
17728    (use (match_operand:HI 3 "memory_operand" "m"))]
17729   "TARGET_USE_FANCY_MATH_387
17730    && flag_unsafe_math_optimizations"
17731   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17732   [(set_attr "type" "frndint")
17733    (set_attr "i387_cw" "ceil")
17734    (set_attr "mode" "XF")])
17735
17736 (define_expand "ceilxf2"
17737   [(use (match_operand:XF 0 "register_operand" ""))
17738    (use (match_operand:XF 1 "register_operand" ""))]
17739   "TARGET_USE_FANCY_MATH_387
17740    && flag_unsafe_math_optimizations"
17741 {
17742   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17743   DONE;
17744 })
17745
17746 (define_expand "ceildf2"
17747   [(use (match_operand:DF 0 "register_operand" ""))
17748    (use (match_operand:DF 1 "register_operand" ""))]
17749   "(TARGET_USE_FANCY_MATH_387
17750     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17751     && flag_unsafe_math_optimizations)
17752    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17753        && !flag_trapping_math
17754        && !optimize_size)"
17755 {
17756   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17757       && !flag_trapping_math
17758       && !optimize_size)
17759     {
17760       if (TARGET_64BIT)
17761         ix86_expand_floorceil (operand0, operand1, false);
17762       else
17763         ix86_expand_floorceildf_32 (operand0, operand1, false);
17764     }
17765   else
17766     {
17767       rtx op0 = gen_reg_rtx (XFmode);
17768       rtx op1 = gen_reg_rtx (XFmode);
17769
17770       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17771       emit_insn (gen_frndintxf2_ceil (op0, op1));
17772
17773       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17774     }
17775   DONE;
17776 })
17777
17778 (define_expand "ceilsf2"
17779   [(use (match_operand:SF 0 "register_operand" ""))
17780    (use (match_operand:SF 1 "register_operand" ""))]
17781   "(TARGET_USE_FANCY_MATH_387
17782     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17783     && flag_unsafe_math_optimizations)
17784    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17785        && !flag_trapping_math
17786        && !optimize_size)"
17787 {
17788   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17789       && !flag_trapping_math
17790       && !optimize_size)
17791     ix86_expand_floorceil (operand0, operand1, false);
17792   else
17793     {
17794       rtx op0 = gen_reg_rtx (XFmode);
17795       rtx op1 = gen_reg_rtx (XFmode);
17796
17797       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17798       emit_insn (gen_frndintxf2_ceil (op0, op1));
17799
17800       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17801     }
17802   DONE;
17803 })
17804
17805 (define_insn_and_split "*fist<mode>2_ceil_1"
17806   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17807         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17808          UNSPEC_FIST_CEIL))
17809    (clobber (reg:CC FLAGS_REG))]
17810   "TARGET_USE_FANCY_MATH_387
17811    && flag_unsafe_math_optimizations
17812    && !(reload_completed || reload_in_progress)"
17813   "#"
17814   "&& 1"
17815   [(const_int 0)]
17816 {
17817   ix86_optimize_mode_switching[I387_CEIL] = 1;
17818
17819   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17820   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17821   if (memory_operand (operands[0], VOIDmode))
17822     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17823                                      operands[2], operands[3]));
17824   else
17825     {
17826       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17827       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17828                                                  operands[2], operands[3],
17829                                                  operands[4]));
17830     }
17831   DONE;
17832 }
17833   [(set_attr "type" "fistp")
17834    (set_attr "i387_cw" "ceil")
17835    (set_attr "mode" "<MODE>")])
17836
17837 (define_insn "fistdi2_ceil"
17838   [(set (match_operand:DI 0 "memory_operand" "=m")
17839         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17840          UNSPEC_FIST_CEIL))
17841    (use (match_operand:HI 2 "memory_operand" "m"))
17842    (use (match_operand:HI 3 "memory_operand" "m"))
17843    (clobber (match_scratch:XF 4 "=&1f"))]
17844   "TARGET_USE_FANCY_MATH_387
17845    && flag_unsafe_math_optimizations"
17846   "* return output_fix_trunc (insn, operands, 0);"
17847   [(set_attr "type" "fistp")
17848    (set_attr "i387_cw" "ceil")
17849    (set_attr "mode" "DI")])
17850
17851 (define_insn "fistdi2_ceil_with_temp"
17852   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17853         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17854          UNSPEC_FIST_CEIL))
17855    (use (match_operand:HI 2 "memory_operand" "m,m"))
17856    (use (match_operand:HI 3 "memory_operand" "m,m"))
17857    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17858    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17859   "TARGET_USE_FANCY_MATH_387
17860    && flag_unsafe_math_optimizations"
17861   "#"
17862   [(set_attr "type" "fistp")
17863    (set_attr "i387_cw" "ceil")
17864    (set_attr "mode" "DI")])
17865
17866 (define_split 
17867   [(set (match_operand:DI 0 "register_operand" "")
17868         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17869          UNSPEC_FIST_CEIL))
17870    (use (match_operand:HI 2 "memory_operand" ""))
17871    (use (match_operand:HI 3 "memory_operand" ""))
17872    (clobber (match_operand:DI 4 "memory_operand" ""))
17873    (clobber (match_scratch 5 ""))]
17874   "reload_completed"
17875   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17876               (use (match_dup 2))
17877               (use (match_dup 3))
17878               (clobber (match_dup 5))])
17879    (set (match_dup 0) (match_dup 4))]
17880   "")
17881
17882 (define_split 
17883   [(set (match_operand:DI 0 "memory_operand" "")
17884         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17885          UNSPEC_FIST_CEIL))
17886    (use (match_operand:HI 2 "memory_operand" ""))
17887    (use (match_operand:HI 3 "memory_operand" ""))
17888    (clobber (match_operand:DI 4 "memory_operand" ""))
17889    (clobber (match_scratch 5 ""))]
17890   "reload_completed"
17891   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17892               (use (match_dup 2))
17893               (use (match_dup 3))
17894               (clobber (match_dup 5))])]
17895   "")
17896
17897 (define_insn "fist<mode>2_ceil"
17898   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17899         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17900          UNSPEC_FIST_CEIL))
17901    (use (match_operand:HI 2 "memory_operand" "m"))
17902    (use (match_operand:HI 3 "memory_operand" "m"))]
17903   "TARGET_USE_FANCY_MATH_387
17904    && flag_unsafe_math_optimizations"
17905   "* return output_fix_trunc (insn, operands, 0);"
17906   [(set_attr "type" "fistp")
17907    (set_attr "i387_cw" "ceil")
17908    (set_attr "mode" "<MODE>")])
17909
17910 (define_insn "fist<mode>2_ceil_with_temp"
17911   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17912         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17913          UNSPEC_FIST_CEIL))
17914    (use (match_operand:HI 2 "memory_operand" "m,m"))
17915    (use (match_operand:HI 3 "memory_operand" "m,m"))
17916    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17917   "TARGET_USE_FANCY_MATH_387
17918    && flag_unsafe_math_optimizations"
17919   "#"
17920   [(set_attr "type" "fistp")
17921    (set_attr "i387_cw" "ceil")
17922    (set_attr "mode" "<MODE>")])
17923
17924 (define_split 
17925   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17926         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17927          UNSPEC_FIST_CEIL))
17928    (use (match_operand:HI 2 "memory_operand" ""))
17929    (use (match_operand:HI 3 "memory_operand" ""))
17930    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17931   "reload_completed"
17932   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17933                                   UNSPEC_FIST_CEIL))
17934               (use (match_dup 2))
17935               (use (match_dup 3))])
17936    (set (match_dup 0) (match_dup 4))]
17937   "")
17938
17939 (define_split 
17940   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17941         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17942          UNSPEC_FIST_CEIL))
17943    (use (match_operand:HI 2 "memory_operand" ""))
17944    (use (match_operand:HI 3 "memory_operand" ""))
17945    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17946   "reload_completed"
17947   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17948                                   UNSPEC_FIST_CEIL))
17949               (use (match_dup 2))
17950               (use (match_dup 3))])]
17951   "")
17952
17953 (define_expand "lceilxf<mode>2"
17954   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17955                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17956                     UNSPEC_FIST_CEIL))
17957               (clobber (reg:CC FLAGS_REG))])]
17958   "TARGET_USE_FANCY_MATH_387
17959    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17960    && flag_unsafe_math_optimizations"
17961   "")
17962
17963 (define_expand "lceil<mode>di2"
17964   [(match_operand:DI 0 "nonimmediate_operand" "")
17965    (match_operand:SSEMODEF 1 "register_operand" "")]
17966   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17967    && !flag_trapping_math"
17968 {
17969   ix86_expand_lfloorceil (operand0, operand1, false);
17970   DONE;
17971 })
17972
17973 (define_expand "lceil<mode>si2"
17974   [(match_operand:SI 0 "nonimmediate_operand" "")
17975    (match_operand:SSEMODEF 1 "register_operand" "")]
17976   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17977    && !flag_trapping_math"
17978 {
17979   ix86_expand_lfloorceil (operand0, operand1, false);
17980   DONE;
17981 })
17982
17983 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17984 (define_insn_and_split "frndintxf2_trunc"
17985   [(set (match_operand:XF 0 "register_operand" "=f")
17986         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17987          UNSPEC_FRNDINT_TRUNC))
17988    (clobber (reg:CC FLAGS_REG))]
17989   "TARGET_USE_FANCY_MATH_387
17990    && flag_unsafe_math_optimizations
17991    && !(reload_completed || reload_in_progress)"
17992   "#"
17993   "&& 1"
17994   [(const_int 0)]
17995 {
17996   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17997
17998   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17999   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18000
18001   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18002                                         operands[2], operands[3]));
18003   DONE;
18004 }
18005   [(set_attr "type" "frndint")
18006    (set_attr "i387_cw" "trunc")
18007    (set_attr "mode" "XF")])
18008
18009 (define_insn "frndintxf2_trunc_i387"
18010   [(set (match_operand:XF 0 "register_operand" "=f")
18011         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18012          UNSPEC_FRNDINT_TRUNC))
18013    (use (match_operand:HI 2 "memory_operand" "m"))
18014    (use (match_operand:HI 3 "memory_operand" "m"))]
18015   "TARGET_USE_FANCY_MATH_387
18016    && flag_unsafe_math_optimizations"
18017   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18018   [(set_attr "type" "frndint")
18019    (set_attr "i387_cw" "trunc")
18020    (set_attr "mode" "XF")])
18021
18022 (define_expand "btruncxf2"
18023   [(use (match_operand:XF 0 "register_operand" ""))
18024    (use (match_operand:XF 1 "register_operand" ""))]
18025   "TARGET_USE_FANCY_MATH_387
18026    && flag_unsafe_math_optimizations"
18027 {
18028   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18029   DONE;
18030 })
18031
18032 (define_expand "btruncdf2"
18033   [(use (match_operand:DF 0 "register_operand" ""))
18034    (use (match_operand:DF 1 "register_operand" ""))]
18035   "TARGET_USE_FANCY_MATH_387
18036    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18037    && flag_unsafe_math_optimizations"
18038 {
18039   rtx op0 = gen_reg_rtx (XFmode);
18040   rtx op1 = gen_reg_rtx (XFmode);
18041
18042   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18043   emit_insn (gen_frndintxf2_trunc (op0, op1));
18044
18045   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18046   DONE;
18047 })
18048
18049 (define_expand "btruncsf2"
18050   [(use (match_operand:SF 0 "register_operand" ""))
18051    (use (match_operand:SF 1 "register_operand" ""))]
18052   "TARGET_USE_FANCY_MATH_387
18053    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18054    && flag_unsafe_math_optimizations"
18055 {
18056   rtx op0 = gen_reg_rtx (XFmode);
18057   rtx op1 = gen_reg_rtx (XFmode);
18058
18059   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18060   emit_insn (gen_frndintxf2_trunc (op0, op1));
18061
18062   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18063   DONE;
18064 })
18065
18066 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18067 (define_insn_and_split "frndintxf2_mask_pm"
18068   [(set (match_operand:XF 0 "register_operand" "=f")
18069         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18070          UNSPEC_FRNDINT_MASK_PM))
18071    (clobber (reg:CC FLAGS_REG))]
18072   "TARGET_USE_FANCY_MATH_387
18073    && flag_unsafe_math_optimizations
18074    && !(reload_completed || reload_in_progress)"
18075   "#"
18076   "&& 1"
18077   [(const_int 0)]
18078 {
18079   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18080
18081   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18082   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18083
18084   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18085                                           operands[2], operands[3]));
18086   DONE;
18087 }
18088   [(set_attr "type" "frndint")
18089    (set_attr "i387_cw" "mask_pm")
18090    (set_attr "mode" "XF")])
18091
18092 (define_insn "frndintxf2_mask_pm_i387"
18093   [(set (match_operand:XF 0 "register_operand" "=f")
18094         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18095          UNSPEC_FRNDINT_MASK_PM))
18096    (use (match_operand:HI 2 "memory_operand" "m"))
18097    (use (match_operand:HI 3 "memory_operand" "m"))]
18098   "TARGET_USE_FANCY_MATH_387
18099    && flag_unsafe_math_optimizations"
18100   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18101   [(set_attr "type" "frndint")
18102    (set_attr "i387_cw" "mask_pm")
18103    (set_attr "mode" "XF")])
18104
18105 (define_expand "nearbyintxf2"
18106   [(use (match_operand:XF 0 "register_operand" ""))
18107    (use (match_operand:XF 1 "register_operand" ""))]
18108   "TARGET_USE_FANCY_MATH_387
18109    && flag_unsafe_math_optimizations"
18110 {
18111   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18112
18113   DONE;
18114 })
18115
18116 (define_expand "nearbyintdf2"
18117   [(use (match_operand:DF 0 "register_operand" ""))
18118    (use (match_operand:DF 1 "register_operand" ""))]
18119   "TARGET_USE_FANCY_MATH_387
18120    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18121    && flag_unsafe_math_optimizations"
18122 {
18123   rtx op0 = gen_reg_rtx (XFmode);
18124   rtx op1 = gen_reg_rtx (XFmode);
18125
18126   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18127   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18128
18129   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18130   DONE;
18131 })
18132
18133 (define_expand "nearbyintsf2"
18134   [(use (match_operand:SF 0 "register_operand" ""))
18135    (use (match_operand:SF 1 "register_operand" ""))]
18136   "TARGET_USE_FANCY_MATH_387
18137    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18138    && flag_unsafe_math_optimizations"
18139 {
18140   rtx op0 = gen_reg_rtx (XFmode);
18141   rtx op1 = gen_reg_rtx (XFmode);
18142
18143   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18144   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18145
18146   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18147   DONE;
18148 })
18149
18150 \f
18151 ;; Block operation instructions
18152
18153 (define_insn "cld"
18154  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18155  ""
18156  "cld"
18157   [(set_attr "type" "cld")])
18158
18159 (define_expand "movmemsi"
18160   [(use (match_operand:BLK 0 "memory_operand" ""))
18161    (use (match_operand:BLK 1 "memory_operand" ""))
18162    (use (match_operand:SI 2 "nonmemory_operand" ""))
18163    (use (match_operand:SI 3 "const_int_operand" ""))]
18164   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18165 {
18166  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18167    DONE;
18168  else
18169    FAIL;
18170 })
18171
18172 (define_expand "movmemdi"
18173   [(use (match_operand:BLK 0 "memory_operand" ""))
18174    (use (match_operand:BLK 1 "memory_operand" ""))
18175    (use (match_operand:DI 2 "nonmemory_operand" ""))
18176    (use (match_operand:DI 3 "const_int_operand" ""))]
18177   "TARGET_64BIT"
18178 {
18179  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18180    DONE;
18181  else
18182    FAIL;
18183 })
18184
18185 ;; Most CPUs don't like single string operations
18186 ;; Handle this case here to simplify previous expander.
18187
18188 (define_expand "strmov"
18189   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18190    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18191    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18192               (clobber (reg:CC FLAGS_REG))])
18193    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18194               (clobber (reg:CC FLAGS_REG))])]
18195   ""
18196 {
18197   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18198
18199   /* If .md ever supports :P for Pmode, these can be directly
18200      in the pattern above.  */
18201   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18202   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18203
18204   if (TARGET_SINGLE_STRINGOP || optimize_size)
18205     {
18206       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18207                                       operands[2], operands[3],
18208                                       operands[5], operands[6]));
18209       DONE;
18210     }
18211
18212   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18213 })
18214
18215 (define_expand "strmov_singleop"
18216   [(parallel [(set (match_operand 1 "memory_operand" "")
18217                    (match_operand 3 "memory_operand" ""))
18218               (set (match_operand 0 "register_operand" "")
18219                    (match_operand 4 "" ""))
18220               (set (match_operand 2 "register_operand" "")
18221                    (match_operand 5 "" ""))
18222               (use (reg:SI DIRFLAG_REG))])]
18223   "TARGET_SINGLE_STRINGOP || optimize_size"
18224   "")
18225
18226 (define_insn "*strmovdi_rex_1"
18227   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18228         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18229    (set (match_operand:DI 0 "register_operand" "=D")
18230         (plus:DI (match_dup 2)
18231                  (const_int 8)))
18232    (set (match_operand:DI 1 "register_operand" "=S")
18233         (plus:DI (match_dup 3)
18234                  (const_int 8)))
18235    (use (reg:SI DIRFLAG_REG))]
18236   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18237   "movsq"
18238   [(set_attr "type" "str")
18239    (set_attr "mode" "DI")
18240    (set_attr "memory" "both")])
18241
18242 (define_insn "*strmovsi_1"
18243   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18244         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18245    (set (match_operand:SI 0 "register_operand" "=D")
18246         (plus:SI (match_dup 2)
18247                  (const_int 4)))
18248    (set (match_operand:SI 1 "register_operand" "=S")
18249         (plus:SI (match_dup 3)
18250                  (const_int 4)))
18251    (use (reg:SI DIRFLAG_REG))]
18252   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18253   "{movsl|movsd}"
18254   [(set_attr "type" "str")
18255    (set_attr "mode" "SI")
18256    (set_attr "memory" "both")])
18257
18258 (define_insn "*strmovsi_rex_1"
18259   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18260         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18261    (set (match_operand:DI 0 "register_operand" "=D")
18262         (plus:DI (match_dup 2)
18263                  (const_int 4)))
18264    (set (match_operand:DI 1 "register_operand" "=S")
18265         (plus:DI (match_dup 3)
18266                  (const_int 4)))
18267    (use (reg:SI DIRFLAG_REG))]
18268   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18269   "{movsl|movsd}"
18270   [(set_attr "type" "str")
18271    (set_attr "mode" "SI")
18272    (set_attr "memory" "both")])
18273
18274 (define_insn "*strmovhi_1"
18275   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18276         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18277    (set (match_operand:SI 0 "register_operand" "=D")
18278         (plus:SI (match_dup 2)
18279                  (const_int 2)))
18280    (set (match_operand:SI 1 "register_operand" "=S")
18281         (plus:SI (match_dup 3)
18282                  (const_int 2)))
18283    (use (reg:SI DIRFLAG_REG))]
18284   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18285   "movsw"
18286   [(set_attr "type" "str")
18287    (set_attr "memory" "both")
18288    (set_attr "mode" "HI")])
18289
18290 (define_insn "*strmovhi_rex_1"
18291   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18292         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18293    (set (match_operand:DI 0 "register_operand" "=D")
18294         (plus:DI (match_dup 2)
18295                  (const_int 2)))
18296    (set (match_operand:DI 1 "register_operand" "=S")
18297         (plus:DI (match_dup 3)
18298                  (const_int 2)))
18299    (use (reg:SI DIRFLAG_REG))]
18300   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18301   "movsw"
18302   [(set_attr "type" "str")
18303    (set_attr "memory" "both")
18304    (set_attr "mode" "HI")])
18305
18306 (define_insn "*strmovqi_1"
18307   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18308         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18309    (set (match_operand:SI 0 "register_operand" "=D")
18310         (plus:SI (match_dup 2)
18311                  (const_int 1)))
18312    (set (match_operand:SI 1 "register_operand" "=S")
18313         (plus:SI (match_dup 3)
18314                  (const_int 1)))
18315    (use (reg:SI DIRFLAG_REG))]
18316   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18317   "movsb"
18318   [(set_attr "type" "str")
18319    (set_attr "memory" "both")
18320    (set_attr "mode" "QI")])
18321
18322 (define_insn "*strmovqi_rex_1"
18323   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18324         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18325    (set (match_operand:DI 0 "register_operand" "=D")
18326         (plus:DI (match_dup 2)
18327                  (const_int 1)))
18328    (set (match_operand:DI 1 "register_operand" "=S")
18329         (plus:DI (match_dup 3)
18330                  (const_int 1)))
18331    (use (reg:SI DIRFLAG_REG))]
18332   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18333   "movsb"
18334   [(set_attr "type" "str")
18335    (set_attr "memory" "both")
18336    (set_attr "mode" "QI")])
18337
18338 (define_expand "rep_mov"
18339   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18340               (set (match_operand 0 "register_operand" "")
18341                    (match_operand 5 "" ""))
18342               (set (match_operand 2 "register_operand" "")
18343                    (match_operand 6 "" ""))
18344               (set (match_operand 1 "memory_operand" "")
18345                    (match_operand 3 "memory_operand" ""))
18346               (use (match_dup 4))
18347               (use (reg:SI DIRFLAG_REG))])]
18348   ""
18349   "")
18350
18351 (define_insn "*rep_movdi_rex64"
18352   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18353    (set (match_operand:DI 0 "register_operand" "=D") 
18354         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18355                             (const_int 3))
18356                  (match_operand:DI 3 "register_operand" "0")))
18357    (set (match_operand:DI 1 "register_operand" "=S") 
18358         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18359                  (match_operand:DI 4 "register_operand" "1")))
18360    (set (mem:BLK (match_dup 3))
18361         (mem:BLK (match_dup 4)))
18362    (use (match_dup 5))
18363    (use (reg:SI DIRFLAG_REG))]
18364   "TARGET_64BIT"
18365   "{rep\;movsq|rep movsq}"
18366   [(set_attr "type" "str")
18367    (set_attr "prefix_rep" "1")
18368    (set_attr "memory" "both")
18369    (set_attr "mode" "DI")])
18370
18371 (define_insn "*rep_movsi"
18372   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18373    (set (match_operand:SI 0 "register_operand" "=D") 
18374         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18375                             (const_int 2))
18376                  (match_operand:SI 3 "register_operand" "0")))
18377    (set (match_operand:SI 1 "register_operand" "=S") 
18378         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18379                  (match_operand:SI 4 "register_operand" "1")))
18380    (set (mem:BLK (match_dup 3))
18381         (mem:BLK (match_dup 4)))
18382    (use (match_dup 5))
18383    (use (reg:SI DIRFLAG_REG))]
18384   "!TARGET_64BIT"
18385   "{rep\;movsl|rep movsd}"
18386   [(set_attr "type" "str")
18387    (set_attr "prefix_rep" "1")
18388    (set_attr "memory" "both")
18389    (set_attr "mode" "SI")])
18390
18391 (define_insn "*rep_movsi_rex64"
18392   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18393    (set (match_operand:DI 0 "register_operand" "=D") 
18394         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18395                             (const_int 2))
18396                  (match_operand:DI 3 "register_operand" "0")))
18397    (set (match_operand:DI 1 "register_operand" "=S") 
18398         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18399                  (match_operand:DI 4 "register_operand" "1")))
18400    (set (mem:BLK (match_dup 3))
18401         (mem:BLK (match_dup 4)))
18402    (use (match_dup 5))
18403    (use (reg:SI DIRFLAG_REG))]
18404   "TARGET_64BIT"
18405   "{rep\;movsl|rep movsd}"
18406   [(set_attr "type" "str")
18407    (set_attr "prefix_rep" "1")
18408    (set_attr "memory" "both")
18409    (set_attr "mode" "SI")])
18410
18411 (define_insn "*rep_movqi"
18412   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18413    (set (match_operand:SI 0 "register_operand" "=D") 
18414         (plus:SI (match_operand:SI 3 "register_operand" "0")
18415                  (match_operand:SI 5 "register_operand" "2")))
18416    (set (match_operand:SI 1 "register_operand" "=S") 
18417         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18418    (set (mem:BLK (match_dup 3))
18419         (mem:BLK (match_dup 4)))
18420    (use (match_dup 5))
18421    (use (reg:SI DIRFLAG_REG))]
18422   "!TARGET_64BIT"
18423   "{rep\;movsb|rep movsb}"
18424   [(set_attr "type" "str")
18425    (set_attr "prefix_rep" "1")
18426    (set_attr "memory" "both")
18427    (set_attr "mode" "SI")])
18428
18429 (define_insn "*rep_movqi_rex64"
18430   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18431    (set (match_operand:DI 0 "register_operand" "=D") 
18432         (plus:DI (match_operand:DI 3 "register_operand" "0")
18433                  (match_operand:DI 5 "register_operand" "2")))
18434    (set (match_operand:DI 1 "register_operand" "=S") 
18435         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18436    (set (mem:BLK (match_dup 3))
18437         (mem:BLK (match_dup 4)))
18438    (use (match_dup 5))
18439    (use (reg:SI DIRFLAG_REG))]
18440   "TARGET_64BIT"
18441   "{rep\;movsb|rep movsb}"
18442   [(set_attr "type" "str")
18443    (set_attr "prefix_rep" "1")
18444    (set_attr "memory" "both")
18445    (set_attr "mode" "SI")])
18446
18447 (define_expand "setmemsi"
18448    [(use (match_operand:BLK 0 "memory_operand" ""))
18449     (use (match_operand:SI 1 "nonmemory_operand" ""))
18450     (use (match_operand 2 "const_int_operand" ""))
18451     (use (match_operand 3 "const_int_operand" ""))]
18452   ""
18453 {
18454  /* If value to set is not zero, use the library routine.  */
18455  if (operands[2] != const0_rtx)
18456    FAIL;
18457
18458  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18459    DONE;
18460  else
18461    FAIL;
18462 })
18463
18464 (define_expand "setmemdi"
18465    [(use (match_operand:BLK 0 "memory_operand" ""))
18466     (use (match_operand:DI 1 "nonmemory_operand" ""))
18467     (use (match_operand 2 "const_int_operand" ""))
18468     (use (match_operand 3 "const_int_operand" ""))]
18469   "TARGET_64BIT"
18470 {
18471  /* If value to set is not zero, use the library routine.  */
18472  if (operands[2] != const0_rtx)
18473    FAIL;
18474
18475  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18476    DONE;
18477  else
18478    FAIL;
18479 })
18480
18481 ;; Most CPUs don't like single string operations
18482 ;; Handle this case here to simplify previous expander.
18483
18484 (define_expand "strset"
18485   [(set (match_operand 1 "memory_operand" "")
18486         (match_operand 2 "register_operand" ""))
18487    (parallel [(set (match_operand 0 "register_operand" "")
18488                    (match_dup 3))
18489               (clobber (reg:CC FLAGS_REG))])]
18490   ""
18491 {
18492   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18493     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18494
18495   /* If .md ever supports :P for Pmode, this can be directly
18496      in the pattern above.  */
18497   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18498                               GEN_INT (GET_MODE_SIZE (GET_MODE
18499                                                       (operands[2]))));
18500   if (TARGET_SINGLE_STRINGOP || optimize_size)
18501     {
18502       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18503                                       operands[3]));
18504       DONE;
18505     }
18506 })
18507
18508 (define_expand "strset_singleop"
18509   [(parallel [(set (match_operand 1 "memory_operand" "")
18510                    (match_operand 2 "register_operand" ""))
18511               (set (match_operand 0 "register_operand" "")
18512                    (match_operand 3 "" ""))
18513               (use (reg:SI DIRFLAG_REG))])]
18514   "TARGET_SINGLE_STRINGOP || optimize_size"
18515   "")
18516
18517 (define_insn "*strsetdi_rex_1"
18518   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18519         (match_operand:DI 2 "register_operand" "a"))
18520    (set (match_operand:DI 0 "register_operand" "=D")
18521         (plus:DI (match_dup 1)
18522                  (const_int 8)))
18523    (use (reg:SI DIRFLAG_REG))]
18524   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18525   "stosq"
18526   [(set_attr "type" "str")
18527    (set_attr "memory" "store")
18528    (set_attr "mode" "DI")])
18529
18530 (define_insn "*strsetsi_1"
18531   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18532         (match_operand:SI 2 "register_operand" "a"))
18533    (set (match_operand:SI 0 "register_operand" "=D")
18534         (plus:SI (match_dup 1)
18535                  (const_int 4)))
18536    (use (reg:SI DIRFLAG_REG))]
18537   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18538   "{stosl|stosd}"
18539   [(set_attr "type" "str")
18540    (set_attr "memory" "store")
18541    (set_attr "mode" "SI")])
18542
18543 (define_insn "*strsetsi_rex_1"
18544   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18545         (match_operand:SI 2 "register_operand" "a"))
18546    (set (match_operand:DI 0 "register_operand" "=D")
18547         (plus:DI (match_dup 1)
18548                  (const_int 4)))
18549    (use (reg:SI DIRFLAG_REG))]
18550   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18551   "{stosl|stosd}"
18552   [(set_attr "type" "str")
18553    (set_attr "memory" "store")
18554    (set_attr "mode" "SI")])
18555
18556 (define_insn "*strsethi_1"
18557   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18558         (match_operand:HI 2 "register_operand" "a"))
18559    (set (match_operand:SI 0 "register_operand" "=D")
18560         (plus:SI (match_dup 1)
18561                  (const_int 2)))
18562    (use (reg:SI DIRFLAG_REG))]
18563   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18564   "stosw"
18565   [(set_attr "type" "str")
18566    (set_attr "memory" "store")
18567    (set_attr "mode" "HI")])
18568
18569 (define_insn "*strsethi_rex_1"
18570   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18571         (match_operand:HI 2 "register_operand" "a"))
18572    (set (match_operand:DI 0 "register_operand" "=D")
18573         (plus:DI (match_dup 1)
18574                  (const_int 2)))
18575    (use (reg:SI DIRFLAG_REG))]
18576   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18577   "stosw"
18578   [(set_attr "type" "str")
18579    (set_attr "memory" "store")
18580    (set_attr "mode" "HI")])
18581
18582 (define_insn "*strsetqi_1"
18583   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18584         (match_operand:QI 2 "register_operand" "a"))
18585    (set (match_operand:SI 0 "register_operand" "=D")
18586         (plus:SI (match_dup 1)
18587                  (const_int 1)))
18588    (use (reg:SI DIRFLAG_REG))]
18589   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18590   "stosb"
18591   [(set_attr "type" "str")
18592    (set_attr "memory" "store")
18593    (set_attr "mode" "QI")])
18594
18595 (define_insn "*strsetqi_rex_1"
18596   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18597         (match_operand:QI 2 "register_operand" "a"))
18598    (set (match_operand:DI 0 "register_operand" "=D")
18599         (plus:DI (match_dup 1)
18600                  (const_int 1)))
18601    (use (reg:SI DIRFLAG_REG))]
18602   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18603   "stosb"
18604   [(set_attr "type" "str")
18605    (set_attr "memory" "store")
18606    (set_attr "mode" "QI")])
18607
18608 (define_expand "rep_stos"
18609   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18610               (set (match_operand 0 "register_operand" "")
18611                    (match_operand 4 "" ""))
18612               (set (match_operand 2 "memory_operand" "") (const_int 0))
18613               (use (match_operand 3 "register_operand" ""))
18614               (use (match_dup 1))
18615               (use (reg:SI DIRFLAG_REG))])]
18616   ""
18617   "")
18618
18619 (define_insn "*rep_stosdi_rex64"
18620   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18621    (set (match_operand:DI 0 "register_operand" "=D") 
18622         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18623                             (const_int 3))
18624                  (match_operand:DI 3 "register_operand" "0")))
18625    (set (mem:BLK (match_dup 3))
18626         (const_int 0))
18627    (use (match_operand:DI 2 "register_operand" "a"))
18628    (use (match_dup 4))
18629    (use (reg:SI DIRFLAG_REG))]
18630   "TARGET_64BIT"
18631   "{rep\;stosq|rep stosq}"
18632   [(set_attr "type" "str")
18633    (set_attr "prefix_rep" "1")
18634    (set_attr "memory" "store")
18635    (set_attr "mode" "DI")])
18636
18637 (define_insn "*rep_stossi"
18638   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18639    (set (match_operand:SI 0 "register_operand" "=D") 
18640         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18641                             (const_int 2))
18642                  (match_operand:SI 3 "register_operand" "0")))
18643    (set (mem:BLK (match_dup 3))
18644         (const_int 0))
18645    (use (match_operand:SI 2 "register_operand" "a"))
18646    (use (match_dup 4))
18647    (use (reg:SI DIRFLAG_REG))]
18648   "!TARGET_64BIT"
18649   "{rep\;stosl|rep stosd}"
18650   [(set_attr "type" "str")
18651    (set_attr "prefix_rep" "1")
18652    (set_attr "memory" "store")
18653    (set_attr "mode" "SI")])
18654
18655 (define_insn "*rep_stossi_rex64"
18656   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18657    (set (match_operand:DI 0 "register_operand" "=D") 
18658         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18659                             (const_int 2))
18660                  (match_operand:DI 3 "register_operand" "0")))
18661    (set (mem:BLK (match_dup 3))
18662         (const_int 0))
18663    (use (match_operand:SI 2 "register_operand" "a"))
18664    (use (match_dup 4))
18665    (use (reg:SI DIRFLAG_REG))]
18666   "TARGET_64BIT"
18667   "{rep\;stosl|rep stosd}"
18668   [(set_attr "type" "str")
18669    (set_attr "prefix_rep" "1")
18670    (set_attr "memory" "store")
18671    (set_attr "mode" "SI")])
18672
18673 (define_insn "*rep_stosqi"
18674   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18675    (set (match_operand:SI 0 "register_operand" "=D") 
18676         (plus:SI (match_operand:SI 3 "register_operand" "0")
18677                  (match_operand:SI 4 "register_operand" "1")))
18678    (set (mem:BLK (match_dup 3))
18679         (const_int 0))
18680    (use (match_operand:QI 2 "register_operand" "a"))
18681    (use (match_dup 4))
18682    (use (reg:SI DIRFLAG_REG))]
18683   "!TARGET_64BIT"
18684   "{rep\;stosb|rep stosb}"
18685   [(set_attr "type" "str")
18686    (set_attr "prefix_rep" "1")
18687    (set_attr "memory" "store")
18688    (set_attr "mode" "QI")])
18689
18690 (define_insn "*rep_stosqi_rex64"
18691   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18692    (set (match_operand:DI 0 "register_operand" "=D") 
18693         (plus:DI (match_operand:DI 3 "register_operand" "0")
18694                  (match_operand:DI 4 "register_operand" "1")))
18695    (set (mem:BLK (match_dup 3))
18696         (const_int 0))
18697    (use (match_operand:QI 2 "register_operand" "a"))
18698    (use (match_dup 4))
18699    (use (reg:SI DIRFLAG_REG))]
18700   "TARGET_64BIT"
18701   "{rep\;stosb|rep stosb}"
18702   [(set_attr "type" "str")
18703    (set_attr "prefix_rep" "1")
18704    (set_attr "memory" "store")
18705    (set_attr "mode" "QI")])
18706
18707 (define_expand "cmpstrnsi"
18708   [(set (match_operand:SI 0 "register_operand" "")
18709         (compare:SI (match_operand:BLK 1 "general_operand" "")
18710                     (match_operand:BLK 2 "general_operand" "")))
18711    (use (match_operand 3 "general_operand" ""))
18712    (use (match_operand 4 "immediate_operand" ""))]
18713   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18714 {
18715   rtx addr1, addr2, out, outlow, count, countreg, align;
18716
18717   /* Can't use this if the user has appropriated esi or edi.  */
18718   if (global_regs[4] || global_regs[5])
18719     FAIL;
18720
18721   out = operands[0];
18722   if (GET_CODE (out) != REG)
18723     out = gen_reg_rtx (SImode);
18724
18725   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18726   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18727   if (addr1 != XEXP (operands[1], 0))
18728     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18729   if (addr2 != XEXP (operands[2], 0))
18730     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18731
18732   count = operands[3];
18733   countreg = ix86_zero_extend_to_Pmode (count);
18734
18735   /* %%% Iff we are testing strict equality, we can use known alignment
18736      to good advantage.  This may be possible with combine, particularly
18737      once cc0 is dead.  */
18738   align = operands[4];
18739
18740   emit_insn (gen_cld ());
18741   if (GET_CODE (count) == CONST_INT)
18742     {
18743       if (INTVAL (count) == 0)
18744         {
18745           emit_move_insn (operands[0], const0_rtx);
18746           DONE;
18747         }
18748       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18749                                      operands[1], operands[2]));
18750     }
18751   else
18752     {
18753       if (TARGET_64BIT)
18754         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18755       else
18756         emit_insn (gen_cmpsi_1 (countreg, countreg));
18757       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18758                                   operands[1], operands[2]));
18759     }
18760
18761   outlow = gen_lowpart (QImode, out);
18762   emit_insn (gen_cmpintqi (outlow));
18763   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18764
18765   if (operands[0] != out)
18766     emit_move_insn (operands[0], out);
18767
18768   DONE;
18769 })
18770
18771 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18772
18773 (define_expand "cmpintqi"
18774   [(set (match_dup 1)
18775         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18776    (set (match_dup 2)
18777         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18778    (parallel [(set (match_operand:QI 0 "register_operand" "")
18779                    (minus:QI (match_dup 1)
18780                              (match_dup 2)))
18781               (clobber (reg:CC FLAGS_REG))])]
18782   ""
18783   "operands[1] = gen_reg_rtx (QImode);
18784    operands[2] = gen_reg_rtx (QImode);")
18785
18786 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18787 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18788
18789 (define_expand "cmpstrnqi_nz_1"
18790   [(parallel [(set (reg:CC FLAGS_REG)
18791                    (compare:CC (match_operand 4 "memory_operand" "")
18792                                (match_operand 5 "memory_operand" "")))
18793               (use (match_operand 2 "register_operand" ""))
18794               (use (match_operand:SI 3 "immediate_operand" ""))
18795               (use (reg:SI DIRFLAG_REG))
18796               (clobber (match_operand 0 "register_operand" ""))
18797               (clobber (match_operand 1 "register_operand" ""))
18798               (clobber (match_dup 2))])]
18799   ""
18800   "")
18801
18802 (define_insn "*cmpstrnqi_nz_1"
18803   [(set (reg:CC FLAGS_REG)
18804         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18805                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18806    (use (match_operand:SI 6 "register_operand" "2"))
18807    (use (match_operand:SI 3 "immediate_operand" "i"))
18808    (use (reg:SI DIRFLAG_REG))
18809    (clobber (match_operand:SI 0 "register_operand" "=S"))
18810    (clobber (match_operand:SI 1 "register_operand" "=D"))
18811    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18812   "!TARGET_64BIT"
18813   "repz{\;| }cmpsb"
18814   [(set_attr "type" "str")
18815    (set_attr "mode" "QI")
18816    (set_attr "prefix_rep" "1")])
18817
18818 (define_insn "*cmpstrnqi_nz_rex_1"
18819   [(set (reg:CC FLAGS_REG)
18820         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18821                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18822    (use (match_operand:DI 6 "register_operand" "2"))
18823    (use (match_operand:SI 3 "immediate_operand" "i"))
18824    (use (reg:SI DIRFLAG_REG))
18825    (clobber (match_operand:DI 0 "register_operand" "=S"))
18826    (clobber (match_operand:DI 1 "register_operand" "=D"))
18827    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18828   "TARGET_64BIT"
18829   "repz{\;| }cmpsb"
18830   [(set_attr "type" "str")
18831    (set_attr "mode" "QI")
18832    (set_attr "prefix_rep" "1")])
18833
18834 ;; The same, but the count is not known to not be zero.
18835
18836 (define_expand "cmpstrnqi_1"
18837   [(parallel [(set (reg:CC FLAGS_REG)
18838                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18839                                      (const_int 0))
18840                   (compare:CC (match_operand 4 "memory_operand" "")
18841                               (match_operand 5 "memory_operand" ""))
18842                   (const_int 0)))
18843               (use (match_operand:SI 3 "immediate_operand" ""))
18844               (use (reg:CC FLAGS_REG))
18845               (use (reg:SI DIRFLAG_REG))
18846               (clobber (match_operand 0 "register_operand" ""))
18847               (clobber (match_operand 1 "register_operand" ""))
18848               (clobber (match_dup 2))])]
18849   ""
18850   "")
18851
18852 (define_insn "*cmpstrnqi_1"
18853   [(set (reg:CC FLAGS_REG)
18854         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18855                              (const_int 0))
18856           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18857                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18858           (const_int 0)))
18859    (use (match_operand:SI 3 "immediate_operand" "i"))
18860    (use (reg:CC FLAGS_REG))
18861    (use (reg:SI DIRFLAG_REG))
18862    (clobber (match_operand:SI 0 "register_operand" "=S"))
18863    (clobber (match_operand:SI 1 "register_operand" "=D"))
18864    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18865   "!TARGET_64BIT"
18866   "repz{\;| }cmpsb"
18867   [(set_attr "type" "str")
18868    (set_attr "mode" "QI")
18869    (set_attr "prefix_rep" "1")])
18870
18871 (define_insn "*cmpstrnqi_rex_1"
18872   [(set (reg:CC FLAGS_REG)
18873         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18874                              (const_int 0))
18875           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18876                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18877           (const_int 0)))
18878    (use (match_operand:SI 3 "immediate_operand" "i"))
18879    (use (reg:CC FLAGS_REG))
18880    (use (reg:SI DIRFLAG_REG))
18881    (clobber (match_operand:DI 0 "register_operand" "=S"))
18882    (clobber (match_operand:DI 1 "register_operand" "=D"))
18883    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18884   "TARGET_64BIT"
18885   "repz{\;| }cmpsb"
18886   [(set_attr "type" "str")
18887    (set_attr "mode" "QI")
18888    (set_attr "prefix_rep" "1")])
18889
18890 (define_expand "strlensi"
18891   [(set (match_operand:SI 0 "register_operand" "")
18892         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18893                     (match_operand:QI 2 "immediate_operand" "")
18894                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18895   ""
18896 {
18897  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18898    DONE;
18899  else
18900    FAIL;
18901 })
18902
18903 (define_expand "strlendi"
18904   [(set (match_operand:DI 0 "register_operand" "")
18905         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18906                     (match_operand:QI 2 "immediate_operand" "")
18907                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18908   ""
18909 {
18910  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18911    DONE;
18912  else
18913    FAIL;
18914 })
18915
18916 (define_expand "strlenqi_1"
18917   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18918               (use (reg:SI DIRFLAG_REG))
18919               (clobber (match_operand 1 "register_operand" ""))
18920               (clobber (reg:CC FLAGS_REG))])]
18921   ""
18922   "")
18923
18924 (define_insn "*strlenqi_1"
18925   [(set (match_operand:SI 0 "register_operand" "=&c")
18926         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18927                     (match_operand:QI 2 "register_operand" "a")
18928                     (match_operand:SI 3 "immediate_operand" "i")
18929                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18930    (use (reg:SI DIRFLAG_REG))
18931    (clobber (match_operand:SI 1 "register_operand" "=D"))
18932    (clobber (reg:CC FLAGS_REG))]
18933   "!TARGET_64BIT"
18934   "repnz{\;| }scasb"
18935   [(set_attr "type" "str")
18936    (set_attr "mode" "QI")
18937    (set_attr "prefix_rep" "1")])
18938
18939 (define_insn "*strlenqi_rex_1"
18940   [(set (match_operand:DI 0 "register_operand" "=&c")
18941         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18942                     (match_operand:QI 2 "register_operand" "a")
18943                     (match_operand:DI 3 "immediate_operand" "i")
18944                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18945    (use (reg:SI DIRFLAG_REG))
18946    (clobber (match_operand:DI 1 "register_operand" "=D"))
18947    (clobber (reg:CC FLAGS_REG))]
18948   "TARGET_64BIT"
18949   "repnz{\;| }scasb"
18950   [(set_attr "type" "str")
18951    (set_attr "mode" "QI")
18952    (set_attr "prefix_rep" "1")])
18953
18954 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18955 ;; handled in combine, but it is not currently up to the task.
18956 ;; When used for their truth value, the cmpstrn* expanders generate
18957 ;; code like this:
18958 ;;
18959 ;;   repz cmpsb
18960 ;;   seta       %al
18961 ;;   setb       %dl
18962 ;;   cmpb       %al, %dl
18963 ;;   jcc        label
18964 ;;
18965 ;; The intermediate three instructions are unnecessary.
18966
18967 ;; This one handles cmpstrn*_nz_1...
18968 (define_peephole2
18969   [(parallel[
18970      (set (reg:CC FLAGS_REG)
18971           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18972                       (mem:BLK (match_operand 5 "register_operand" ""))))
18973      (use (match_operand 6 "register_operand" ""))
18974      (use (match_operand:SI 3 "immediate_operand" ""))
18975      (use (reg:SI DIRFLAG_REG))
18976      (clobber (match_operand 0 "register_operand" ""))
18977      (clobber (match_operand 1 "register_operand" ""))
18978      (clobber (match_operand 2 "register_operand" ""))])
18979    (set (match_operand:QI 7 "register_operand" "")
18980         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18981    (set (match_operand:QI 8 "register_operand" "")
18982         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18983    (set (reg FLAGS_REG)
18984         (compare (match_dup 7) (match_dup 8)))
18985   ]
18986   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18987   [(parallel[
18988      (set (reg:CC FLAGS_REG)
18989           (compare:CC (mem:BLK (match_dup 4))
18990                       (mem:BLK (match_dup 5))))
18991      (use (match_dup 6))
18992      (use (match_dup 3))
18993      (use (reg:SI DIRFLAG_REG))
18994      (clobber (match_dup 0))
18995      (clobber (match_dup 1))
18996      (clobber (match_dup 2))])]
18997   "")
18998
18999 ;; ...and this one handles cmpstrn*_1.
19000 (define_peephole2
19001   [(parallel[
19002      (set (reg:CC FLAGS_REG)
19003           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19004                                (const_int 0))
19005             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19006                         (mem:BLK (match_operand 5 "register_operand" "")))
19007             (const_int 0)))
19008      (use (match_operand:SI 3 "immediate_operand" ""))
19009      (use (reg:CC FLAGS_REG))
19010      (use (reg:SI DIRFLAG_REG))
19011      (clobber (match_operand 0 "register_operand" ""))
19012      (clobber (match_operand 1 "register_operand" ""))
19013      (clobber (match_operand 2 "register_operand" ""))])
19014    (set (match_operand:QI 7 "register_operand" "")
19015         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19016    (set (match_operand:QI 8 "register_operand" "")
19017         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19018    (set (reg FLAGS_REG)
19019         (compare (match_dup 7) (match_dup 8)))
19020   ]
19021   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19022   [(parallel[
19023      (set (reg:CC FLAGS_REG)
19024           (if_then_else:CC (ne (match_dup 6)
19025                                (const_int 0))
19026             (compare:CC (mem:BLK (match_dup 4))
19027                         (mem:BLK (match_dup 5)))
19028             (const_int 0)))
19029      (use (match_dup 3))
19030      (use (reg:CC FLAGS_REG))
19031      (use (reg:SI DIRFLAG_REG))
19032      (clobber (match_dup 0))
19033      (clobber (match_dup 1))
19034      (clobber (match_dup 2))])]
19035   "")
19036
19037
19038 \f
19039 ;; Conditional move instructions.
19040
19041 (define_expand "movdicc"
19042   [(set (match_operand:DI 0 "register_operand" "")
19043         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19044                          (match_operand:DI 2 "general_operand" "")
19045                          (match_operand:DI 3 "general_operand" "")))]
19046   "TARGET_64BIT"
19047   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19048
19049 (define_insn "x86_movdicc_0_m1_rex64"
19050   [(set (match_operand:DI 0 "register_operand" "=r")
19051         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19052           (const_int -1)
19053           (const_int 0)))
19054    (clobber (reg:CC FLAGS_REG))]
19055   "TARGET_64BIT"
19056   "sbb{q}\t%0, %0"
19057   ; Since we don't have the proper number of operands for an alu insn,
19058   ; fill in all the blanks.
19059   [(set_attr "type" "alu")
19060    (set_attr "pent_pair" "pu")
19061    (set_attr "memory" "none")
19062    (set_attr "imm_disp" "false")
19063    (set_attr "mode" "DI")
19064    (set_attr "length_immediate" "0")])
19065
19066 (define_insn "*movdicc_c_rex64"
19067   [(set (match_operand:DI 0 "register_operand" "=r,r")
19068         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
19069                                 [(reg FLAGS_REG) (const_int 0)])
19070                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19071                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19072   "TARGET_64BIT && TARGET_CMOVE
19073    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19074   "@
19075    cmov%O2%C1\t{%2, %0|%0, %2}
19076    cmov%O2%c1\t{%3, %0|%0, %3}"
19077   [(set_attr "type" "icmov")
19078    (set_attr "mode" "DI")])
19079
19080 (define_expand "movsicc"
19081   [(set (match_operand:SI 0 "register_operand" "")
19082         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19083                          (match_operand:SI 2 "general_operand" "")
19084                          (match_operand:SI 3 "general_operand" "")))]
19085   ""
19086   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19087
19088 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19089 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19090 ;; So just document what we're doing explicitly.
19091
19092 (define_insn "x86_movsicc_0_m1"
19093   [(set (match_operand:SI 0 "register_operand" "=r")
19094         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19095           (const_int -1)
19096           (const_int 0)))
19097    (clobber (reg:CC FLAGS_REG))]
19098   ""
19099   "sbb{l}\t%0, %0"
19100   ; Since we don't have the proper number of operands for an alu insn,
19101   ; fill in all the blanks.
19102   [(set_attr "type" "alu")
19103    (set_attr "pent_pair" "pu")
19104    (set_attr "memory" "none")
19105    (set_attr "imm_disp" "false")
19106    (set_attr "mode" "SI")
19107    (set_attr "length_immediate" "0")])
19108
19109 (define_insn "*movsicc_noc"
19110   [(set (match_operand:SI 0 "register_operand" "=r,r")
19111         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
19112                                 [(reg FLAGS_REG) (const_int 0)])
19113                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19114                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19115   "TARGET_CMOVE
19116    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19117   "@
19118    cmov%O2%C1\t{%2, %0|%0, %2}
19119    cmov%O2%c1\t{%3, %0|%0, %3}"
19120   [(set_attr "type" "icmov")
19121    (set_attr "mode" "SI")])
19122
19123 (define_expand "movhicc"
19124   [(set (match_operand:HI 0 "register_operand" "")
19125         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19126                          (match_operand:HI 2 "general_operand" "")
19127                          (match_operand:HI 3 "general_operand" "")))]
19128   "TARGET_HIMODE_MATH"
19129   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19130
19131 (define_insn "*movhicc_noc"
19132   [(set (match_operand:HI 0 "register_operand" "=r,r")
19133         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
19134                                 [(reg FLAGS_REG) (const_int 0)])
19135                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19136                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19137   "TARGET_CMOVE
19138    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19139   "@
19140    cmov%O2%C1\t{%2, %0|%0, %2}
19141    cmov%O2%c1\t{%3, %0|%0, %3}"
19142   [(set_attr "type" "icmov")
19143    (set_attr "mode" "HI")])
19144
19145 (define_expand "movqicc"
19146   [(set (match_operand:QI 0 "register_operand" "")
19147         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19148                          (match_operand:QI 2 "general_operand" "")
19149                          (match_operand:QI 3 "general_operand" "")))]
19150   "TARGET_QIMODE_MATH"
19151   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19152
19153 (define_insn_and_split "*movqicc_noc"
19154   [(set (match_operand:QI 0 "register_operand" "=r,r")
19155         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
19156                                 [(match_operand 4 "flags_reg_operand" "")
19157                                  (const_int 0)])
19158                       (match_operand:QI 2 "register_operand" "r,0")
19159                       (match_operand:QI 3 "register_operand" "0,r")))]
19160   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19161   "#"
19162   "&& reload_completed"
19163   [(set (match_dup 0)
19164         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19165                       (match_dup 2)
19166                       (match_dup 3)))]
19167   "operands[0] = gen_lowpart (SImode, operands[0]);
19168    operands[2] = gen_lowpart (SImode, operands[2]);
19169    operands[3] = gen_lowpart (SImode, operands[3]);"
19170   [(set_attr "type" "icmov")
19171    (set_attr "mode" "SI")])
19172
19173 (define_expand "movsfcc"
19174   [(set (match_operand:SF 0 "register_operand" "")
19175         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19176                          (match_operand:SF 2 "register_operand" "")
19177                          (match_operand:SF 3 "register_operand" "")))]
19178   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19179   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19180
19181 (define_insn "*movsfcc_1_387"
19182   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19183         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19184                                 [(reg FLAGS_REG) (const_int 0)])
19185                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19186                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19187   "TARGET_80387 && TARGET_CMOVE
19188    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19189   "@
19190    fcmov%F1\t{%2, %0|%0, %2}
19191    fcmov%f1\t{%3, %0|%0, %3}
19192    cmov%O2%C1\t{%2, %0|%0, %2}
19193    cmov%O2%c1\t{%3, %0|%0, %3}"
19194   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19195    (set_attr "mode" "SF,SF,SI,SI")])
19196
19197 (define_expand "movdfcc"
19198   [(set (match_operand:DF 0 "register_operand" "")
19199         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19200                          (match_operand:DF 2 "register_operand" "")
19201                          (match_operand:DF 3 "register_operand" "")))]
19202   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19203   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19204
19205 (define_insn "*movdfcc_1"
19206   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19207         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19208                                 [(reg FLAGS_REG) (const_int 0)])
19209                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19210                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19211   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19212    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19213   "@
19214    fcmov%F1\t{%2, %0|%0, %2}
19215    fcmov%f1\t{%3, %0|%0, %3}
19216    #
19217    #"
19218   [(set_attr "type" "fcmov,fcmov,multi,multi")
19219    (set_attr "mode" "DF")])
19220
19221 (define_insn "*movdfcc_1_rex64"
19222   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19223         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19224                                 [(reg FLAGS_REG) (const_int 0)])
19225                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19226                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19227   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19228    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19229   "@
19230    fcmov%F1\t{%2, %0|%0, %2}
19231    fcmov%f1\t{%3, %0|%0, %3}
19232    cmov%O2%C1\t{%2, %0|%0, %2}
19233    cmov%O2%c1\t{%3, %0|%0, %3}"
19234   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19235    (set_attr "mode" "DF")])
19236
19237 (define_split
19238   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19239         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19240                                 [(match_operand 4 "flags_reg_operand" "")
19241                                  (const_int 0)])
19242                       (match_operand:DF 2 "nonimmediate_operand" "")
19243                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19244   "!TARGET_64BIT && reload_completed"
19245   [(set (match_dup 2)
19246         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19247                       (match_dup 5)
19248                       (match_dup 7)))
19249    (set (match_dup 3)
19250         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19251                       (match_dup 6)
19252                       (match_dup 8)))]
19253   "split_di (operands+2, 1, operands+5, operands+6);
19254    split_di (operands+3, 1, operands+7, operands+8);
19255    split_di (operands, 1, operands+2, operands+3);")
19256
19257 (define_expand "movxfcc"
19258   [(set (match_operand:XF 0 "register_operand" "")
19259         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19260                          (match_operand:XF 2 "register_operand" "")
19261                          (match_operand:XF 3 "register_operand" "")))]
19262   "TARGET_80387 && TARGET_CMOVE"
19263   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19264
19265 (define_insn "*movxfcc_1"
19266   [(set (match_operand:XF 0 "register_operand" "=f,f")
19267         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19268                                 [(reg FLAGS_REG) (const_int 0)])
19269                       (match_operand:XF 2 "register_operand" "f,0")
19270                       (match_operand:XF 3 "register_operand" "0,f")))]
19271   "TARGET_80387 && TARGET_CMOVE"
19272   "@
19273    fcmov%F1\t{%2, %0|%0, %2}
19274    fcmov%f1\t{%3, %0|%0, %3}"
19275   [(set_attr "type" "fcmov")
19276    (set_attr "mode" "XF")])
19277
19278 ;; These versions of the min/max patterns are intentionally ignorant of
19279 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19280 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19281 ;; are undefined in this condition, we're certain this is correct.
19282
19283 (define_insn "sminsf3"
19284   [(set (match_operand:SF 0 "register_operand" "=x")
19285         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19286                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19287   "TARGET_SSE_MATH"
19288   "minss\t{%2, %0|%0, %2}"
19289   [(set_attr "type" "sseadd")
19290    (set_attr "mode" "SF")])
19291
19292 (define_insn "smaxsf3"
19293   [(set (match_operand:SF 0 "register_operand" "=x")
19294         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19295                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19296   "TARGET_SSE_MATH"
19297   "maxss\t{%2, %0|%0, %2}"
19298   [(set_attr "type" "sseadd")
19299    (set_attr "mode" "SF")])
19300
19301 (define_insn "smindf3"
19302   [(set (match_operand:DF 0 "register_operand" "=x")
19303         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19304                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19305   "TARGET_SSE2 && TARGET_SSE_MATH"
19306   "minsd\t{%2, %0|%0, %2}"
19307   [(set_attr "type" "sseadd")
19308    (set_attr "mode" "DF")])
19309
19310 (define_insn "smaxdf3"
19311   [(set (match_operand:DF 0 "register_operand" "=x")
19312         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19313                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19314   "TARGET_SSE2 && TARGET_SSE_MATH"
19315   "maxsd\t{%2, %0|%0, %2}"
19316   [(set_attr "type" "sseadd")
19317    (set_attr "mode" "DF")])
19318
19319 ;; These versions of the min/max patterns implement exactly the operations
19320 ;;   min = (op1 < op2 ? op1 : op2)
19321 ;;   max = (!(op1 < op2) ? op1 : op2)
19322 ;; Their operands are not commutative, and thus they may be used in the
19323 ;; presence of -0.0 and NaN.
19324
19325 (define_insn "*ieee_sminsf3"
19326   [(set (match_operand:SF 0 "register_operand" "=x")
19327         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19328                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19329                    UNSPEC_IEEE_MIN))]
19330   "TARGET_SSE_MATH"
19331   "minss\t{%2, %0|%0, %2}"
19332   [(set_attr "type" "sseadd")
19333    (set_attr "mode" "SF")])
19334
19335 (define_insn "*ieee_smaxsf3"
19336   [(set (match_operand:SF 0 "register_operand" "=x")
19337         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19338                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19339                    UNSPEC_IEEE_MAX))]
19340   "TARGET_SSE_MATH"
19341   "maxss\t{%2, %0|%0, %2}"
19342   [(set_attr "type" "sseadd")
19343    (set_attr "mode" "SF")])
19344
19345 (define_insn "*ieee_smindf3"
19346   [(set (match_operand:DF 0 "register_operand" "=x")
19347         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19348                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19349                    UNSPEC_IEEE_MIN))]
19350   "TARGET_SSE2 && TARGET_SSE_MATH"
19351   "minsd\t{%2, %0|%0, %2}"
19352   [(set_attr "type" "sseadd")
19353    (set_attr "mode" "DF")])
19354
19355 (define_insn "*ieee_smaxdf3"
19356   [(set (match_operand:DF 0 "register_operand" "=x")
19357         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19358                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19359                    UNSPEC_IEEE_MAX))]
19360   "TARGET_SSE2 && TARGET_SSE_MATH"
19361   "maxsd\t{%2, %0|%0, %2}"
19362   [(set_attr "type" "sseadd")
19363    (set_attr "mode" "DF")])
19364
19365 ;; Make two stack loads independent:
19366 ;;   fld aa              fld aa
19367 ;;   fld %st(0)     ->   fld bb
19368 ;;   fmul bb             fmul %st(1), %st
19369 ;;
19370 ;; Actually we only match the last two instructions for simplicity.
19371 (define_peephole2
19372   [(set (match_operand 0 "fp_register_operand" "")
19373         (match_operand 1 "fp_register_operand" ""))
19374    (set (match_dup 0)
19375         (match_operator 2 "binary_fp_operator"
19376            [(match_dup 0)
19377             (match_operand 3 "memory_operand" "")]))]
19378   "REGNO (operands[0]) != REGNO (operands[1])"
19379   [(set (match_dup 0) (match_dup 3))
19380    (set (match_dup 0) (match_dup 4))]
19381
19382   ;; The % modifier is not operational anymore in peephole2's, so we have to
19383   ;; swap the operands manually in the case of addition and multiplication.
19384   "if (COMMUTATIVE_ARITH_P (operands[2]))
19385      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19386                                  operands[0], operands[1]);
19387    else
19388      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19389                                  operands[1], operands[0]);")
19390
19391 ;; Conditional addition patterns
19392 (define_expand "addqicc"
19393   [(match_operand:QI 0 "register_operand" "")
19394    (match_operand 1 "comparison_operator" "")
19395    (match_operand:QI 2 "register_operand" "")
19396    (match_operand:QI 3 "const_int_operand" "")]
19397   ""
19398   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19399
19400 (define_expand "addhicc"
19401   [(match_operand:HI 0 "register_operand" "")
19402    (match_operand 1 "comparison_operator" "")
19403    (match_operand:HI 2 "register_operand" "")
19404    (match_operand:HI 3 "const_int_operand" "")]
19405   ""
19406   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19407
19408 (define_expand "addsicc"
19409   [(match_operand:SI 0 "register_operand" "")
19410    (match_operand 1 "comparison_operator" "")
19411    (match_operand:SI 2 "register_operand" "")
19412    (match_operand:SI 3 "const_int_operand" "")]
19413   ""
19414   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19415
19416 (define_expand "adddicc"
19417   [(match_operand:DI 0 "register_operand" "")
19418    (match_operand 1 "comparison_operator" "")
19419    (match_operand:DI 2 "register_operand" "")
19420    (match_operand:DI 3 "const_int_operand" "")]
19421   "TARGET_64BIT"
19422   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19423
19424 \f
19425 ;; Misc patterns (?)
19426
19427 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19428 ;; Otherwise there will be nothing to keep
19429 ;; 
19430 ;; [(set (reg ebp) (reg esp))]
19431 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19432 ;;  (clobber (eflags)]
19433 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19434 ;;
19435 ;; in proper program order.
19436 (define_insn "pro_epilogue_adjust_stack_1"
19437   [(set (match_operand:SI 0 "register_operand" "=r,r")
19438         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19439                  (match_operand:SI 2 "immediate_operand" "i,i")))
19440    (clobber (reg:CC FLAGS_REG))
19441    (clobber (mem:BLK (scratch)))]
19442   "!TARGET_64BIT"
19443 {
19444   switch (get_attr_type (insn))
19445     {
19446     case TYPE_IMOV:
19447       return "mov{l}\t{%1, %0|%0, %1}";
19448
19449     case TYPE_ALU:
19450       if (GET_CODE (operands[2]) == CONST_INT
19451           && (INTVAL (operands[2]) == 128
19452               || (INTVAL (operands[2]) < 0
19453                   && INTVAL (operands[2]) != -128)))
19454         {
19455           operands[2] = GEN_INT (-INTVAL (operands[2]));
19456           return "sub{l}\t{%2, %0|%0, %2}";
19457         }
19458       return "add{l}\t{%2, %0|%0, %2}";
19459
19460     case TYPE_LEA:
19461       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19462       return "lea{l}\t{%a2, %0|%0, %a2}";
19463
19464     default:
19465       gcc_unreachable ();
19466     }
19467 }
19468   [(set (attr "type")
19469         (cond [(eq_attr "alternative" "0")
19470                  (const_string "alu")
19471                (match_operand:SI 2 "const0_operand" "")
19472                  (const_string "imov")
19473               ]
19474               (const_string "lea")))
19475    (set_attr "mode" "SI")])
19476
19477 (define_insn "pro_epilogue_adjust_stack_rex64"
19478   [(set (match_operand:DI 0 "register_operand" "=r,r")
19479         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19480                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19481    (clobber (reg:CC FLAGS_REG))
19482    (clobber (mem:BLK (scratch)))]
19483   "TARGET_64BIT"
19484 {
19485   switch (get_attr_type (insn))
19486     {
19487     case TYPE_IMOV:
19488       return "mov{q}\t{%1, %0|%0, %1}";
19489
19490     case TYPE_ALU:
19491       if (GET_CODE (operands[2]) == CONST_INT
19492           /* Avoid overflows.  */
19493           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19494           && (INTVAL (operands[2]) == 128
19495               || (INTVAL (operands[2]) < 0
19496                   && INTVAL (operands[2]) != -128)))
19497         {
19498           operands[2] = GEN_INT (-INTVAL (operands[2]));
19499           return "sub{q}\t{%2, %0|%0, %2}";
19500         }
19501       return "add{q}\t{%2, %0|%0, %2}";
19502
19503     case TYPE_LEA:
19504       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19505       return "lea{q}\t{%a2, %0|%0, %a2}";
19506
19507     default:
19508       gcc_unreachable ();
19509     }
19510 }
19511   [(set (attr "type")
19512         (cond [(eq_attr "alternative" "0")
19513                  (const_string "alu")
19514                (match_operand:DI 2 "const0_operand" "")
19515                  (const_string "imov")
19516               ]
19517               (const_string "lea")))
19518    (set_attr "mode" "DI")])
19519
19520 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19521   [(set (match_operand:DI 0 "register_operand" "=r,r")
19522         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19523                  (match_operand:DI 3 "immediate_operand" "i,i")))
19524    (use (match_operand:DI 2 "register_operand" "r,r"))
19525    (clobber (reg:CC FLAGS_REG))
19526    (clobber (mem:BLK (scratch)))]
19527   "TARGET_64BIT"
19528 {
19529   switch (get_attr_type (insn))
19530     {
19531     case TYPE_ALU:
19532       return "add{q}\t{%2, %0|%0, %2}";
19533
19534     case TYPE_LEA:
19535       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19536       return "lea{q}\t{%a2, %0|%0, %a2}";
19537
19538     default:
19539       gcc_unreachable ();
19540     }
19541 }
19542   [(set_attr "type" "alu,lea")
19543    (set_attr "mode" "DI")])
19544
19545 (define_expand "allocate_stack_worker"
19546   [(match_operand:SI 0 "register_operand" "")]
19547   "TARGET_STACK_PROBE"
19548 {
19549   if (reload_completed)
19550     {
19551       if (TARGET_64BIT)
19552         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19553       else
19554         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19555     }
19556   else
19557     {
19558       if (TARGET_64BIT)
19559         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19560       else
19561         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19562     }
19563   DONE;
19564 })
19565
19566 (define_insn "allocate_stack_worker_1"
19567   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19568     UNSPECV_STACK_PROBE)
19569    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19570    (clobber (match_scratch:SI 1 "=0"))
19571    (clobber (reg:CC FLAGS_REG))]
19572   "!TARGET_64BIT && TARGET_STACK_PROBE"
19573   "call\t__alloca"
19574   [(set_attr "type" "multi")
19575    (set_attr "length" "5")])
19576
19577 (define_expand "allocate_stack_worker_postreload"
19578   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19579                                     UNSPECV_STACK_PROBE)
19580               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19581               (clobber (match_dup 0))
19582               (clobber (reg:CC FLAGS_REG))])]
19583   ""
19584   "")
19585
19586 (define_insn "allocate_stack_worker_rex64"
19587   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19588     UNSPECV_STACK_PROBE)
19589    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19590    (clobber (match_scratch:DI 1 "=0"))
19591    (clobber (reg:CC FLAGS_REG))]
19592   "TARGET_64BIT && TARGET_STACK_PROBE"
19593   "call\t__alloca"
19594   [(set_attr "type" "multi")
19595    (set_attr "length" "5")])
19596
19597 (define_expand "allocate_stack_worker_rex64_postreload"
19598   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19599                                     UNSPECV_STACK_PROBE)
19600               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19601               (clobber (match_dup 0))
19602               (clobber (reg:CC FLAGS_REG))])]
19603   ""
19604   "")
19605
19606 (define_expand "allocate_stack"
19607   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19608                    (minus:SI (reg:SI SP_REG)
19609                              (match_operand:SI 1 "general_operand" "")))
19610               (clobber (reg:CC FLAGS_REG))])
19611    (parallel [(set (reg:SI SP_REG)
19612                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19613               (clobber (reg:CC FLAGS_REG))])]
19614   "TARGET_STACK_PROBE"
19615 {
19616 #ifdef CHECK_STACK_LIMIT
19617   if (GET_CODE (operands[1]) == CONST_INT
19618       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19619     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19620                            operands[1]));
19621   else 
19622 #endif
19623     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19624                                                             operands[1])));
19625
19626   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19627   DONE;
19628 })
19629
19630 (define_expand "builtin_setjmp_receiver"
19631   [(label_ref (match_operand 0 "" ""))]
19632   "!TARGET_64BIT && flag_pic"
19633 {
19634   if (TARGET_MACHO)
19635     {
19636       rtx xops[3];
19637       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19638       rtx label_rtx = gen_label_rtx ();
19639       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19640       xops[0] = xops[1] = picreg;
19641       xops[2] = gen_rtx_CONST (SImode,
19642                   gen_rtx_MINUS (SImode,
19643                     gen_rtx_LABEL_REF (SImode, label_rtx),
19644                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19645       ix86_expand_binary_operator (MINUS, SImode, xops);
19646     }
19647   else
19648     emit_insn (gen_set_got (pic_offset_table_rtx));
19649   DONE;
19650 })
19651 \f
19652 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19653
19654 (define_split
19655   [(set (match_operand 0 "register_operand" "")
19656         (match_operator 3 "promotable_binary_operator"
19657            [(match_operand 1 "register_operand" "")
19658             (match_operand 2 "aligned_operand" "")]))
19659    (clobber (reg:CC FLAGS_REG))]
19660   "! TARGET_PARTIAL_REG_STALL && reload_completed
19661    && ((GET_MODE (operands[0]) == HImode 
19662         && ((!optimize_size && !TARGET_FAST_PREFIX)
19663             /* ??? next two lines just !satisfies_constraint_K (...) */
19664             || GET_CODE (operands[2]) != CONST_INT
19665             || satisfies_constraint_K (operands[2])))
19666        || (GET_MODE (operands[0]) == QImode 
19667            && (TARGET_PROMOTE_QImode || optimize_size)))"
19668   [(parallel [(set (match_dup 0)
19669                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19670               (clobber (reg:CC FLAGS_REG))])]
19671   "operands[0] = gen_lowpart (SImode, operands[0]);
19672    operands[1] = gen_lowpart (SImode, operands[1]);
19673    if (GET_CODE (operands[3]) != ASHIFT)
19674      operands[2] = gen_lowpart (SImode, operands[2]);
19675    PUT_MODE (operands[3], SImode);")
19676
19677 ; Promote the QImode tests, as i386 has encoding of the AND
19678 ; instruction with 32-bit sign-extended immediate and thus the
19679 ; instruction size is unchanged, except in the %eax case for
19680 ; which it is increased by one byte, hence the ! optimize_size.
19681 (define_split
19682   [(set (match_operand 0 "flags_reg_operand" "")
19683         (match_operator 2 "compare_operator"
19684           [(and (match_operand 3 "aligned_operand" "")
19685                 (match_operand 4 "const_int_operand" ""))
19686            (const_int 0)]))
19687    (set (match_operand 1 "register_operand" "")
19688         (and (match_dup 3) (match_dup 4)))]
19689   "! TARGET_PARTIAL_REG_STALL && reload_completed
19690    /* Ensure that the operand will remain sign-extended immediate.  */
19691    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19692    && ! optimize_size
19693    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19694        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19695   [(parallel [(set (match_dup 0)
19696                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19697                                     (const_int 0)]))
19698               (set (match_dup 1)
19699                    (and:SI (match_dup 3) (match_dup 4)))])]
19700 {
19701   operands[4]
19702     = gen_int_mode (INTVAL (operands[4])
19703                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19704   operands[1] = gen_lowpart (SImode, operands[1]);
19705   operands[3] = gen_lowpart (SImode, operands[3]);
19706 })
19707
19708 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19709 ; the TEST instruction with 32-bit sign-extended immediate and thus
19710 ; the instruction size would at least double, which is not what we
19711 ; want even with ! optimize_size.
19712 (define_split
19713   [(set (match_operand 0 "flags_reg_operand" "")
19714         (match_operator 1 "compare_operator"
19715           [(and (match_operand:HI 2 "aligned_operand" "")
19716                 (match_operand:HI 3 "const_int_operand" ""))
19717            (const_int 0)]))]
19718   "! TARGET_PARTIAL_REG_STALL && reload_completed
19719    /* Ensure that the operand will remain sign-extended immediate.  */
19720    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19721    && ! TARGET_FAST_PREFIX
19722    && ! optimize_size"
19723   [(set (match_dup 0)
19724         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19725                          (const_int 0)]))]
19726 {
19727   operands[3]
19728     = gen_int_mode (INTVAL (operands[3])
19729                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19730   operands[2] = gen_lowpart (SImode, operands[2]);
19731 })
19732
19733 (define_split
19734   [(set (match_operand 0 "register_operand" "")
19735         (neg (match_operand 1 "register_operand" "")))
19736    (clobber (reg:CC FLAGS_REG))]
19737   "! TARGET_PARTIAL_REG_STALL && reload_completed
19738    && (GET_MODE (operands[0]) == HImode
19739        || (GET_MODE (operands[0]) == QImode 
19740            && (TARGET_PROMOTE_QImode || optimize_size)))"
19741   [(parallel [(set (match_dup 0)
19742                    (neg:SI (match_dup 1)))
19743               (clobber (reg:CC FLAGS_REG))])]
19744   "operands[0] = gen_lowpart (SImode, operands[0]);
19745    operands[1] = gen_lowpart (SImode, operands[1]);")
19746
19747 (define_split
19748   [(set (match_operand 0 "register_operand" "")
19749         (not (match_operand 1 "register_operand" "")))]
19750   "! TARGET_PARTIAL_REG_STALL && reload_completed
19751    && (GET_MODE (operands[0]) == HImode
19752        || (GET_MODE (operands[0]) == QImode 
19753            && (TARGET_PROMOTE_QImode || optimize_size)))"
19754   [(set (match_dup 0)
19755         (not:SI (match_dup 1)))]
19756   "operands[0] = gen_lowpart (SImode, operands[0]);
19757    operands[1] = gen_lowpart (SImode, operands[1]);")
19758
19759 (define_split 
19760   [(set (match_operand 0 "register_operand" "")
19761         (if_then_else (match_operator 1 "comparison_operator" 
19762                                 [(reg FLAGS_REG) (const_int 0)])
19763                       (match_operand 2 "register_operand" "")
19764                       (match_operand 3 "register_operand" "")))]
19765   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19766    && (GET_MODE (operands[0]) == HImode
19767        || (GET_MODE (operands[0]) == QImode 
19768            && (TARGET_PROMOTE_QImode || optimize_size)))"
19769   [(set (match_dup 0)
19770         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19771   "operands[0] = gen_lowpart (SImode, operands[0]);
19772    operands[2] = gen_lowpart (SImode, operands[2]);
19773    operands[3] = gen_lowpart (SImode, operands[3]);")
19774                         
19775 \f
19776 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19777 ;; transform a complex memory operation into two memory to register operations.
19778
19779 ;; Don't push memory operands
19780 (define_peephole2
19781   [(set (match_operand:SI 0 "push_operand" "")
19782         (match_operand:SI 1 "memory_operand" ""))
19783    (match_scratch:SI 2 "r")]
19784   "!optimize_size && !TARGET_PUSH_MEMORY
19785    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19786   [(set (match_dup 2) (match_dup 1))
19787    (set (match_dup 0) (match_dup 2))]
19788   "")
19789
19790 (define_peephole2
19791   [(set (match_operand:DI 0 "push_operand" "")
19792         (match_operand:DI 1 "memory_operand" ""))
19793    (match_scratch:DI 2 "r")]
19794   "!optimize_size && !TARGET_PUSH_MEMORY
19795    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19796   [(set (match_dup 2) (match_dup 1))
19797    (set (match_dup 0) (match_dup 2))]
19798   "")
19799
19800 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19801 ;; SImode pushes.
19802 (define_peephole2
19803   [(set (match_operand:SF 0 "push_operand" "")
19804         (match_operand:SF 1 "memory_operand" ""))
19805    (match_scratch:SF 2 "r")]
19806   "!optimize_size && !TARGET_PUSH_MEMORY
19807    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19808   [(set (match_dup 2) (match_dup 1))
19809    (set (match_dup 0) (match_dup 2))]
19810   "")
19811
19812 (define_peephole2
19813   [(set (match_operand:HI 0 "push_operand" "")
19814         (match_operand:HI 1 "memory_operand" ""))
19815    (match_scratch:HI 2 "r")]
19816   "!optimize_size && !TARGET_PUSH_MEMORY
19817    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19818   [(set (match_dup 2) (match_dup 1))
19819    (set (match_dup 0) (match_dup 2))]
19820   "")
19821
19822 (define_peephole2
19823   [(set (match_operand:QI 0 "push_operand" "")
19824         (match_operand:QI 1 "memory_operand" ""))
19825    (match_scratch:QI 2 "q")]
19826   "!optimize_size && !TARGET_PUSH_MEMORY
19827    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19828   [(set (match_dup 2) (match_dup 1))
19829    (set (match_dup 0) (match_dup 2))]
19830   "")
19831
19832 ;; Don't move an immediate directly to memory when the instruction
19833 ;; gets too big.
19834 (define_peephole2
19835   [(match_scratch:SI 1 "r")
19836    (set (match_operand:SI 0 "memory_operand" "")
19837         (const_int 0))]
19838   "! optimize_size
19839    && ! TARGET_USE_MOV0
19840    && TARGET_SPLIT_LONG_MOVES
19841    && get_attr_length (insn) >= ix86_cost->large_insn
19842    && peep2_regno_dead_p (0, FLAGS_REG)"
19843   [(parallel [(set (match_dup 1) (const_int 0))
19844               (clobber (reg:CC FLAGS_REG))])
19845    (set (match_dup 0) (match_dup 1))]
19846   "")
19847
19848 (define_peephole2
19849   [(match_scratch:HI 1 "r")
19850    (set (match_operand:HI 0 "memory_operand" "")
19851         (const_int 0))]
19852   "! optimize_size
19853    && ! TARGET_USE_MOV0
19854    && TARGET_SPLIT_LONG_MOVES
19855    && get_attr_length (insn) >= ix86_cost->large_insn
19856    && peep2_regno_dead_p (0, FLAGS_REG)"
19857   [(parallel [(set (match_dup 2) (const_int 0))
19858               (clobber (reg:CC FLAGS_REG))])
19859    (set (match_dup 0) (match_dup 1))]
19860   "operands[2] = gen_lowpart (SImode, operands[1]);")
19861
19862 (define_peephole2
19863   [(match_scratch:QI 1 "q")
19864    (set (match_operand:QI 0 "memory_operand" "")
19865         (const_int 0))]
19866   "! optimize_size
19867    && ! TARGET_USE_MOV0
19868    && TARGET_SPLIT_LONG_MOVES
19869    && get_attr_length (insn) >= ix86_cost->large_insn
19870    && peep2_regno_dead_p (0, FLAGS_REG)"
19871   [(parallel [(set (match_dup 2) (const_int 0))
19872               (clobber (reg:CC FLAGS_REG))])
19873    (set (match_dup 0) (match_dup 1))]
19874   "operands[2] = gen_lowpart (SImode, operands[1]);")
19875
19876 (define_peephole2
19877   [(match_scratch:SI 2 "r")
19878    (set (match_operand:SI 0 "memory_operand" "")
19879         (match_operand:SI 1 "immediate_operand" ""))]
19880   "! optimize_size
19881    && get_attr_length (insn) >= ix86_cost->large_insn
19882    && TARGET_SPLIT_LONG_MOVES"
19883   [(set (match_dup 2) (match_dup 1))
19884    (set (match_dup 0) (match_dup 2))]
19885   "")
19886
19887 (define_peephole2
19888   [(match_scratch:HI 2 "r")
19889    (set (match_operand:HI 0 "memory_operand" "")
19890         (match_operand:HI 1 "immediate_operand" ""))]
19891   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19892   && TARGET_SPLIT_LONG_MOVES"
19893   [(set (match_dup 2) (match_dup 1))
19894    (set (match_dup 0) (match_dup 2))]
19895   "")
19896
19897 (define_peephole2
19898   [(match_scratch:QI 2 "q")
19899    (set (match_operand:QI 0 "memory_operand" "")
19900         (match_operand:QI 1 "immediate_operand" ""))]
19901   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19902   && TARGET_SPLIT_LONG_MOVES"
19903   [(set (match_dup 2) (match_dup 1))
19904    (set (match_dup 0) (match_dup 2))]
19905   "")
19906
19907 ;; Don't compare memory with zero, load and use a test instead.
19908 (define_peephole2
19909   [(set (match_operand 0 "flags_reg_operand" "")
19910         (match_operator 1 "compare_operator"
19911           [(match_operand:SI 2 "memory_operand" "")
19912            (const_int 0)]))
19913    (match_scratch:SI 3 "r")]
19914   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19915   [(set (match_dup 3) (match_dup 2))
19916    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19917   "")
19918
19919 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19920 ;; Don't split NOTs with a displacement operand, because resulting XOR
19921 ;; will not be pairable anyway.
19922 ;;
19923 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19924 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19925 ;; so this split helps here as well.
19926 ;;
19927 ;; Note: Can't do this as a regular split because we can't get proper
19928 ;; lifetime information then.
19929
19930 (define_peephole2
19931   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19932         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19933   "!optimize_size
19934    && peep2_regno_dead_p (0, FLAGS_REG)
19935    && ((TARGET_PENTIUM 
19936         && (GET_CODE (operands[0]) != MEM
19937             || !memory_displacement_operand (operands[0], SImode)))
19938        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19939   [(parallel [(set (match_dup 0)
19940                    (xor:SI (match_dup 1) (const_int -1)))
19941               (clobber (reg:CC FLAGS_REG))])]
19942   "")
19943
19944 (define_peephole2
19945   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19946         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19947   "!optimize_size
19948    && peep2_regno_dead_p (0, FLAGS_REG)
19949    && ((TARGET_PENTIUM 
19950         && (GET_CODE (operands[0]) != MEM
19951             || !memory_displacement_operand (operands[0], HImode)))
19952        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19953   [(parallel [(set (match_dup 0)
19954                    (xor:HI (match_dup 1) (const_int -1)))
19955               (clobber (reg:CC FLAGS_REG))])]
19956   "")
19957
19958 (define_peephole2
19959   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19960         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19961   "!optimize_size
19962    && peep2_regno_dead_p (0, FLAGS_REG)
19963    && ((TARGET_PENTIUM 
19964         && (GET_CODE (operands[0]) != MEM
19965             || !memory_displacement_operand (operands[0], QImode)))
19966        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19967   [(parallel [(set (match_dup 0)
19968                    (xor:QI (match_dup 1) (const_int -1)))
19969               (clobber (reg:CC FLAGS_REG))])]
19970   "")
19971
19972 ;; Non pairable "test imm, reg" instructions can be translated to
19973 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19974 ;; byte opcode instead of two, have a short form for byte operands),
19975 ;; so do it for other CPUs as well.  Given that the value was dead,
19976 ;; this should not create any new dependencies.  Pass on the sub-word
19977 ;; versions if we're concerned about partial register stalls.
19978
19979 (define_peephole2
19980   [(set (match_operand 0 "flags_reg_operand" "")
19981         (match_operator 1 "compare_operator"
19982           [(and:SI (match_operand:SI 2 "register_operand" "")
19983                    (match_operand:SI 3 "immediate_operand" ""))
19984            (const_int 0)]))]
19985   "ix86_match_ccmode (insn, CCNOmode)
19986    && (true_regnum (operands[2]) != 0
19987        || satisfies_constraint_K (operands[3]))
19988    && peep2_reg_dead_p (1, operands[2])"
19989   [(parallel
19990      [(set (match_dup 0)
19991            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19992                             (const_int 0)]))
19993       (set (match_dup 2)
19994            (and:SI (match_dup 2) (match_dup 3)))])]
19995   "")
19996
19997 ;; We don't need to handle HImode case, because it will be promoted to SImode
19998 ;; on ! TARGET_PARTIAL_REG_STALL
19999
20000 (define_peephole2
20001   [(set (match_operand 0 "flags_reg_operand" "")
20002         (match_operator 1 "compare_operator"
20003           [(and:QI (match_operand:QI 2 "register_operand" "")
20004                    (match_operand:QI 3 "immediate_operand" ""))
20005            (const_int 0)]))]
20006   "! TARGET_PARTIAL_REG_STALL
20007    && ix86_match_ccmode (insn, CCNOmode)
20008    && true_regnum (operands[2]) != 0
20009    && peep2_reg_dead_p (1, operands[2])"
20010   [(parallel
20011      [(set (match_dup 0)
20012            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20013                             (const_int 0)]))
20014       (set (match_dup 2)
20015            (and:QI (match_dup 2) (match_dup 3)))])]
20016   "")
20017
20018 (define_peephole2
20019   [(set (match_operand 0 "flags_reg_operand" "")
20020         (match_operator 1 "compare_operator"
20021           [(and:SI
20022              (zero_extract:SI
20023                (match_operand 2 "ext_register_operand" "")
20024                (const_int 8)
20025                (const_int 8))
20026              (match_operand 3 "const_int_operand" ""))
20027            (const_int 0)]))]
20028   "! TARGET_PARTIAL_REG_STALL
20029    && ix86_match_ccmode (insn, CCNOmode)
20030    && true_regnum (operands[2]) != 0
20031    && peep2_reg_dead_p (1, operands[2])"
20032   [(parallel [(set (match_dup 0)
20033                    (match_op_dup 1
20034                      [(and:SI
20035                         (zero_extract:SI
20036                           (match_dup 2)
20037                           (const_int 8)
20038                           (const_int 8))
20039                         (match_dup 3))
20040                       (const_int 0)]))
20041               (set (zero_extract:SI (match_dup 2)
20042                                     (const_int 8)
20043                                     (const_int 8))
20044                    (and:SI 
20045                      (zero_extract:SI
20046                        (match_dup 2)
20047                        (const_int 8)
20048                        (const_int 8))
20049                      (match_dup 3)))])]
20050   "")
20051
20052 ;; Don't do logical operations with memory inputs.
20053 (define_peephole2
20054   [(match_scratch:SI 2 "r")
20055    (parallel [(set (match_operand:SI 0 "register_operand" "")
20056                    (match_operator:SI 3 "arith_or_logical_operator"
20057                      [(match_dup 0)
20058                       (match_operand:SI 1 "memory_operand" "")]))
20059               (clobber (reg:CC FLAGS_REG))])]
20060   "! optimize_size && ! TARGET_READ_MODIFY"
20061   [(set (match_dup 2) (match_dup 1))
20062    (parallel [(set (match_dup 0)
20063                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20064               (clobber (reg:CC FLAGS_REG))])]
20065   "")
20066
20067 (define_peephole2
20068   [(match_scratch:SI 2 "r")
20069    (parallel [(set (match_operand:SI 0 "register_operand" "")
20070                    (match_operator:SI 3 "arith_or_logical_operator"
20071                      [(match_operand:SI 1 "memory_operand" "")
20072                       (match_dup 0)]))
20073               (clobber (reg:CC FLAGS_REG))])]
20074   "! optimize_size && ! TARGET_READ_MODIFY"
20075   [(set (match_dup 2) (match_dup 1))
20076    (parallel [(set (match_dup 0)
20077                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20078               (clobber (reg:CC FLAGS_REG))])]
20079   "")
20080
20081 ; Don't do logical operations with memory outputs
20082 ;
20083 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20084 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20085 ; the same decoder scheduling characteristics as the original.
20086
20087 (define_peephole2
20088   [(match_scratch:SI 2 "r")
20089    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20090                    (match_operator:SI 3 "arith_or_logical_operator"
20091                      [(match_dup 0)
20092                       (match_operand:SI 1 "nonmemory_operand" "")]))
20093               (clobber (reg:CC FLAGS_REG))])]
20094   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20095   [(set (match_dup 2) (match_dup 0))
20096    (parallel [(set (match_dup 2)
20097                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20098               (clobber (reg:CC FLAGS_REG))])
20099    (set (match_dup 0) (match_dup 2))]
20100   "")
20101
20102 (define_peephole2
20103   [(match_scratch:SI 2 "r")
20104    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20105                    (match_operator:SI 3 "arith_or_logical_operator"
20106                      [(match_operand:SI 1 "nonmemory_operand" "")
20107                       (match_dup 0)]))
20108               (clobber (reg:CC FLAGS_REG))])]
20109   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20110   [(set (match_dup 2) (match_dup 0))
20111    (parallel [(set (match_dup 2)
20112                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20113               (clobber (reg:CC FLAGS_REG))])
20114    (set (match_dup 0) (match_dup 2))]
20115   "")
20116
20117 ;; Attempt to always use XOR for zeroing registers.
20118 (define_peephole2
20119   [(set (match_operand 0 "register_operand" "")
20120         (match_operand 1 "const0_operand" ""))]
20121   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20122    && (! TARGET_USE_MOV0 || optimize_size)
20123    && GENERAL_REG_P (operands[0])
20124    && peep2_regno_dead_p (0, FLAGS_REG)"
20125   [(parallel [(set (match_dup 0) (const_int 0))
20126               (clobber (reg:CC FLAGS_REG))])]
20127 {
20128   operands[0] = gen_lowpart (word_mode, operands[0]);
20129 })
20130
20131 (define_peephole2
20132   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20133         (const_int 0))]
20134   "(GET_MODE (operands[0]) == QImode
20135     || GET_MODE (operands[0]) == HImode)
20136    && (! TARGET_USE_MOV0 || optimize_size)
20137    && peep2_regno_dead_p (0, FLAGS_REG)"
20138   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20139               (clobber (reg:CC FLAGS_REG))])])
20140
20141 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20142 (define_peephole2
20143   [(set (match_operand 0 "register_operand" "")
20144         (const_int -1))]
20145   "(GET_MODE (operands[0]) == HImode
20146     || GET_MODE (operands[0]) == SImode 
20147     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20148    && (optimize_size || TARGET_PENTIUM)
20149    && peep2_regno_dead_p (0, FLAGS_REG)"
20150   [(parallel [(set (match_dup 0) (const_int -1))
20151               (clobber (reg:CC FLAGS_REG))])]
20152   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20153                               operands[0]);")
20154
20155 ;; Attempt to convert simple leas to adds. These can be created by
20156 ;; move expanders.
20157 (define_peephole2
20158   [(set (match_operand:SI 0 "register_operand" "")
20159         (plus:SI (match_dup 0)
20160                  (match_operand:SI 1 "nonmemory_operand" "")))]
20161   "peep2_regno_dead_p (0, FLAGS_REG)"
20162   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20163               (clobber (reg:CC FLAGS_REG))])]
20164   "")
20165
20166 (define_peephole2
20167   [(set (match_operand:SI 0 "register_operand" "")
20168         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20169                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20170   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20171   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20172               (clobber (reg:CC FLAGS_REG))])]
20173   "operands[2] = gen_lowpart (SImode, operands[2]);")
20174
20175 (define_peephole2
20176   [(set (match_operand:DI 0 "register_operand" "")
20177         (plus:DI (match_dup 0)
20178                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20179   "peep2_regno_dead_p (0, FLAGS_REG)"
20180   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20181               (clobber (reg:CC FLAGS_REG))])]
20182   "")
20183
20184 (define_peephole2
20185   [(set (match_operand:SI 0 "register_operand" "")
20186         (mult:SI (match_dup 0)
20187                  (match_operand:SI 1 "const_int_operand" "")))]
20188   "exact_log2 (INTVAL (operands[1])) >= 0
20189    && peep2_regno_dead_p (0, FLAGS_REG)"
20190   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20191               (clobber (reg:CC FLAGS_REG))])]
20192   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20193
20194 (define_peephole2
20195   [(set (match_operand:DI 0 "register_operand" "")
20196         (mult:DI (match_dup 0)
20197                  (match_operand:DI 1 "const_int_operand" "")))]
20198   "exact_log2 (INTVAL (operands[1])) >= 0
20199    && peep2_regno_dead_p (0, FLAGS_REG)"
20200   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20201               (clobber (reg:CC FLAGS_REG))])]
20202   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20203
20204 (define_peephole2
20205   [(set (match_operand:SI 0 "register_operand" "")
20206         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20207                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20208   "exact_log2 (INTVAL (operands[2])) >= 0
20209    && REGNO (operands[0]) == REGNO (operands[1])
20210    && peep2_regno_dead_p (0, FLAGS_REG)"
20211   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20212               (clobber (reg:CC FLAGS_REG))])]
20213   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20214
20215 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20216 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20217 ;; many CPUs it is also faster, since special hardware to avoid esp
20218 ;; dependencies is present.
20219
20220 ;; While some of these conversions may be done using splitters, we use peepholes
20221 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20222
20223 ;; Convert prologue esp subtractions to push.
20224 ;; We need register to push.  In order to keep verify_flow_info happy we have
20225 ;; two choices
20226 ;; - use scratch and clobber it in order to avoid dependencies
20227 ;; - use already live register
20228 ;; We can't use the second way right now, since there is no reliable way how to
20229 ;; verify that given register is live.  First choice will also most likely in
20230 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20231 ;; call clobbered registers are dead.  We may want to use base pointer as an
20232 ;; alternative when no register is available later.
20233
20234 (define_peephole2
20235   [(match_scratch:SI 0 "r")
20236    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20237               (clobber (reg:CC FLAGS_REG))
20238               (clobber (mem:BLK (scratch)))])]
20239   "optimize_size || !TARGET_SUB_ESP_4"
20240   [(clobber (match_dup 0))
20241    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20242               (clobber (mem:BLK (scratch)))])])
20243
20244 (define_peephole2
20245   [(match_scratch:SI 0 "r")
20246    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20247               (clobber (reg:CC FLAGS_REG))
20248               (clobber (mem:BLK (scratch)))])]
20249   "optimize_size || !TARGET_SUB_ESP_8"
20250   [(clobber (match_dup 0))
20251    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20252    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20253               (clobber (mem:BLK (scratch)))])])
20254
20255 ;; Convert esp subtractions to push.
20256 (define_peephole2
20257   [(match_scratch:SI 0 "r")
20258    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20259               (clobber (reg:CC FLAGS_REG))])]
20260   "optimize_size || !TARGET_SUB_ESP_4"
20261   [(clobber (match_dup 0))
20262    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20263
20264 (define_peephole2
20265   [(match_scratch:SI 0 "r")
20266    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20267               (clobber (reg:CC FLAGS_REG))])]
20268   "optimize_size || !TARGET_SUB_ESP_8"
20269   [(clobber (match_dup 0))
20270    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20271    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20272
20273 ;; Convert epilogue deallocator to pop.
20274 (define_peephole2
20275   [(match_scratch:SI 0 "r")
20276    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20277               (clobber (reg:CC FLAGS_REG))
20278               (clobber (mem:BLK (scratch)))])]
20279   "optimize_size || !TARGET_ADD_ESP_4"
20280   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20281               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20282               (clobber (mem:BLK (scratch)))])]
20283   "")
20284
20285 ;; Two pops case is tricky, since pop causes dependency on destination register.
20286 ;; We use two registers if available.
20287 (define_peephole2
20288   [(match_scratch:SI 0 "r")
20289    (match_scratch:SI 1 "r")
20290    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20291               (clobber (reg:CC FLAGS_REG))
20292               (clobber (mem:BLK (scratch)))])]
20293   "optimize_size || !TARGET_ADD_ESP_8"
20294   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20295               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20296               (clobber (mem:BLK (scratch)))])
20297    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20298               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20299   "")
20300
20301 (define_peephole2
20302   [(match_scratch:SI 0 "r")
20303    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20304               (clobber (reg:CC FLAGS_REG))
20305               (clobber (mem:BLK (scratch)))])]
20306   "optimize_size"
20307   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20308               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20309               (clobber (mem:BLK (scratch)))])
20310    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20311               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20312   "")
20313
20314 ;; Convert esp additions to pop.
20315 (define_peephole2
20316   [(match_scratch:SI 0 "r")
20317    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20318               (clobber (reg:CC FLAGS_REG))])]
20319   ""
20320   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20321               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20322   "")
20323
20324 ;; Two pops case is tricky, since pop causes dependency on destination register.
20325 ;; We use two registers if available.
20326 (define_peephole2
20327   [(match_scratch:SI 0 "r")
20328    (match_scratch:SI 1 "r")
20329    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20330               (clobber (reg:CC FLAGS_REG))])]
20331   ""
20332   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20333               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20334    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20336   "")
20337
20338 (define_peephole2
20339   [(match_scratch:SI 0 "r")
20340    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20341               (clobber (reg:CC FLAGS_REG))])]
20342   "optimize_size"
20343   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20344               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20345    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20346               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20347   "")
20348 \f
20349 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20350 ;; required and register dies.  Similarly for 128 to plus -128.
20351 (define_peephole2
20352   [(set (match_operand 0 "flags_reg_operand" "")
20353         (match_operator 1 "compare_operator"
20354           [(match_operand 2 "register_operand" "")
20355            (match_operand 3 "const_int_operand" "")]))]
20356   "(INTVAL (operands[3]) == -1
20357     || INTVAL (operands[3]) == 1
20358     || INTVAL (operands[3]) == 128)
20359    && ix86_match_ccmode (insn, CCGCmode)
20360    && peep2_reg_dead_p (1, operands[2])"
20361   [(parallel [(set (match_dup 0)
20362                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20363               (clobber (match_dup 2))])]
20364   "")
20365 \f
20366 (define_peephole2
20367   [(match_scratch:DI 0 "r")
20368    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20369               (clobber (reg:CC FLAGS_REG))
20370               (clobber (mem:BLK (scratch)))])]
20371   "optimize_size || !TARGET_SUB_ESP_4"
20372   [(clobber (match_dup 0))
20373    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20374               (clobber (mem:BLK (scratch)))])])
20375
20376 (define_peephole2
20377   [(match_scratch:DI 0 "r")
20378    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20379               (clobber (reg:CC FLAGS_REG))
20380               (clobber (mem:BLK (scratch)))])]
20381   "optimize_size || !TARGET_SUB_ESP_8"
20382   [(clobber (match_dup 0))
20383    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20384    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20385               (clobber (mem:BLK (scratch)))])])
20386
20387 ;; Convert esp subtractions to push.
20388 (define_peephole2
20389   [(match_scratch:DI 0 "r")
20390    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20391               (clobber (reg:CC FLAGS_REG))])]
20392   "optimize_size || !TARGET_SUB_ESP_4"
20393   [(clobber (match_dup 0))
20394    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20395
20396 (define_peephole2
20397   [(match_scratch:DI 0 "r")
20398    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20399               (clobber (reg:CC FLAGS_REG))])]
20400   "optimize_size || !TARGET_SUB_ESP_8"
20401   [(clobber (match_dup 0))
20402    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20403    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20404
20405 ;; Convert epilogue deallocator to pop.
20406 (define_peephole2
20407   [(match_scratch:DI 0 "r")
20408    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20409               (clobber (reg:CC FLAGS_REG))
20410               (clobber (mem:BLK (scratch)))])]
20411   "optimize_size || !TARGET_ADD_ESP_4"
20412   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20413               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20414               (clobber (mem:BLK (scratch)))])]
20415   "")
20416
20417 ;; Two pops case is tricky, since pop causes dependency on destination register.
20418 ;; We use two registers if available.
20419 (define_peephole2
20420   [(match_scratch:DI 0 "r")
20421    (match_scratch:DI 1 "r")
20422    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20423               (clobber (reg:CC FLAGS_REG))
20424               (clobber (mem:BLK (scratch)))])]
20425   "optimize_size || !TARGET_ADD_ESP_8"
20426   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20427               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20428               (clobber (mem:BLK (scratch)))])
20429    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20430               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20431   "")
20432
20433 (define_peephole2
20434   [(match_scratch:DI 0 "r")
20435    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20436               (clobber (reg:CC FLAGS_REG))
20437               (clobber (mem:BLK (scratch)))])]
20438   "optimize_size"
20439   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20440               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20441               (clobber (mem:BLK (scratch)))])
20442    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20443               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20444   "")
20445
20446 ;; Convert esp additions to pop.
20447 (define_peephole2
20448   [(match_scratch:DI 0 "r")
20449    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20450               (clobber (reg:CC FLAGS_REG))])]
20451   ""
20452   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20453               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20454   "")
20455
20456 ;; Two pops case is tricky, since pop causes dependency on destination register.
20457 ;; We use two registers if available.
20458 (define_peephole2
20459   [(match_scratch:DI 0 "r")
20460    (match_scratch:DI 1 "r")
20461    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20462               (clobber (reg:CC FLAGS_REG))])]
20463   ""
20464   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20465               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20466    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20467               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20468   "")
20469
20470 (define_peephole2
20471   [(match_scratch:DI 0 "r")
20472    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20473               (clobber (reg:CC FLAGS_REG))])]
20474   "optimize_size"
20475   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20476               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20477    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20478               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20479   "")
20480 \f
20481 ;; Convert imul by three, five and nine into lea
20482 (define_peephole2
20483   [(parallel
20484     [(set (match_operand:SI 0 "register_operand" "")
20485           (mult:SI (match_operand:SI 1 "register_operand" "")
20486                    (match_operand:SI 2 "const_int_operand" "")))
20487      (clobber (reg:CC FLAGS_REG))])]
20488   "INTVAL (operands[2]) == 3
20489    || INTVAL (operands[2]) == 5
20490    || INTVAL (operands[2]) == 9"
20491   [(set (match_dup 0)
20492         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20493                  (match_dup 1)))]
20494   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20495
20496 (define_peephole2
20497   [(parallel
20498     [(set (match_operand:SI 0 "register_operand" "")
20499           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20500                    (match_operand:SI 2 "const_int_operand" "")))
20501      (clobber (reg:CC FLAGS_REG))])]
20502   "!optimize_size 
20503    && (INTVAL (operands[2]) == 3
20504        || INTVAL (operands[2]) == 5
20505        || INTVAL (operands[2]) == 9)"
20506   [(set (match_dup 0) (match_dup 1))
20507    (set (match_dup 0)
20508         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20509                  (match_dup 0)))]
20510   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20511
20512 (define_peephole2
20513   [(parallel
20514     [(set (match_operand:DI 0 "register_operand" "")
20515           (mult:DI (match_operand:DI 1 "register_operand" "")
20516                    (match_operand:DI 2 "const_int_operand" "")))
20517      (clobber (reg:CC FLAGS_REG))])]
20518   "TARGET_64BIT
20519    && (INTVAL (operands[2]) == 3
20520        || INTVAL (operands[2]) == 5
20521        || INTVAL (operands[2]) == 9)"
20522   [(set (match_dup 0)
20523         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20524                  (match_dup 1)))]
20525   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20526
20527 (define_peephole2
20528   [(parallel
20529     [(set (match_operand:DI 0 "register_operand" "")
20530           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20531                    (match_operand:DI 2 "const_int_operand" "")))
20532      (clobber (reg:CC FLAGS_REG))])]
20533   "TARGET_64BIT
20534    && !optimize_size 
20535    && (INTVAL (operands[2]) == 3
20536        || INTVAL (operands[2]) == 5
20537        || INTVAL (operands[2]) == 9)"
20538   [(set (match_dup 0) (match_dup 1))
20539    (set (match_dup 0)
20540         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20541                  (match_dup 0)))]
20542   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20543
20544 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20545 ;; imul $32bit_imm, reg, reg is direct decoded.
20546 (define_peephole2
20547   [(match_scratch:DI 3 "r")
20548    (parallel [(set (match_operand:DI 0 "register_operand" "")
20549                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20550                             (match_operand:DI 2 "immediate_operand" "")))
20551               (clobber (reg:CC FLAGS_REG))])]
20552   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20553    && !satisfies_constraint_K (operands[2])"
20554   [(set (match_dup 3) (match_dup 1))
20555    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20556               (clobber (reg:CC FLAGS_REG))])]
20557 "")
20558
20559 (define_peephole2
20560   [(match_scratch:SI 3 "r")
20561    (parallel [(set (match_operand:SI 0 "register_operand" "")
20562                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20563                             (match_operand:SI 2 "immediate_operand" "")))
20564               (clobber (reg:CC FLAGS_REG))])]
20565   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20566    && !satisfies_constraint_K (operands[2])"
20567   [(set (match_dup 3) (match_dup 1))
20568    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20569               (clobber (reg:CC FLAGS_REG))])]
20570 "")
20571
20572 (define_peephole2
20573   [(match_scratch:SI 3 "r")
20574    (parallel [(set (match_operand:DI 0 "register_operand" "")
20575                    (zero_extend:DI
20576                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20577                               (match_operand:SI 2 "immediate_operand" ""))))
20578               (clobber (reg:CC FLAGS_REG))])]
20579   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20580    && !satisfies_constraint_K (operands[2])"
20581   [(set (match_dup 3) (match_dup 1))
20582    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20583               (clobber (reg:CC FLAGS_REG))])]
20584 "")
20585
20586 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20587 ;; Convert it into imul reg, reg
20588 ;; It would be better to force assembler to encode instruction using long
20589 ;; immediate, but there is apparently no way to do so.
20590 (define_peephole2
20591   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20592                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20593                             (match_operand:DI 2 "const_int_operand" "")))
20594               (clobber (reg:CC FLAGS_REG))])
20595    (match_scratch:DI 3 "r")]
20596   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20597    && satisfies_constraint_K (operands[2])"
20598   [(set (match_dup 3) (match_dup 2))
20599    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20600               (clobber (reg:CC FLAGS_REG))])]
20601 {
20602   if (!rtx_equal_p (operands[0], operands[1]))
20603     emit_move_insn (operands[0], operands[1]);
20604 })
20605
20606 (define_peephole2
20607   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20608                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20609                             (match_operand:SI 2 "const_int_operand" "")))
20610               (clobber (reg:CC FLAGS_REG))])
20611    (match_scratch:SI 3 "r")]
20612   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20613    && satisfies_constraint_K (operands[2])"
20614   [(set (match_dup 3) (match_dup 2))
20615    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20616               (clobber (reg:CC FLAGS_REG))])]
20617 {
20618   if (!rtx_equal_p (operands[0], operands[1]))
20619     emit_move_insn (operands[0], operands[1]);
20620 })
20621
20622 (define_peephole2
20623   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20624                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20625                             (match_operand:HI 2 "immediate_operand" "")))
20626               (clobber (reg:CC FLAGS_REG))])
20627    (match_scratch:HI 3 "r")]
20628   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20629   [(set (match_dup 3) (match_dup 2))
20630    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20631               (clobber (reg:CC FLAGS_REG))])]
20632 {
20633   if (!rtx_equal_p (operands[0], operands[1]))
20634     emit_move_insn (operands[0], operands[1]);
20635 })
20636
20637 ;; After splitting up read-modify operations, array accesses with memory
20638 ;; operands might end up in form:
20639 ;;  sall    $2, %eax
20640 ;;  movl    4(%esp), %edx
20641 ;;  addl    %edx, %eax
20642 ;; instead of pre-splitting:
20643 ;;  sall    $2, %eax
20644 ;;  addl    4(%esp), %eax
20645 ;; Turn it into:
20646 ;;  movl    4(%esp), %edx
20647 ;;  leal    (%edx,%eax,4), %eax
20648
20649 (define_peephole2
20650   [(parallel [(set (match_operand 0 "register_operand" "")
20651                    (ashift (match_operand 1 "register_operand" "")
20652                            (match_operand 2 "const_int_operand" "")))
20653                (clobber (reg:CC FLAGS_REG))])
20654    (set (match_operand 3 "register_operand")
20655         (match_operand 4 "x86_64_general_operand" ""))
20656    (parallel [(set (match_operand 5 "register_operand" "")
20657                    (plus (match_operand 6 "register_operand" "")
20658                          (match_operand 7 "register_operand" "")))
20659                    (clobber (reg:CC FLAGS_REG))])]
20660   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20661    /* Validate MODE for lea.  */
20662    && ((!TARGET_PARTIAL_REG_STALL
20663         && (GET_MODE (operands[0]) == QImode
20664             || GET_MODE (operands[0]) == HImode))
20665        || GET_MODE (operands[0]) == SImode 
20666        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20667    /* We reorder load and the shift.  */
20668    && !rtx_equal_p (operands[1], operands[3])
20669    && !reg_overlap_mentioned_p (operands[0], operands[4])
20670    /* Last PLUS must consist of operand 0 and 3.  */
20671    && !rtx_equal_p (operands[0], operands[3])
20672    && (rtx_equal_p (operands[3], operands[6])
20673        || rtx_equal_p (operands[3], operands[7]))
20674    && (rtx_equal_p (operands[0], operands[6])
20675        || rtx_equal_p (operands[0], operands[7]))
20676    /* The intermediate operand 0 must die or be same as output.  */
20677    && (rtx_equal_p (operands[0], operands[5])
20678        || peep2_reg_dead_p (3, operands[0]))"
20679   [(set (match_dup 3) (match_dup 4))
20680    (set (match_dup 0) (match_dup 1))]
20681 {
20682   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20683   int scale = 1 << INTVAL (operands[2]);
20684   rtx index = gen_lowpart (Pmode, operands[1]);
20685   rtx base = gen_lowpart (Pmode, operands[3]);
20686   rtx dest = gen_lowpart (mode, operands[5]);
20687
20688   operands[1] = gen_rtx_PLUS (Pmode, base,
20689                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20690   if (mode != Pmode)
20691     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20692   operands[0] = dest;
20693 })
20694 \f
20695 ;; Call-value patterns last so that the wildcard operand does not
20696 ;; disrupt insn-recog's switch tables.
20697
20698 (define_insn "*call_value_pop_0"
20699   [(set (match_operand 0 "" "")
20700         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20701               (match_operand:SI 2 "" "")))
20702    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20703                             (match_operand:SI 3 "immediate_operand" "")))]
20704   "!TARGET_64BIT"
20705 {
20706   if (SIBLING_CALL_P (insn))
20707     return "jmp\t%P1";
20708   else
20709     return "call\t%P1";
20710 }
20711   [(set_attr "type" "callv")])
20712
20713 (define_insn "*call_value_pop_1"
20714   [(set (match_operand 0 "" "")
20715         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20716               (match_operand:SI 2 "" "")))
20717    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20718                             (match_operand:SI 3 "immediate_operand" "i")))]
20719   "!TARGET_64BIT"
20720 {
20721   if (constant_call_address_operand (operands[1], Pmode))
20722     {
20723       if (SIBLING_CALL_P (insn))
20724         return "jmp\t%P1";
20725       else
20726         return "call\t%P1";
20727     }
20728   if (SIBLING_CALL_P (insn))
20729     return "jmp\t%A1";
20730   else
20731     return "call\t%A1";
20732 }
20733   [(set_attr "type" "callv")])
20734
20735 (define_insn "*call_value_0"
20736   [(set (match_operand 0 "" "")
20737         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20738               (match_operand:SI 2 "" "")))]
20739   "!TARGET_64BIT"
20740 {
20741   if (SIBLING_CALL_P (insn))
20742     return "jmp\t%P1";
20743   else
20744     return "call\t%P1";
20745 }
20746   [(set_attr "type" "callv")])
20747
20748 (define_insn "*call_value_0_rex64"
20749   [(set (match_operand 0 "" "")
20750         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20751               (match_operand:DI 2 "const_int_operand" "")))]
20752   "TARGET_64BIT"
20753 {
20754   if (SIBLING_CALL_P (insn))
20755     return "jmp\t%P1";
20756   else
20757     return "call\t%P1";
20758 }
20759   [(set_attr "type" "callv")])
20760
20761 (define_insn "*call_value_1"
20762   [(set (match_operand 0 "" "")
20763         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20764               (match_operand:SI 2 "" "")))]
20765   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20766 {
20767   if (constant_call_address_operand (operands[1], Pmode))
20768     return "call\t%P1";
20769   return "call\t%A1";
20770 }
20771   [(set_attr "type" "callv")])
20772
20773 (define_insn "*sibcall_value_1"
20774   [(set (match_operand 0 "" "")
20775         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20776               (match_operand:SI 2 "" "")))]
20777   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20778 {
20779   if (constant_call_address_operand (operands[1], Pmode))
20780     return "jmp\t%P1";
20781   return "jmp\t%A1";
20782 }
20783   [(set_attr "type" "callv")])
20784
20785 (define_insn "*call_value_1_rex64"
20786   [(set (match_operand 0 "" "")
20787         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20788               (match_operand:DI 2 "" "")))]
20789   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20790 {
20791   if (constant_call_address_operand (operands[1], Pmode))
20792     return "call\t%P1";
20793   return "call\t%A1";
20794 }
20795   [(set_attr "type" "callv")])
20796
20797 (define_insn "*sibcall_value_1_rex64"
20798   [(set (match_operand 0 "" "")
20799         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20800               (match_operand:DI 2 "" "")))]
20801   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20802   "jmp\t%P1"
20803   [(set_attr "type" "callv")])
20804
20805 (define_insn "*sibcall_value_1_rex64_v"
20806   [(set (match_operand 0 "" "")
20807         (call (mem:QI (reg:DI R11_REG))
20808               (match_operand:DI 1 "" "")))]
20809   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20810   "jmp\t*%%r11"
20811   [(set_attr "type" "callv")])
20812 \f
20813 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20814 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20815 ;; caught for use by garbage collectors and the like.  Using an insn that
20816 ;; maps to SIGILL makes it more likely the program will rightfully die.
20817 ;; Keeping with tradition, "6" is in honor of #UD.
20818 (define_insn "trap"
20819   [(trap_if (const_int 1) (const_int 6))]
20820   ""
20821   { return ASM_SHORT "0x0b0f"; }
20822   [(set_attr "length" "2")])
20823
20824 (define_expand "sse_prologue_save"
20825   [(parallel [(set (match_operand:BLK 0 "" "")
20826                    (unspec:BLK [(reg:DI 22)
20827                                 (reg:DI 23)
20828                                 (reg:DI 24)
20829                                 (reg:DI 25)
20830                                 (reg:DI 26)
20831                                 (reg:DI 27)
20832                                 (reg:DI 28)
20833                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20834               (use (match_operand:DI 1 "register_operand" ""))
20835               (use (match_operand:DI 2 "immediate_operand" ""))
20836               (use (label_ref:DI (match_operand 3 "" "")))])]
20837   "TARGET_64BIT"
20838   "")
20839
20840 (define_insn "*sse_prologue_save_insn"
20841   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20842                           (match_operand:DI 4 "const_int_operand" "n")))
20843         (unspec:BLK [(reg:DI 22)
20844                      (reg:DI 23)
20845                      (reg:DI 24)
20846                      (reg:DI 25)
20847                      (reg:DI 26)
20848                      (reg:DI 27)
20849                      (reg:DI 28)
20850                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20851    (use (match_operand:DI 1 "register_operand" "r"))
20852    (use (match_operand:DI 2 "const_int_operand" "i"))
20853    (use (label_ref:DI (match_operand 3 "" "X")))]
20854   "TARGET_64BIT
20855    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20856    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20857   "*
20858 {
20859   int i;
20860   operands[0] = gen_rtx_MEM (Pmode,
20861                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20862   output_asm_insn (\"jmp\\t%A1\", operands);
20863   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20864     {
20865       operands[4] = adjust_address (operands[0], DImode, i*16);
20866       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20867       PUT_MODE (operands[4], TImode);
20868       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20869         output_asm_insn (\"rex\", operands);
20870       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20871     }
20872   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20873                              CODE_LABEL_NUMBER (operands[3]));
20874   RET;
20875 }
20876   "
20877   [(set_attr "type" "other")
20878    (set_attr "length_immediate" "0")
20879    (set_attr "length_address" "0")
20880    (set_attr "length" "135")
20881    (set_attr "memory" "store")
20882    (set_attr "modrm" "0")
20883    (set_attr "mode" "DI")])
20884
20885 (define_expand "prefetch"
20886   [(prefetch (match_operand 0 "address_operand" "")
20887              (match_operand:SI 1 "const_int_operand" "")
20888              (match_operand:SI 2 "const_int_operand" ""))]
20889   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20890 {
20891   int rw = INTVAL (operands[1]);
20892   int locality = INTVAL (operands[2]);
20893
20894   gcc_assert (rw == 0 || rw == 1);
20895   gcc_assert (locality >= 0 && locality <= 3);
20896   gcc_assert (GET_MODE (operands[0]) == Pmode
20897               || GET_MODE (operands[0]) == VOIDmode);
20898
20899   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20900      supported by SSE counterpart or the SSE prefetch is not available
20901      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20902      of locality.  */
20903   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20904     operands[2] = GEN_INT (3);
20905   else
20906     operands[1] = const0_rtx;
20907 })
20908
20909 (define_insn "*prefetch_sse"
20910   [(prefetch (match_operand:SI 0 "address_operand" "p")
20911              (const_int 0)
20912              (match_operand:SI 1 "const_int_operand" ""))]
20913   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20914 {
20915   static const char * const patterns[4] = {
20916    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20917   };
20918
20919   int locality = INTVAL (operands[1]);
20920   gcc_assert (locality >= 0 && locality <= 3);
20921
20922   return patterns[locality];  
20923 }
20924   [(set_attr "type" "sse")
20925    (set_attr "memory" "none")])
20926
20927 (define_insn "*prefetch_sse_rex"
20928   [(prefetch (match_operand:DI 0 "address_operand" "p")
20929              (const_int 0)
20930              (match_operand:SI 1 "const_int_operand" ""))]
20931   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20932 {
20933   static const char * const patterns[4] = {
20934    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20935   };
20936
20937   int locality = INTVAL (operands[1]);
20938   gcc_assert (locality >= 0 && locality <= 3);
20939
20940   return patterns[locality];  
20941 }
20942   [(set_attr "type" "sse")
20943    (set_attr "memory" "none")])
20944
20945 (define_insn "*prefetch_3dnow"
20946   [(prefetch (match_operand:SI 0 "address_operand" "p")
20947              (match_operand:SI 1 "const_int_operand" "n")
20948              (const_int 3))]
20949   "TARGET_3DNOW && !TARGET_64BIT"
20950 {
20951   if (INTVAL (operands[1]) == 0)
20952     return "prefetch\t%a0";
20953   else
20954     return "prefetchw\t%a0";
20955 }
20956   [(set_attr "type" "mmx")
20957    (set_attr "memory" "none")])
20958
20959 (define_insn "*prefetch_3dnow_rex"
20960   [(prefetch (match_operand:DI 0 "address_operand" "p")
20961              (match_operand:SI 1 "const_int_operand" "n")
20962              (const_int 3))]
20963   "TARGET_3DNOW && TARGET_64BIT"
20964 {
20965   if (INTVAL (operands[1]) == 0)
20966     return "prefetch\t%a0";
20967   else
20968     return "prefetchw\t%a0";
20969 }
20970   [(set_attr "type" "mmx")
20971    (set_attr "memory" "none")])
20972
20973 (define_expand "stack_protect_set"
20974   [(match_operand 0 "memory_operand" "")
20975    (match_operand 1 "memory_operand" "")]
20976   ""
20977 {
20978 #ifdef TARGET_THREAD_SSP_OFFSET
20979   if (TARGET_64BIT)
20980     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20981                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20982   else
20983     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20984                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20985 #else
20986   if (TARGET_64BIT)
20987     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20988   else
20989     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20990 #endif
20991   DONE;
20992 })
20993
20994 (define_insn "stack_protect_set_si"
20995   [(set (match_operand:SI 0 "memory_operand" "=m")
20996         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20997    (set (match_scratch:SI 2 "=&r") (const_int 0))
20998    (clobber (reg:CC FLAGS_REG))]
20999   ""
21000   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21001   [(set_attr "type" "multi")])
21002
21003 (define_insn "stack_protect_set_di"
21004   [(set (match_operand:DI 0 "memory_operand" "=m")
21005         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21006    (set (match_scratch:DI 2 "=&r") (const_int 0))
21007    (clobber (reg:CC FLAGS_REG))]
21008   "TARGET_64BIT"
21009   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21010   [(set_attr "type" "multi")])
21011
21012 (define_insn "stack_tls_protect_set_si"
21013   [(set (match_operand:SI 0 "memory_operand" "=m")
21014         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21015    (set (match_scratch:SI 2 "=&r") (const_int 0))
21016    (clobber (reg:CC FLAGS_REG))]
21017   ""
21018   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21019   [(set_attr "type" "multi")])
21020
21021 (define_insn "stack_tls_protect_set_di"
21022   [(set (match_operand:DI 0 "memory_operand" "=m")
21023         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21024    (set (match_scratch:DI 2 "=&r") (const_int 0))
21025    (clobber (reg:CC FLAGS_REG))]
21026   "TARGET_64BIT"
21027   {
21028      /* The kernel uses a different segment register for performance reasons; a
21029         system call would not have to trash the userspace segment register,
21030         which would be expensive */
21031      if (ix86_cmodel != CM_KERNEL)
21032         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21033      else
21034         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21035   }
21036   [(set_attr "type" "multi")])
21037
21038 (define_expand "stack_protect_test"
21039   [(match_operand 0 "memory_operand" "")
21040    (match_operand 1 "memory_operand" "")
21041    (match_operand 2 "" "")]
21042   ""
21043 {
21044   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21045   ix86_compare_op0 = operands[0];
21046   ix86_compare_op1 = operands[1];
21047   ix86_compare_emitted = flags;
21048
21049 #ifdef TARGET_THREAD_SSP_OFFSET
21050   if (TARGET_64BIT)
21051     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21052                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21053   else
21054     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21055                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21056 #else
21057   if (TARGET_64BIT)
21058     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21059   else
21060     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21061 #endif
21062   emit_jump_insn (gen_beq (operands[2]));
21063   DONE;
21064 })
21065
21066 (define_insn "stack_protect_test_si"
21067   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21068         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21069                      (match_operand:SI 2 "memory_operand" "m")]
21070                     UNSPEC_SP_TEST))
21071    (clobber (match_scratch:SI 3 "=&r"))]
21072   ""
21073   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21074   [(set_attr "type" "multi")])
21075
21076 (define_insn "stack_protect_test_di"
21077   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21078         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21079                      (match_operand:DI 2 "memory_operand" "m")]
21080                     UNSPEC_SP_TEST))
21081    (clobber (match_scratch:DI 3 "=&r"))]
21082   "TARGET_64BIT"
21083   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21084   [(set_attr "type" "multi")])
21085
21086 (define_insn "stack_tls_protect_test_si"
21087   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21088         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21089                      (match_operand:SI 2 "const_int_operand" "i")]
21090                     UNSPEC_SP_TLS_TEST))
21091    (clobber (match_scratch:SI 3 "=r"))]
21092   ""
21093   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21094   [(set_attr "type" "multi")])
21095
21096 (define_insn "stack_tls_protect_test_di"
21097   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21098         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21099                      (match_operand:DI 2 "const_int_operand" "i")]
21100                     UNSPEC_SP_TLS_TEST))
21101    (clobber (match_scratch:DI 3 "=r"))]
21102   "TARGET_64BIT"
21103   {
21104      /* The kernel uses a different segment register for performance reasons; a
21105         system call would not have to trash the userspace segment register,
21106         which would be expensive */
21107      if (ix86_cmodel != CM_KERNEL)
21108         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21109      else
21110         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21111   }
21112   [(set_attr "type" "multi")])
21113
21114 (include "mmx.md")
21115 (include "sse.md")
21116 (include "sync.md")