86ea88c63396eeeac479748e1f5ae46421b7b340
[dragonfly.git] / contrib / gcc-3.4 / 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
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, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FSCALE               67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; REP instruction
124    (UNSPEC_REP                  75)
125   ])
126
127 (define_constants
128   [(UNSPECV_BLOCKAGE            0)
129    (UNSPECV_STACK_PROBE         10)
130    (UNSPECV_EH_RETURN           13)
131    (UNSPECV_EMMS                31)
132    (UNSPECV_LDMXCSR             37)
133    (UNSPECV_STMXCSR             40)
134    (UNSPECV_FEMMS               46)
135    (UNSPECV_CLFLUSH             57)
136    (UNSPECV_ALIGN               68)
137    (UNSPECV_MONITOR             69)
138    (UNSPECV_MWAIT               70)
139   ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first.  This allows for better optimization.  For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type.  This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153   (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type.  Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158   "other,multi,
159    alu,alu1,negnot,imov,imovx,lea,
160    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161    icmp,test,ibr,setcc,icmov,
162    push,pop,call,callv,leave,
163    str,cld,
164    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165    sselog,sseiadd,sseishft,sseimul,
166    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168   (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173   (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178            (const_string "i387")
179          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181            (const_string "sse")
182          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183            (const_string "mmx")
184          (eq_attr "type" "other")
185            (const_string "unknown")]
186          (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191            (const_int 0)
192          (eq_attr "unit" "i387,sse,mmx")
193            (const_int 0)
194          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195                           imul,icmp,push,pop")
196            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197          (eq_attr "type" "imov,test")
198            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199          (eq_attr "type" "call")
200            (if_then_else (match_operand 0 "constant_call_address_operand" "")
201              (const_int 4)
202              (const_int 0))
203          (eq_attr "type" "callv")
204            (if_then_else (match_operand 1 "constant_call_address_operand" "")
205              (const_int 4)
206              (const_int 0))
207          ;; We don't know the size before shorten_branches.  Expect
208          ;; the instruction to fit for better scheduling.
209          (eq_attr "type" "ibr")
210            (const_int 1)
211          ]
212          (symbol_ref "/* Update immediate_length and other attributes! */
213                       abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218            (const_int 0)
219          (and (eq_attr "type" "call")
220               (match_operand 0 "constant_call_address_operand" ""))
221              (const_int 0)
222          (and (eq_attr "type" "callv")
223               (match_operand 1 "constant_call_address_operand" ""))
224              (const_int 0)
225          ]
226          (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230   (if_then_else (ior (eq_attr "mode" "HI")
231                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232     (const_int 1)
233     (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" "" 
237   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238     (const_int 1)
239     (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243   (if_then_else 
244     (ior (eq_attr "type" "imovx,setcc,icmov")
245          (eq_attr "unit" "sse,mmx"))
246     (const_int 1)
247     (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_rex" ""
251   (cond [(and (eq_attr "mode" "DI")
252               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253            (const_int 1)
254          (and (eq_attr "mode" "QI")
255               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256                   (const_int 0)))
257            (const_int 1)
258          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259              (const_int 0))
260            (const_int 1)
261         ]
262         (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266   (cond [(eq_attr "type" "str,cld,leave")
267            (const_int 0)
268          (eq_attr "unit" "i387")
269            (const_int 0)
270          (and (eq_attr "type" "incdec")
271               (ior (match_operand:SI 1 "register_operand" "")
272                    (match_operand:HI 1 "register_operand" "")))
273            (const_int 0)
274          (and (eq_attr "type" "push")
275               (not (match_operand 1 "memory_operand" "")))
276            (const_int 0)
277          (and (eq_attr "type" "pop")
278               (not (match_operand 0 "memory_operand" "")))
279            (const_int 0)
280          (and (eq_attr "type" "imov")
281               (and (match_operand 0 "register_operand" "")
282                    (match_operand 1 "immediate_operand" "")))
283            (const_int 0)
284          (and (eq_attr "type" "call")
285               (match_operand 0 "constant_call_address_operand" ""))
286              (const_int 0)
287          (and (eq_attr "type" "callv")
288               (match_operand 1 "constant_call_address_operand" ""))
289              (const_int 0)
290          ]
291          (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297   (cond [(eq_attr "type" "other,multi,fistp")
298            (const_int 16)
299          (eq_attr "type" "fcmp")
300            (const_int 4)
301          (eq_attr "unit" "i387")
302            (plus (const_int 2)
303                  (plus (attr "prefix_data16")
304                        (attr "length_address")))]
305          (plus (plus (attr "modrm")
306                      (plus (attr "prefix_0f")
307                            (plus (attr "prefix_rex")
308                                  (const_int 1))))
309                (plus (attr "prefix_rep")
310                      (plus (attr "prefix_data16")
311                            (plus (attr "length_immediate")
312                                  (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319   (cond [(eq_attr "type" "other,multi,str")
320            (const_string "unknown")
321          (eq_attr "type" "lea,fcmov,fpspc,cld")
322            (const_string "none")
323          (eq_attr "type" "fistp,leave")
324            (const_string "both")
325          (eq_attr "type" "push")
326            (if_then_else (match_operand 1 "memory_operand" "")
327              (const_string "both")
328              (const_string "store"))
329          (eq_attr "type" "pop")
330            (if_then_else (match_operand 0 "memory_operand" "")
331              (const_string "both")
332              (const_string "load"))
333          (eq_attr "type" "setcc")
334            (if_then_else (match_operand 0 "memory_operand" "")
335              (const_string "store")
336              (const_string "none"))
337          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338            (if_then_else (ior (match_operand 0 "memory_operand" "")
339                               (match_operand 1 "memory_operand" ""))
340              (const_string "load")
341              (const_string "none"))
342          (eq_attr "type" "ibr")
343            (if_then_else (match_operand 0 "memory_operand" "")
344              (const_string "load")
345              (const_string "none"))
346          (eq_attr "type" "call")
347            (if_then_else (match_operand 0 "constant_call_address_operand" "")
348              (const_string "none")
349              (const_string "load"))
350          (eq_attr "type" "callv")
351            (if_then_else (match_operand 1 "constant_call_address_operand" "")
352              (const_string "none")
353              (const_string "load"))
354          (and (eq_attr "type" "alu1,negnot,ishift1")
355               (match_operand 1 "memory_operand" ""))
356            (const_string "both")
357          (and (match_operand 0 "memory_operand" "")
358               (match_operand 1 "memory_operand" ""))
359            (const_string "both")
360          (match_operand 0 "memory_operand" "")
361            (const_string "store")
362          (match_operand 1 "memory_operand" "")
363            (const_string "load")
364          (and (eq_attr "type"
365                  "!alu1,negnot,ishift1,
366                    imov,imovx,icmp,test,
367                    fmov,fcmp,fsgn,
368                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369                    mmx,mmxmov,mmxcmp,mmxcvt")
370               (match_operand 2 "memory_operand" ""))
371            (const_string "load")
372          (and (eq_attr "type" "icmov")
373               (match_operand 3 "memory_operand" ""))
374            (const_string "load")
375         ]
376         (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381   (cond [(eq_attr "type" "other,multi")
382            (const_string "unknown")
383          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384               (and (match_operand 0 "memory_displacement_operand" "")
385                    (match_operand 1 "immediate_operand" "")))
386            (const_string "true")
387          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388               (and (match_operand 0 "memory_displacement_operand" "")
389                    (match_operand 2 "immediate_operand" "")))
390            (const_string "true")
391         ]
392         (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397   (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401   [(set_attr "length" "128")
402    (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416   [(set (reg:CC 17)
417         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418                     (match_operand:DI 1 "x86_64_general_operand" "")))]
419   ""
420 {
421   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422     operands[0] = force_reg (DImode, operands[0]);
423   ix86_compare_op0 = operands[0];
424   ix86_compare_op1 = operands[1];
425   DONE;
426 })
427
428 (define_expand "cmpsi"
429   [(set (reg:CC 17)
430         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431                     (match_operand:SI 1 "general_operand" "")))]
432   ""
433 {
434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435     operands[0] = force_reg (SImode, operands[0]);
436   ix86_compare_op0 = operands[0];
437   ix86_compare_op1 = operands[1];
438   DONE;
439 })
440
441 (define_expand "cmphi"
442   [(set (reg:CC 17)
443         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444                     (match_operand:HI 1 "general_operand" "")))]
445   ""
446 {
447   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448     operands[0] = force_reg (HImode, operands[0]);
449   ix86_compare_op0 = operands[0];
450   ix86_compare_op1 = operands[1];
451   DONE;
452 })
453
454 (define_expand "cmpqi"
455   [(set (reg:CC 17)
456         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457                     (match_operand:QI 1 "general_operand" "")))]
458   "TARGET_QIMODE_MATH"
459 {
460   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461     operands[0] = force_reg (QImode, operands[0]);
462   ix86_compare_op0 = operands[0];
463   ix86_compare_op1 = operands[1];
464   DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468   [(set (reg 17)
469         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470                  (match_operand:DI 1 "const0_operand" "n,n")))]
471   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472   "@
473    test{q}\t{%0, %0|%0, %0}
474    cmp{q}\t{%1, %0|%0, %1}"
475   [(set_attr "type" "test,icmp")
476    (set_attr "length_immediate" "0,1")
477    (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480   [(set (reg 17)
481         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483                  (const_int 0)))]
484   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485   "cmp{q}\t{%1, %0|%0, %1}"
486   [(set_attr "type" "icmp")
487    (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490   [(set (reg:CC 17)
491         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492                     (match_operand:DI 1 "general_operand" "")))]
493   "TARGET_64BIT"
494   "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497   [(set (reg 17)
498         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501   "cmp{q}\t{%1, %0|%0, %1}"
502   [(set_attr "type" "icmp")
503    (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507   [(set (reg 17)
508         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509                  (match_operand:SI 1 "const0_operand" "n,n")))]
510   "ix86_match_ccmode (insn, CCNOmode)"
511   "@
512    test{l}\t{%0, %0|%0, %0}
513    cmp{l}\t{%1, %0|%0, %1}"
514   [(set_attr "type" "test,icmp")
515    (set_attr "length_immediate" "0,1")
516    (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519   [(set (reg 17)
520         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521                            (match_operand:SI 1 "general_operand" "ri,mr"))
522                  (const_int 0)))]
523   "ix86_match_ccmode (insn, CCGOCmode)"
524   "cmp{l}\t{%1, %0|%0, %1}"
525   [(set_attr "type" "icmp")
526    (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529   [(set (reg:CC 17)
530         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531                     (match_operand:SI 1 "general_operand" "ri,mr")))]
532   ""
533   "")
534
535 (define_insn "*cmpsi_1_insn"
536   [(set (reg 17)
537         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538                  (match_operand:SI 1 "general_operand" "ri,mr")))]
539   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540     && ix86_match_ccmode (insn, CCmode)"
541   "cmp{l}\t{%1, %0|%0, %1}"
542   [(set_attr "type" "icmp")
543    (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546   [(set (reg 17)
547         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548                  (match_operand:HI 1 "const0_operand" "n,n")))]
549   "ix86_match_ccmode (insn, CCNOmode)"
550   "@
551    test{w}\t{%0, %0|%0, %0}
552    cmp{w}\t{%1, %0|%0, %1}"
553   [(set_attr "type" "test,icmp")
554    (set_attr "length_immediate" "0,1")
555    (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558   [(set (reg 17)
559         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560                            (match_operand:HI 1 "general_operand" "ri,mr"))
561                  (const_int 0)))]
562   "ix86_match_ccmode (insn, CCGOCmode)"
563   "cmp{w}\t{%1, %0|%0, %1}"
564   [(set_attr "type" "icmp")
565    (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568   [(set (reg 17)
569         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570                  (match_operand:HI 1 "general_operand" "ri,mr")))]
571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572    && ix86_match_ccmode (insn, CCmode)"
573   "cmp{w}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578   [(set (reg 17)
579         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580                  (match_operand:QI 1 "const0_operand" "n,n")))]
581   "ix86_match_ccmode (insn, CCNOmode)"
582   "@
583    test{b}\t{%0, %0|%0, %0}
584    cmp{b}\t{$0, %0|%0, 0}"
585   [(set_attr "type" "test,icmp")
586    (set_attr "length_immediate" "0,1")
587    (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590   [(set (reg 17)
591         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592                  (match_operand:QI 1 "general_operand" "qi,mq")))]
593   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594     && ix86_match_ccmode (insn, CCmode)"
595   "cmp{b}\t{%1, %0|%0, %1}"
596   [(set_attr "type" "icmp")
597    (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600   [(set (reg 17)
601         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602                            (match_operand:QI 1 "general_operand" "qi,mq"))
603                  (const_int 0)))]
604   "ix86_match_ccmode (insn, CCGOCmode)"
605   "cmp{b}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610   [(set (reg 17)
611         (compare
612           (match_operand:QI 0 "general_operand" "Qm")
613           (subreg:QI
614             (zero_extract:SI
615               (match_operand 1 "ext_register_operand" "Q")
616               (const_int 8)
617               (const_int 8)) 0)))]
618   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619   "cmp{b}\t{%h1, %0|%0, %h1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624   [(set (reg 17)
625         (compare
626           (match_operand:QI 0 "register_operand" "Q")
627           (subreg:QI
628             (zero_extract:SI
629               (match_operand 1 "ext_register_operand" "Q")
630               (const_int 8)
631               (const_int 8)) 0)))]
632   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633   "cmp{b}\t{%h1, %0|%0, %h1}"
634   [(set_attr "type" "icmp")
635    (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638   [(set (reg 17)
639         (compare
640           (subreg:QI
641             (zero_extract:SI
642               (match_operand 0 "ext_register_operand" "Q")
643               (const_int 8)
644               (const_int 8)) 0)
645           (match_operand:QI 1 "const0_operand" "n")))]
646   "ix86_match_ccmode (insn, CCNOmode)"
647   "test{b}\t%h0, %h0"
648   [(set_attr "type" "test")
649    (set_attr "length_immediate" "0")
650    (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653   [(set (reg:CC 17)
654         (compare:CC
655           (subreg:QI
656             (zero_extract:SI
657               (match_operand 0 "ext_register_operand" "")
658               (const_int 8)
659               (const_int 8)) 0)
660           (match_operand:QI 1 "general_operand" "")))]
661   ""
662   "")
663
664 (define_insn "cmpqi_ext_3_insn"
665   [(set (reg 17)
666         (compare
667           (subreg:QI
668             (zero_extract:SI
669               (match_operand 0 "ext_register_operand" "Q")
670               (const_int 8)
671               (const_int 8)) 0)
672           (match_operand:QI 1 "general_operand" "Qmn")))]
673   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674   "cmp{b}\t{%1, %h0|%h0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679   [(set (reg 17)
680         (compare
681           (subreg:QI
682             (zero_extract:SI
683               (match_operand 0 "ext_register_operand" "Q")
684               (const_int 8)
685               (const_int 8)) 0)
686           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688   "cmp{b}\t{%1, %h0|%h0, %1}"
689   [(set_attr "type" "icmp")
690    (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693   [(set (reg 17)
694         (compare
695           (subreg:QI
696             (zero_extract:SI
697               (match_operand 0 "ext_register_operand" "Q")
698               (const_int 8)
699               (const_int 8)) 0)
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %h0|%h0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares.  Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716   [(set (reg:CC 17)
717         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719   "TARGET_80387"
720 {
721   ix86_compare_op0 = operands[0];
722   ix86_compare_op1 = operands[1];
723   DONE;
724 })
725
726 (define_expand "cmpdf"
727   [(set (reg:CC 17)
728         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730   "TARGET_80387 || TARGET_SSE2"
731 {
732   ix86_compare_op0 = operands[0];
733   ix86_compare_op1 = operands[1];
734   DONE;
735 })
736
737 (define_expand "cmpsf"
738   [(set (reg:CC 17)
739         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741   "TARGET_80387 || TARGET_SSE"
742 {
743   ix86_compare_op0 = operands[0];
744   ix86_compare_op1 = operands[1];
745   DONE;
746 })
747
748 ;; FP compares, step 1:
749 ;; Set the FP condition codes.
750 ;;
751 ;; CCFPmode     compare with exceptions
752 ;; CCFPUmode    compare with no exceptions
753
754 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755 ;; and that fp moves clobber the condition codes, and that there is
756 ;; currently no way to describe this fact to reg-stack.  So there are
757 ;; no splitters yet for this.
758
759 ;; %%% YIKES!  This scheme does not retain a strong connection between 
760 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761 ;; work!  Only allow tos/mem with tos in op 0.
762 ;;
763 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
764 ;; things aren't as bad as they sound...
765
766 (define_insn "*cmpfp_0"
767   [(set (match_operand:HI 0 "register_operand" "=a")
768         (unspec:HI
769           [(compare:CCFP (match_operand 1 "register_operand" "f")
770                          (match_operand 2 "const0_operand" "X"))]
771           UNSPEC_FNSTSW))]
772   "TARGET_80387
773    && FLOAT_MODE_P (GET_MODE (operands[1]))
774    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775 {
776   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777     return "ftst\;fnstsw\t%0\;fstp\t%y0";
778   else
779     return "ftst\;fnstsw\t%0";
780 }
781   [(set_attr "type" "multi")
782    (set (attr "mode")
783      (cond [(match_operand:SF 1 "" "")
784               (const_string "SF")
785             (match_operand:DF 1 "" "")
786               (const_string "DF")
787            ]
788            (const_string "XF")))])
789
790 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
791 ;; used to manage the reg stack popping would not be preserved.
792
793 (define_insn "*cmpfp_2_sf"
794   [(set (reg:CCFP 18)
795         (compare:CCFP
796           (match_operand:SF 0 "register_operand" "f")
797           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798   "TARGET_80387"
799   "* return output_fp_compare (insn, operands, 0, 0);"
800   [(set_attr "type" "fcmp")
801    (set_attr "mode" "SF")])
802
803 (define_insn "*cmpfp_2_sf_1"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809           UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 2, 0);"
812   [(set_attr "type" "fcmp")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_2_df"
816   [(set (reg:CCFP 18)
817         (compare:CCFP
818           (match_operand:DF 0 "register_operand" "f")
819           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820   "TARGET_80387"
821   "* return output_fp_compare (insn, operands, 0, 0);"
822   [(set_attr "type" "fcmp")
823    (set_attr "mode" "DF")])
824
825 (define_insn "*cmpfp_2_df_1"
826   [(set (match_operand:HI 0 "register_operand" "=a")
827         (unspec:HI
828           [(compare:CCFP
829              (match_operand:DF 1 "register_operand" "f")
830              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831           UNSPEC_FNSTSW))]
832   "TARGET_80387"
833   "* return output_fp_compare (insn, operands, 2, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_2_xf"
838   [(set (reg:CCFP 18)
839         (compare:CCFP
840           (match_operand:XF 0 "register_operand" "f")
841           (match_operand:XF 1 "register_operand" "f")))]
842   "TARGET_80387"
843   "* return output_fp_compare (insn, operands, 0, 0);"
844   [(set_attr "type" "fcmp")
845    (set_attr "mode" "XF")])
846
847 (define_insn "*cmpfp_2_xf_1"
848   [(set (match_operand:HI 0 "register_operand" "=a")
849         (unspec:HI
850           [(compare:CCFP
851              (match_operand:XF 1 "register_operand" "f")
852              (match_operand:XF 2 "register_operand" "f"))]
853           UNSPEC_FNSTSW))]
854   "TARGET_80387"
855   "* return output_fp_compare (insn, operands, 2, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2u"
860   [(set (reg:CCFPU 18)
861         (compare:CCFPU
862           (match_operand 0 "register_operand" "f")
863           (match_operand 1 "register_operand" "f")))]
864   "TARGET_80387
865    && FLOAT_MODE_P (GET_MODE (operands[0]))
866    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867   "* return output_fp_compare (insn, operands, 0, 1);"
868   [(set_attr "type" "fcmp")
869    (set (attr "mode")
870      (cond [(match_operand:SF 1 "" "")
871               (const_string "SF")
872             (match_operand:DF 1 "" "")
873               (const_string "DF")
874            ]
875            (const_string "XF")))])
876
877 (define_insn "*cmpfp_2u_1"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFPU
881              (match_operand 1 "register_operand" "f")
882              (match_operand 2 "register_operand" "f"))]
883           UNSPEC_FNSTSW))]
884   "TARGET_80387
885    && FLOAT_MODE_P (GET_MODE (operands[1]))
886    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887   "* return output_fp_compare (insn, operands, 2, 1);"
888   [(set_attr "type" "multi")
889    (set (attr "mode")
890      (cond [(match_operand:SF 1 "" "")
891               (const_string "SF")
892             (match_operand:DF 1 "" "")
893               (const_string "DF")
894            ]
895            (const_string "XF")))])
896
897 ;; Patterns to match the SImode-in-memory ficom instructions.
898 ;;
899 ;; %%% Play games with accepting gp registers, as otherwise we have to
900 ;; force them to memory during rtl generation, which is no good.  We
901 ;; can get rid of this once we teach reload to do memory input reloads 
902 ;; via pushes.
903
904 (define_insn "*ficom_1"
905   [(set (reg:CCFP 18)
906         (compare:CCFP
907           (match_operand 0 "register_operand" "f,f")
908           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911   "#")
912
913 ;; Split the not-really-implemented gp register case into a
914 ;; push-op-pop sequence.
915 ;;
916 ;; %%% This is most efficient, but am I gonna get in trouble
917 ;; for separating cc0_setter and cc0_user?
918
919 (define_split
920   [(set (reg:CCFP 18)
921         (compare:CCFP
922           (match_operand:SF 0 "register_operand" "")
923           (float (match_operand:SI 1 "register_operand" ""))))]
924   "0 && TARGET_80387 && reload_completed"
925   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932 ;; FP compares, step 2
933 ;; Move the fpsw to ax.
934
935 (define_insn "*x86_fnstsw_1"
936   [(set (match_operand:HI 0 "register_operand" "=a")
937         (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938   "TARGET_80387"
939   "fnstsw\t%0"
940   [(set_attr "length" "2")
941    (set_attr "mode" "SI")
942    (set_attr "unit" "i387")
943    (set_attr "ppro_uops" "few")])
944
945 ;; FP compares, step 3
946 ;; Get ax into flags, general case.
947
948 (define_insn "x86_sahf_1"
949   [(set (reg:CC 17)
950         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951   "!TARGET_64BIT"
952   "sahf"
953   [(set_attr "length" "1")
954    (set_attr "athlon_decode" "vector")
955    (set_attr "mode" "SI")
956    (set_attr "ppro_uops" "one")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i"
961   [(set (reg:CCFP 17)
962         (compare:CCFP (match_operand 0 "register_operand" "f")
963                       (match_operand 1 "register_operand" "f")))]
964   "TARGET_80387 && TARGET_CMOVE
965    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966    && FLOAT_MODE_P (GET_MODE (operands[0]))
967    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968   "* return output_fp_compare (insn, operands, 1, 0);"
969   [(set_attr "type" "fcmp")
970    (set (attr "mode")
971      (cond [(match_operand:SF 1 "" "")
972               (const_string "SF")
973             (match_operand:DF 1 "" "")
974               (const_string "DF")
975            ]
976            (const_string "XF")))
977    (set_attr "athlon_decode" "vector")])
978
979 (define_insn "*cmpfp_i_sse"
980   [(set (reg:CCFP 17)
981         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983   "TARGET_80387
984    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986   "* return output_fp_compare (insn, operands, 1, 0);"
987   [(set_attr "type" "fcmp,ssecomi")
988    (set (attr "mode")
989      (if_then_else (match_operand:SF 1 "" "")
990         (const_string "SF")
991         (const_string "DF")))
992    (set_attr "athlon_decode" "vector")])
993
994 (define_insn "*cmpfp_i_sse_only"
995   [(set (reg:CCFP 17)
996         (compare:CCFP (match_operand 0 "register_operand" "x")
997                       (match_operand 1 "nonimmediate_operand" "xm")))]
998   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")])
1007
1008 (define_insn "*cmpfp_iu"
1009   [(set (reg:CCFPU 17)
1010         (compare:CCFPU (match_operand 0 "register_operand" "f")
1011                        (match_operand 1 "register_operand" "f")))]
1012   "TARGET_80387 && TARGET_CMOVE
1013    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014    && FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 1);"
1017   [(set_attr "type" "fcmp")
1018    (set (attr "mode")
1019      (cond [(match_operand:SF 1 "" "")
1020               (const_string "SF")
1021             (match_operand:DF 1 "" "")
1022               (const_string "DF")
1023            ]
1024            (const_string "XF")))
1025    (set_attr "athlon_decode" "vector")])
1026
1027 (define_insn "*cmpfp_iu_sse"
1028   [(set (reg:CCFPU 17)
1029         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031   "TARGET_80387
1032    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 1);"
1035   [(set_attr "type" "fcmp,ssecomi")
1036    (set (attr "mode")
1037      (if_then_else (match_operand:SF 1 "" "")
1038         (const_string "SF")
1039         (const_string "DF")))
1040    (set_attr "athlon_decode" "vector")])
1041
1042 (define_insn "*cmpfp_iu_sse_only"
1043   [(set (reg:CCFPU 17)
1044         (compare:CCFPU (match_operand 0 "register_operand" "x")
1045                        (match_operand 1 "nonimmediate_operand" "xm")))]
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 \f
1056 ;; Move instructions.
1057
1058 ;; General case of fullword move.
1059
1060 (define_expand "movsi"
1061   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062         (match_operand:SI 1 "general_operand" ""))]
1063   ""
1064   "ix86_expand_move (SImode, operands); DONE;")
1065
1066 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1067 ;; general_operand.
1068 ;;
1069 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1070 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072 ;; targets without our curiosities, and it is just as easy to represent
1073 ;; this differently.
1074
1075 (define_insn "*pushsi2"
1076   [(set (match_operand:SI 0 "push_operand" "=<")
1077         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078   "!TARGET_64BIT"
1079   "push{l}\t%1"
1080   [(set_attr "type" "push")
1081    (set_attr "mode" "SI")])
1082
1083 ;; For 64BIT abi we always round up to 8 bytes.
1084 (define_insn "*pushsi2_rex64"
1085   [(set (match_operand:SI 0 "push_operand" "=X")
1086         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087   "TARGET_64BIT"
1088   "push{q}\t%q1"
1089   [(set_attr "type" "push")
1090    (set_attr "mode" "SI")])
1091
1092 (define_insn "*pushsi2_prologue"
1093   [(set (match_operand:SI 0 "push_operand" "=<")
1094         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095    (clobber (mem:BLK (scratch)))]
1096   "!TARGET_64BIT"
1097   "push{l}\t%1"
1098   [(set_attr "type" "push")
1099    (set_attr "mode" "SI")])
1100
1101 (define_insn "*popsi1_epilogue"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103         (mem:SI (reg:SI 7)))
1104    (set (reg:SI 7)
1105         (plus:SI (reg:SI 7) (const_int 4)))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "pop{l}\t%0"
1109   [(set_attr "type" "pop")
1110    (set_attr "mode" "SI")])
1111
1112 (define_insn "popsi1"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI 7)))
1115    (set (reg:SI 7)
1116         (plus:SI (reg:SI 7) (const_int 4)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "*movsi_xor"
1123   [(set (match_operand:SI 0 "register_operand" "=r")
1124         (match_operand:SI 1 "const0_operand" "i"))
1125    (clobber (reg:CC 17))]
1126   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127   "xor{l}\t{%0, %0|%0, %0}"
1128   [(set_attr "type" "alu1")
1129    (set_attr "mode" "SI")
1130    (set_attr "length_immediate" "0")])
1131  
1132 (define_insn "*movsi_or"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "immediate_operand" "i"))
1135    (clobber (reg:CC 17))]
1136   "reload_completed
1137    && operands[1] == constm1_rtx
1138    && (TARGET_PENTIUM || optimize_size)"
1139 {
1140   operands[1] = constm1_rtx;
1141   return "or{l}\t{%1, %0|%0, %1}";
1142 }
1143   [(set_attr "type" "alu1")
1144    (set_attr "mode" "SI")
1145    (set_attr "length_immediate" "1")])
1146
1147 (define_insn "*movsi_1"
1148   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152 {
1153   switch (get_attr_type (insn))
1154     {
1155     case TYPE_SSEMOV:
1156       if (get_attr_mode (insn) == MODE_TI)
1157         return "movdqa\t{%1, %0|%0, %1}";
1158       return "movd\t{%1, %0|%0, %1}";
1159
1160     case TYPE_MMXMOV:
1161       if (get_attr_mode (insn) == MODE_DI)
1162         return "movq\t{%1, %0|%0, %1}";
1163       return "movd\t{%1, %0|%0, %1}";
1164
1165     case TYPE_LEA:
1166       return "lea{l}\t{%1, %0|%0, %1}";
1167
1168     default:
1169       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170         abort();
1171       return "mov{l}\t{%1, %0|%0, %1}";
1172     }
1173 }
1174   [(set (attr "type")
1175      (cond [(eq_attr "alternative" "2,3,4")
1176               (const_string "mmxmov")
1177             (eq_attr "alternative" "5,6,7")
1178               (const_string "ssemov")
1179             (and (ne (symbol_ref "flag_pic") (const_int 0))
1180                  (match_operand:SI 1 "symbolic_operand" ""))
1181               (const_string "lea")
1182            ]
1183            (const_string "imov")))
1184    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186 (define_insn "*movsi_1_nointernunit"
1187   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191 {
1192   switch (get_attr_type (insn))
1193     {
1194     case TYPE_SSEMOV:
1195       if (get_attr_mode (insn) == MODE_TI)
1196         return "movdqa\t{%1, %0|%0, %1}";
1197       return "movd\t{%1, %0|%0, %1}";
1198
1199     case TYPE_MMXMOV:
1200       if (get_attr_mode (insn) == MODE_DI)
1201         return "movq\t{%1, %0|%0, %1}";
1202       return "movd\t{%1, %0|%0, %1}";
1203
1204     case TYPE_LEA:
1205       return "lea{l}\t{%1, %0|%0, %1}";
1206
1207     default:
1208       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209         abort();
1210       return "mov{l}\t{%1, %0|%0, %1}";
1211     }
1212 }
1213   [(set (attr "type")
1214      (cond [(eq_attr "alternative" "2,3,4")
1215               (const_string "mmxmov")
1216             (eq_attr "alternative" "5,6,7")
1217               (const_string "ssemov")
1218             (and (ne (symbol_ref "flag_pic") (const_int 0))
1219                  (match_operand:SI 1 "symbolic_operand" ""))
1220               (const_string "lea")
1221            ]
1222            (const_string "imov")))
1223    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225 ;; Stores and loads of ax to arbitrary constant address.
1226 ;; We fake an second form of instruction to force reload to load address
1227 ;; into register when rax is not available
1228 (define_insn "*movabssi_1_rex64"
1229   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232   "@
1233    movabs{l}\t{%1, %P0|%P0, %1}
1234    mov{l}\t{%1, %a0|%a0, %1}"
1235   [(set_attr "type" "imov")
1236    (set_attr "modrm" "0,*")
1237    (set_attr "length_address" "8,0")
1238    (set_attr "length_immediate" "0,*")
1239    (set_attr "memory" "store")
1240    (set_attr "mode" "SI")])
1241
1242 (define_insn "*movabssi_2_rex64"
1243   [(set (match_operand:SI 0 "register_operand" "=a,r")
1244         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246   "@
1247    movabs{l}\t{%P1, %0|%0, %P1}
1248    mov{l}\t{%a1, %0|%0, %a1}"
1249   [(set_attr "type" "imov")
1250    (set_attr "modrm" "0,*")
1251    (set_attr "length_address" "8,0")
1252    (set_attr "length_immediate" "0")
1253    (set_attr "memory" "load")
1254    (set_attr "mode" "SI")])
1255
1256 (define_insn "*swapsi"
1257   [(set (match_operand:SI 0 "register_operand" "+r")
1258         (match_operand:SI 1 "register_operand" "+r"))
1259    (set (match_dup 1)
1260         (match_dup 0))]
1261   ""
1262   "xchg{l}\t%1, %0"
1263   [(set_attr "type" "imov")
1264    (set_attr "pent_pair" "np")
1265    (set_attr "athlon_decode" "vector")
1266    (set_attr "mode" "SI")
1267    (set_attr "modrm" "0")
1268    (set_attr "ppro_uops" "few")])
1269
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=<,<")
1278         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279   "!TARGET_64BIT"
1280   "@
1281    push{w}\t{|WORD PTR }%1
1282    push{w}\t%1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(and (eq_attr "alternative" "0")
1315                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316                           (const_int 0))
1317                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1318                           (const_int 0))))
1319               (const_string "imov")
1320             (and (eq_attr "alternative" "1,2")
1321                  (match_operand:HI 1 "aligned_operand" ""))
1322               (const_string "imov")
1323             (and (ne (symbol_ref "TARGET_MOVX")
1324                      (const_int 0))
1325                  (eq_attr "alternative" "0,2"))
1326               (const_string "imovx")
1327            ]
1328            (const_string "imov")))
1329     (set (attr "mode")
1330       (cond [(eq_attr "type" "imovx")
1331                (const_string "SI")
1332              (and (eq_attr "alternative" "1,2")
1333                   (match_operand:HI 1 "aligned_operand" ""))
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "0")
1336                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337                            (const_int 0))
1338                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1339                            (const_int 0))))
1340                (const_string "SI")
1341             ]
1342             (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351   "@
1352    movabs{w}\t{%1, %P0|%P0, %1}
1353    mov{w}\t{%1, %a0|%a0, %1}"
1354   [(set_attr "type" "imov")
1355    (set_attr "modrm" "0,*")
1356    (set_attr "length_address" "8,0")
1357    (set_attr "length_immediate" "0,*")
1358    (set_attr "memory" "store")
1359    (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362   [(set (match_operand:HI 0 "register_operand" "=a,r")
1363         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365   "@
1366    movabs{w}\t{%P1, %0|%0, %P1}
1367    mov{w}\t{%a1, %0|%0, %a1}"
1368   [(set_attr "type" "imov")
1369    (set_attr "modrm" "0,*")
1370    (set_attr "length_address" "8,0")
1371    (set_attr "length_immediate" "0")
1372    (set_attr "memory" "load")
1373    (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376   [(set (match_operand:HI 0 "register_operand" "+r")
1377         (match_operand:HI 1 "register_operand" "+r"))
1378    (set (match_dup 1)
1379         (match_dup 0))]
1380   "TARGET_PARTIAL_REG_STALL"
1381   "xchg{w}\t%1, %0"
1382   [(set_attr "type" "imov")
1383    (set_attr "pent_pair" "np")
1384    (set_attr "mode" "HI")
1385    (set_attr "modrm" "0")
1386    (set_attr "ppro_uops" "few")])
1387
1388 (define_insn "*swaphi_2"
1389   [(set (match_operand:HI 0 "register_operand" "+r")
1390         (match_operand:HI 1 "register_operand" "+r"))
1391    (set (match_dup 1)
1392         (match_dup 0))]
1393   "! TARGET_PARTIAL_REG_STALL"
1394   "xchg{l}\t%k1, %k0"
1395   [(set_attr "type" "imov")
1396    (set_attr "pent_pair" "np")
1397    (set_attr "mode" "SI")
1398    (set_attr "modrm" "0")
1399    (set_attr "ppro_uops" "few")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC 17))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X,X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444   "!TARGET_64BIT"
1445   "@
1446    push{w}\t{|word ptr }%1
1447    push{w}\t%w1"
1448   [(set_attr "type" "push")
1449    (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453   [(set (match_operand:QI 0 "push_operand" "=X")
1454         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455   "TARGET_64BIT"
1456   "push{q}\t%q1"
1457   [(set_attr "type" "push")
1458    (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there.  Then we use movzx.
1470 (define_insn "*movqi_1"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1473   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475   switch (get_attr_type (insn))
1476     {
1477     case TYPE_IMOVX:
1478       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1479         abort ();
1480       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481     default:
1482       if (get_attr_mode (insn) == MODE_SI)
1483         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484       else
1485         return "mov{b}\t{%1, %0|%0, %1}";
1486     }
1487 }
1488   [(set (attr "type")
1489      (cond [(and (eq_attr "alternative" "3")
1490                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491                           (const_int 0))
1492                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1493                           (const_int 0))))
1494               (const_string "imov")
1495             (eq_attr "alternative" "3,5")
1496               (const_string "imovx")
1497             (and (ne (symbol_ref "TARGET_MOVX")
1498                      (const_int 0))
1499                  (eq_attr "alternative" "2"))
1500               (const_string "imovx")
1501            ]
1502            (const_string "imov")))
1503    (set (attr "mode")
1504       (cond [(eq_attr "alternative" "3,4,5")
1505                (const_string "SI")
1506              (eq_attr "alternative" "6")
1507                (const_string "QI")
1508              (eq_attr "type" "imovx")
1509                (const_string "SI")
1510              (and (eq_attr "type" "imov")
1511                   (and (eq_attr "alternative" "0,1,2")
1512                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513                            (const_int 0))))
1514                (const_string "SI")
1515              ;; Avoid partial register stalls when not using QImode arithmetic
1516              (and (eq_attr "type" "imov")
1517                   (and (eq_attr "alternative" "0,1,2")
1518                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                 (const_int 0))
1520                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1521                                 (const_int 0)))))
1522                (const_string "SI")
1523            ]
1524            (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527   [(parallel [(match_operand:QI 0 "" "=m")
1528               (match_operand:QI 1 "register_operand" "r")
1529               (match_operand:QI 2 "register_operand" "=&q")])]
1530   ""
1531 {
1532   rtx op0, op1, op2;
1533   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535   if (reg_overlap_mentioned_p (op2, op0))
1536     abort ();
1537   if (! q_regs_operand (op1, QImode))
1538     {
1539       emit_insn (gen_movqi (op2, op1));
1540       op1 = op2;
1541     }
1542   emit_insn (gen_movqi (op0, op1));
1543   DONE;
1544 })
1545
1546 (define_insn "*swapqi"
1547   [(set (match_operand:QI 0 "register_operand" "+r")
1548         (match_operand:QI 1 "register_operand" "+r"))
1549    (set (match_dup 1)
1550         (match_dup 0))]
1551   ""
1552   "xchg{b}\t%1, %0"
1553   [(set_attr "type" "imov")
1554    (set_attr "pent_pair" "np")
1555    (set_attr "mode" "QI")
1556    (set_attr "modrm" "0")
1557    (set_attr "ppro_uops" "few")])
1558
1559 (define_expand "movstrictqi"
1560   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1561         (match_operand:QI 1 "general_operand" ""))]
1562   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1563 {
1564   /* Don't generate memory->memory moves, go through a register.  */
1565   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1566     operands[1] = force_reg (QImode, operands[1]);
1567 })
1568
1569 (define_insn "*movstrictqi_1"
1570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1571         (match_operand:QI 1 "general_operand" "*qn,m"))]
1572   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1573    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1574   "mov{b}\t{%1, %0|%0, %1}"
1575   [(set_attr "type" "imov")
1576    (set_attr "mode" "QI")])
1577
1578 (define_insn "*movstrictqi_xor"
1579   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1580         (match_operand:QI 1 "const0_operand" "i"))
1581    (clobber (reg:CC 17))]
1582   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1583   "xor{b}\t{%0, %0|%0, %0}"
1584   [(set_attr "type" "alu1")
1585    (set_attr "mode" "QI")
1586    (set_attr "length_immediate" "0")])
1587
1588 (define_insn "*movsi_extv_1"
1589   [(set (match_operand:SI 0 "register_operand" "=R")
1590         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1591                          (const_int 8)
1592                          (const_int 8)))]
1593   ""
1594   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1595   [(set_attr "type" "imovx")
1596    (set_attr "mode" "SI")])
1597
1598 (define_insn "*movhi_extv_1"
1599   [(set (match_operand:HI 0 "register_operand" "=R")
1600         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1601                          (const_int 8)
1602                          (const_int 8)))]
1603   ""
1604   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1605   [(set_attr "type" "imovx")
1606    (set_attr "mode" "SI")])
1607
1608 (define_insn "*movqi_extv_1"
1609   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1610         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1611                          (const_int 8)
1612                          (const_int 8)))]
1613   "!TARGET_64BIT"
1614 {
1615   switch (get_attr_type (insn))
1616     {
1617     case TYPE_IMOVX:
1618       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1619     default:
1620       return "mov{b}\t{%h1, %0|%0, %h1}";
1621     }
1622 }
1623   [(set (attr "type")
1624      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1625                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1626                              (ne (symbol_ref "TARGET_MOVX")
1627                                  (const_int 0))))
1628         (const_string "imovx")
1629         (const_string "imov")))
1630    (set (attr "mode")
1631      (if_then_else (eq_attr "type" "imovx")
1632         (const_string "SI")
1633         (const_string "QI")))])
1634
1635 (define_insn "*movqi_extv_1_rex64"
1636   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1637         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638                          (const_int 8)
1639                          (const_int 8)))]
1640   "TARGET_64BIT"
1641 {
1642   switch (get_attr_type (insn))
1643     {
1644     case TYPE_IMOVX:
1645       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1646     default:
1647       return "mov{b}\t{%h1, %0|%0, %h1}";
1648     }
1649 }
1650   [(set (attr "type")
1651      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1652                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1653                              (ne (symbol_ref "TARGET_MOVX")
1654                                  (const_int 0))))
1655         (const_string "imovx")
1656         (const_string "imov")))
1657    (set (attr "mode")
1658      (if_then_else (eq_attr "type" "imovx")
1659         (const_string "SI")
1660         (const_string "QI")))])
1661
1662 ;; Stores and loads of ax to arbitrary constant address.
1663 ;; We fake an second form of instruction to force reload to load address
1664 ;; into register when rax is not available
1665 (define_insn "*movabsqi_1_rex64"
1666   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1667         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1668   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1669   "@
1670    movabs{b}\t{%1, %P0|%P0, %1}
1671    mov{b}\t{%1, %a0|%a0, %1}"
1672   [(set_attr "type" "imov")
1673    (set_attr "modrm" "0,*")
1674    (set_attr "length_address" "8,0")
1675    (set_attr "length_immediate" "0,*")
1676    (set_attr "memory" "store")
1677    (set_attr "mode" "QI")])
1678
1679 (define_insn "*movabsqi_2_rex64"
1680   [(set (match_operand:QI 0 "register_operand" "=a,r")
1681         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1682   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1683   "@
1684    movabs{b}\t{%P1, %0|%0, %P1}
1685    mov{b}\t{%a1, %0|%0, %a1}"
1686   [(set_attr "type" "imov")
1687    (set_attr "modrm" "0,*")
1688    (set_attr "length_address" "8,0")
1689    (set_attr "length_immediate" "0")
1690    (set_attr "memory" "load")
1691    (set_attr "mode" "QI")])
1692
1693 (define_insn "*movsi_extzv_1"
1694   [(set (match_operand:SI 0 "register_operand" "=R")
1695         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1696                          (const_int 8)
1697                          (const_int 8)))]
1698   ""
1699   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1700   [(set_attr "type" "imovx")
1701    (set_attr "mode" "SI")])
1702
1703 (define_insn "*movqi_extzv_2"
1704   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1705         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1706                                     (const_int 8)
1707                                     (const_int 8)) 0))]
1708   "!TARGET_64BIT"
1709 {
1710   switch (get_attr_type (insn))
1711     {
1712     case TYPE_IMOVX:
1713       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1714     default:
1715       return "mov{b}\t{%h1, %0|%0, %h1}";
1716     }
1717 }
1718   [(set (attr "type")
1719      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721                              (ne (symbol_ref "TARGET_MOVX")
1722                                  (const_int 0))))
1723         (const_string "imovx")
1724         (const_string "imov")))
1725    (set (attr "mode")
1726      (if_then_else (eq_attr "type" "imovx")
1727         (const_string "SI")
1728         (const_string "QI")))])
1729
1730 (define_insn "*movqi_extzv_2_rex64"
1731   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "TARGET_64BIT"
1736 {
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1744 }
1745   [(set (attr "type")
1746      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747                         (ne (symbol_ref "TARGET_MOVX")
1748                             (const_int 0)))
1749         (const_string "imovx")
1750         (const_string "imov")))
1751    (set (attr "mode")
1752      (if_then_else (eq_attr "type" "imovx")
1753         (const_string "SI")
1754         (const_string "QI")))])
1755
1756 (define_insn "movsi_insv_1"
1757   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1758                          (const_int 8)
1759                          (const_int 8))
1760         (match_operand:SI 1 "general_operand" "Qmn"))]
1761   "!TARGET_64BIT"
1762   "mov{b}\t{%b1, %h0|%h0, %b1}"
1763   [(set_attr "type" "imov")
1764    (set_attr "mode" "QI")])
1765
1766 (define_insn "movdi_insv_1_rex64"
1767   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1768                          (const_int 8)
1769                          (const_int 8))
1770         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1771   "TARGET_64BIT"
1772   "mov{b}\t{%b1, %h0|%h0, %b1}"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "QI")])
1775
1776 (define_insn "*movqi_insv_2"
1777   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778                          (const_int 8)
1779                          (const_int 8))
1780         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1781                      (const_int 8)))]
1782   ""
1783   "mov{b}\t{%h1, %h0|%h0, %h1}"
1784   [(set_attr "type" "imov")
1785    (set_attr "mode" "QI")])
1786
1787 (define_expand "movdi"
1788   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1789         (match_operand:DI 1 "general_operand" ""))]
1790   ""
1791   "ix86_expand_move (DImode, operands); DONE;")
1792
1793 (define_insn "*pushdi"
1794   [(set (match_operand:DI 0 "push_operand" "=<")
1795         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1796   "!TARGET_64BIT"
1797   "#")
1798
1799 (define_insn "pushdi2_rex64"
1800   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1801         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1802   "TARGET_64BIT"
1803   "@
1804    push{q}\t%1
1805    #"
1806   [(set_attr "type" "push,multi")
1807    (set_attr "mode" "DI")])
1808
1809 ;; Convert impossible pushes of immediate to existing instructions.
1810 ;; First try to get scratch register and go through it.  In case this
1811 ;; fails, push sign extended lower part first and then overwrite
1812 ;; upper part by 32bit move.
1813 (define_peephole2
1814   [(match_scratch:DI 2 "r")
1815    (set (match_operand:DI 0 "push_operand" "")
1816         (match_operand:DI 1 "immediate_operand" ""))]
1817   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1818    && !x86_64_immediate_operand (operands[1], DImode)"
1819   [(set (match_dup 2) (match_dup 1))
1820    (set (match_dup 0) (match_dup 2))]
1821   "")
1822
1823 ;; We need to define this as both peepholer and splitter for case
1824 ;; peephole2 pass is not run.
1825 (define_peephole2
1826   [(set (match_operand:DI 0 "push_operand" "")
1827         (match_operand:DI 1 "immediate_operand" ""))]
1828   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1829    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1830   [(set (match_dup 0) (match_dup 1))
1831    (set (match_dup 2) (match_dup 3))]
1832   "split_di (operands + 1, 1, operands + 2, operands + 3);
1833    operands[1] = gen_lowpart (DImode, operands[2]);
1834    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1835                                                     GEN_INT (4)));
1836   ")
1837
1838 (define_split
1839   [(set (match_operand:DI 0 "push_operand" "")
1840         (match_operand:DI 1 "immediate_operand" ""))]
1841   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1842    && !symbolic_operand (operands[1], DImode)
1843    && !x86_64_immediate_operand (operands[1], DImode)"
1844   [(set (match_dup 0) (match_dup 1))
1845    (set (match_dup 2) (match_dup 3))]
1846   "split_di (operands + 1, 1, operands + 2, operands + 3);
1847    operands[1] = gen_lowpart (DImode, operands[2]);
1848    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1849                                                     GEN_INT (4)));
1850   ")
1851
1852 (define_insn "*pushdi2_prologue_rex64"
1853   [(set (match_operand:DI 0 "push_operand" "=<")
1854         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1855    (clobber (mem:BLK (scratch)))]
1856   "TARGET_64BIT"
1857   "push{q}\t%1"
1858   [(set_attr "type" "push")
1859    (set_attr "mode" "DI")])
1860
1861 (define_insn "*popdi1_epilogue_rex64"
1862   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1863         (mem:DI (reg:DI 7)))
1864    (set (reg:DI 7)
1865         (plus:DI (reg:DI 7) (const_int 8)))
1866    (clobber (mem:BLK (scratch)))]
1867   "TARGET_64BIT"
1868   "pop{q}\t%0"
1869   [(set_attr "type" "pop")
1870    (set_attr "mode" "DI")])
1871
1872 (define_insn "popdi1"
1873   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1874         (mem:DI (reg:DI 7)))
1875    (set (reg:DI 7)
1876         (plus:DI (reg:DI 7) (const_int 8)))]
1877   "TARGET_64BIT"
1878   "pop{q}\t%0"
1879   [(set_attr "type" "pop")
1880    (set_attr "mode" "DI")])
1881
1882 (define_insn "*movdi_xor_rex64"
1883   [(set (match_operand:DI 0 "register_operand" "=r")
1884         (match_operand:DI 1 "const0_operand" "i"))
1885    (clobber (reg:CC 17))]
1886   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1887    && reload_completed"
1888   "xor{l}\t{%k0, %k0|%k0, %k0}"
1889   [(set_attr "type" "alu1")
1890    (set_attr "mode" "SI")
1891    (set_attr "length_immediate" "0")])
1892
1893 (define_insn "*movdi_or_rex64"
1894   [(set (match_operand:DI 0 "register_operand" "=r")
1895         (match_operand:DI 1 "const_int_operand" "i"))
1896    (clobber (reg:CC 17))]
1897   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1898    && reload_completed
1899    && operands[1] == constm1_rtx"
1900 {
1901   operands[1] = constm1_rtx;
1902   return "or{q}\t{%1, %0|%0, %1}";
1903 }
1904   [(set_attr "type" "alu1")
1905    (set_attr "mode" "DI")
1906    (set_attr "length_immediate" "1")])
1907
1908 (define_insn "*movdi_2"
1909   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1910         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1911   "!TARGET_64BIT
1912    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1913   "@
1914    #
1915    #
1916    movq\t{%1, %0|%0, %1}
1917    movq\t{%1, %0|%0, %1}
1918    movq\t{%1, %0|%0, %1}
1919    movdqa\t{%1, %0|%0, %1}
1920    movq\t{%1, %0|%0, %1}"
1921   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1922    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1923
1924 (define_split
1925   [(set (match_operand:DI 0 "push_operand" "")
1926         (match_operand:DI 1 "general_operand" ""))]
1927   "!TARGET_64BIT && reload_completed
1928    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1929   [(const_int 0)]
1930   "ix86_split_long_move (operands); DONE;")
1931
1932 ;; %%% This multiword shite has got to go.
1933 (define_split
1934   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1935         (match_operand:DI 1 "general_operand" ""))]
1936   "!TARGET_64BIT && reload_completed
1937    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1938    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1939   [(const_int 0)]
1940   "ix86_split_long_move (operands); DONE;")
1941
1942 (define_insn "*movdi_1_rex64"
1943   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1944         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1945   "TARGET_64BIT
1946    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1947    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1948 {
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1975 }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "4")
1982               (const_string "multi")
1983             (and (ne (symbol_ref "flag_pic") (const_int 0))
1984                  (match_operand:DI 1 "symbolic_operand" ""))
1985               (const_string "lea")
1986            ]
1987            (const_string "imov")))
1988    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1989    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1990    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1991
1992 (define_insn "*movdi_1_rex64_nointerunit"
1993   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1994         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1995   "TARGET_64BIT
1996    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1997    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1998 {
1999   switch (get_attr_type (insn))
2000     {
2001     case TYPE_SSEMOV:
2002       if (get_attr_mode (insn) == MODE_TI)
2003           return "movdqa\t{%1, %0|%0, %1}";
2004       /* FALLTHRU */
2005     case TYPE_MMXMOV:
2006       return "movq\t{%1, %0|%0, %1}";
2007     case TYPE_MULTI:
2008       return "#";
2009     case TYPE_LEA:
2010       return "lea{q}\t{%a1, %0|%0, %a1}";
2011     default:
2012       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2013         abort ();
2014       if (get_attr_mode (insn) == MODE_SI)
2015         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2016       else if (which_alternative == 2)
2017         return "movabs{q}\t{%1, %0|%0, %1}";
2018       else
2019         return "mov{q}\t{%1, %0|%0, %1}";
2020     }
2021 }
2022   [(set (attr "type")
2023      (cond [(eq_attr "alternative" "5,6,7")
2024               (const_string "mmxmov")
2025             (eq_attr "alternative" "8,9,10")
2026               (const_string "ssemov")
2027             (eq_attr "alternative" "4")
2028               (const_string "multi")
2029             (and (ne (symbol_ref "flag_pic") (const_int 0))
2030                  (match_operand:DI 1 "symbolic_operand" ""))
2031               (const_string "lea")
2032            ]
2033            (const_string "imov")))
2034    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2035    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2036    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2037
2038 ;; Stores and loads of ax to arbitrary constant address.
2039 ;; We fake an second form of instruction to force reload to load address
2040 ;; into register when rax is not available
2041 (define_insn "*movabsdi_1_rex64"
2042   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2043         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2044   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2045   "@
2046    movabs{q}\t{%1, %P0|%P0, %1}
2047    mov{q}\t{%1, %a0|%a0, %1}"
2048   [(set_attr "type" "imov")
2049    (set_attr "modrm" "0,*")
2050    (set_attr "length_address" "8,0")
2051    (set_attr "length_immediate" "0,*")
2052    (set_attr "memory" "store")
2053    (set_attr "mode" "DI")])
2054
2055 (define_insn "*movabsdi_2_rex64"
2056   [(set (match_operand:DI 0 "register_operand" "=a,r")
2057         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2058   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2059   "@
2060    movabs{q}\t{%P1, %0|%0, %P1}
2061    mov{q}\t{%a1, %0|%0, %a1}"
2062   [(set_attr "type" "imov")
2063    (set_attr "modrm" "0,*")
2064    (set_attr "length_address" "8,0")
2065    (set_attr "length_immediate" "0")
2066    (set_attr "memory" "load")
2067    (set_attr "mode" "DI")])
2068
2069 ;; Convert impossible stores of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it.  In case this
2071 ;; fails, move by 32bit parts.
2072 (define_peephole2
2073   [(match_scratch:DI 2 "r")
2074    (set (match_operand:DI 0 "memory_operand" "")
2075         (match_operand:DI 1 "immediate_operand" ""))]
2076   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2077    && !x86_64_immediate_operand (operands[1], DImode)"
2078   [(set (match_dup 2) (match_dup 1))
2079    (set (match_dup 0) (match_dup 2))]
2080   "")
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 (define_peephole2
2085   [(set (match_operand:DI 0 "memory_operand" "")
2086         (match_operand:DI 1 "immediate_operand" ""))]
2087   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089   [(set (match_dup 2) (match_dup 3))
2090    (set (match_dup 4) (match_dup 5))]
2091   "split_di (operands, 2, operands + 2, operands + 4);")
2092
2093 (define_split
2094   [(set (match_operand:DI 0 "memory_operand" "")
2095         (match_operand:DI 1 "immediate_operand" ""))]
2096   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2097    && !symbolic_operand (operands[1], DImode)
2098    && !x86_64_immediate_operand (operands[1], DImode)"
2099   [(set (match_dup 2) (match_dup 3))
2100    (set (match_dup 4) (match_dup 5))]
2101   "split_di (operands, 2, operands + 2, operands + 4);")
2102
2103 (define_insn "*swapdi_rex64"
2104   [(set (match_operand:DI 0 "register_operand" "+r")
2105         (match_operand:DI 1 "register_operand" "+r"))
2106    (set (match_dup 1)
2107         (match_dup 0))]
2108   "TARGET_64BIT"
2109   "xchg{q}\t%1, %0"
2110   [(set_attr "type" "imov")
2111    (set_attr "pent_pair" "np")
2112    (set_attr "athlon_decode" "vector")
2113    (set_attr "mode" "DI")
2114    (set_attr "modrm" "0")
2115    (set_attr "ppro_uops" "few")])
2116
2117   
2118 (define_expand "movsf"
2119   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2120         (match_operand:SF 1 "general_operand" ""))]
2121   ""
2122   "ix86_expand_move (SFmode, operands); DONE;")
2123
2124 (define_insn "*pushsf"
2125   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2126         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2127   "!TARGET_64BIT"
2128 {
2129   switch (which_alternative)
2130     {
2131     case 1:
2132       return "push{l}\t%1";
2133
2134     default:
2135       /* This insn should be already split before reg-stack.  */
2136       abort ();
2137     }
2138 }
2139   [(set_attr "type" "multi,push,multi")
2140    (set_attr "mode" "SF,SI,SF")])
2141
2142 (define_insn "*pushsf_rex64"
2143   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2144         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2145   "TARGET_64BIT"
2146 {
2147   switch (which_alternative)
2148     {
2149     case 1:
2150       return "push{q}\t%q1";
2151
2152     default:
2153       /* This insn should be already split before reg-stack.  */
2154       abort ();
2155     }
2156 }
2157   [(set_attr "type" "multi,push,multi")
2158    (set_attr "mode" "SF,DI,SF")])
2159
2160 (define_split
2161   [(set (match_operand:SF 0 "push_operand" "")
2162         (match_operand:SF 1 "memory_operand" ""))]
2163   "reload_completed
2164    && GET_CODE (operands[1]) == MEM
2165    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2166    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2167   [(set (match_dup 0)
2168         (match_dup 1))]
2169   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2170
2171
2172 ;; %%% Kill this when call knows how to work this out.
2173 (define_split
2174   [(set (match_operand:SF 0 "push_operand" "")
2175         (match_operand:SF 1 "any_fp_register_operand" ""))]
2176   "!TARGET_64BIT"
2177   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2178    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2179
2180 (define_split
2181   [(set (match_operand:SF 0 "push_operand" "")
2182         (match_operand:SF 1 "any_fp_register_operand" ""))]
2183   "TARGET_64BIT"
2184   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2185    (set (mem:SF (reg:DI 7)) (match_dup 1))])
2186
2187 (define_insn "*movsf_1"
2188   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2189         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2190   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2191    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2192    && (reload_in_progress || reload_completed
2193        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2194        || GET_CODE (operands[1]) != CONST_DOUBLE
2195        || memory_operand (operands[0], SFmode))" 
2196 {
2197   switch (which_alternative)
2198     {
2199     case 0:
2200       if (REG_P (operands[1])
2201           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2202         return "fstp\t%y0";
2203       else if (STACK_TOP_P (operands[0]))
2204         return "fld%z1\t%y1";
2205       else
2206         return "fst\t%y0";
2207
2208     case 1:
2209       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2210         return "fstp%z0\t%y0";
2211       else
2212         return "fst%z0\t%y0";
2213
2214     case 2:
2215       return standard_80387_constant_opcode (operands[1]);
2216
2217     case 3:
2218     case 4:
2219       return "mov{l}\t{%1, %0|%0, %1}";
2220     case 5:
2221       if (get_attr_mode (insn) == MODE_TI)
2222         return "pxor\t%0, %0";
2223       else
2224         return "xorps\t%0, %0";
2225     case 6:
2226       if (get_attr_mode (insn) == MODE_V4SF)
2227         return "movaps\t{%1, %0|%0, %1}";
2228       else
2229         return "movss\t{%1, %0|%0, %1}";
2230     case 7:
2231     case 8:
2232       return "movss\t{%1, %0|%0, %1}";
2233
2234     case 9:
2235     case 10:
2236       return "movd\t{%1, %0|%0, %1}";
2237
2238     case 11:
2239       return "movq\t{%1, %0|%0, %1}";
2240
2241     default:
2242       abort();
2243     }
2244 }
2245   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2246    (set (attr "mode")
2247         (cond [(eq_attr "alternative" "3,4,9,10")
2248                  (const_string "SI")
2249                (eq_attr "alternative" "5")
2250                  (if_then_else
2251                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2252                                  (const_int 0))
2253                              (ne (symbol_ref "TARGET_SSE2")
2254                                  (const_int 0)))
2255                         (eq (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "TI")
2258                    (const_string "V4SF"))
2259                /* For architectures resolving dependencies on
2260                   whole SSE registers use APS move to break dependency
2261                   chains, otherwise use short move to avoid extra work. 
2262
2263                   Do the same for architectures resolving dependencies on
2264                   the parts.  While in DF mode it is better to always handle
2265                   just register parts, the SF mode is different due to lack
2266                   of instructions to load just part of the register.  It is
2267                   better to maintain the whole registers in single format
2268                   to avoid problems on using packed logical operations.  */
2269                (eq_attr "alternative" "6")
2270                  (if_then_else
2271                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2272                             (const_int 0))
2273                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2274                             (const_int 0)))
2275                    (const_string "V4SF")
2276                    (const_string "SF"))
2277                (eq_attr "alternative" "11")
2278                  (const_string "DI")]
2279                (const_string "SF")))])
2280
2281 (define_insn "*movsf_1_nointerunit"
2282   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2283         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       if (REG_P (operands[1])
2295           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2296         {
2297           if (REGNO (operands[0]) == FIRST_STACK_REG
2298               && TARGET_USE_FFREEP)
2299             return "ffreep\t%y0";
2300           return "fstp\t%y0";
2301         }
2302       else if (STACK_TOP_P (operands[0]))
2303         return "fld%z1\t%y1";
2304       else
2305         return "fst\t%y0";
2306
2307     case 1:
2308       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2309         return "fstp%z0\t%y0";
2310       else
2311         return "fst%z0\t%y0";
2312
2313     case 2:
2314       return standard_80387_constant_opcode (operands[1]);
2315
2316     case 3:
2317     case 4:
2318       return "mov{l}\t{%1, %0|%0, %1}";
2319     case 5:
2320       if (get_attr_mode (insn) == MODE_TI)
2321         return "pxor\t%0, %0";
2322       else
2323         return "xorps\t%0, %0";
2324     case 6:
2325       if (get_attr_mode (insn) == MODE_V4SF)
2326         return "movaps\t{%1, %0|%0, %1}";
2327       else
2328         return "movss\t{%1, %0|%0, %1}";
2329     case 7:
2330     case 8:
2331       return "movss\t{%1, %0|%0, %1}";
2332
2333     case 9:
2334     case 10:
2335       return "movd\t{%1, %0|%0, %1}";
2336
2337     case 11:
2338       return "movq\t{%1, %0|%0, %1}";
2339
2340     default:
2341       abort();
2342     }
2343 }
2344   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2345    (set (attr "mode")
2346         (cond [(eq_attr "alternative" "3,4,9,10")
2347                  (const_string "SI")
2348                (eq_attr "alternative" "5")
2349                  (if_then_else
2350                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2351                                  (const_int 0))
2352                              (ne (symbol_ref "TARGET_SSE2")
2353                                  (const_int 0)))
2354                         (eq (symbol_ref "optimize_size")
2355                             (const_int 0)))
2356                    (const_string "TI")
2357                    (const_string "V4SF"))
2358                /* For architectures resolving dependencies on
2359                   whole SSE registers use APS move to break dependency
2360                   chains, otherwise use short move to avoid extra work. 
2361
2362                   Do the same for architectures resolving dependencies on
2363                   the parts.  While in DF mode it is better to always handle
2364                   just register parts, the SF mode is different due to lack
2365                   of instructions to load just part of the register.  It is
2366                   better to maintain the whole registers in single format
2367                   to avoid problems on using packed logical operations.  */
2368                (eq_attr "alternative" "6")
2369                  (if_then_else
2370                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2371                             (const_int 0))
2372                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2373                             (const_int 0)))
2374                    (const_string "V4SF")
2375                    (const_string "SF"))
2376                (eq_attr "alternative" "11")
2377                  (const_string "DI")]
2378                (const_string "SF")))])
2379
2380 (define_insn "*swapsf"
2381   [(set (match_operand:SF 0 "register_operand" "+f")
2382         (match_operand:SF 1 "register_operand" "+f"))
2383    (set (match_dup 1)
2384         (match_dup 0))]
2385   "reload_completed || !TARGET_SSE"
2386 {
2387   if (STACK_TOP_P (operands[0]))
2388     return "fxch\t%1";
2389   else
2390     return "fxch\t%0";
2391 }
2392   [(set_attr "type" "fxch")
2393    (set_attr "mode" "SF")])
2394
2395 (define_expand "movdf"
2396   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2397         (match_operand:DF 1 "general_operand" ""))]
2398   ""
2399   "ix86_expand_move (DFmode, operands); DONE;")
2400
2401 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2402 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2403 ;; On the average, pushdf using integers can be still shorter.  Allow this
2404 ;; pattern for optimize_size too.
2405
2406 (define_insn "*pushdf_nointeger"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2409   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,SI,DF")])
2416
2417 (define_insn "*pushdf_integer"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2420   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422   /* This insn should be already split before reg-stack.  */
2423   abort ();
2424 }
2425   [(set_attr "type" "multi")
2426    (set_attr "mode" "DF,SI,DF")])
2427
2428 ;; %%% Kill this when call knows how to work this out.
2429 (define_split
2430   [(set (match_operand:DF 0 "push_operand" "")
2431         (match_operand:DF 1 "any_fp_register_operand" ""))]
2432   "!TARGET_64BIT && reload_completed"
2433   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2434    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2435   "")
2436
2437 (define_split
2438   [(set (match_operand:DF 0 "push_operand" "")
2439         (match_operand:DF 1 "any_fp_register_operand" ""))]
2440   "TARGET_64BIT && reload_completed"
2441   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2442    (set (mem:DF (reg:DI 7)) (match_dup 1))]
2443   "")
2444
2445 (define_split
2446   [(set (match_operand:DF 0 "push_operand" "")
2447         (match_operand:DF 1 "general_operand" ""))]
2448   "reload_completed"
2449   [(const_int 0)]
2450   "ix86_split_long_move (operands); DONE;")
2451
2452 ;; Moving is usually shorter when only FP registers are used. This separate
2453 ;; movdf pattern avoids the use of integer registers for FP operations
2454 ;; when optimizing for size.
2455
2456 (define_insn "*movdf_nointeger"
2457   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2458         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2459   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2460    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2461    && (reload_in_progress || reload_completed
2462        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2463        || GET_CODE (operands[1]) != CONST_DOUBLE
2464        || memory_operand (operands[0], DFmode))" 
2465 {
2466   switch (which_alternative)
2467     {
2468     case 0:
2469       if (REG_P (operands[1])
2470           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2471         {
2472           if (REGNO (operands[0]) == FIRST_STACK_REG
2473               && TARGET_USE_FFREEP)
2474             return "ffreep\t%y0";
2475           return "fstp\t%y0";
2476         }
2477       else if (STACK_TOP_P (operands[0]))
2478         return "fld%z1\t%y1";
2479       else
2480         return "fst\t%y0";
2481
2482     case 1:
2483       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2484         return "fstp%z0\t%y0";
2485       else
2486         return "fst%z0\t%y0";
2487
2488     case 2:
2489       return standard_80387_constant_opcode (operands[1]);
2490
2491     case 3:
2492     case 4:
2493       return "#";
2494     case 5:
2495       switch (get_attr_mode (insn))
2496         {
2497         case MODE_V4SF:
2498           return "xorps\t%0, %0";
2499         case MODE_V2DF:
2500           return "xorpd\t%0, %0";
2501         case MODE_TI:
2502           return "pxor\t%0, %0";
2503         default:
2504           abort ();
2505         }
2506     case 6:
2507       switch (get_attr_mode (insn))
2508         {
2509         case MODE_V4SF:
2510           return "movaps\t{%1, %0|%0, %1}";
2511         case MODE_V2DF:
2512           return "movapd\t{%1, %0|%0, %1}";
2513         case MODE_DF:
2514           return "movsd\t{%1, %0|%0, %1}";
2515         default:
2516           abort ();
2517         }
2518     case 7:
2519       if (get_attr_mode (insn) == MODE_V2DF)
2520         return "movlpd\t{%1, %0|%0, %1}";
2521       else
2522         return "movsd\t{%1, %0|%0, %1}";
2523     case 8:
2524       return "movsd\t{%1, %0|%0, %1}";
2525
2526     default:
2527       abort();
2528     }
2529 }
2530   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2531    (set (attr "mode")
2532         (cond [(eq_attr "alternative" "3,4")
2533                  (const_string "SI")
2534                /* xorps is one byte shorter.  */
2535                (eq_attr "alternative" "5")
2536                  (cond [(ne (symbol_ref "optimize_size")
2537                             (const_int 0))
2538                           (const_string "V4SF")
2539                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2540                             (const_int 0))
2541                           (const_string "TI")]
2542                        (const_string "V2DF"))
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                    (const_string "DF"))
2557                /* For architectures resolving dependencies on register
2558                   parts we may avoid extra work to zero out upper part
2559                   of register.  */
2560                (eq_attr "alternative" "7")
2561                  (if_then_else
2562                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2563                        (const_int 0))
2564                    (const_string "V2DF")
2565                    (const_string "DF"))]
2566                (const_string "DF")))])
2567
2568 (define_insn "*movdf_integer"
2569   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2570         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2572    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2573    && (reload_in_progress || reload_completed
2574        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2575        || GET_CODE (operands[1]) != CONST_DOUBLE
2576        || memory_operand (operands[0], DFmode))" 
2577 {
2578   switch (which_alternative)
2579     {
2580     case 0:
2581       if (REG_P (operands[1])
2582           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         {
2584           if (REGNO (operands[0]) == FIRST_STACK_REG
2585               && TARGET_USE_FFREEP)
2586             return "ffreep\t%y0";
2587           return "fstp\t%y0";
2588         }
2589       else if (STACK_TOP_P (operands[0]))
2590         return "fld%z1\t%y1";
2591       else
2592         return "fst\t%y0";
2593
2594     case 1:
2595       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596         return "fstp%z0\t%y0";
2597       else
2598         return "fst%z0\t%y0";
2599
2600     case 2:
2601       return standard_80387_constant_opcode (operands[1]);
2602
2603     case 3:
2604     case 4:
2605       return "#";
2606
2607     case 5:
2608       switch (get_attr_mode (insn))
2609         {
2610         case MODE_V4SF:
2611           return "xorps\t%0, %0";
2612         case MODE_V2DF:
2613           return "xorpd\t%0, %0";
2614         case MODE_TI:
2615           return "pxor\t%0, %0";
2616         default:
2617           abort ();
2618         }
2619     case 6:
2620       switch (get_attr_mode (insn))
2621         {
2622         case MODE_V4SF:
2623           return "movaps\t{%1, %0|%0, %1}";
2624         case MODE_V2DF:
2625           return "movapd\t{%1, %0|%0, %1}";
2626         case MODE_DF:
2627           return "movsd\t{%1, %0|%0, %1}";
2628         default:
2629           abort ();
2630         }
2631     case 7:
2632       if (get_attr_mode (insn) == MODE_V2DF)
2633         return "movlpd\t{%1, %0|%0, %1}";
2634       else
2635         return "movsd\t{%1, %0|%0, %1}";
2636     case 8:
2637       return "movsd\t{%1, %0|%0, %1}";
2638
2639     default:
2640       abort();
2641     }
2642 }
2643   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2644    (set (attr "mode")
2645         (cond [(eq_attr "alternative" "3,4")
2646                  (const_string "SI")
2647                /* xorps is one byte shorter.  */
2648                (eq_attr "alternative" "5")
2649                  (cond [(ne (symbol_ref "optimize_size")
2650                             (const_int 0))
2651                           (const_string "V4SF")
2652                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2653                             (const_int 0))
2654                           (const_string "TI")]
2655                        (const_string "V2DF"))
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.  
2659
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                   [(ne (symbol_ref "optimize_size")
2664                        (const_int 0))
2665                      (const_string "V4SF")
2666                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                        (const_int 0))
2668                      (const_string "V2DF")]
2669                    (const_string "DF"))
2670                /* For architectures resolving dependencies on register
2671                   parts we may avoid extra work to zero out upper part
2672                   of register.  */
2673                (eq_attr "alternative" "7")
2674                  (if_then_else
2675                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2676                        (const_int 0))
2677                    (const_string "V2DF")
2678                    (const_string "DF"))]
2679                (const_string "DF")))])
2680
2681 (define_split
2682   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2683         (match_operand:DF 1 "general_operand" ""))]
2684   "reload_completed
2685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2686    && ! (ANY_FP_REG_P (operands[0]) || 
2687          (GET_CODE (operands[0]) == SUBREG
2688           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2689    && ! (ANY_FP_REG_P (operands[1]) || 
2690          (GET_CODE (operands[1]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2692   [(const_int 0)]
2693   "ix86_split_long_move (operands); DONE;")
2694
2695 (define_insn "*swapdf"
2696   [(set (match_operand:DF 0 "register_operand" "+f")
2697         (match_operand:DF 1 "register_operand" "+f"))
2698    (set (match_dup 1)
2699         (match_dup 0))]
2700   "reload_completed || !TARGET_SSE2"
2701 {
2702   if (STACK_TOP_P (operands[0]))
2703     return "fxch\t%1";
2704   else
2705     return "fxch\t%0";
2706 }
2707   [(set_attr "type" "fxch")
2708    (set_attr "mode" "DF")])
2709
2710 (define_expand "movxf"
2711   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2712         (match_operand:XF 1 "general_operand" ""))]
2713   ""
2714   "ix86_expand_move (XFmode, operands); DONE;")
2715
2716 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2717 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2718 ;; Pushing using integer instructions is longer except for constants
2719 ;; and direct memory references.
2720 ;; (assuming that any given constant is pushed only once, but this ought to be
2721 ;;  handled elsewhere).
2722
2723 (define_insn "*pushxf_nointeger"
2724   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2725         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2726   "optimize_size"
2727 {
2728   /* This insn should be already split before reg-stack.  */
2729   abort ();
2730 }
2731   [(set_attr "type" "multi")
2732    (set_attr "mode" "XF,SI,SI")])
2733
2734 (define_insn "*pushxf_integer"
2735   [(set (match_operand:XF 0 "push_operand" "=<,<")
2736         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737   "!optimize_size"
2738 {
2739   /* This insn should be already split before reg-stack.  */
2740   abort ();
2741 }
2742   [(set_attr "type" "multi")
2743    (set_attr "mode" "XF,SI")])
2744
2745 (define_split
2746   [(set (match_operand 0 "push_operand" "")
2747         (match_operand 1 "general_operand" ""))]
2748   "reload_completed
2749    && (GET_MODE (operands[0]) == XFmode
2750        || GET_MODE (operands[0]) == DFmode)
2751    && !ANY_FP_REG_P (operands[1])"
2752   [(const_int 0)]
2753   "ix86_split_long_move (operands); DONE;")
2754
2755 (define_split
2756   [(set (match_operand:XF 0 "push_operand" "")
2757         (match_operand:XF 1 "any_fp_register_operand" ""))]
2758   "!TARGET_64BIT"
2759   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2760    (set (mem:XF (reg:SI 7)) (match_dup 1))]
2761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2762
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "TARGET_64BIT"
2767   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2768    (set (mem:XF (reg:DI 7)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770
2771 ;; Do not use integer registers when optimizing for size
2772 (define_insn "*movxf_nointeger"
2773   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2774         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775   "optimize_size
2776    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777    && (reload_in_progress || reload_completed
2778        || GET_CODE (operands[1]) != CONST_DOUBLE
2779        || memory_operand (operands[0], XFmode))" 
2780 {
2781   switch (which_alternative)
2782     {
2783     case 0:
2784       if (REG_P (operands[1])
2785           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2786         {
2787           if (REGNO (operands[0]) == FIRST_STACK_REG
2788               && TARGET_USE_FFREEP)
2789             return "ffreep\t%y0";
2790           return "fstp\t%y0";
2791         }
2792       else if (STACK_TOP_P (operands[0]))
2793         return "fld%z1\t%y1";
2794       else
2795         return "fst\t%y0";
2796
2797     case 1:
2798       /* There is no non-popping store to memory for XFmode.  So if
2799          we need one, follow the store with a load.  */
2800       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2801         return "fstp%z0\t%y0\;fld%z0\t%y0";
2802       else
2803         return "fstp%z0\t%y0";
2804
2805     case 2:
2806       return standard_80387_constant_opcode (operands[1]);
2807
2808     case 3: case 4:
2809       return "#";
2810     }
2811   abort();
2812 }
2813   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814    (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816 (define_insn "*movxf_integer"
2817   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2818         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2819   "!optimize_size
2820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821    && (reload_in_progress || reload_completed
2822        || GET_CODE (operands[1]) != CONST_DOUBLE
2823        || memory_operand (operands[0], XFmode))" 
2824 {
2825   switch (which_alternative)
2826     {
2827     case 0:
2828       if (REG_P (operands[1])
2829           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2830         {
2831           if (REGNO (operands[0]) == FIRST_STACK_REG
2832               && TARGET_USE_FFREEP)
2833             return "ffreep\t%y0";
2834           return "fstp\t%y0";
2835         }
2836       else if (STACK_TOP_P (operands[0]))
2837         return "fld%z1\t%y1";
2838       else
2839         return "fst\t%y0";
2840
2841     case 1:
2842       /* There is no non-popping store to memory for XFmode.  So if
2843          we need one, follow the store with a load.  */
2844       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845         return "fstp%z0\t%y0\;fld%z0\t%y0";
2846       else
2847         return "fstp%z0\t%y0";
2848
2849     case 2:
2850       return standard_80387_constant_opcode (operands[1]);
2851
2852     case 3: case 4:
2853       return "#";
2854     }
2855   abort();
2856 }
2857   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2858    (set_attr "mode" "XF,XF,XF,SI,SI")])
2859
2860 (define_split
2861   [(set (match_operand 0 "nonimmediate_operand" "")
2862         (match_operand 1 "general_operand" ""))]
2863   "reload_completed
2864    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2865    && GET_MODE (operands[0]) == XFmode
2866    && ! (ANY_FP_REG_P (operands[0]) || 
2867          (GET_CODE (operands[0]) == SUBREG
2868           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2869    && ! (ANY_FP_REG_P (operands[1]) || 
2870          (GET_CODE (operands[1]) == SUBREG
2871           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2872   [(const_int 0)]
2873   "ix86_split_long_move (operands); DONE;")
2874
2875 (define_split
2876   [(set (match_operand 0 "register_operand" "")
2877         (match_operand 1 "memory_operand" ""))]
2878   "reload_completed
2879    && GET_CODE (operands[1]) == MEM
2880    && (GET_MODE (operands[0]) == XFmode
2881        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2882    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2883    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2884   [(set (match_dup 0) (match_dup 1))]
2885 {
2886   rtx c = get_pool_constant (XEXP (operands[1], 0));
2887   rtx r = operands[0];
2888
2889   if (GET_CODE (r) == SUBREG)
2890     r = SUBREG_REG (r);
2891
2892   if (SSE_REG_P (r))
2893     {
2894       if (!standard_sse_constant_p (c))
2895         FAIL;
2896     }
2897   else if (FP_REG_P (r))
2898     {
2899       if (!standard_80387_constant_p (c))
2900         FAIL;
2901     }
2902   else if (MMX_REG_P (r))
2903     FAIL;
2904
2905   operands[1] = c;
2906 })
2907
2908 (define_insn "swapxf"
2909   [(set (match_operand:XF 0 "register_operand" "+f")
2910         (match_operand:XF 1 "register_operand" "+f"))
2911    (set (match_dup 1)
2912         (match_dup 0))]
2913   ""
2914 {
2915   if (STACK_TOP_P (operands[0]))
2916     return "fxch\t%1";
2917   else
2918     return "fxch\t%0";
2919 }
2920   [(set_attr "type" "fxch")
2921    (set_attr "mode" "XF")])
2922 \f
2923 ;; Zero extension instructions
2924
2925 (define_expand "zero_extendhisi2"
2926   [(set (match_operand:SI 0 "register_operand" "")
2927      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2928   ""
2929 {
2930   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2931     {
2932       operands[1] = force_reg (HImode, operands[1]);
2933       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2934       DONE;
2935     }
2936 })
2937
2938 (define_insn "zero_extendhisi2_and"
2939   [(set (match_operand:SI 0 "register_operand" "=r")
2940      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2941    (clobber (reg:CC 17))]
2942   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2943   "#"
2944   [(set_attr "type" "alu1")
2945    (set_attr "mode" "SI")])
2946
2947 (define_split
2948   [(set (match_operand:SI 0 "register_operand" "")
2949         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2950    (clobber (reg:CC 17))]
2951   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2952   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2953               (clobber (reg:CC 17))])]
2954   "")
2955
2956 (define_insn "*zero_extendhisi2_movzwl"
2957   [(set (match_operand:SI 0 "register_operand" "=r")
2958      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2959   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2960   "movz{wl|x}\t{%1, %0|%0, %1}"
2961   [(set_attr "type" "imovx")
2962    (set_attr "mode" "SI")])
2963
2964 (define_expand "zero_extendqihi2"
2965   [(parallel
2966     [(set (match_operand:HI 0 "register_operand" "")
2967        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2968      (clobber (reg:CC 17))])]
2969   ""
2970   "")
2971
2972 (define_insn "*zero_extendqihi2_and"
2973   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2974      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2975    (clobber (reg:CC 17))]
2976   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2977   "#"
2978   [(set_attr "type" "alu1")
2979    (set_attr "mode" "HI")])
2980
2981 (define_insn "*zero_extendqihi2_movzbw_and"
2982   [(set (match_operand:HI 0 "register_operand" "=r,r")
2983      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2984    (clobber (reg:CC 17))]
2985   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2986   "#"
2987   [(set_attr "type" "imovx,alu1")
2988    (set_attr "mode" "HI")])
2989
2990 (define_insn "*zero_extendqihi2_movzbw"
2991   [(set (match_operand:HI 0 "register_operand" "=r")
2992      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2993   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2994   "movz{bw|x}\t{%1, %0|%0, %1}"
2995   [(set_attr "type" "imovx")
2996    (set_attr "mode" "HI")])
2997
2998 ;; For the movzbw case strip only the clobber
2999 (define_split
3000   [(set (match_operand:HI 0 "register_operand" "")
3001         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3002    (clobber (reg:CC 17))]
3003   "reload_completed 
3004    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3005    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3008
3009 ;; When source and destination does not overlap, clear destination
3010 ;; first and then do the movb
3011 (define_split
3012   [(set (match_operand:HI 0 "register_operand" "")
3013         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3014    (clobber (reg:CC 17))]
3015   "reload_completed
3016    && ANY_QI_REG_P (operands[0])
3017    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3018    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3019   [(set (match_dup 0) (const_int 0))
3020    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3021   "operands[2] = gen_lowpart (QImode, operands[0]);")
3022
3023 ;; Rest is handled by single and.
3024 (define_split
3025   [(set (match_operand:HI 0 "register_operand" "")
3026         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3027    (clobber (reg:CC 17))]
3028   "reload_completed
3029    && true_regnum (operands[0]) == true_regnum (operands[1])"
3030   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3031               (clobber (reg:CC 17))])]
3032   "")
3033
3034 (define_expand "zero_extendqisi2"
3035   [(parallel
3036     [(set (match_operand:SI 0 "register_operand" "")
3037        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3038      (clobber (reg:CC 17))])]
3039   ""
3040   "")
3041
3042 (define_insn "*zero_extendqisi2_and"
3043   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3044      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3045    (clobber (reg:CC 17))]
3046   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3047   "#"
3048   [(set_attr "type" "alu1")
3049    (set_attr "mode" "SI")])
3050
3051 (define_insn "*zero_extendqisi2_movzbw_and"
3052   [(set (match_operand:SI 0 "register_operand" "=r,r")
3053      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3054    (clobber (reg:CC 17))]
3055   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3056   "#"
3057   [(set_attr "type" "imovx,alu1")
3058    (set_attr "mode" "SI")])
3059
3060 (define_insn "*zero_extendqisi2_movzbw"
3061   [(set (match_operand:SI 0 "register_operand" "=r")
3062      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3063   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3064   "movz{bl|x}\t{%1, %0|%0, %1}"
3065   [(set_attr "type" "imovx")
3066    (set_attr "mode" "SI")])
3067
3068 ;; For the movzbl case strip only the clobber
3069 (define_split
3070   [(set (match_operand:SI 0 "register_operand" "")
3071         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3072    (clobber (reg:CC 17))]
3073   "reload_completed 
3074    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3075    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3076   [(set (match_dup 0)
3077         (zero_extend:SI (match_dup 1)))])
3078
3079 ;; When source and destination does not overlap, clear destination
3080 ;; first and then do the movb
3081 (define_split
3082   [(set (match_operand:SI 0 "register_operand" "")
3083         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084    (clobber (reg:CC 17))]
3085   "reload_completed
3086    && ANY_QI_REG_P (operands[0])
3087    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3088    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3089    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3090   [(set (match_dup 0) (const_int 0))
3091    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3092   "operands[2] = gen_lowpart (QImode, operands[0]);")
3093
3094 ;; Rest is handled by single and.
3095 (define_split
3096   [(set (match_operand:SI 0 "register_operand" "")
3097         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3098    (clobber (reg:CC 17))]
3099   "reload_completed
3100    && true_regnum (operands[0]) == true_regnum (operands[1])"
3101   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3102               (clobber (reg:CC 17))])]
3103   "")
3104
3105 ;; %%% Kill me once multi-word ops are sane.
3106 (define_expand "zero_extendsidi2"
3107   [(set (match_operand:DI 0 "register_operand" "=r")
3108      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3109   ""
3110   "if (!TARGET_64BIT)
3111      {
3112        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3113        DONE;
3114      }
3115   ")
3116
3117 (define_insn "zero_extendsidi2_32"
3118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3119         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3120    (clobber (reg:CC 17))]
3121   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3122   "@
3123    #
3124    #
3125    #
3126    movd\t{%1, %0|%0, %1}
3127    movd\t{%1, %0|%0, %1}"
3128   [(set_attr "mode" "SI,SI,SI,DI,TI")
3129    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3130
3131 (define_insn "*zero_extendsidi2_32_1"
3132   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3133         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3134    (clobber (reg:CC 17))]
3135   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3136   "@
3137    #
3138    #
3139    #
3140    movd\t{%1, %0|%0, %1}
3141    movd\t{%1, %0|%0, %1}"
3142   [(set_attr "mode" "SI,SI,SI,DI,TI")
3143    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3144
3145 (define_insn "zero_extendsidi2_rex64"
3146   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3147      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3148   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3149   "@
3150    mov\t{%k1, %k0|%k0, %k1}
3151    #
3152    movd\t{%1, %0|%0, %1}
3153    movd\t{%1, %0|%0, %1}"
3154   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3155    (set_attr "mode" "SI,DI,DI,TI")])
3156
3157 (define_insn "*zero_extendsidi2_rex64_1"
3158   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3159      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3160   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3161   "@
3162    mov\t{%k1, %k0|%k0, %k1}
3163    #
3164    movd\t{%1, %0|%0, %1}
3165    movd\t{%1, %0|%0, %1}"
3166   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3167    (set_attr "mode" "SI,DI,SI,SI")])
3168
3169 (define_split
3170   [(set (match_operand:DI 0 "memory_operand" "")
3171      (zero_extend:DI (match_dup 0)))]
3172   "TARGET_64BIT"
3173   [(set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_split 
3177   [(set (match_operand:DI 0 "register_operand" "")
3178         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3179    (clobber (reg:CC 17))]
3180   "!TARGET_64BIT && reload_completed
3181    && true_regnum (operands[0]) == true_regnum (operands[1])"
3182   [(set (match_dup 4) (const_int 0))]
3183   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3184
3185 (define_split 
3186   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3187         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3188    (clobber (reg:CC 17))]
3189   "!TARGET_64BIT && reload_completed
3190    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3191   [(set (match_dup 3) (match_dup 1))
3192    (set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_insn "zero_extendhidi2"
3196   [(set (match_operand:DI 0 "register_operand" "=r,r")
3197      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3198   "TARGET_64BIT"
3199   "@
3200    movz{wl|x}\t{%1, %k0|%k0, %1} 
3201    movz{wq|x}\t{%1, %0|%0, %1}"
3202   [(set_attr "type" "imovx")
3203    (set_attr "mode" "SI,DI")])
3204
3205 (define_insn "zero_extendqidi2"
3206   [(set (match_operand:DI 0 "register_operand" "=r,r")
3207      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3208   "TARGET_64BIT"
3209   "@
3210    movz{bl|x}\t{%1, %k0|%k0, %1} 
3211    movz{bq|x}\t{%1, %0|%0, %1}"
3212   [(set_attr "type" "imovx")
3213    (set_attr "mode" "SI,DI")])
3214 \f
3215 ;; Sign extension instructions
3216
3217 (define_expand "extendsidi2"
3218   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3219                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3220               (clobber (reg:CC 17))
3221               (clobber (match_scratch:SI 2 ""))])]
3222   ""
3223 {
3224   if (TARGET_64BIT)
3225     {
3226       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3227       DONE;
3228     }
3229 })
3230
3231 (define_insn "*extendsidi2_1"
3232   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3233         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3234    (clobber (reg:CC 17))
3235    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3236   "!TARGET_64BIT"
3237   "#")
3238
3239 (define_insn "extendsidi2_rex64"
3240   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3241         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3242   "TARGET_64BIT"
3243   "@
3244    {cltq|cdqe}
3245    movs{lq|x}\t{%1,%0|%0, %1}"
3246   [(set_attr "type" "imovx")
3247    (set_attr "mode" "DI")
3248    (set_attr "prefix_0f" "0")
3249    (set_attr "modrm" "0,1")])
3250
3251 (define_insn "extendhidi2"
3252   [(set (match_operand:DI 0 "register_operand" "=r")
3253         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3254   "TARGET_64BIT"
3255   "movs{wq|x}\t{%1,%0|%0, %1}"
3256   [(set_attr "type" "imovx")
3257    (set_attr "mode" "DI")])
3258
3259 (define_insn "extendqidi2"
3260   [(set (match_operand:DI 0 "register_operand" "=r")
3261         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3262   "TARGET_64BIT"
3263   "movs{bq|x}\t{%1,%0|%0, %1}"
3264    [(set_attr "type" "imovx")
3265     (set_attr "mode" "DI")])
3266
3267 ;; Extend to memory case when source register does die.
3268 (define_split 
3269   [(set (match_operand:DI 0 "memory_operand" "")
3270         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3271    (clobber (reg:CC 17))
3272    (clobber (match_operand:SI 2 "register_operand" ""))]
3273   "(reload_completed
3274     && dead_or_set_p (insn, operands[1])
3275     && !reg_mentioned_p (operands[1], operands[0]))"
3276   [(set (match_dup 3) (match_dup 1))
3277    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3278               (clobber (reg:CC 17))])
3279    (set (match_dup 4) (match_dup 1))]
3280   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3281
3282 ;; Extend to memory case when source register does not die.
3283 (define_split 
3284   [(set (match_operand:DI 0 "memory_operand" "")
3285         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286    (clobber (reg:CC 17))
3287    (clobber (match_operand:SI 2 "register_operand" ""))]
3288   "reload_completed"
3289   [(const_int 0)]
3290 {
3291   split_di (&operands[0], 1, &operands[3], &operands[4]);
3292
3293   emit_move_insn (operands[3], operands[1]);
3294
3295   /* Generate a cltd if possible and doing so it profitable.  */
3296   if (true_regnum (operands[1]) == 0
3297       && true_regnum (operands[2]) == 1
3298       && (optimize_size || TARGET_USE_CLTD))
3299     {
3300       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3301     }
3302   else
3303     {
3304       emit_move_insn (operands[2], operands[1]);
3305       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3306     }
3307   emit_move_insn (operands[4], operands[2]);
3308   DONE;
3309 })
3310
3311 ;; Extend to register case.  Optimize case where source and destination
3312 ;; registers match and cases where we can use cltd.
3313 (define_split 
3314   [(set (match_operand:DI 0 "register_operand" "")
3315         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3316    (clobber (reg:CC 17))
3317    (clobber (match_scratch:SI 2 ""))]
3318   "reload_completed"
3319   [(const_int 0)]
3320 {
3321   split_di (&operands[0], 1, &operands[3], &operands[4]);
3322
3323   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3324     emit_move_insn (operands[3], operands[1]);
3325
3326   /* Generate a cltd if possible and doing so it profitable.  */
3327   if (true_regnum (operands[3]) == 0
3328       && (optimize_size || TARGET_USE_CLTD))
3329     {
3330       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3331       DONE;
3332     }
3333
3334   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[4], operands[1]);
3336
3337   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3338   DONE;
3339 })
3340
3341 (define_insn "extendhisi2"
3342   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3343         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3344   ""
3345 {
3346   switch (get_attr_prefix_0f (insn))
3347     {
3348     case 0:
3349       return "{cwtl|cwde}";
3350     default:
3351       return "movs{wl|x}\t{%1,%0|%0, %1}";
3352     }
3353 }
3354   [(set_attr "type" "imovx")
3355    (set_attr "mode" "SI")
3356    (set (attr "prefix_0f")
3357      ;; movsx is short decodable while cwtl is vector decoded.
3358      (if_then_else (and (eq_attr "cpu" "!k6")
3359                         (eq_attr "alternative" "0"))
3360         (const_string "0")
3361         (const_string "1")))
3362    (set (attr "modrm")
3363      (if_then_else (eq_attr "prefix_0f" "0")
3364         (const_string "0")
3365         (const_string "1")))])
3366
3367 (define_insn "*extendhisi2_zext"
3368   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3369         (zero_extend:DI
3370           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3371   "TARGET_64BIT"
3372 {
3373   switch (get_attr_prefix_0f (insn))
3374     {
3375     case 0:
3376       return "{cwtl|cwde}";
3377     default:
3378       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3379     }
3380 }
3381   [(set_attr "type" "imovx")
3382    (set_attr "mode" "SI")
3383    (set (attr "prefix_0f")
3384      ;; movsx is short decodable while cwtl is vector decoded.
3385      (if_then_else (and (eq_attr "cpu" "!k6")
3386                         (eq_attr "alternative" "0"))
3387         (const_string "0")
3388         (const_string "1")))
3389    (set (attr "modrm")
3390      (if_then_else (eq_attr "prefix_0f" "0")
3391         (const_string "0")
3392         (const_string "1")))])
3393
3394 (define_insn "extendqihi2"
3395   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3396         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3397   ""
3398 {
3399   switch (get_attr_prefix_0f (insn))
3400     {
3401     case 0:
3402       return "{cbtw|cbw}";
3403     default:
3404       return "movs{bw|x}\t{%1,%0|%0, %1}";
3405     }
3406 }
3407   [(set_attr "type" "imovx")
3408    (set_attr "mode" "HI")
3409    (set (attr "prefix_0f")
3410      ;; movsx is short decodable while cwtl is vector decoded.
3411      (if_then_else (and (eq_attr "cpu" "!k6")
3412                         (eq_attr "alternative" "0"))
3413         (const_string "0")
3414         (const_string "1")))
3415    (set (attr "modrm")
3416      (if_then_else (eq_attr "prefix_0f" "0")
3417         (const_string "0")
3418         (const_string "1")))])
3419
3420 (define_insn "extendqisi2"
3421   [(set (match_operand:SI 0 "register_operand" "=r")
3422         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3423   ""
3424   "movs{bl|x}\t{%1,%0|%0, %1}"
3425    [(set_attr "type" "imovx")
3426     (set_attr "mode" "SI")])
3427
3428 (define_insn "*extendqisi2_zext"
3429   [(set (match_operand:DI 0 "register_operand" "=r")
3430         (zero_extend:DI
3431           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3432   "TARGET_64BIT"
3433   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3434    [(set_attr "type" "imovx")
3435     (set_attr "mode" "SI")])
3436 \f
3437 ;; Conversions between float and double.
3438
3439 ;; These are all no-ops in the model used for the 80387.  So just
3440 ;; emit moves.
3441
3442 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3443 (define_insn "*dummy_extendsfdf2"
3444   [(set (match_operand:DF 0 "push_operand" "=<")
3445         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3446   "0"
3447   "#")
3448
3449 (define_split
3450   [(set (match_operand:DF 0 "push_operand" "")
3451         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3452   "!TARGET_64BIT"
3453   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3454    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3455
3456 (define_split
3457   [(set (match_operand:DF 0 "push_operand" "")
3458         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3459   "TARGET_64BIT"
3460   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3461    (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3462
3463 (define_insn "*dummy_extendsfxf2"
3464   [(set (match_operand:XF 0 "push_operand" "=<")
3465         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3466   "0"
3467   "#")
3468
3469 (define_split
3470   [(set (match_operand:XF 0 "push_operand" "")
3471         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3472   ""
3473   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3474    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3475   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3476
3477 (define_split
3478   [(set (match_operand:XF 0 "push_operand" "")
3479         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3480   "TARGET_64BIT"
3481   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3482    (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3483   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3484
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3488   ""
3489   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3490    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3496   "TARGET_64BIT"
3497   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3498    (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_expand "extendsfdf2"
3502   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3503         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3504   "TARGET_80387 || TARGET_SSE2"
3505 {
3506   /* ??? Needed for compress_float_constant since all fp constants
3507      are LEGITIMATE_CONSTANT_P.  */
3508   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3509     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3510   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3511     operands[1] = force_reg (SFmode, operands[1]);
3512 })
3513
3514 (define_insn "*extendsfdf2_1"
3515   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3516         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3517   "(TARGET_80387 || TARGET_SSE2)
3518    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3519 {
3520   switch (which_alternative)
3521     {
3522     case 0:
3523       if (REG_P (operands[1])
3524           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3525         return "fstp\t%y0";
3526       else if (STACK_TOP_P (operands[0]))
3527         return "fld%z1\t%y1";
3528       else
3529         return "fst\t%y0";
3530
3531     case 1:
3532       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3533         return "fstp%z0\t%y0";
3534
3535       else
3536         return "fst%z0\t%y0";
3537     case 2:
3538       return "cvtss2sd\t{%1, %0|%0, %1}";
3539
3540     default:
3541       abort ();
3542     }
3543 }
3544   [(set_attr "type" "fmov,fmov,ssecvt")
3545    (set_attr "mode" "SF,XF,DF")])
3546
3547 (define_insn "*extendsfdf2_1_sse_only"
3548   [(set (match_operand:DF 0 "register_operand" "=Y")
3549         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3550   "!TARGET_80387 && TARGET_SSE2
3551    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552   "cvtss2sd\t{%1, %0|%0, %1}"
3553   [(set_attr "type" "ssecvt")
3554    (set_attr "mode" "DF")])
3555
3556 (define_expand "extendsfxf2"
3557   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3558         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3559   "TARGET_80387"
3560 {
3561   /* ??? Needed for compress_float_constant since all fp constants
3562      are LEGITIMATE_CONSTANT_P.  */
3563   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3564     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3565   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3566     operands[1] = force_reg (SFmode, operands[1]);
3567 })
3568
3569 (define_insn "*extendsfxf2_1"
3570   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3571         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3572   "TARGET_80387
3573    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3574 {
3575   switch (which_alternative)
3576     {
3577     case 0:
3578       if (REG_P (operands[1])
3579           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580         return "fstp\t%y0";
3581       else if (STACK_TOP_P (operands[0]))
3582         return "fld%z1\t%y1";
3583       else
3584         return "fst\t%y0";
3585
3586     case 1:
3587       /* There is no non-popping store to memory for XFmode.  So if
3588          we need one, follow the store with a load.  */
3589       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3591       else
3592         return "fstp%z0\t%y0";
3593
3594     default:
3595       abort ();
3596     }
3597 }
3598   [(set_attr "type" "fmov")
3599    (set_attr "mode" "SF,XF")])
3600
3601 (define_expand "extenddfxf2"
3602   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3603         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3604   "TARGET_80387"
3605 {
3606   /* ??? Needed for compress_float_constant since all fp constants
3607      are LEGITIMATE_CONSTANT_P.  */
3608   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3610   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3611     operands[1] = force_reg (DFmode, operands[1]);
3612 })
3613
3614 (define_insn "*extenddfxf2_1"
3615   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3616         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3617   "TARGET_80387
3618    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (REG_P (operands[1])
3624           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3625         return "fstp\t%y0";
3626       else if (STACK_TOP_P (operands[0]))
3627         return "fld%z1\t%y1";
3628       else
3629         return "fst\t%y0";
3630
3631     case 1:
3632       /* There is no non-popping store to memory for XFmode.  So if
3633          we need one, follow the store with a load.  */
3634       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3636       else
3637         return "fstp%z0\t%y0";
3638
3639     default:
3640       abort ();
3641     }
3642 }
3643   [(set_attr "type" "fmov")
3644    (set_attr "mode" "DF,XF")])
3645
3646 ;; %%% This seems bad bad news.
3647 ;; This cannot output into an f-reg because there is no way to be sure
3648 ;; of truncating in that case.  Otherwise this is just like a simple move
3649 ;; insn.  So we pretend we can output to a reg in order to get better
3650 ;; register preferencing, but we really use a stack slot.
3651
3652 (define_expand "truncdfsf2"
3653   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3654                    (float_truncate:SF
3655                     (match_operand:DF 1 "register_operand" "")))
3656               (clobber (match_dup 2))])]
3657   "TARGET_80387 || TARGET_SSE2"
3658   "
3659    if (TARGET_80387)
3660      operands[2] = assign_386_stack_local (SFmode, 0);
3661    else
3662      {
3663         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3664         DONE;
3665      }
3666 ")
3667
3668 (define_insn "*truncdfsf2_1"
3669   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3670         (float_truncate:SF
3671          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3672    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3673   "TARGET_80387 && !TARGET_SSE2"
3674 {
3675   switch (which_alternative)
3676     {
3677     case 0:
3678       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3679         return "fstp%z0\t%y0";
3680       else
3681         return "fst%z0\t%y0";
3682     default:
3683       abort ();
3684     }
3685 }
3686   [(set_attr "type" "fmov,multi,multi,multi")
3687    (set_attr "mode" "SF,SF,SF,SF")])
3688
3689 (define_insn "*truncdfsf2_1_sse"
3690   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3691         (float_truncate:SF
3692          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3693    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3694   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3695 {
3696   switch (which_alternative)
3697     {
3698     case 0:
3699       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3700         return "fstp%z0\t%y0";
3701       else
3702         return "fst%z0\t%y0";
3703     case 4:
3704       return "#";
3705     default:
3706       abort ();
3707     }
3708 }
3709   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3710    (set_attr "mode" "SF,SF,SF,SF,DF")])
3711
3712 (define_insn "*truncdfsf2_1_sse_nooverlap"
3713   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3714         (float_truncate:SF
3715          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3716    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3717   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3718 {
3719   switch (which_alternative)
3720     {
3721     case 0:
3722       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723         return "fstp%z0\t%y0";
3724       else
3725         return "fst%z0\t%y0";
3726     case 4:
3727       return "#";
3728     default:
3729       abort ();
3730     }
3731 }
3732   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3733    (set_attr "mode" "SF,SF,SF,SF,DF")])
3734
3735 (define_insn "*truncdfsf2_2"
3736   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3737         (float_truncate:SF
3738          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3739   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3740    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3741 {
3742   switch (which_alternative)
3743     {
3744     case 0:
3745     case 1:
3746       return "cvtsd2ss\t{%1, %0|%0, %1}";
3747     case 2:
3748       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3749         return "fstp%z0\t%y0";
3750       else
3751         return "fst%z0\t%y0";
3752     default:
3753       abort ();
3754     }
3755 }
3756   [(set_attr "type" "ssecvt,ssecvt,fmov")
3757    (set_attr "athlon_decode" "vector,double,*")
3758    (set_attr "mode" "SF,SF,SF")])
3759
3760 (define_insn "*truncdfsf2_2_nooverlap"
3761   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3762         (float_truncate:SF
3763          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3764   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3765    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3766 {
3767   switch (which_alternative)
3768     {
3769     case 0:
3770       return "#";
3771     case 1:
3772       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3773         return "fstp%z0\t%y0";
3774       else
3775         return "fst%z0\t%y0";
3776     default:
3777       abort ();
3778     }
3779 }
3780   [(set_attr "type" "ssecvt,fmov")
3781    (set_attr "mode" "DF,SF")])
3782
3783 (define_insn "*truncdfsf2_3"
3784   [(set (match_operand:SF 0 "memory_operand" "=m")
3785         (float_truncate:SF
3786          (match_operand:DF 1 "register_operand" "f")))]
3787   "TARGET_80387"
3788 {
3789   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3790     return "fstp%z0\t%y0";
3791   else
3792     return "fst%z0\t%y0";
3793 }
3794   [(set_attr "type" "fmov")
3795    (set_attr "mode" "SF")])
3796
3797 (define_insn "truncdfsf2_sse_only"
3798   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3799         (float_truncate:SF
3800          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3801   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3802   "cvtsd2ss\t{%1, %0|%0, %1}"
3803   [(set_attr "type" "ssecvt")
3804    (set_attr "athlon_decode" "vector,double")
3805    (set_attr "mode" "SF")])
3806
3807 (define_insn "*truncdfsf2_sse_only_nooverlap"
3808   [(set (match_operand:SF 0 "register_operand" "=&Y")
3809         (float_truncate:SF
3810          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3811   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3812   "#"
3813   [(set_attr "type" "ssecvt")
3814    (set_attr "mode" "DF")])
3815
3816 (define_split
3817   [(set (match_operand:SF 0 "memory_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "register_operand" "")))
3820    (clobber (match_operand:SF 2 "memory_operand" ""))]
3821   "TARGET_80387"
3822   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3823   "")
3824
3825 ; Avoid possible reformatting penalty on the destination by first
3826 ; zeroing it out
3827 (define_split
3828   [(set (match_operand:SF 0 "register_operand" "")
3829         (float_truncate:SF
3830          (match_operand:DF 1 "nonimmediate_operand" "")))
3831    (clobber (match_operand 2 "" ""))]
3832   "TARGET_80387 && reload_completed
3833    && SSE_REG_P (operands[0])
3834    && !STACK_REG_P (operands[1])"
3835   [(const_int 0)]
3836 {
3837   rtx src, dest;
3838   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3839     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3840   else
3841     {
3842       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3843       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3844       /* simplify_gen_subreg refuses to widen memory references.  */
3845       if (GET_CODE (src) == SUBREG)
3846         alter_subreg (&src);
3847       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3848         abort ();
3849       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3850       emit_insn (gen_cvtsd2ss (dest, dest, src));
3851     }
3852   DONE;
3853 })
3854
3855 (define_split
3856   [(set (match_operand:SF 0 "register_operand" "")
3857         (float_truncate:SF
3858          (match_operand:DF 1 "nonimmediate_operand" "")))]
3859   "TARGET_80387 && reload_completed
3860    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3861   [(const_int 0)]
3862 {
3863   rtx src, dest;
3864   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3865   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3866   /* simplify_gen_subreg refuses to widen memory references.  */
3867   if (GET_CODE (src) == SUBREG)
3868     alter_subreg (&src);
3869   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3870     abort ();
3871   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3872   emit_insn (gen_cvtsd2ss (dest, dest, src));
3873   DONE;
3874 })
3875
3876 (define_split
3877   [(set (match_operand:SF 0 "register_operand" "")
3878         (float_truncate:SF
3879          (match_operand:DF 1 "fp_register_operand" "")))
3880    (clobber (match_operand:SF 2 "memory_operand" ""))]
3881   "TARGET_80387 && reload_completed"
3882   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3883    (set (match_dup 0) (match_dup 2))]
3884   "")
3885
3886 (define_expand "truncxfsf2"
3887   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3888                    (float_truncate:SF
3889                     (match_operand:XF 1 "register_operand" "")))
3890               (clobber (match_dup 2))])]
3891   "TARGET_80387"
3892   "operands[2] = assign_386_stack_local (SFmode, 0);")
3893
3894 (define_insn "*truncxfsf2_1"
3895   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3896         (float_truncate:SF
3897          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3898    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3899   "TARGET_80387"
3900 {
3901   switch (which_alternative)
3902     {
3903     case 0:
3904       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3905         return "fstp%z0\t%y0";
3906       else
3907         return "fst%z0\t%y0";
3908     default:
3909       abort();
3910     }
3911 }
3912   [(set_attr "type" "fmov,multi,multi,multi")
3913    (set_attr "mode" "SF")])
3914
3915 (define_insn "*truncxfsf2_2"
3916   [(set (match_operand:SF 0 "memory_operand" "=m")
3917         (float_truncate:SF
3918          (match_operand:XF 1 "register_operand" "f")))]
3919   "TARGET_80387"
3920 {
3921   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3922     return "fstp%z0\t%y0";
3923   else
3924     return "fst%z0\t%y0";
3925 }
3926   [(set_attr "type" "fmov")
3927    (set_attr "mode" "SF")])
3928
3929 (define_split
3930   [(set (match_operand:SF 0 "memory_operand" "")
3931         (float_truncate:SF
3932          (match_operand:XF 1 "register_operand" "")))
3933    (clobber (match_operand:SF 2 "memory_operand" ""))]
3934   "TARGET_80387"
3935   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3936   "")
3937
3938 (define_split
3939   [(set (match_operand:SF 0 "register_operand" "")
3940         (float_truncate:SF
3941          (match_operand:XF 1 "register_operand" "")))
3942    (clobber (match_operand:SF 2 "memory_operand" ""))]
3943   "TARGET_80387 && reload_completed"
3944   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945    (set (match_dup 0) (match_dup 2))]
3946   "")
3947
3948 (define_expand "truncxfdf2"
3949   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3950                    (float_truncate:DF
3951                     (match_operand:XF 1 "register_operand" "")))
3952               (clobber (match_dup 2))])]
3953   "TARGET_80387"
3954   "operands[2] = assign_386_stack_local (DFmode, 0);")
3955
3956 (define_insn "*truncxfdf2_1"
3957   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3958         (float_truncate:DF
3959          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3960    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3961   "TARGET_80387"
3962 {
3963   switch (which_alternative)
3964     {
3965     case 0:
3966       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3967         return "fstp%z0\t%y0";
3968       else
3969         return "fst%z0\t%y0";
3970     default:
3971       abort();
3972     }
3973   abort ();
3974 }
3975   [(set_attr "type" "fmov,multi,multi,multi")
3976    (set_attr "mode" "DF")])
3977
3978 (define_insn "*truncxfdf2_2"
3979   [(set (match_operand:DF 0 "memory_operand" "=m")
3980         (float_truncate:DF
3981           (match_operand:XF 1 "register_operand" "f")))]
3982   "TARGET_80387"
3983 {
3984   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3985     return "fstp%z0\t%y0";
3986   else
3987     return "fst%z0\t%y0";
3988 }
3989   [(set_attr "type" "fmov")
3990    (set_attr "mode" "DF")])
3991
3992 (define_split
3993   [(set (match_operand:DF 0 "memory_operand" "")
3994         (float_truncate:DF
3995          (match_operand:XF 1 "register_operand" "")))
3996    (clobber (match_operand:DF 2 "memory_operand" ""))]
3997   "TARGET_80387"
3998   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3999   "")
4000
4001 (define_split
4002   [(set (match_operand:DF 0 "register_operand" "")
4003         (float_truncate:DF
4004          (match_operand:XF 1 "register_operand" "")))
4005    (clobber (match_operand:DF 2 "memory_operand" ""))]
4006   "TARGET_80387 && reload_completed"
4007   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008    (set (match_dup 0) (match_dup 2))]
4009   "")
4010
4011 \f
4012 ;; %%% Break up all these bad boys.
4013
4014 ;; Signed conversion to DImode.
4015
4016 (define_expand "fix_truncxfdi2"
4017   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018         (fix:DI (match_operand:XF 1 "register_operand" "")))]
4019   "TARGET_80387"
4020   "")
4021
4022 (define_expand "fix_truncdfdi2"
4023   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024         (fix:DI (match_operand:DF 1 "register_operand" "")))]
4025   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4026 {
4027   if (TARGET_64BIT && TARGET_SSE2)
4028    {
4029      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4030      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4031      if (out != operands[0])
4032         emit_move_insn (operands[0], out);
4033      DONE;
4034    }
4035 })
4036
4037 (define_expand "fix_truncsfdi2"
4038   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4039         (fix:DI (match_operand:SF 1 "register_operand" "")))]
4040   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4041 {
4042   if (TARGET_SSE && TARGET_64BIT)
4043    {
4044      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4045      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4046      if (out != operands[0])
4047         emit_move_insn (operands[0], out);
4048      DONE;
4049    }
4050 })
4051
4052 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4053 ;; of the machinery.
4054 (define_insn_and_split "*fix_truncdi_1"
4055   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4056         (fix:DI (match_operand 1 "register_operand" "f,f")))]
4057   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4058    && !reload_completed && !reload_in_progress
4059    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4060   "#"
4061   "&& 1"
4062   [(const_int 0)]
4063 {
4064   ix86_optimize_mode_switching = 1;
4065   operands[2] = assign_386_stack_local (HImode, 1);
4066   operands[3] = assign_386_stack_local (HImode, 2);
4067   if (memory_operand (operands[0], VOIDmode))
4068     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4069                                        operands[2], operands[3]));
4070   else
4071     {
4072       operands[4] = assign_386_stack_local (DImode, 0);
4073       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4074                                            operands[2], operands[3],
4075                                            operands[4]));
4076     }
4077   DONE;
4078 }
4079   [(set_attr "type" "fistp")
4080    (set_attr "mode" "DI")])
4081
4082 (define_insn "fix_truncdi_nomemory"
4083   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4084         (fix:DI (match_operand 1 "register_operand" "f,f")))
4085    (use (match_operand:HI 2 "memory_operand" "m,m"))
4086    (use (match_operand:HI 3 "memory_operand" "m,m"))
4087    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4088    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4089   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4090    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4091   "#"
4092   [(set_attr "type" "fistp")
4093    (set_attr "mode" "DI")])
4094
4095 (define_insn "fix_truncdi_memory"
4096   [(set (match_operand:DI 0 "memory_operand" "=m")
4097         (fix:DI (match_operand 1 "register_operand" "f")))
4098    (use (match_operand:HI 2 "memory_operand" "m"))
4099    (use (match_operand:HI 3 "memory_operand" "m"))
4100    (clobber (match_scratch:DF 4 "=&1f"))]
4101   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4102    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4103   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4104   [(set_attr "type" "fistp")
4105    (set_attr "mode" "DI")])
4106
4107 (define_split 
4108   [(set (match_operand:DI 0 "register_operand" "")
4109         (fix:DI (match_operand 1 "register_operand" "")))
4110    (use (match_operand:HI 2 "memory_operand" ""))
4111    (use (match_operand:HI 3 "memory_operand" ""))
4112    (clobber (match_operand:DI 4 "memory_operand" ""))
4113    (clobber (match_scratch 5 ""))]
4114   "reload_completed"
4115   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4116               (use (match_dup 2))
4117               (use (match_dup 3))
4118               (clobber (match_dup 5))])
4119    (set (match_dup 0) (match_dup 4))]
4120   "")
4121
4122 (define_split 
4123   [(set (match_operand:DI 0 "memory_operand" "")
4124         (fix:DI (match_operand 1 "register_operand" "")))
4125    (use (match_operand:HI 2 "memory_operand" ""))
4126    (use (match_operand:HI 3 "memory_operand" ""))
4127    (clobber (match_operand:DI 4 "memory_operand" ""))
4128    (clobber (match_scratch 5 ""))]
4129   "reload_completed"
4130   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4131               (use (match_dup 2))
4132               (use (match_dup 3))
4133               (clobber (match_dup 5))])]
4134   "")
4135
4136 ;; When SSE available, it is always faster to use it!
4137 (define_insn "fix_truncsfdi_sse"
4138   [(set (match_operand:DI 0 "register_operand" "=r,r")
4139         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4140   "TARGET_64BIT && TARGET_SSE"
4141   "cvttss2si{q}\t{%1, %0|%0, %1}"
4142   [(set_attr "type" "sseicvt")
4143    (set_attr "mode" "SF")
4144    (set_attr "athlon_decode" "double,vector")])
4145
4146 ;; Avoid vector decoded form of the instruction.
4147 (define_peephole2
4148   [(match_scratch:SF 2 "x")
4149    (set (match_operand:DI 0 "register_operand" "")
4150         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4151   "TARGET_K8 && !optimize_size"
4152   [(set (match_dup 2) (match_dup 1))
4153    (set (match_dup 0) (fix:DI (match_dup 2)))]
4154   "")
4155
4156 (define_insn "fix_truncdfdi_sse"
4157   [(set (match_operand:DI 0 "register_operand" "=r,r")
4158         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4159   "TARGET_64BIT && TARGET_SSE2"
4160   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4161   [(set_attr "type" "sseicvt,sseicvt")
4162    (set_attr "mode" "DF")
4163    (set_attr "athlon_decode" "double,vector")])
4164
4165 ;; Avoid vector decoded form of the instruction.
4166 (define_peephole2
4167   [(match_scratch:DF 2 "Y")
4168    (set (match_operand:DI 0 "register_operand" "")
4169         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4170   "TARGET_K8 && !optimize_size"
4171   [(set (match_dup 2) (match_dup 1))
4172    (set (match_dup 0) (fix:DI (match_dup 2)))]
4173   "")
4174
4175 ;; Signed conversion to SImode.
4176
4177 (define_expand "fix_truncxfsi2"
4178   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4179         (fix:SI (match_operand:XF 1 "register_operand" "")))]
4180   "TARGET_80387"
4181   "")
4182
4183 (define_expand "fix_truncdfsi2"
4184   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4185         (fix:SI (match_operand:DF 1 "register_operand" "")))]
4186   "TARGET_80387 || TARGET_SSE2"
4187 {
4188   if (TARGET_SSE2)
4189    {
4190      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4191      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4192      if (out != operands[0])
4193         emit_move_insn (operands[0], out);
4194      DONE;
4195    }
4196 })
4197
4198 (define_expand "fix_truncsfsi2"
4199   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4200         (fix:SI (match_operand:SF 1 "register_operand" "")))]
4201   "TARGET_80387 || TARGET_SSE"
4202 {
4203   if (TARGET_SSE)
4204    {
4205      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4206      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4207      if (out != operands[0])
4208         emit_move_insn (operands[0], out);
4209      DONE;
4210    }
4211 })
4212
4213 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4214 ;; of the machinery.
4215 (define_insn_and_split "*fix_truncsi_1"
4216   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4217         (fix:SI (match_operand 1 "register_operand" "f,f")))]
4218   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4219    && !reload_completed && !reload_in_progress
4220    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4221   "#"
4222   "&& 1"
4223   [(const_int 0)]
4224 {
4225   ix86_optimize_mode_switching = 1;
4226   operands[2] = assign_386_stack_local (HImode, 1);
4227   operands[3] = assign_386_stack_local (HImode, 2);
4228   if (memory_operand (operands[0], VOIDmode))
4229     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4230                                        operands[2], operands[3]));
4231   else
4232     {
4233       operands[4] = assign_386_stack_local (SImode, 0);
4234       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4235                                            operands[2], operands[3],
4236                                            operands[4]));
4237     }
4238   DONE;
4239 }
4240   [(set_attr "type" "fistp")
4241    (set_attr "mode" "SI")])
4242
4243 (define_insn "fix_truncsi_nomemory"
4244   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4245         (fix:SI (match_operand 1 "register_operand" "f,f")))
4246    (use (match_operand:HI 2 "memory_operand" "m,m"))
4247    (use (match_operand:HI 3 "memory_operand" "m,m"))
4248    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4249   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4250    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4251   "#"
4252   [(set_attr "type" "fistp")
4253    (set_attr "mode" "SI")])
4254
4255 (define_insn "fix_truncsi_memory"
4256   [(set (match_operand:SI 0 "memory_operand" "=m")
4257         (fix:SI (match_operand 1 "register_operand" "f")))
4258    (use (match_operand:HI 2 "memory_operand" "m"))
4259    (use (match_operand:HI 3 "memory_operand" "m"))]
4260   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4262   "* return output_fix_trunc (insn, operands);"
4263   [(set_attr "type" "fistp")
4264    (set_attr "mode" "SI")])
4265
4266 ;; When SSE available, it is always faster to use it!
4267 (define_insn "fix_truncsfsi_sse"
4268   [(set (match_operand:SI 0 "register_operand" "=r,r")
4269         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4270   "TARGET_SSE"
4271   "cvttss2si\t{%1, %0|%0, %1}"
4272   [(set_attr "type" "sseicvt")
4273    (set_attr "mode" "DF")
4274    (set_attr "athlon_decode" "double,vector")])
4275
4276 ;; Avoid vector decoded form of the instruction.
4277 (define_peephole2
4278   [(match_scratch:SF 2 "x")
4279    (set (match_operand:SI 0 "register_operand" "")
4280         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4281   "TARGET_K8 && !optimize_size"
4282   [(set (match_dup 2) (match_dup 1))
4283    (set (match_dup 0) (fix:SI (match_dup 2)))]
4284   "")
4285
4286 (define_insn "fix_truncdfsi_sse"
4287   [(set (match_operand:SI 0 "register_operand" "=r,r")
4288         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4289   "TARGET_SSE2"
4290   "cvttsd2si\t{%1, %0|%0, %1}"
4291   [(set_attr "type" "sseicvt")
4292    (set_attr "mode" "DF")
4293    (set_attr "athlon_decode" "double,vector")])
4294
4295 ;; Avoid vector decoded form of the instruction.
4296 (define_peephole2
4297   [(match_scratch:DF 2 "Y")
4298    (set (match_operand:SI 0 "register_operand" "")
4299         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4300   "TARGET_K8 && !optimize_size"
4301   [(set (match_dup 2) (match_dup 1))
4302    (set (match_dup 0) (fix:SI (match_dup 2)))]
4303   "")
4304
4305 (define_split 
4306   [(set (match_operand:SI 0 "register_operand" "")
4307         (fix:SI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:SI 4 "memory_operand" ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])
4315    (set (match_dup 0) (match_dup 4))]
4316   "")
4317
4318 (define_split 
4319   [(set (match_operand:SI 0 "memory_operand" "")
4320         (fix:SI (match_operand 1 "register_operand" "")))
4321    (use (match_operand:HI 2 "memory_operand" ""))
4322    (use (match_operand:HI 3 "memory_operand" ""))
4323    (clobber (match_operand:SI 4 "memory_operand" ""))]
4324   "reload_completed"
4325   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4326               (use (match_dup 2))
4327               (use (match_dup 3))])]
4328   "")
4329
4330 ;; Signed conversion to HImode.
4331
4332 (define_expand "fix_truncxfhi2"
4333   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4334         (fix:HI (match_operand:XF 1 "register_operand" "")))]
4335   "TARGET_80387"
4336   "")
4337
4338 (define_expand "fix_truncdfhi2"
4339   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4340         (fix:HI (match_operand:DF 1 "register_operand" "")))]
4341   "TARGET_80387 && !TARGET_SSE2"
4342   "")
4343
4344 (define_expand "fix_truncsfhi2"
4345   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346         (fix:HI (match_operand:SF 1 "register_operand" "")))]
4347   "TARGET_80387 && !TARGET_SSE"
4348   "")
4349
4350 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4351 ;; of the machinery.
4352 (define_insn_and_split "*fix_trunchi_1"
4353   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4354         (fix:HI (match_operand 1 "register_operand" "f,f")))]
4355   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4356    && !reload_completed && !reload_in_progress
4357    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4358   "#"
4359   ""
4360   [(const_int 0)]
4361 {
4362   ix86_optimize_mode_switching = 1;
4363   operands[2] = assign_386_stack_local (HImode, 1);
4364   operands[3] = assign_386_stack_local (HImode, 2);
4365   if (memory_operand (operands[0], VOIDmode))
4366     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4367                                        operands[2], operands[3]));
4368   else
4369     {
4370       operands[4] = assign_386_stack_local (HImode, 0);
4371       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4372                                            operands[2], operands[3],
4373                                            operands[4]));
4374     }
4375   DONE;
4376 }
4377   [(set_attr "type" "fistp")
4378    (set_attr "mode" "HI")])
4379
4380 (define_insn "fix_trunchi_nomemory"
4381   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4382         (fix:HI (match_operand 1 "register_operand" "f,f")))
4383    (use (match_operand:HI 2 "memory_operand" "m,m"))
4384    (use (match_operand:HI 3 "memory_operand" "m,m"))
4385    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4386   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388   "#"
4389   [(set_attr "type" "fistp")
4390    (set_attr "mode" "HI")])
4391
4392 (define_insn "fix_trunchi_memory"
4393   [(set (match_operand:HI 0 "memory_operand" "=m")
4394         (fix:HI (match_operand 1 "register_operand" "f")))
4395    (use (match_operand:HI 2 "memory_operand" "m"))
4396    (use (match_operand:HI 3 "memory_operand" "m"))]
4397   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4398    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4399   "* return output_fix_trunc (insn, operands);"
4400   [(set_attr "type" "fistp")
4401    (set_attr "mode" "HI")])
4402
4403 (define_split 
4404   [(set (match_operand:HI 0 "memory_operand" "")
4405         (fix:HI (match_operand 1 "register_operand" "")))
4406    (use (match_operand:HI 2 "memory_operand" ""))
4407    (use (match_operand:HI 3 "memory_operand" ""))
4408    (clobber (match_operand:HI 4 "memory_operand" ""))]
4409   "reload_completed"
4410   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4411               (use (match_dup 2))
4412               (use (match_dup 3))])]
4413   "")
4414
4415 (define_split 
4416   [(set (match_operand:HI 0 "register_operand" "")
4417         (fix:HI (match_operand 1 "register_operand" "")))
4418    (use (match_operand:HI 2 "memory_operand" ""))
4419    (use (match_operand:HI 3 "memory_operand" ""))
4420    (clobber (match_operand:HI 4 "memory_operand" ""))]
4421   "reload_completed"
4422   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4423               (use (match_dup 2))
4424               (use (match_dup 3))
4425               (clobber (match_dup 4))])
4426    (set (match_dup 0) (match_dup 4))]
4427   "")
4428
4429 ;; %% Not used yet.
4430 (define_insn "x86_fnstcw_1"
4431   [(set (match_operand:HI 0 "memory_operand" "=m")
4432         (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4433   "TARGET_80387"
4434   "fnstcw\t%0"
4435   [(set_attr "length" "2")
4436    (set_attr "mode" "HI")
4437    (set_attr "unit" "i387")
4438    (set_attr "ppro_uops" "few")])
4439
4440 (define_insn "x86_fldcw_1"
4441   [(set (reg:HI 18)
4442         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4443   "TARGET_80387"
4444   "fldcw\t%0"
4445   [(set_attr "length" "2")
4446    (set_attr "mode" "HI")
4447    (set_attr "unit" "i387")
4448    (set_attr "athlon_decode" "vector")
4449    (set_attr "ppro_uops" "few")])
4450 \f
4451 ;; Conversion between fixed point and floating point.
4452
4453 ;; Even though we only accept memory inputs, the backend _really_
4454 ;; wants to be able to do this between registers.
4455
4456 (define_expand "floathisf2"
4457   [(set (match_operand:SF 0 "register_operand" "")
4458         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4459   "TARGET_SSE || TARGET_80387"
4460 {
4461   if (TARGET_SSE && TARGET_SSE_MATH)
4462     {
4463       emit_insn (gen_floatsisf2 (operands[0],
4464                                  convert_to_mode (SImode, operands[1], 0)));
4465       DONE;
4466     }
4467 })
4468
4469 (define_insn "*floathisf2_1"
4470   [(set (match_operand:SF 0 "register_operand" "=f,f")
4471         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4472   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4473   "@
4474    fild%z1\t%1
4475    #"
4476   [(set_attr "type" "fmov,multi")
4477    (set_attr "mode" "SF")
4478    (set_attr "fp_int_src" "true")])
4479
4480 (define_expand "floatsisf2"
4481   [(set (match_operand:SF 0 "register_operand" "")
4482         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4483   "TARGET_SSE || TARGET_80387"
4484   "")
4485
4486 (define_insn "*floatsisf2_i387"
4487   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4488         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4489   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4490   "@
4491    fild%z1\t%1
4492    #
4493    cvtsi2ss\t{%1, %0|%0, %1}
4494    cvtsi2ss\t{%1, %0|%0, %1}"
4495   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4496    (set_attr "mode" "SF")
4497    (set_attr "athlon_decode" "*,*,vector,double")
4498    (set_attr "fp_int_src" "true")])
4499
4500 (define_insn "*floatsisf2_sse"
4501   [(set (match_operand:SF 0 "register_operand" "=x,x")
4502         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4503   "TARGET_SSE"
4504   "cvtsi2ss\t{%1, %0|%0, %1}"
4505   [(set_attr "type" "sseicvt")
4506    (set_attr "mode" "SF")
4507    (set_attr "athlon_decode" "vector,double")
4508    (set_attr "fp_int_src" "true")])
4509
4510 ; Avoid possible reformatting penalty on the destination by first
4511 ; zeroing it out
4512 (define_split
4513   [(set (match_operand:SF 0 "register_operand" "")
4514         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4515   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4516    && SSE_REG_P (operands[0])"
4517   [(const_int 0)]
4518 {
4519   rtx dest;
4520   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4521   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4522   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4523   DONE;
4524 })
4525
4526 (define_expand "floatdisf2"
4527   [(set (match_operand:SF 0 "register_operand" "")
4528         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4529   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4530   "")
4531
4532 (define_insn "*floatdisf2_i387_only"
4533   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4534         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4535   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "SF")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_insn "*floatdisf2_i387"
4544   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4545         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4546   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4547   "@
4548    fild%z1\t%1
4549    #
4550    cvtsi2ss{q}\t{%1, %0|%0, %1}
4551    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4552   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4553    (set_attr "mode" "SF")
4554    (set_attr "athlon_decode" "*,*,vector,double")
4555    (set_attr "fp_int_src" "true")])
4556
4557 (define_insn "*floatdisf2_sse"
4558   [(set (match_operand:SF 0 "register_operand" "=x,x")
4559         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4560   "TARGET_64BIT && TARGET_SSE"
4561   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562   [(set_attr "type" "sseicvt")
4563    (set_attr "mode" "SF")
4564    (set_attr "athlon_decode" "vector,double")
4565    (set_attr "fp_int_src" "true")])
4566
4567 ; Avoid possible reformatting penalty on the destination by first
4568 ; zeroing it out
4569 (define_split
4570   [(set (match_operand:SF 0 "register_operand" "")
4571         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4572   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4573    && SSE_REG_P (operands[0])"
4574   [(const_int 0)]
4575 {
4576   rtx dest;
4577   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4578   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4579   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4580   DONE;
4581 })
4582
4583 (define_expand "floathidf2"
4584   [(set (match_operand:DF 0 "register_operand" "")
4585         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4586   "TARGET_SSE2 || TARGET_80387"
4587 {
4588   if (TARGET_SSE && TARGET_SSE_MATH)
4589     {
4590       emit_insn (gen_floatsidf2 (operands[0],
4591                                  convert_to_mode (SImode, operands[1], 0)));
4592       DONE;
4593     }
4594 })
4595
4596 (define_insn "*floathidf2_1"
4597   [(set (match_operand:DF 0 "register_operand" "=f,f")
4598         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4599   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4600   "@
4601    fild%z1\t%1
4602    #"
4603   [(set_attr "type" "fmov,multi")
4604    (set_attr "mode" "DF")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_expand "floatsidf2"
4608   [(set (match_operand:DF 0 "register_operand" "")
4609         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4610   "TARGET_80387 || TARGET_SSE2"
4611   "")
4612
4613 (define_insn "*floatsidf2_i387"
4614   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4615         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4616   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4617   "@
4618    fild%z1\t%1
4619    #
4620    cvtsi2sd\t{%1, %0|%0, %1}
4621    cvtsi2sd\t{%1, %0|%0, %1}"
4622   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623    (set_attr "mode" "DF")
4624    (set_attr "athlon_decode" "*,*,double,direct")
4625    (set_attr "fp_int_src" "true")])
4626
4627 (define_insn "*floatsidf2_sse"
4628   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4629         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4630   "TARGET_SSE2"
4631   "cvtsi2sd\t{%1, %0|%0, %1}"
4632   [(set_attr "type" "sseicvt")
4633    (set_attr "mode" "DF")
4634    (set_attr "athlon_decode" "double,direct")
4635    (set_attr "fp_int_src" "true")])
4636
4637 (define_expand "floatdidf2"
4638   [(set (match_operand:DF 0 "register_operand" "")
4639         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4640   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4641   "")
4642
4643 (define_insn "*floatdidf2_i387_only"
4644   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4645         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4646   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "DF")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatdidf2_i387"
4655   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4656         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4657   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4658   "@
4659    fild%z1\t%1
4660    #
4661    cvtsi2sd{q}\t{%1, %0|%0, %1}
4662    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4663   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4664    (set_attr "mode" "DF")
4665    (set_attr "athlon_decode" "*,*,double,direct")
4666    (set_attr "fp_int_src" "true")])
4667
4668 (define_insn "*floatdidf2_sse"
4669   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4670         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4671   "TARGET_SSE2"
4672   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673   [(set_attr "type" "sseicvt")
4674    (set_attr "mode" "DF")
4675    (set_attr "athlon_decode" "double,direct")
4676    (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "floathixf2"
4679   [(set (match_operand:XF 0 "register_operand" "=f,f")
4680         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4681   "TARGET_80387"
4682   "@
4683    fild%z1\t%1
4684    #"
4685   [(set_attr "type" "fmov,multi")
4686    (set_attr "mode" "XF")
4687    (set_attr "fp_int_src" "true")])
4688
4689 (define_insn "floatsixf2"
4690   [(set (match_operand:XF 0 "register_operand" "=f,f")
4691         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4692   "TARGET_80387"
4693   "@
4694    fild%z1\t%1
4695    #"
4696   [(set_attr "type" "fmov,multi")
4697    (set_attr "mode" "XF")
4698    (set_attr "fp_int_src" "true")])
4699
4700 (define_insn "floatdixf2"
4701   [(set (match_operand:XF 0 "register_operand" "=f,f")
4702         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4703   "TARGET_80387"
4704   "@
4705    fild%z1\t%1
4706    #"
4707   [(set_attr "type" "fmov,multi")
4708    (set_attr "mode" "XF")
4709    (set_attr "fp_int_src" "true")])
4710
4711 ;; %%% Kill these when reload knows how to do it.
4712 (define_split
4713   [(set (match_operand 0 "fp_register_operand" "")
4714         (float (match_operand 1 "register_operand" "")))]
4715   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4716   [(const_int 0)]
4717 {
4718   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4719   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4720   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4721   ix86_free_from_memory (GET_MODE (operands[1]));
4722   DONE;
4723 })
4724
4725 (define_expand "floatunssisf2"
4726   [(use (match_operand:SF 0 "register_operand" ""))
4727    (use (match_operand:SI 1 "register_operand" ""))]
4728   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4729   "x86_emit_floatuns (operands); DONE;")
4730
4731 (define_expand "floatunsdisf2"
4732   [(use (match_operand:SF 0 "register_operand" ""))
4733    (use (match_operand:DI 1 "register_operand" ""))]
4734   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4735   "x86_emit_floatuns (operands); DONE;")
4736
4737 (define_expand "floatunsdidf2"
4738   [(use (match_operand:DF 0 "register_operand" ""))
4739    (use (match_operand:DI 1 "register_operand" ""))]
4740   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4741   "x86_emit_floatuns (operands); DONE;")
4742 \f
4743 ;; SSE extract/set expanders
4744
4745 (define_expand "vec_setv2df"
4746   [(match_operand:V2DF 0 "register_operand" "")
4747    (match_operand:DF 1 "register_operand" "")
4748    (match_operand 2 "const_int_operand" "")]
4749   "TARGET_SSE2"
4750 {
4751   switch (INTVAL (operands[2]))
4752     {
4753     case 0:
4754       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4755                                  simplify_gen_subreg (V2DFmode, operands[1],
4756                                                       DFmode, 0)));
4757       break;
4758     case 1:
4759       {
4760         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4761
4762         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4763       }
4764       break;
4765     default:
4766       abort ();
4767     }
4768   DONE;
4769 })
4770
4771 (define_expand "vec_extractv2df"
4772   [(match_operand:DF 0 "register_operand" "")
4773    (match_operand:V2DF 1 "register_operand" "")
4774    (match_operand 2 "const_int_operand" "")]
4775   "TARGET_SSE2"
4776 {
4777   switch (INTVAL (operands[2]))
4778     {
4779     case 0:
4780       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4781       break;
4782     case 1:
4783       {
4784         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4785
4786         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4787       }
4788       break;
4789     default:
4790       abort ();
4791     }
4792   DONE;
4793 })
4794
4795 (define_expand "vec_initv2df"
4796   [(match_operand:V2DF 0 "register_operand" "")
4797    (match_operand 1 "" "")]
4798   "TARGET_SSE2"
4799 {
4800   ix86_expand_vector_init (operands[0], operands[1]);
4801   DONE;
4802 })
4803
4804 (define_expand "vec_setv4sf"
4805   [(match_operand:V4SF 0 "register_operand" "")
4806    (match_operand:SF 1 "register_operand" "")
4807    (match_operand 2 "const_int_operand" "")]
4808   "TARGET_SSE"
4809 {
4810   switch (INTVAL (operands[2]))
4811     {
4812     case 0:
4813       emit_insn (gen_sse_movss (operands[0], operands[0],
4814                                 simplify_gen_subreg (V4SFmode, operands[1],
4815                                                      SFmode, 0)));
4816       break;
4817     case 1:
4818       {
4819         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4820         rtx tmp = gen_reg_rtx (V4SFmode);
4821  
4822         emit_move_insn (tmp, operands[0]);
4823         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4824         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4825         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4826                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4827       }
4828     case 2:
4829       {
4830         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4831         rtx tmp = gen_reg_rtx (V4SFmode);
4832
4833         emit_move_insn (tmp, operands[0]);
4834         emit_insn (gen_sse_movss (tmp, tmp, op1));
4835         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4837       }
4838       break;
4839     case 3:
4840       {
4841         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842         rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844         emit_move_insn (tmp, operands[0]);
4845         emit_insn (gen_sse_movss (tmp, tmp, op1));
4846         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4848       }
4849       break;
4850     default:
4851       abort ();
4852     }
4853   DONE;
4854 })
4855
4856 (define_expand "vec_extractv4sf"
4857   [(match_operand:SF 0 "register_operand" "")
4858    (match_operand:V4SF 1 "register_operand" "")
4859    (match_operand 2 "const_int_operand" "")]
4860   "TARGET_SSE"
4861 {
4862   switch (INTVAL (operands[2]))
4863     {
4864     case 0:
4865       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4866       break;
4867     case 1:
4868       {
4869         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870         rtx tmp = gen_reg_rtx (V4SFmode);
4871  
4872         emit_move_insn (tmp, operands[1]);
4873         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4874                                    GEN_INT (1)));
4875       }
4876     case 2:
4877       {
4878         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4879         rtx tmp = gen_reg_rtx (V4SFmode);
4880  
4881         emit_move_insn (tmp, operands[1]);
4882         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4883       }
4884     case 3:
4885       {
4886         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4887         rtx tmp = gen_reg_rtx (V4SFmode);
4888  
4889         emit_move_insn (tmp, operands[1]);
4890         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4891                                    GEN_INT (3)));
4892       }
4893     default:
4894       abort ();
4895     }
4896   DONE;
4897 })
4898
4899 (define_expand "vec_initv4sf"
4900   [(match_operand:V4SF 0 "register_operand" "")
4901    (match_operand 1 "" "")]
4902   "TARGET_SSE"
4903 {
4904   ix86_expand_vector_init (operands[0], operands[1]);
4905   DONE;
4906 })
4907 \f
4908 ;; Add instructions
4909
4910 ;; %%% splits for addsidi3
4911 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4912 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4913 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4914
4915 (define_expand "adddi3"
4916   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4918                  (match_operand:DI 2 "x86_64_general_operand" "")))
4919    (clobber (reg:CC 17))]
4920   ""
4921   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4922
4923 (define_insn "*adddi3_1"
4924   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4925         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4926                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4927    (clobber (reg:CC 17))]
4928   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4929   "#")
4930
4931 (define_split
4932   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4934                  (match_operand:DI 2 "general_operand" "")))
4935    (clobber (reg:CC 17))]
4936   "!TARGET_64BIT && reload_completed"
4937   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4938                                           UNSPEC_ADD_CARRY))
4939               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4940    (parallel [(set (match_dup 3)
4941                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4942                                      (match_dup 4))
4943                             (match_dup 5)))
4944               (clobber (reg:CC 17))])]
4945   "split_di (operands+0, 1, operands+0, operands+3);
4946    split_di (operands+1, 1, operands+1, operands+4);
4947    split_di (operands+2, 1, operands+2, operands+5);")
4948
4949 (define_insn "adddi3_carry_rex64"
4950   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4951           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4952                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4953                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4954    (clobber (reg:CC 17))]
4955   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4956   "adc{q}\t{%2, %0|%0, %2}"
4957   [(set_attr "type" "alu")
4958    (set_attr "pent_pair" "pu")
4959    (set_attr "mode" "DI")
4960    (set_attr "ppro_uops" "few")])
4961
4962 (define_insn "*adddi3_cc_rex64"
4963   [(set (reg:CC 17)
4964         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4965                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4966                    UNSPEC_ADD_CARRY))
4967    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4968         (plus:DI (match_dup 1) (match_dup 2)))]
4969   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970   "add{q}\t{%2, %0|%0, %2}"
4971   [(set_attr "type" "alu")
4972    (set_attr "mode" "DI")])
4973
4974 (define_insn "addqi3_carry"
4975   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4976           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4977                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4978                    (match_operand:QI 2 "general_operand" "qi,qm")))
4979    (clobber (reg:CC 17))]
4980   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4981   "adc{b}\t{%2, %0|%0, %2}"
4982   [(set_attr "type" "alu")
4983    (set_attr "pent_pair" "pu")
4984    (set_attr "mode" "QI")
4985    (set_attr "ppro_uops" "few")])
4986
4987 (define_insn "addhi3_carry"
4988   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4989           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4990                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4991                    (match_operand:HI 2 "general_operand" "ri,rm")))
4992    (clobber (reg:CC 17))]
4993   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4994   "adc{w}\t{%2, %0|%0, %2}"
4995   [(set_attr "type" "alu")
4996    (set_attr "pent_pair" "pu")
4997    (set_attr "mode" "HI")
4998    (set_attr "ppro_uops" "few")])
4999
5000 (define_insn "addsi3_carry"
5001   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5002           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5003                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5004                    (match_operand:SI 2 "general_operand" "ri,rm")))
5005    (clobber (reg:CC 17))]
5006   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5007   "adc{l}\t{%2, %0|%0, %2}"
5008   [(set_attr "type" "alu")
5009    (set_attr "pent_pair" "pu")
5010    (set_attr "mode" "SI")
5011    (set_attr "ppro_uops" "few")])
5012
5013 (define_insn "*addsi3_carry_zext"
5014   [(set (match_operand:DI 0 "register_operand" "=r")
5015           (zero_extend:DI 
5016             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5017                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5018                      (match_operand:SI 2 "general_operand" "rim"))))
5019    (clobber (reg:CC 17))]
5020   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5021   "adc{l}\t{%2, %k0|%k0, %2}"
5022   [(set_attr "type" "alu")
5023    (set_attr "pent_pair" "pu")
5024    (set_attr "mode" "SI")
5025    (set_attr "ppro_uops" "few")])
5026
5027 (define_insn "*addsi3_cc"
5028   [(set (reg:CC 17)
5029         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5030                     (match_operand:SI 2 "general_operand" "ri,rm")]
5031                    UNSPEC_ADD_CARRY))
5032    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5033         (plus:SI (match_dup 1) (match_dup 2)))]
5034   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5035   "add{l}\t{%2, %0|%0, %2}"
5036   [(set_attr "type" "alu")
5037    (set_attr "mode" "SI")])
5038
5039 (define_insn "addqi3_cc"
5040   [(set (reg:CC 17)
5041         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5042                     (match_operand:QI 2 "general_operand" "qi,qm")]
5043                    UNSPEC_ADD_CARRY))
5044    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5045         (plus:QI (match_dup 1) (match_dup 2)))]
5046   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5047   "add{b}\t{%2, %0|%0, %2}"
5048   [(set_attr "type" "alu")
5049    (set_attr "mode" "QI")])
5050
5051 (define_expand "addsi3"
5052   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5053                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5054                             (match_operand:SI 2 "general_operand" "")))
5055               (clobber (reg:CC 17))])]
5056   ""
5057   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5058
5059 (define_insn "*lea_1"
5060   [(set (match_operand:SI 0 "register_operand" "=r")
5061         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5062   "!TARGET_64BIT"
5063   "lea{l}\t{%a1, %0|%0, %a1}"
5064   [(set_attr "type" "lea")
5065    (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_1_rex64"
5068   [(set (match_operand:SI 0 "register_operand" "=r")
5069         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5070   "TARGET_64BIT"
5071   "lea{l}\t{%a1, %0|%0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn "*lea_1_zext"
5076   [(set (match_operand:DI 0 "register_operand" "=r")
5077         (zero_extend:DI
5078          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5079   "TARGET_64BIT"
5080   "lea{l}\t{%a1, %k0|%k0, %a1}"
5081   [(set_attr "type" "lea")
5082    (set_attr "mode" "SI")])
5083
5084 (define_insn "*lea_2_rex64"
5085   [(set (match_operand:DI 0 "register_operand" "=r")
5086         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5087   "TARGET_64BIT"
5088   "lea{q}\t{%a1, %0|%0, %a1}"
5089   [(set_attr "type" "lea")
5090    (set_attr "mode" "DI")])
5091
5092 ;; The lea patterns for non-Pmodes needs to be matched by several
5093 ;; insns converted to real lea by splitters.
5094
5095 (define_insn_and_split "*lea_general_1"
5096   [(set (match_operand 0 "register_operand" "=r")
5097         (plus (plus (match_operand 1 "index_register_operand" "r")
5098                     (match_operand 2 "register_operand" "r"))
5099               (match_operand 3 "immediate_operand" "i")))]
5100   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5101     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5102    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5103    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5104    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5105    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5106        || GET_MODE (operands[3]) == VOIDmode)"
5107   "#"
5108   "&& reload_completed"
5109   [(const_int 0)]
5110 {
5111   rtx pat;
5112   operands[0] = gen_lowpart (SImode, operands[0]);
5113   operands[1] = gen_lowpart (Pmode, operands[1]);
5114   operands[2] = gen_lowpart (Pmode, operands[2]);
5115   operands[3] = gen_lowpart (Pmode, operands[3]);
5116   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5117                       operands[3]);
5118   if (Pmode != SImode)
5119     pat = gen_rtx_SUBREG (SImode, pat, 0);
5120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5121   DONE;
5122 }
5123   [(set_attr "type" "lea")
5124    (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_1_zext"
5127   [(set (match_operand:DI 0 "register_operand" "=r")
5128         (zero_extend:DI
5129           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5130                             (match_operand:SI 2 "register_operand" "r"))
5131                    (match_operand:SI 3 "immediate_operand" "i"))))]
5132   "TARGET_64BIT"
5133   "#"
5134   "&& reload_completed"
5135   [(set (match_dup 0)
5136         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5137                                                      (match_dup 2))
5138                                             (match_dup 3)) 0)))]
5139 {
5140   operands[1] = gen_lowpart (Pmode, operands[1]);
5141   operands[2] = gen_lowpart (Pmode, operands[2]);
5142   operands[3] = gen_lowpart (Pmode, operands[3]);
5143 }
5144   [(set_attr "type" "lea")
5145    (set_attr "mode" "SI")])
5146
5147 (define_insn_and_split "*lea_general_2"
5148   [(set (match_operand 0 "register_operand" "=r")
5149         (plus (mult (match_operand 1 "index_register_operand" "r")
5150                     (match_operand 2 "const248_operand" "i"))
5151               (match_operand 3 "nonmemory_operand" "ri")))]
5152   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5153     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5154    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5155    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5156    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5157        || GET_MODE (operands[3]) == VOIDmode)"
5158   "#"
5159   "&& reload_completed"
5160   [(const_int 0)]
5161 {
5162   rtx pat;
5163   operands[0] = gen_lowpart (SImode, operands[0]);
5164   operands[1] = gen_lowpart (Pmode, operands[1]);
5165   operands[3] = gen_lowpart (Pmode, operands[3]);
5166   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5167                       operands[3]);
5168   if (Pmode != SImode)
5169     pat = gen_rtx_SUBREG (SImode, pat, 0);
5170   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5171   DONE;
5172 }
5173   [(set_attr "type" "lea")
5174    (set_attr "mode" "SI")])
5175
5176 (define_insn_and_split "*lea_general_2_zext"
5177   [(set (match_operand:DI 0 "register_operand" "=r")
5178         (zero_extend:DI
5179           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5180                             (match_operand:SI 2 "const248_operand" "n"))
5181                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5182   "TARGET_64BIT"
5183   "#"
5184   "&& reload_completed"
5185   [(set (match_dup 0)
5186         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5187                                                      (match_dup 2))
5188                                             (match_dup 3)) 0)))]
5189 {
5190   operands[1] = gen_lowpart (Pmode, operands[1]);
5191   operands[3] = gen_lowpart (Pmode, operands[3]);
5192 }
5193   [(set_attr "type" "lea")
5194    (set_attr "mode" "SI")])
5195
5196 (define_insn_and_split "*lea_general_3"
5197   [(set (match_operand 0 "register_operand" "=r")
5198         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5199                           (match_operand 2 "const248_operand" "i"))
5200                     (match_operand 3 "register_operand" "r"))
5201               (match_operand 4 "immediate_operand" "i")))]
5202   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5203     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5204    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5205    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5206    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5207   "#"
5208   "&& reload_completed"
5209   [(const_int 0)]
5210 {
5211   rtx pat;
5212   operands[0] = gen_lowpart (SImode, operands[0]);
5213   operands[1] = gen_lowpart (Pmode, operands[1]);
5214   operands[3] = gen_lowpart (Pmode, operands[3]);
5215   operands[4] = gen_lowpart (Pmode, operands[4]);
5216   pat = gen_rtx_PLUS (Pmode,
5217                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5218                                                          operands[2]),
5219                                     operands[3]),
5220                       operands[4]);
5221   if (Pmode != SImode)
5222     pat = gen_rtx_SUBREG (SImode, pat, 0);
5223   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5224   DONE;
5225 }
5226   [(set_attr "type" "lea")
5227    (set_attr "mode" "SI")])
5228
5229 (define_insn_and_split "*lea_general_3_zext"
5230   [(set (match_operand:DI 0 "register_operand" "=r")
5231         (zero_extend:DI
5232           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5233                                      (match_operand:SI 2 "const248_operand" "n"))
5234                             (match_operand:SI 3 "register_operand" "r"))
5235                    (match_operand:SI 4 "immediate_operand" "i"))))]
5236   "TARGET_64BIT"
5237   "#"
5238   "&& reload_completed"
5239   [(set (match_dup 0)
5240         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5241                                                               (match_dup 2))
5242                                                      (match_dup 3))
5243                                             (match_dup 4)) 0)))]
5244 {
5245   operands[1] = gen_lowpart (Pmode, operands[1]);
5246   operands[3] = gen_lowpart (Pmode, operands[3]);
5247   operands[4] = gen_lowpart (Pmode, operands[4]);
5248 }
5249   [(set_attr "type" "lea")
5250    (set_attr "mode" "SI")])
5251
5252 (define_insn "*adddi_1_rex64"
5253   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5254         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5255                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5256    (clobber (reg:CC 17))]
5257   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5258 {
5259   switch (get_attr_type (insn))
5260     {
5261     case TYPE_LEA:
5262       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5263       return "lea{q}\t{%a2, %0|%0, %a2}";
5264
5265     case TYPE_INCDEC:
5266       if (! rtx_equal_p (operands[0], operands[1]))
5267         abort ();
5268       if (operands[2] == const1_rtx)
5269         return "inc{q}\t%0";
5270       else if (operands[2] == constm1_rtx)
5271         return "dec{q}\t%0";
5272       else
5273         abort ();
5274
5275     default:
5276       if (! rtx_equal_p (operands[0], operands[1]))
5277         abort ();
5278
5279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5280          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5281       if (GET_CODE (operands[2]) == CONST_INT
5282           /* Avoid overflows.  */
5283           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5284           && (INTVAL (operands[2]) == 128
5285               || (INTVAL (operands[2]) < 0
5286                   && INTVAL (operands[2]) != -128)))
5287         {
5288           operands[2] = GEN_INT (-INTVAL (operands[2]));
5289           return "sub{q}\t{%2, %0|%0, %2}";
5290         }
5291       return "add{q}\t{%2, %0|%0, %2}";
5292     }
5293 }
5294   [(set (attr "type")
5295      (cond [(eq_attr "alternative" "2")
5296               (const_string "lea")
5297             ; Current assemblers are broken and do not allow @GOTOFF in
5298             ; ought but a memory context.
5299             (match_operand:DI 2 "pic_symbolic_operand" "")
5300               (const_string "lea")
5301             (match_operand:DI 2 "incdec_operand" "")
5302               (const_string "incdec")
5303            ]
5304            (const_string "alu")))
5305    (set_attr "mode" "DI")])
5306
5307 ;; Convert lea to the lea pattern to avoid flags dependency.
5308 (define_split
5309   [(set (match_operand:DI 0 "register_operand" "")
5310         (plus:DI (match_operand:DI 1 "register_operand" "")
5311                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5312    (clobber (reg:CC 17))]
5313   "TARGET_64BIT && reload_completed
5314    && true_regnum (operands[0]) != true_regnum (operands[1])"
5315   [(set (match_dup 0)
5316         (plus:DI (match_dup 1)
5317                  (match_dup 2)))]
5318   "")
5319
5320 (define_insn "*adddi_2_rex64"
5321   [(set (reg 17)
5322         (compare
5323           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5324                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5325           (const_int 0)))                       
5326    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5327         (plus:DI (match_dup 1) (match_dup 2)))]
5328   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5329    && ix86_binary_operator_ok (PLUS, DImode, operands)
5330    /* Current assemblers are broken and do not allow @GOTOFF in
5331       ought but a memory context.  */
5332    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5333 {
5334   switch (get_attr_type (insn))
5335     {
5336     case TYPE_INCDEC:
5337       if (! rtx_equal_p (operands[0], operands[1]))
5338         abort ();
5339       if (operands[2] == const1_rtx)
5340         return "inc{q}\t%0";
5341       else if (operands[2] == constm1_rtx)
5342         return "dec{q}\t%0";
5343       else
5344         abort ();
5345
5346     default:
5347       if (! rtx_equal_p (operands[0], operands[1]))
5348         abort ();
5349       /* ???? We ought to handle there the 32bit case too
5350          - do we need new constraint?  */
5351       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5353       if (GET_CODE (operands[2]) == CONST_INT
5354           /* Avoid overflows.  */
5355           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5356           && (INTVAL (operands[2]) == 128
5357               || (INTVAL (operands[2]) < 0
5358                   && INTVAL (operands[2]) != -128)))
5359         {
5360           operands[2] = GEN_INT (-INTVAL (operands[2]));
5361           return "sub{q}\t{%2, %0|%0, %2}";
5362         }
5363       return "add{q}\t{%2, %0|%0, %2}";
5364     }
5365 }
5366   [(set (attr "type")
5367      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5368         (const_string "incdec")
5369         (const_string "alu")))
5370    (set_attr "mode" "DI")])
5371
5372 (define_insn "*adddi_3_rex64"
5373   [(set (reg 17)
5374         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5375                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5376    (clobber (match_scratch:DI 0 "=r"))]
5377   "TARGET_64BIT
5378    && ix86_match_ccmode (insn, CCZmode)
5379    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5380    /* Current assemblers are broken and do not allow @GOTOFF in
5381       ought but a memory context.  */
5382    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5383 {
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_INCDEC:
5387       if (! rtx_equal_p (operands[0], operands[1]))
5388         abort ();
5389       if (operands[2] == const1_rtx)
5390         return "inc{q}\t%0";
5391       else if (operands[2] == constm1_rtx)
5392         return "dec{q}\t%0";
5393       else
5394         abort ();
5395
5396     default:
5397       if (! rtx_equal_p (operands[0], operands[1]))
5398         abort ();
5399       /* ???? We ought to handle there the 32bit case too
5400          - do we need new constraint?  */
5401       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5402          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5403       if (GET_CODE (operands[2]) == CONST_INT
5404           /* Avoid overflows.  */
5405           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5406           && (INTVAL (operands[2]) == 128
5407               || (INTVAL (operands[2]) < 0
5408                   && INTVAL (operands[2]) != -128)))
5409         {
5410           operands[2] = GEN_INT (-INTVAL (operands[2]));
5411           return "sub{q}\t{%2, %0|%0, %2}";
5412         }
5413       return "add{q}\t{%2, %0|%0, %2}";
5414     }
5415 }
5416   [(set (attr "type")
5417      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5418         (const_string "incdec")
5419         (const_string "alu")))
5420    (set_attr "mode" "DI")])
5421
5422 ; For comparisons against 1, -1 and 128, we may generate better code
5423 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5424 ; is matched then.  We can't accept general immediate, because for
5425 ; case of overflows,  the result is messed up.
5426 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5427 ; when negated.
5428 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5429 ; only for comparisons not depending on it.
5430 (define_insn "*adddi_4_rex64"
5431   [(set (reg 17)
5432         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5433                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5434    (clobber (match_scratch:DI 0 "=rm"))]
5435   "TARGET_64BIT
5436    &&  ix86_match_ccmode (insn, CCGCmode)"
5437 {
5438   switch (get_attr_type (insn))
5439     {
5440     case TYPE_INCDEC:
5441       if (operands[2] == constm1_rtx)
5442         return "inc{q}\t%0";
5443       else if (operands[2] == const1_rtx)
5444         return "dec{q}\t%0";
5445       else
5446         abort();
5447
5448     default:
5449       if (! rtx_equal_p (operands[0], operands[1]))
5450         abort ();
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if ((INTVAL (operands[2]) == -128
5454            || (INTVAL (operands[2]) > 0
5455                && INTVAL (operands[2]) != 128))
5456           /* Avoid overflows.  */
5457           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5458         return "sub{q}\t{%2, %0|%0, %2}";
5459       operands[2] = GEN_INT (-INTVAL (operands[2]));
5460       return "add{q}\t{%2, %0|%0, %2}";
5461     }
5462 }
5463   [(set (attr "type")
5464      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5465         (const_string "incdec")
5466         (const_string "alu")))
5467    (set_attr "mode" "DI")])
5468
5469 (define_insn "*adddi_5_rex64"
5470   [(set (reg 17)
5471         (compare
5472           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5473                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5474           (const_int 0)))                       
5475    (clobber (match_scratch:DI 0 "=r"))]
5476   "TARGET_64BIT
5477    && ix86_match_ccmode (insn, CCGOCmode)
5478    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5479    /* Current assemblers are broken and do not allow @GOTOFF in
5480       ought but a memory context.  */
5481    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5482 {
5483   switch (get_attr_type (insn))
5484     {
5485     case TYPE_INCDEC:
5486       if (! rtx_equal_p (operands[0], operands[1]))
5487         abort ();
5488       if (operands[2] == const1_rtx)
5489         return "inc{q}\t%0";
5490       else if (operands[2] == constm1_rtx)
5491         return "dec{q}\t%0";
5492       else
5493         abort();
5494
5495     default:
5496       if (! rtx_equal_p (operands[0], operands[1]))
5497         abort ();
5498       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5499          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5500       if (GET_CODE (operands[2]) == CONST_INT
5501           /* Avoid overflows.  */
5502           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5503           && (INTVAL (operands[2]) == 128
5504               || (INTVAL (operands[2]) < 0
5505                   && INTVAL (operands[2]) != -128)))
5506         {
5507           operands[2] = GEN_INT (-INTVAL (operands[2]));
5508           return "sub{q}\t{%2, %0|%0, %2}";
5509         }
5510       return "add{q}\t{%2, %0|%0, %2}";
5511     }
5512 }
5513   [(set (attr "type")
5514      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5515         (const_string "incdec")
5516         (const_string "alu")))
5517    (set_attr "mode" "DI")])
5518
5519
5520 (define_insn "*addsi_1"
5521   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5522         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5523                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5524    (clobber (reg:CC 17))]
5525   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5526 {
5527   switch (get_attr_type (insn))
5528     {
5529     case TYPE_LEA:
5530       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5531       return "lea{l}\t{%a2, %0|%0, %a2}";
5532
5533     case TYPE_INCDEC:
5534       if (! rtx_equal_p (operands[0], operands[1]))
5535         abort ();
5536       if (operands[2] == const1_rtx)
5537         return "inc{l}\t%0";
5538       else if (operands[2] == constm1_rtx)
5539         return "dec{l}\t%0";
5540       else
5541         abort();
5542
5543     default:
5544       if (! rtx_equal_p (operands[0], operands[1]))
5545         abort ();
5546
5547       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5548          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5549       if (GET_CODE (operands[2]) == CONST_INT
5550           && (INTVAL (operands[2]) == 128
5551               || (INTVAL (operands[2]) < 0
5552                   && INTVAL (operands[2]) != -128)))
5553         {
5554           operands[2] = GEN_INT (-INTVAL (operands[2]));
5555           return "sub{l}\t{%2, %0|%0, %2}";
5556         }
5557       return "add{l}\t{%2, %0|%0, %2}";
5558     }
5559 }
5560   [(set (attr "type")
5561      (cond [(eq_attr "alternative" "2")
5562               (const_string "lea")
5563             ; Current assemblers are broken and do not allow @GOTOFF in
5564             ; ought but a memory context.
5565             (match_operand:SI 2 "pic_symbolic_operand" "")
5566               (const_string "lea")
5567             (match_operand:SI 2 "incdec_operand" "")
5568               (const_string "incdec")
5569            ]
5570            (const_string "alu")))
5571    (set_attr "mode" "SI")])
5572
5573 ;; Convert lea to the lea pattern to avoid flags dependency.
5574 (define_split
5575   [(set (match_operand 0 "register_operand" "")
5576         (plus (match_operand 1 "register_operand" "")
5577               (match_operand 2 "nonmemory_operand" "")))
5578    (clobber (reg:CC 17))]
5579   "reload_completed
5580    && true_regnum (operands[0]) != true_regnum (operands[1])"
5581   [(const_int 0)]
5582 {
5583   rtx pat;
5584   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5585      may confuse gen_lowpart.  */
5586   if (GET_MODE (operands[0]) != Pmode)
5587     {
5588       operands[1] = gen_lowpart (Pmode, operands[1]);
5589       operands[2] = gen_lowpart (Pmode, operands[2]);
5590     }
5591   operands[0] = gen_lowpart (SImode, operands[0]);
5592   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5593   if (Pmode != SImode)
5594     pat = gen_rtx_SUBREG (SImode, pat, 0);
5595   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5596   DONE;
5597 })
5598
5599 ;; It may seem that nonimmediate operand is proper one for operand 1.
5600 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5601 ;; we take care in ix86_binary_operator_ok to not allow two memory
5602 ;; operands so proper swapping will be done in reload.  This allow
5603 ;; patterns constructed from addsi_1 to match.
5604 (define_insn "addsi_1_zext"
5605   [(set (match_operand:DI 0 "register_operand" "=r,r")
5606         (zero_extend:DI
5607           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5608                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5609    (clobber (reg:CC 17))]
5610   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5611 {
5612   switch (get_attr_type (insn))
5613     {
5614     case TYPE_LEA:
5615       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5616       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5617
5618     case TYPE_INCDEC:
5619       if (operands[2] == const1_rtx)
5620         return "inc{l}\t%k0";
5621       else if (operands[2] == constm1_rtx)
5622         return "dec{l}\t%k0";
5623       else
5624         abort();
5625
5626     default:
5627       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5628          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5629       if (GET_CODE (operands[2]) == CONST_INT
5630           && (INTVAL (operands[2]) == 128
5631               || (INTVAL (operands[2]) < 0
5632                   && INTVAL (operands[2]) != -128)))
5633         {
5634           operands[2] = GEN_INT (-INTVAL (operands[2]));
5635           return "sub{l}\t{%2, %k0|%k0, %2}";
5636         }
5637       return "add{l}\t{%2, %k0|%k0, %2}";
5638     }
5639 }
5640   [(set (attr "type")
5641      (cond [(eq_attr "alternative" "1")
5642               (const_string "lea")
5643             ; Current assemblers are broken and do not allow @GOTOFF in
5644             ; ought but a memory context.
5645             (match_operand:SI 2 "pic_symbolic_operand" "")
5646               (const_string "lea")
5647             (match_operand:SI 2 "incdec_operand" "")
5648               (const_string "incdec")
5649            ]
5650            (const_string "alu")))
5651    (set_attr "mode" "SI")])
5652
5653 ;; Convert lea to the lea pattern to avoid flags dependency.
5654 (define_split
5655   [(set (match_operand:DI 0 "register_operand" "")
5656         (zero_extend:DI
5657           (plus:SI (match_operand:SI 1 "register_operand" "")
5658                    (match_operand:SI 2 "nonmemory_operand" ""))))
5659    (clobber (reg:CC 17))]
5660   "TARGET_64BIT && reload_completed
5661    && true_regnum (operands[0]) != true_regnum (operands[1])"
5662   [(set (match_dup 0)
5663         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5664 {
5665   operands[1] = gen_lowpart (Pmode, operands[1]);
5666   operands[2] = gen_lowpart (Pmode, operands[2]);
5667 })
5668
5669 (define_insn "*addsi_2"
5670   [(set (reg 17)
5671         (compare
5672           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5673                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5674           (const_int 0)))                       
5675    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5676         (plus:SI (match_dup 1) (match_dup 2)))]
5677   "ix86_match_ccmode (insn, CCGOCmode)
5678    && ix86_binary_operator_ok (PLUS, SImode, operands)
5679    /* Current assemblers are broken and do not allow @GOTOFF in
5680       ought but a memory context.  */
5681    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5682 {
5683   switch (get_attr_type (insn))
5684     {
5685     case TYPE_INCDEC:
5686       if (! rtx_equal_p (operands[0], operands[1]))
5687         abort ();
5688       if (operands[2] == const1_rtx)
5689         return "inc{l}\t%0";
5690       else if (operands[2] == constm1_rtx)
5691         return "dec{l}\t%0";
5692       else
5693         abort();
5694
5695     default:
5696       if (! rtx_equal_p (operands[0], operands[1]))
5697         abort ();
5698       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5699          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5700       if (GET_CODE (operands[2]) == CONST_INT
5701           && (INTVAL (operands[2]) == 128
5702               || (INTVAL (operands[2]) < 0
5703                   && INTVAL (operands[2]) != -128)))
5704         {
5705           operands[2] = GEN_INT (-INTVAL (operands[2]));
5706           return "sub{l}\t{%2, %0|%0, %2}";
5707         }
5708       return "add{l}\t{%2, %0|%0, %2}";
5709     }
5710 }
5711   [(set (attr "type")
5712      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713         (const_string "incdec")
5714         (const_string "alu")))
5715    (set_attr "mode" "SI")])
5716
5717 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5718 (define_insn "*addsi_2_zext"
5719   [(set (reg 17)
5720         (compare
5721           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5722                    (match_operand:SI 2 "general_operand" "rmni"))
5723           (const_int 0)))                       
5724    (set (match_operand:DI 0 "register_operand" "=r")
5725         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5726   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5727    && ix86_binary_operator_ok (PLUS, SImode, operands)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       if (operands[2] == const1_rtx)
5736         return "inc{l}\t%k0";
5737       else if (operands[2] == constm1_rtx)
5738         return "dec{l}\t%k0";
5739       else
5740         abort();
5741
5742     default:
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if (GET_CODE (operands[2]) == CONST_INT
5746           && (INTVAL (operands[2]) == 128
5747               || (INTVAL (operands[2]) < 0
5748                   && INTVAL (operands[2]) != -128)))
5749         {
5750           operands[2] = GEN_INT (-INTVAL (operands[2]));
5751           return "sub{l}\t{%2, %k0|%k0, %2}";
5752         }
5753       return "add{l}\t{%2, %k0|%k0, %2}";
5754     }
5755 }
5756   [(set (attr "type")
5757      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758         (const_string "incdec")
5759         (const_string "alu")))
5760    (set_attr "mode" "SI")])
5761
5762 (define_insn "*addsi_3"
5763   [(set (reg 17)
5764         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5765                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5766    (clobber (match_scratch:SI 0 "=r"))]
5767   "ix86_match_ccmode (insn, CCZmode)
5768    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5769    /* Current assemblers are broken and do not allow @GOTOFF in
5770       ought but a memory context.  */
5771    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5772 {
5773   switch (get_attr_type (insn))
5774     {
5775     case TYPE_INCDEC:
5776       if (! rtx_equal_p (operands[0], operands[1]))
5777         abort ();
5778       if (operands[2] == const1_rtx)
5779         return "inc{l}\t%0";
5780       else if (operands[2] == constm1_rtx)
5781         return "dec{l}\t%0";
5782       else
5783         abort();
5784
5785     default:
5786       if (! rtx_equal_p (operands[0], operands[1]))
5787         abort ();
5788       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5789          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5790       if (GET_CODE (operands[2]) == CONST_INT
5791           && (INTVAL (operands[2]) == 128
5792               || (INTVAL (operands[2]) < 0
5793                   && INTVAL (operands[2]) != -128)))
5794         {
5795           operands[2] = GEN_INT (-INTVAL (operands[2]));
5796           return "sub{l}\t{%2, %0|%0, %2}";
5797         }
5798       return "add{l}\t{%2, %0|%0, %2}";
5799     }
5800 }
5801   [(set (attr "type")
5802      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803         (const_string "incdec")
5804         (const_string "alu")))
5805    (set_attr "mode" "SI")])
5806
5807 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5808 (define_insn "*addsi_3_zext"
5809   [(set (reg 17)
5810         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5811                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5812    (set (match_operand:DI 0 "register_operand" "=r")
5813         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5814   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5815    && ix86_binary_operator_ok (PLUS, SImode, operands)
5816    /* Current assemblers are broken and do not allow @GOTOFF in
5817       ought but a memory context.  */
5818    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5819 {
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{l}\t%k0";
5825       else if (operands[2] == constm1_rtx)
5826         return "dec{l}\t%k0";
5827       else
5828         abort();
5829
5830     default:
5831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833       if (GET_CODE (operands[2]) == CONST_INT
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{l}\t{%2, %k0|%k0, %2}";
5840         }
5841       return "add{l}\t{%2, %k0|%k0, %2}";
5842     }
5843 }
5844   [(set (attr "type")
5845      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5846         (const_string "incdec")
5847         (const_string "alu")))
5848    (set_attr "mode" "SI")])
5849
5850 ; For comparisons against 1, -1 and 128, we may generate better code
5851 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5852 ; is matched then.  We can't accept general immediate, because for
5853 ; case of overflows,  the result is messed up.
5854 ; This pattern also don't hold of 0x80000000, since the value overflows
5855 ; when negated.
5856 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5857 ; only for comparisons not depending on it.
5858 (define_insn "*addsi_4"
5859   [(set (reg 17)
5860         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5861                  (match_operand:SI 2 "const_int_operand" "n")))
5862    (clobber (match_scratch:SI 0 "=rm"))]
5863   "ix86_match_ccmode (insn, CCGCmode)
5864    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5865 {
5866   switch (get_attr_type (insn))
5867     {
5868     case TYPE_INCDEC:
5869       if (operands[2] == constm1_rtx)
5870         return "inc{l}\t%0";
5871       else if (operands[2] == const1_rtx)
5872         return "dec{l}\t%0";
5873       else
5874         abort();
5875
5876     default:
5877       if (! rtx_equal_p (operands[0], operands[1]))
5878         abort ();
5879       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881       if ((INTVAL (operands[2]) == -128
5882            || (INTVAL (operands[2]) > 0
5883                && INTVAL (operands[2]) != 128)))
5884         return "sub{l}\t{%2, %0|%0, %2}";
5885       operands[2] = GEN_INT (-INTVAL (operands[2]));
5886       return "add{l}\t{%2, %0|%0, %2}";
5887     }
5888 }
5889   [(set (attr "type")
5890      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5891         (const_string "incdec")
5892         (const_string "alu")))
5893    (set_attr "mode" "SI")])
5894
5895 (define_insn "*addsi_5"
5896   [(set (reg 17)
5897         (compare
5898           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5899                    (match_operand:SI 2 "general_operand" "rmni"))
5900           (const_int 0)))                       
5901    (clobber (match_scratch:SI 0 "=r"))]
5902   "ix86_match_ccmode (insn, CCGOCmode)
5903    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5904    /* Current assemblers are broken and do not allow @GOTOFF in
5905       ought but a memory context.  */
5906    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5907 {
5908   switch (get_attr_type (insn))
5909     {
5910     case TYPE_INCDEC:
5911       if (! rtx_equal_p (operands[0], operands[1]))
5912         abort ();
5913       if (operands[2] == const1_rtx)
5914         return "inc{l}\t%0";
5915       else if (operands[2] == constm1_rtx)
5916         return "dec{l}\t%0";
5917       else
5918         abort();
5919
5920     default:
5921       if (! rtx_equal_p (operands[0], operands[1]))
5922         abort ();
5923       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5924          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5925       if (GET_CODE (operands[2]) == CONST_INT
5926           && (INTVAL (operands[2]) == 128
5927               || (INTVAL (operands[2]) < 0
5928                   && INTVAL (operands[2]) != -128)))
5929         {
5930           operands[2] = GEN_INT (-INTVAL (operands[2]));
5931           return "sub{l}\t{%2, %0|%0, %2}";
5932         }
5933       return "add{l}\t{%2, %0|%0, %2}";
5934     }
5935 }
5936   [(set (attr "type")
5937      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5938         (const_string "incdec")
5939         (const_string "alu")))
5940    (set_attr "mode" "SI")])
5941
5942 (define_expand "addhi3"
5943   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5944                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5945                             (match_operand:HI 2 "general_operand" "")))
5946               (clobber (reg:CC 17))])]
5947   "TARGET_HIMODE_MATH"
5948   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5949
5950 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5951 ;; type optimizations enabled by define-splits.  This is not important
5952 ;; for PII, and in fact harmful because of partial register stalls.
5953
5954 (define_insn "*addhi_1_lea"
5955   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5956         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5957                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5958    (clobber (reg:CC 17))]
5959   "!TARGET_PARTIAL_REG_STALL
5960    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5961 {
5962   switch (get_attr_type (insn))
5963     {
5964     case TYPE_LEA:
5965       return "#";
5966     case TYPE_INCDEC:
5967       if (operands[2] == const1_rtx)
5968         return "inc{w}\t%0";
5969       else if (operands[2] == constm1_rtx)
5970         return "dec{w}\t%0";
5971       abort();
5972
5973     default:
5974       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5976       if (GET_CODE (operands[2]) == CONST_INT
5977           && (INTVAL (operands[2]) == 128
5978               || (INTVAL (operands[2]) < 0
5979                   && INTVAL (operands[2]) != -128)))
5980         {
5981           operands[2] = GEN_INT (-INTVAL (operands[2]));
5982           return "sub{w}\t{%2, %0|%0, %2}";
5983         }
5984       return "add{w}\t{%2, %0|%0, %2}";
5985     }
5986 }
5987   [(set (attr "type")
5988      (if_then_else (eq_attr "alternative" "2")
5989         (const_string "lea")
5990         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5991            (const_string "incdec")
5992            (const_string "alu"))))
5993    (set_attr "mode" "HI,HI,SI")])
5994
5995 (define_insn "*addhi_1"
5996   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5997         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5998                  (match_operand:HI 2 "general_operand" "ri,rm")))
5999    (clobber (reg:CC 17))]
6000   "TARGET_PARTIAL_REG_STALL
6001    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6002 {
6003   switch (get_attr_type (insn))
6004     {
6005     case TYPE_INCDEC:
6006       if (operands[2] == const1_rtx)
6007         return "inc{w}\t%0";
6008       else if (operands[2] == constm1_rtx)
6009         return "dec{w}\t%0";
6010       abort();
6011
6012     default:
6013       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6014          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6015       if (GET_CODE (operands[2]) == CONST_INT
6016           && (INTVAL (operands[2]) == 128
6017               || (INTVAL (operands[2]) < 0
6018                   && INTVAL (operands[2]) != -128)))
6019         {
6020           operands[2] = GEN_INT (-INTVAL (operands[2]));
6021           return "sub{w}\t{%2, %0|%0, %2}";
6022         }
6023       return "add{w}\t{%2, %0|%0, %2}";
6024     }
6025 }
6026   [(set (attr "type")
6027      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6028         (const_string "incdec")
6029         (const_string "alu")))
6030    (set_attr "mode" "HI")])
6031
6032 (define_insn "*addhi_2"
6033   [(set (reg 17)
6034         (compare
6035           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6036                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6037           (const_int 0)))                       
6038    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6039         (plus:HI (match_dup 1) (match_dup 2)))]
6040   "ix86_match_ccmode (insn, CCGOCmode)
6041    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6042 {
6043   switch (get_attr_type (insn))
6044     {
6045     case TYPE_INCDEC:
6046       if (operands[2] == const1_rtx)
6047         return "inc{w}\t%0";
6048       else if (operands[2] == constm1_rtx)
6049         return "dec{w}\t%0";
6050       abort();
6051
6052     default:
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (GET_CODE (operands[2]) == CONST_INT
6056           && (INTVAL (operands[2]) == 128
6057               || (INTVAL (operands[2]) < 0
6058                   && INTVAL (operands[2]) != -128)))
6059         {
6060           operands[2] = GEN_INT (-INTVAL (operands[2]));
6061           return "sub{w}\t{%2, %0|%0, %2}";
6062         }
6063       return "add{w}\t{%2, %0|%0, %2}";
6064     }
6065 }
6066   [(set (attr "type")
6067      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6068         (const_string "incdec")
6069         (const_string "alu")))
6070    (set_attr "mode" "HI")])
6071
6072 (define_insn "*addhi_3"
6073   [(set (reg 17)
6074         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6075                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6076    (clobber (match_scratch:HI 0 "=r"))]
6077   "ix86_match_ccmode (insn, CCZmode)
6078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6079 {
6080   switch (get_attr_type (insn))
6081     {
6082     case TYPE_INCDEC:
6083       if (operands[2] == const1_rtx)
6084         return "inc{w}\t%0";
6085       else if (operands[2] == constm1_rtx)
6086         return "dec{w}\t%0";
6087       abort();
6088
6089     default:
6090       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6091          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6092       if (GET_CODE (operands[2]) == CONST_INT
6093           && (INTVAL (operands[2]) == 128
6094               || (INTVAL (operands[2]) < 0
6095                   && INTVAL (operands[2]) != -128)))
6096         {
6097           operands[2] = GEN_INT (-INTVAL (operands[2]));
6098           return "sub{w}\t{%2, %0|%0, %2}";
6099         }
6100       return "add{w}\t{%2, %0|%0, %2}";
6101     }
6102 }
6103   [(set (attr "type")
6104      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6105         (const_string "incdec")
6106         (const_string "alu")))
6107    (set_attr "mode" "HI")])
6108
6109 ; See comments above addsi_3_imm for details.
6110 (define_insn "*addhi_4"
6111   [(set (reg 17)
6112         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6113                  (match_operand:HI 2 "const_int_operand" "n")))
6114    (clobber (match_scratch:HI 0 "=rm"))]
6115   "ix86_match_ccmode (insn, CCGCmode)
6116    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6117 {
6118   switch (get_attr_type (insn))
6119     {
6120     case TYPE_INCDEC:
6121       if (operands[2] == constm1_rtx)
6122         return "inc{w}\t%0";
6123       else if (operands[2] == const1_rtx)
6124         return "dec{w}\t%0";
6125       else
6126         abort();
6127
6128     default:
6129       if (! rtx_equal_p (operands[0], operands[1]))
6130         abort ();
6131       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6132          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6133       if ((INTVAL (operands[2]) == -128
6134            || (INTVAL (operands[2]) > 0
6135                && INTVAL (operands[2]) != 128)))
6136         return "sub{w}\t{%2, %0|%0, %2}";
6137       operands[2] = GEN_INT (-INTVAL (operands[2]));
6138       return "add{w}\t{%2, %0|%0, %2}";
6139     }
6140 }
6141   [(set (attr "type")
6142      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6143         (const_string "incdec")
6144         (const_string "alu")))
6145    (set_attr "mode" "SI")])
6146
6147
6148 (define_insn "*addhi_5"
6149   [(set (reg 17)
6150         (compare
6151           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6152                    (match_operand:HI 2 "general_operand" "rmni"))
6153           (const_int 0)))                       
6154    (clobber (match_scratch:HI 0 "=r"))]
6155   "ix86_match_ccmode (insn, CCGOCmode)
6156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6157 {
6158   switch (get_attr_type (insn))
6159     {
6160     case TYPE_INCDEC:
6161       if (operands[2] == const1_rtx)
6162         return "inc{w}\t%0";
6163       else if (operands[2] == constm1_rtx)
6164         return "dec{w}\t%0";
6165       abort();
6166
6167     default:
6168       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6169          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6170       if (GET_CODE (operands[2]) == CONST_INT
6171           && (INTVAL (operands[2]) == 128
6172               || (INTVAL (operands[2]) < 0
6173                   && INTVAL (operands[2]) != -128)))
6174         {
6175           operands[2] = GEN_INT (-INTVAL (operands[2]));
6176           return "sub{w}\t{%2, %0|%0, %2}";
6177         }
6178       return "add{w}\t{%2, %0|%0, %2}";
6179     }
6180 }
6181   [(set (attr "type")
6182      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6183         (const_string "incdec")
6184         (const_string "alu")))
6185    (set_attr "mode" "HI")])
6186
6187 (define_expand "addqi3"
6188   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6189                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6190                             (match_operand:QI 2 "general_operand" "")))
6191               (clobber (reg:CC 17))])]
6192   "TARGET_QIMODE_MATH"
6193   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6194
6195 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6196 (define_insn "*addqi_1_lea"
6197   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6198         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6199                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6200    (clobber (reg:CC 17))]
6201   "!TARGET_PARTIAL_REG_STALL
6202    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6203 {
6204   int widen = (which_alternative == 2);
6205   switch (get_attr_type (insn))
6206     {
6207     case TYPE_LEA:
6208       return "#";
6209     case TYPE_INCDEC:
6210       if (operands[2] == const1_rtx)
6211         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6212       else if (operands[2] == constm1_rtx)
6213         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6214       abort();
6215
6216     default:
6217       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6218          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6219       if (GET_CODE (operands[2]) == CONST_INT
6220           && (INTVAL (operands[2]) == 128
6221               || (INTVAL (operands[2]) < 0
6222                   && INTVAL (operands[2]) != -128)))
6223         {
6224           operands[2] = GEN_INT (-INTVAL (operands[2]));
6225           if (widen)
6226             return "sub{l}\t{%2, %k0|%k0, %2}";
6227           else
6228             return "sub{b}\t{%2, %0|%0, %2}";
6229         }
6230       if (widen)
6231         return "add{l}\t{%k2, %k0|%k0, %k2}";
6232       else
6233         return "add{b}\t{%2, %0|%0, %2}";
6234     }
6235 }
6236   [(set (attr "type")
6237      (if_then_else (eq_attr "alternative" "3")
6238         (const_string "lea")
6239         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240            (const_string "incdec")
6241            (const_string "alu"))))
6242    (set_attr "mode" "QI,QI,SI,SI")])
6243
6244 (define_insn "*addqi_1"
6245   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6246         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6247                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6248    (clobber (reg:CC 17))]
6249   "TARGET_PARTIAL_REG_STALL
6250    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6251 {
6252   int widen = (which_alternative == 2);
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == const1_rtx)
6257         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6258       else if (operands[2] == constm1_rtx)
6259         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6260       abort();
6261
6262     default:
6263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6265       if (GET_CODE (operands[2]) == CONST_INT
6266           && (INTVAL (operands[2]) == 128
6267               || (INTVAL (operands[2]) < 0
6268                   && INTVAL (operands[2]) != -128)))
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           if (widen)
6272             return "sub{l}\t{%2, %k0|%k0, %2}";
6273           else
6274             return "sub{b}\t{%2, %0|%0, %2}";
6275         }
6276       if (widen)
6277         return "add{l}\t{%k2, %k0|%k0, %k2}";
6278       else
6279         return "add{b}\t{%2, %0|%0, %2}";
6280     }
6281 }
6282   [(set (attr "type")
6283      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6284         (const_string "incdec")
6285         (const_string "alu")))
6286    (set_attr "mode" "QI,QI,SI")])
6287
6288 (define_insn "*addqi_1_slp"
6289   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6290         (plus:QI (match_dup 0)
6291                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6292    (clobber (reg:CC 17))]
6293   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6294    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6295 {
6296   switch (get_attr_type (insn))
6297     {
6298     case TYPE_INCDEC:
6299       if (operands[1] == const1_rtx)
6300         return "inc{b}\t%0";
6301       else if (operands[1] == constm1_rtx)
6302         return "dec{b}\t%0";
6303       abort();
6304
6305     default:
6306       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6307       if (GET_CODE (operands[1]) == CONST_INT
6308           && INTVAL (operands[1]) < 0)
6309         {
6310           operands[1] = GEN_INT (-INTVAL (operands[1]));
6311           return "sub{b}\t{%1, %0|%0, %1}";
6312         }
6313       return "add{b}\t{%1, %0|%0, %1}";
6314     }
6315 }
6316   [(set (attr "type")
6317      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6318         (const_string "incdec")
6319         (const_string "alu1")))
6320    (set_attr "mode" "QI")])
6321
6322 (define_insn "*addqi_2"
6323   [(set (reg 17)
6324         (compare
6325           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6326                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6327           (const_int 0)))
6328    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6329         (plus:QI (match_dup 1) (match_dup 2)))]
6330   "ix86_match_ccmode (insn, CCGOCmode)
6331    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6332 {
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[2] == const1_rtx)
6337         return "inc{b}\t%0";
6338       else if (operands[2] == constm1_rtx
6339                || (GET_CODE (operands[2]) == CONST_INT
6340                    && INTVAL (operands[2]) == 255))
6341         return "dec{b}\t%0";
6342       abort();
6343
6344     default:
6345       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6346       if (GET_CODE (operands[2]) == CONST_INT
6347           && INTVAL (operands[2]) < 0)
6348         {
6349           operands[2] = GEN_INT (-INTVAL (operands[2]));
6350           return "sub{b}\t{%2, %0|%0, %2}";
6351         }
6352       return "add{b}\t{%2, %0|%0, %2}";
6353     }
6354 }
6355   [(set (attr "type")
6356      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357         (const_string "incdec")
6358         (const_string "alu")))
6359    (set_attr "mode" "QI")])
6360
6361 (define_insn "*addqi_3"
6362   [(set (reg 17)
6363         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6364                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6365    (clobber (match_scratch:QI 0 "=q"))]
6366   "ix86_match_ccmode (insn, CCZmode)
6367    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6368 {
6369   switch (get_attr_type (insn))
6370     {
6371     case TYPE_INCDEC:
6372       if (operands[2] == const1_rtx)
6373         return "inc{b}\t%0";
6374       else if (operands[2] == constm1_rtx
6375                || (GET_CODE (operands[2]) == CONST_INT
6376                    && INTVAL (operands[2]) == 255))
6377         return "dec{b}\t%0";
6378       abort();
6379
6380     default:
6381       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6382       if (GET_CODE (operands[2]) == CONST_INT
6383           && INTVAL (operands[2]) < 0)
6384         {
6385           operands[2] = GEN_INT (-INTVAL (operands[2]));
6386           return "sub{b}\t{%2, %0|%0, %2}";
6387         }
6388       return "add{b}\t{%2, %0|%0, %2}";
6389     }
6390 }
6391   [(set (attr "type")
6392      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6393         (const_string "incdec")
6394         (const_string "alu")))
6395    (set_attr "mode" "QI")])
6396
6397 ; See comments above addsi_3_imm for details.
6398 (define_insn "*addqi_4"
6399   [(set (reg 17)
6400         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6401                  (match_operand:QI 2 "const_int_operand" "n")))
6402    (clobber (match_scratch:QI 0 "=qm"))]
6403   "ix86_match_ccmode (insn, CCGCmode)
6404    && (INTVAL (operands[2]) & 0xff) != 0x80"
6405 {
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == constm1_rtx
6410           || (GET_CODE (operands[2]) == CONST_INT
6411               && INTVAL (operands[2]) == 255))
6412         return "inc{b}\t%0";
6413       else if (operands[2] == const1_rtx)
6414         return "dec{b}\t%0";
6415       else
6416         abort();
6417
6418     default:
6419       if (! rtx_equal_p (operands[0], operands[1]))
6420         abort ();
6421       if (INTVAL (operands[2]) < 0)
6422         {
6423           operands[2] = GEN_INT (-INTVAL (operands[2]));
6424           return "add{b}\t{%2, %0|%0, %2}";
6425         }
6426       return "sub{b}\t{%2, %0|%0, %2}";
6427     }
6428 }
6429   [(set (attr "type")
6430      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6431         (const_string "incdec")
6432         (const_string "alu")))
6433    (set_attr "mode" "QI")])
6434
6435
6436 (define_insn "*addqi_5"
6437   [(set (reg 17)
6438         (compare
6439           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6440                    (match_operand:QI 2 "general_operand" "qmni"))
6441           (const_int 0)))
6442    (clobber (match_scratch:QI 0 "=q"))]
6443   "ix86_match_ccmode (insn, CCGOCmode)
6444    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6445 {
6446   switch (get_attr_type (insn))
6447     {
6448     case TYPE_INCDEC:
6449       if (operands[2] == const1_rtx)
6450         return "inc{b}\t%0";
6451       else if (operands[2] == constm1_rtx
6452                || (GET_CODE (operands[2]) == CONST_INT
6453                    && INTVAL (operands[2]) == 255))
6454         return "dec{b}\t%0";
6455       abort();
6456
6457     default:
6458       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6459       if (GET_CODE (operands[2]) == CONST_INT
6460           && INTVAL (operands[2]) < 0)
6461         {
6462           operands[2] = GEN_INT (-INTVAL (operands[2]));
6463           return "sub{b}\t{%2, %0|%0, %2}";
6464         }
6465       return "add{b}\t{%2, %0|%0, %2}";
6466     }
6467 }
6468   [(set (attr "type")
6469      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6470         (const_string "incdec")
6471         (const_string "alu")))
6472    (set_attr "mode" "QI")])
6473
6474
6475 (define_insn "addqi_ext_1"
6476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6477                          (const_int 8)
6478                          (const_int 8))
6479         (plus:SI
6480           (zero_extract:SI
6481             (match_operand 1 "ext_register_operand" "0")
6482             (const_int 8)
6483             (const_int 8))
6484           (match_operand:QI 2 "general_operand" "Qmn")))
6485    (clobber (reg:CC 17))]
6486   "!TARGET_64BIT"
6487 {
6488   switch (get_attr_type (insn))
6489     {
6490     case TYPE_INCDEC:
6491       if (operands[2] == const1_rtx)
6492         return "inc{b}\t%h0";
6493       else if (operands[2] == constm1_rtx
6494                || (GET_CODE (operands[2]) == CONST_INT
6495                    && INTVAL (operands[2]) == 255))
6496         return "dec{b}\t%h0";
6497       abort();
6498
6499     default:
6500       return "add{b}\t{%2, %h0|%h0, %2}";
6501     }
6502 }
6503   [(set (attr "type")
6504      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6505         (const_string "incdec")
6506         (const_string "alu")))
6507    (set_attr "mode" "QI")])
6508
6509 (define_insn "*addqi_ext_1_rex64"
6510   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6511                          (const_int 8)
6512                          (const_int 8))
6513         (plus:SI
6514           (zero_extract:SI
6515             (match_operand 1 "ext_register_operand" "0")
6516             (const_int 8)
6517             (const_int 8))
6518           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6519    (clobber (reg:CC 17))]
6520   "TARGET_64BIT"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{b}\t%h0";
6527       else if (operands[2] == constm1_rtx
6528                || (GET_CODE (operands[2]) == CONST_INT
6529                    && INTVAL (operands[2]) == 255))
6530         return "dec{b}\t%h0";
6531       abort();
6532
6533     default:
6534       return "add{b}\t{%2, %h0|%h0, %2}";
6535     }
6536 }
6537   [(set (attr "type")
6538      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6539         (const_string "incdec")
6540         (const_string "alu")))
6541    (set_attr "mode" "QI")])
6542
6543 (define_insn "*addqi_ext_2"
6544   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6545                          (const_int 8)
6546                          (const_int 8))
6547         (plus:SI
6548           (zero_extract:SI
6549             (match_operand 1 "ext_register_operand" "%0")
6550             (const_int 8)
6551             (const_int 8))
6552           (zero_extract:SI
6553             (match_operand 2 "ext_register_operand" "Q")
6554             (const_int 8)
6555             (const_int 8))))
6556    (clobber (reg:CC 17))]
6557   ""
6558   "add{b}\t{%h2, %h0|%h0, %h2}"
6559   [(set_attr "type" "alu")
6560    (set_attr "mode" "QI")])
6561
6562 ;; The patterns that match these are at the end of this file.
6563
6564 (define_expand "addxf3"
6565   [(set (match_operand:XF 0 "register_operand" "")
6566         (plus:XF (match_operand:XF 1 "register_operand" "")
6567                  (match_operand:XF 2 "register_operand" "")))]
6568   "TARGET_80387"
6569   "")
6570
6571 (define_expand "adddf3"
6572   [(set (match_operand:DF 0 "register_operand" "")
6573         (plus:DF (match_operand:DF 1 "register_operand" "")
6574                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6575   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6576   "")
6577
6578 (define_expand "addsf3"
6579   [(set (match_operand:SF 0 "register_operand" "")
6580         (plus:SF (match_operand:SF 1 "register_operand" "")
6581                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6582   "TARGET_80387 || TARGET_SSE_MATH"
6583   "")
6584 \f
6585 ;; Subtract instructions
6586
6587 ;; %%% splits for subsidi3
6588
6589 (define_expand "subdi3"
6590   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592                              (match_operand:DI 2 "x86_64_general_operand" "")))
6593               (clobber (reg:CC 17))])]
6594   ""
6595   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6596
6597 (define_insn "*subdi3_1"
6598   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6599         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6600                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6601    (clobber (reg:CC 17))]
6602   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6603   "#")
6604
6605 (define_split
6606   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6607         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6608                   (match_operand:DI 2 "general_operand" "")))
6609    (clobber (reg:CC 17))]
6610   "!TARGET_64BIT && reload_completed"
6611   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6612               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6613    (parallel [(set (match_dup 3)
6614                    (minus:SI (match_dup 4)
6615                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6616                                       (match_dup 5))))
6617               (clobber (reg:CC 17))])]
6618   "split_di (operands+0, 1, operands+0, operands+3);
6619    split_di (operands+1, 1, operands+1, operands+4);
6620    split_di (operands+2, 1, operands+2, operands+5);")
6621
6622 (define_insn "subdi3_carry_rex64"
6623   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6625             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6626                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6627    (clobber (reg:CC 17))]
6628   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6629   "sbb{q}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "pent_pair" "pu")
6632    (set_attr "ppro_uops" "few")
6633    (set_attr "mode" "DI")])
6634
6635 (define_insn "*subdi_1_rex64"
6636   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6637         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6638                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6639    (clobber (reg:CC 17))]
6640   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6641   "sub{q}\t{%2, %0|%0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "mode" "DI")])
6644
6645 (define_insn "*subdi_2_rex64"
6646   [(set (reg 17)
6647         (compare
6648           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6649                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6650           (const_int 0)))
6651    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6652         (minus:DI (match_dup 1) (match_dup 2)))]
6653   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6654    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655   "sub{q}\t{%2, %0|%0, %2}"
6656   [(set_attr "type" "alu")
6657    (set_attr "mode" "DI")])
6658
6659 (define_insn "*subdi_3_rex63"
6660   [(set (reg 17)
6661         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6662                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6663    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6664         (minus:DI (match_dup 1) (match_dup 2)))]
6665   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6666    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6667   "sub{q}\t{%2, %0|%0, %2}"
6668   [(set_attr "type" "alu")
6669    (set_attr "mode" "DI")])
6670
6671 (define_insn "subqi3_carry"
6672   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6673           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6674             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6675                (match_operand:QI 2 "general_operand" "qi,qm"))))
6676    (clobber (reg:CC 17))]
6677   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6678   "sbb{b}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "pent_pair" "pu")
6681    (set_attr "ppro_uops" "few")
6682    (set_attr "mode" "QI")])
6683
6684 (define_insn "subhi3_carry"
6685   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6686           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6687             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6688                (match_operand:HI 2 "general_operand" "ri,rm"))))
6689    (clobber (reg:CC 17))]
6690   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6691   "sbb{w}\t{%2, %0|%0, %2}"
6692   [(set_attr "type" "alu")
6693    (set_attr "pent_pair" "pu")
6694    (set_attr "ppro_uops" "few")
6695    (set_attr "mode" "HI")])
6696
6697 (define_insn "subsi3_carry"
6698   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6699           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6700             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6701                (match_operand:SI 2 "general_operand" "ri,rm"))))
6702    (clobber (reg:CC 17))]
6703   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6704   "sbb{l}\t{%2, %0|%0, %2}"
6705   [(set_attr "type" "alu")
6706    (set_attr "pent_pair" "pu")
6707    (set_attr "ppro_uops" "few")
6708    (set_attr "mode" "SI")])
6709
6710 (define_insn "subsi3_carry_zext"
6711   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6712           (zero_extend:DI
6713             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6714               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6715                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6716    (clobber (reg:CC 17))]
6717   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718   "sbb{l}\t{%2, %k0|%k0, %2}"
6719   [(set_attr "type" "alu")
6720    (set_attr "pent_pair" "pu")
6721    (set_attr "ppro_uops" "few")
6722    (set_attr "mode" "SI")])
6723
6724 (define_expand "subsi3"
6725   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6726                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6727                              (match_operand:SI 2 "general_operand" "")))
6728               (clobber (reg:CC 17))])]
6729   ""
6730   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6731
6732 (define_insn "*subsi_1"
6733   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6734         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6735                   (match_operand:SI 2 "general_operand" "ri,rm")))
6736    (clobber (reg:CC 17))]
6737   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6738   "sub{l}\t{%2, %0|%0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "SI")])
6741
6742 (define_insn "*subsi_1_zext"
6743   [(set (match_operand:DI 0 "register_operand" "=r")
6744         (zero_extend:DI
6745           (minus:SI (match_operand:SI 1 "register_operand" "0")
6746                     (match_operand:SI 2 "general_operand" "rim"))))
6747    (clobber (reg:CC 17))]
6748   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749   "sub{l}\t{%2, %k0|%k0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "mode" "SI")])
6752
6753 (define_insn "*subsi_2"
6754   [(set (reg 17)
6755         (compare
6756           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757                     (match_operand:SI 2 "general_operand" "ri,rm"))
6758           (const_int 0)))
6759    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6760         (minus:SI (match_dup 1) (match_dup 2)))]
6761   "ix86_match_ccmode (insn, CCGOCmode)
6762    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763   "sub{l}\t{%2, %0|%0, %2}"
6764   [(set_attr "type" "alu")
6765    (set_attr "mode" "SI")])
6766
6767 (define_insn "*subsi_2_zext"
6768   [(set (reg 17)
6769         (compare
6770           (minus:SI (match_operand:SI 1 "register_operand" "0")
6771                     (match_operand:SI 2 "general_operand" "rim"))
6772           (const_int 0)))
6773    (set (match_operand:DI 0 "register_operand" "=r")
6774         (zero_extend:DI
6775           (minus:SI (match_dup 1)
6776                     (match_dup 2))))]
6777   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6778    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779   "sub{l}\t{%2, %k0|%k0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "SI")])
6782
6783 (define_insn "*subsi_3"
6784   [(set (reg 17)
6785         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6786                  (match_operand:SI 2 "general_operand" "ri,rm")))
6787    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6788         (minus:SI (match_dup 1) (match_dup 2)))]
6789   "ix86_match_ccmode (insn, CCmode)
6790    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6791   "sub{l}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "mode" "SI")])
6794
6795 (define_insn "*subsi_3_zext"
6796   [(set (reg 17)
6797         (compare (match_operand:SI 1 "register_operand" "0")
6798                  (match_operand:SI 2 "general_operand" "rim")))
6799    (set (match_operand:DI 0 "register_operand" "=r")
6800         (zero_extend:DI
6801           (minus:SI (match_dup 1)
6802                     (match_dup 2))))]
6803   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{q}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "DI")])
6808
6809 (define_expand "subhi3"
6810   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6811                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6812                              (match_operand:HI 2 "general_operand" "")))
6813               (clobber (reg:CC 17))])]
6814   "TARGET_HIMODE_MATH"
6815   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6816
6817 (define_insn "*subhi_1"
6818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6819         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6820                   (match_operand:HI 2 "general_operand" "ri,rm")))
6821    (clobber (reg:CC 17))]
6822   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6823   "sub{w}\t{%2, %0|%0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "mode" "HI")])
6826
6827 (define_insn "*subhi_2"
6828   [(set (reg 17)
6829         (compare
6830           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6831                     (match_operand:HI 2 "general_operand" "ri,rm"))
6832           (const_int 0)))
6833    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834         (minus:HI (match_dup 1) (match_dup 2)))]
6835   "ix86_match_ccmode (insn, CCGOCmode)
6836    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6837   "sub{w}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "HI")])
6840
6841 (define_insn "*subhi_3"
6842   [(set (reg 17)
6843         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6844                  (match_operand:HI 2 "general_operand" "ri,rm")))
6845    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6846         (minus:HI (match_dup 1) (match_dup 2)))]
6847   "ix86_match_ccmode (insn, CCmode)
6848    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6849   "sub{w}\t{%2, %0|%0, %2}"
6850   [(set_attr "type" "alu")
6851    (set_attr "mode" "HI")])
6852
6853 (define_expand "subqi3"
6854   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6855                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6856                              (match_operand:QI 2 "general_operand" "")))
6857               (clobber (reg:CC 17))])]
6858   "TARGET_QIMODE_MATH"
6859   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6860
6861 (define_insn "*subqi_1"
6862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6863         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6864                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6865    (clobber (reg:CC 17))]
6866   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6867   "sub{b}\t{%2, %0|%0, %2}"
6868   [(set_attr "type" "alu")
6869    (set_attr "mode" "QI")])
6870
6871 (define_insn "*subqi_1_slp"
6872   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6873         (minus:QI (match_dup 0)
6874                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6875    (clobber (reg:CC 17))]
6876   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6877    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6878   "sub{b}\t{%1, %0|%0, %1}"
6879   [(set_attr "type" "alu1")
6880    (set_attr "mode" "QI")])
6881
6882 (define_insn "*subqi_2"
6883   [(set (reg 17)
6884         (compare
6885           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6886                     (match_operand:QI 2 "general_operand" "qi,qm"))
6887           (const_int 0)))
6888    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6889         (minus:HI (match_dup 1) (match_dup 2)))]
6890   "ix86_match_ccmode (insn, CCGOCmode)
6891    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6892   "sub{b}\t{%2, %0|%0, %2}"
6893   [(set_attr "type" "alu")
6894    (set_attr "mode" "QI")])
6895
6896 (define_insn "*subqi_3"
6897   [(set (reg 17)
6898         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6899                  (match_operand:QI 2 "general_operand" "qi,qm")))
6900    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6901         (minus:HI (match_dup 1) (match_dup 2)))]
6902   "ix86_match_ccmode (insn, CCmode)
6903    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6904   "sub{b}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "alu")
6906    (set_attr "mode" "QI")])
6907
6908 ;; The patterns that match these are at the end of this file.
6909
6910 (define_expand "subxf3"
6911   [(set (match_operand:XF 0 "register_operand" "")
6912         (minus:XF (match_operand:XF 1 "register_operand" "")
6913                   (match_operand:XF 2 "register_operand" "")))]
6914   "TARGET_80387"
6915   "")
6916
6917 (define_expand "subdf3"
6918   [(set (match_operand:DF 0 "register_operand" "")
6919         (minus:DF (match_operand:DF 1 "register_operand" "")
6920                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6921   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6922   "")
6923
6924 (define_expand "subsf3"
6925   [(set (match_operand:SF 0 "register_operand" "")
6926         (minus:SF (match_operand:SF 1 "register_operand" "")
6927                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6928   "TARGET_80387 || TARGET_SSE_MATH"
6929   "")
6930 \f
6931 ;; Multiply instructions
6932
6933 (define_expand "muldi3"
6934   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6935                    (mult:DI (match_operand:DI 1 "register_operand" "")
6936                             (match_operand:DI 2 "x86_64_general_operand" "")))
6937               (clobber (reg:CC 17))])]
6938   "TARGET_64BIT"
6939   "")
6940
6941 (define_insn "*muldi3_1_rex64"
6942   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6943         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6944                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6945    (clobber (reg:CC 17))]
6946   "TARGET_64BIT
6947    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948   "@
6949    imul{q}\t{%2, %1, %0|%0, %1, %2}
6950    imul{q}\t{%2, %1, %0|%0, %1, %2}
6951    imul{q}\t{%2, %0|%0, %2}"
6952   [(set_attr "type" "imul")
6953    (set_attr "prefix_0f" "0,0,1")
6954    (set (attr "athlon_decode")
6955         (cond [(eq_attr "cpu" "athlon")
6956                   (const_string "vector")
6957                (eq_attr "alternative" "1")
6958                   (const_string "vector")
6959                (and (eq_attr "alternative" "2")
6960                     (match_operand 1 "memory_operand" ""))
6961                   (const_string "vector")]
6962               (const_string "direct")))
6963    (set_attr "mode" "DI")])
6964
6965 (define_expand "mulsi3"
6966   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6967                    (mult:SI (match_operand:SI 1 "register_operand" "")
6968                             (match_operand:SI 2 "general_operand" "")))
6969               (clobber (reg:CC 17))])]
6970   ""
6971   "")
6972
6973 (define_insn "*mulsi3_1"
6974   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6975         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6976                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6977    (clobber (reg:CC 17))]
6978   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6979   "@
6980    imul{l}\t{%2, %1, %0|%0, %1, %2}
6981    imul{l}\t{%2, %1, %0|%0, %1, %2}
6982    imul{l}\t{%2, %0|%0, %2}"
6983   [(set_attr "type" "imul")
6984    (set_attr "prefix_0f" "0,0,1")
6985    (set (attr "athlon_decode")
6986         (cond [(eq_attr "cpu" "athlon")
6987                   (const_string "vector")
6988                (eq_attr "alternative" "1")
6989                   (const_string "vector")
6990                (and (eq_attr "alternative" "2")
6991                     (match_operand 1 "memory_operand" ""))
6992                   (const_string "vector")]
6993               (const_string "direct")))
6994    (set_attr "mode" "SI")])
6995
6996 (define_insn "*mulsi3_1_zext"
6997   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6998         (zero_extend:DI
6999           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7000                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7001    (clobber (reg:CC 17))]
7002   "TARGET_64BIT
7003    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7004   "@
7005    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7006    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7007    imul{l}\t{%2, %k0|%k0, %2}"
7008   [(set_attr "type" "imul")
7009    (set_attr "prefix_0f" "0,0,1")
7010    (set (attr "athlon_decode")
7011         (cond [(eq_attr "cpu" "athlon")
7012                   (const_string "vector")
7013                (eq_attr "alternative" "1")
7014                   (const_string "vector")
7015                (and (eq_attr "alternative" "2")
7016                     (match_operand 1 "memory_operand" ""))
7017                   (const_string "vector")]
7018               (const_string "direct")))
7019    (set_attr "mode" "SI")])
7020
7021 (define_expand "mulhi3"
7022   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023                    (mult:HI (match_operand:HI 1 "register_operand" "")
7024                             (match_operand:HI 2 "general_operand" "")))
7025               (clobber (reg:CC 17))])]
7026   "TARGET_HIMODE_MATH"
7027   "")
7028
7029 (define_insn "*mulhi3_1"
7030   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7031         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7032                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7033    (clobber (reg:CC 17))]
7034   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7035   "@
7036    imul{w}\t{%2, %1, %0|%0, %1, %2}
7037    imul{w}\t{%2, %1, %0|%0, %1, %2}
7038    imul{w}\t{%2, %0|%0, %2}"
7039   [(set_attr "type" "imul")
7040    (set_attr "prefix_0f" "0,0,1")
7041    (set (attr "athlon_decode")
7042         (cond [(eq_attr "cpu" "athlon")
7043                   (const_string "vector")
7044                (eq_attr "alternative" "1,2")
7045                   (const_string "vector")]
7046               (const_string "direct")))
7047    (set_attr "mode" "HI")])
7048
7049 (define_expand "mulqi3"
7050   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7051                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7052                             (match_operand:QI 2 "register_operand" "")))
7053               (clobber (reg:CC 17))])]
7054   "TARGET_QIMODE_MATH"
7055   "")
7056
7057 (define_insn "*mulqi3_1"
7058   [(set (match_operand:QI 0 "register_operand" "=a")
7059         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7060                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7061    (clobber (reg:CC 17))]
7062   "TARGET_QIMODE_MATH
7063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7064   "mul{b}\t%2"
7065   [(set_attr "type" "imul")
7066    (set_attr "length_immediate" "0")
7067    (set (attr "athlon_decode")
7068      (if_then_else (eq_attr "cpu" "athlon")
7069         (const_string "vector")
7070         (const_string "direct")))
7071    (set_attr "mode" "QI")])
7072
7073 (define_expand "umulqihi3"
7074   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7075                    (mult:HI (zero_extend:HI
7076                               (match_operand:QI 1 "nonimmediate_operand" ""))
7077                             (zero_extend:HI
7078                               (match_operand:QI 2 "register_operand" ""))))
7079               (clobber (reg:CC 17))])]
7080   "TARGET_QIMODE_MATH"
7081   "")
7082
7083 (define_insn "*umulqihi3_1"
7084   [(set (match_operand:HI 0 "register_operand" "=a")
7085         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7086                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7087    (clobber (reg:CC 17))]
7088   "TARGET_QIMODE_MATH
7089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090   "mul{b}\t%2"
7091   [(set_attr "type" "imul")
7092    (set_attr "length_immediate" "0")
7093    (set (attr "athlon_decode")
7094      (if_then_else (eq_attr "cpu" "athlon")
7095         (const_string "vector")
7096         (const_string "direct")))
7097    (set_attr "mode" "QI")])
7098
7099 (define_expand "mulqihi3"
7100   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7101                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7102                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7103               (clobber (reg:CC 17))])]
7104   "TARGET_QIMODE_MATH"
7105   "")
7106
7107 (define_insn "*mulqihi3_insn"
7108   [(set (match_operand:HI 0 "register_operand" "=a")
7109         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7110                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7111    (clobber (reg:CC 17))]
7112   "TARGET_QIMODE_MATH
7113    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7114   "imul{b}\t%2"
7115   [(set_attr "type" "imul")
7116    (set_attr "length_immediate" "0")
7117    (set (attr "athlon_decode")
7118      (if_then_else (eq_attr "cpu" "athlon")
7119         (const_string "vector")
7120         (const_string "direct")))
7121    (set_attr "mode" "QI")])
7122
7123 (define_expand "umulditi3"
7124   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7125                    (mult:TI (zero_extend:TI
7126                               (match_operand:DI 1 "nonimmediate_operand" ""))
7127                             (zero_extend:TI
7128                               (match_operand:DI 2 "register_operand" ""))))
7129               (clobber (reg:CC 17))])]
7130   "TARGET_64BIT"
7131   "")
7132
7133 (define_insn "*umulditi3_insn"
7134   [(set (match_operand:TI 0 "register_operand" "=A")
7135         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7136                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7137    (clobber (reg:CC 17))]
7138   "TARGET_64BIT
7139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140   "mul{q}\t%2"
7141   [(set_attr "type" "imul")
7142    (set_attr "ppro_uops" "few")
7143    (set_attr "length_immediate" "0")
7144    (set (attr "athlon_decode")
7145      (if_then_else (eq_attr "cpu" "athlon")
7146         (const_string "vector")
7147         (const_string "double")))
7148    (set_attr "mode" "DI")])
7149
7150 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7151 (define_expand "umulsidi3"
7152   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7153                    (mult:DI (zero_extend:DI
7154                               (match_operand:SI 1 "nonimmediate_operand" ""))
7155                             (zero_extend:DI
7156                               (match_operand:SI 2 "register_operand" ""))))
7157               (clobber (reg:CC 17))])]
7158   "!TARGET_64BIT"
7159   "")
7160
7161 (define_insn "*umulsidi3_insn"
7162   [(set (match_operand:DI 0 "register_operand" "=A")
7163         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7164                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7165    (clobber (reg:CC 17))]
7166   "!TARGET_64BIT
7167    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7168   "mul{l}\t%2"
7169   [(set_attr "type" "imul")
7170    (set_attr "ppro_uops" "few")
7171    (set_attr "length_immediate" "0")
7172    (set (attr "athlon_decode")
7173      (if_then_else (eq_attr "cpu" "athlon")
7174         (const_string "vector")
7175         (const_string "double")))
7176    (set_attr "mode" "SI")])
7177
7178 (define_expand "mulditi3"
7179   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7180                    (mult:TI (sign_extend:TI
7181                               (match_operand:DI 1 "nonimmediate_operand" ""))
7182                             (sign_extend:TI
7183                               (match_operand:DI 2 "register_operand" ""))))
7184               (clobber (reg:CC 17))])]
7185   "TARGET_64BIT"
7186   "")
7187
7188 (define_insn "*mulditi3_insn"
7189   [(set (match_operand:TI 0 "register_operand" "=A")
7190         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7191                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7192    (clobber (reg:CC 17))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "imul{q}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "mode" "DI")])
7203
7204 (define_expand "mulsidi3"
7205   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7206                    (mult:DI (sign_extend:DI
7207                               (match_operand:SI 1 "nonimmediate_operand" ""))
7208                             (sign_extend:DI
7209                               (match_operand:SI 2 "register_operand" ""))))
7210               (clobber (reg:CC 17))])]
7211   "!TARGET_64BIT"
7212   "")
7213
7214 (define_insn "*mulsidi3_insn"
7215   [(set (match_operand:DI 0 "register_operand" "=A")
7216         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7217                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7218    (clobber (reg:CC 17))]
7219   "!TARGET_64BIT
7220    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7221   "imul{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_expand "umuldi3_highpart"
7231   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7232                    (truncate:DI
7233                      (lshiftrt:TI
7234                        (mult:TI (zero_extend:TI
7235                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7236                                 (zero_extend:TI
7237                                   (match_operand:DI 2 "register_operand" "")))
7238                        (const_int 64))))
7239               (clobber (match_scratch:DI 3 ""))
7240               (clobber (reg:CC 17))])]
7241   "TARGET_64BIT"
7242   "")
7243
7244 (define_insn "*umuldi3_highpart_rex64"
7245   [(set (match_operand:DI 0 "register_operand" "=d")
7246         (truncate:DI
7247           (lshiftrt:TI
7248             (mult:TI (zero_extend:TI
7249                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7250                      (zero_extend:TI
7251                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7252             (const_int 64))))
7253    (clobber (match_scratch:DI 3 "=1"))
7254    (clobber (reg:CC 17))]
7255   "TARGET_64BIT
7256    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7257   "mul{q}\t%2"
7258   [(set_attr "type" "imul")
7259    (set_attr "ppro_uops" "few")
7260    (set_attr "length_immediate" "0")
7261    (set (attr "athlon_decode")
7262      (if_then_else (eq_attr "cpu" "athlon")
7263         (const_string "vector")
7264         (const_string "double")))
7265    (set_attr "mode" "DI")])
7266
7267 (define_expand "umulsi3_highpart"
7268   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7269                    (truncate:SI
7270                      (lshiftrt:DI
7271                        (mult:DI (zero_extend:DI
7272                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7273                                 (zero_extend:DI
7274                                   (match_operand:SI 2 "register_operand" "")))
7275                        (const_int 32))))
7276               (clobber (match_scratch:SI 3 ""))
7277               (clobber (reg:CC 17))])]
7278   ""
7279   "")
7280
7281 (define_insn "*umulsi3_highpart_insn"
7282   [(set (match_operand:SI 0 "register_operand" "=d")
7283         (truncate:SI
7284           (lshiftrt:DI
7285             (mult:DI (zero_extend:DI
7286                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7287                      (zero_extend:DI
7288                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7289             (const_int 32))))
7290    (clobber (match_scratch:SI 3 "=1"))
7291    (clobber (reg:CC 17))]
7292   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7293   "mul{l}\t%2"
7294   [(set_attr "type" "imul")
7295    (set_attr "ppro_uops" "few")
7296    (set_attr "length_immediate" "0")
7297    (set (attr "athlon_decode")
7298      (if_then_else (eq_attr "cpu" "athlon")
7299         (const_string "vector")
7300         (const_string "double")))
7301    (set_attr "mode" "SI")])
7302
7303 (define_insn "*umulsi3_highpart_zext"
7304   [(set (match_operand:DI 0 "register_operand" "=d")
7305         (zero_extend:DI (truncate:SI
7306           (lshiftrt:DI
7307             (mult:DI (zero_extend:DI
7308                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7309                      (zero_extend:DI
7310                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7311             (const_int 32)))))
7312    (clobber (match_scratch:SI 3 "=1"))
7313    (clobber (reg:CC 17))]
7314   "TARGET_64BIT
7315    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7316   "mul{l}\t%2"
7317   [(set_attr "type" "imul")
7318    (set_attr "ppro_uops" "few")
7319    (set_attr "length_immediate" "0")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "SI")])
7325
7326 (define_expand "smuldi3_highpart"
7327   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328                    (truncate:DI
7329                      (lshiftrt:TI
7330                        (mult:TI (sign_extend:TI
7331                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7332                                 (sign_extend:TI
7333                                   (match_operand:DI 2 "register_operand" "")))
7334                        (const_int 64))))
7335               (clobber (match_scratch:DI 3 ""))
7336               (clobber (reg:CC 17))])]
7337   "TARGET_64BIT"
7338   "")
7339
7340 (define_insn "*smuldi3_highpart_rex64"
7341   [(set (match_operand:DI 0 "register_operand" "=d")
7342         (truncate:DI
7343           (lshiftrt:TI
7344             (mult:TI (sign_extend:TI
7345                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7346                      (sign_extend:TI
7347                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348             (const_int 64))))
7349    (clobber (match_scratch:DI 3 "=1"))
7350    (clobber (reg:CC 17))]
7351   "TARGET_64BIT
7352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7353   "imul{q}\t%2"
7354   [(set_attr "type" "imul")
7355    (set_attr "ppro_uops" "few")
7356    (set (attr "athlon_decode")
7357      (if_then_else (eq_attr "cpu" "athlon")
7358         (const_string "vector")
7359         (const_string "double")))
7360    (set_attr "mode" "DI")])
7361
7362 (define_expand "smulsi3_highpart"
7363   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7364                    (truncate:SI
7365                      (lshiftrt:DI
7366                        (mult:DI (sign_extend:DI
7367                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7368                                 (sign_extend:DI
7369                                   (match_operand:SI 2 "register_operand" "")))
7370                        (const_int 32))))
7371               (clobber (match_scratch:SI 3 ""))
7372               (clobber (reg:CC 17))])]
7373   ""
7374   "")
7375
7376 (define_insn "*smulsi3_highpart_insn"
7377   [(set (match_operand:SI 0 "register_operand" "=d")
7378         (truncate:SI
7379           (lshiftrt:DI
7380             (mult:DI (sign_extend:DI
7381                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7382                      (sign_extend:DI
7383                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7384             (const_int 32))))
7385    (clobber (match_scratch:SI 3 "=1"))
7386    (clobber (reg:CC 17))]
7387   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7388   "imul{l}\t%2"
7389   [(set_attr "type" "imul")
7390    (set_attr "ppro_uops" "few")
7391    (set (attr "athlon_decode")
7392      (if_then_else (eq_attr "cpu" "athlon")
7393         (const_string "vector")
7394         (const_string "double")))
7395    (set_attr "mode" "SI")])
7396
7397 (define_insn "*smulsi3_highpart_zext"
7398   [(set (match_operand:DI 0 "register_operand" "=d")
7399         (zero_extend:DI (truncate:SI
7400           (lshiftrt:DI
7401             (mult:DI (sign_extend:DI
7402                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7403                      (sign_extend:DI
7404                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7405             (const_int 32)))))
7406    (clobber (match_scratch:SI 3 "=1"))
7407    (clobber (reg:CC 17))]
7408   "TARGET_64BIT
7409    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7410   "imul{l}\t%2"
7411   [(set_attr "type" "imul")
7412    (set_attr "ppro_uops" "few")
7413    (set (attr "athlon_decode")
7414      (if_then_else (eq_attr "cpu" "athlon")
7415         (const_string "vector")
7416         (const_string "double")))
7417    (set_attr "mode" "SI")])
7418
7419 ;; The patterns that match these are at the end of this file.
7420
7421 (define_expand "mulxf3"
7422   [(set (match_operand:XF 0 "register_operand" "")
7423         (mult:XF (match_operand:XF 1 "register_operand" "")
7424                  (match_operand:XF 2 "register_operand" "")))]
7425   "TARGET_80387"
7426   "")
7427
7428 (define_expand "muldf3"
7429   [(set (match_operand:DF 0 "register_operand" "")
7430         (mult:DF (match_operand:DF 1 "register_operand" "")
7431                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7432   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7433   "")
7434
7435 (define_expand "mulsf3"
7436   [(set (match_operand:SF 0 "register_operand" "")
7437         (mult:SF (match_operand:SF 1 "register_operand" "")
7438                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7439   "TARGET_80387 || TARGET_SSE_MATH"
7440   "")
7441 \f
7442 ;; Divide instructions
7443
7444 (define_insn "divqi3"
7445   [(set (match_operand:QI 0 "register_operand" "=a")
7446         (div:QI (match_operand:HI 1 "register_operand" "0")
7447                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7448    (clobber (reg:CC 17))]
7449   "TARGET_QIMODE_MATH"
7450   "idiv{b}\t%2"
7451   [(set_attr "type" "idiv")
7452    (set_attr "mode" "QI")
7453    (set_attr "ppro_uops" "few")])
7454
7455 (define_insn "udivqi3"
7456   [(set (match_operand:QI 0 "register_operand" "=a")
7457         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7458                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7459    (clobber (reg:CC 17))]
7460   "TARGET_QIMODE_MATH"
7461   "div{b}\t%2"
7462   [(set_attr "type" "idiv")
7463    (set_attr "mode" "QI")
7464    (set_attr "ppro_uops" "few")])
7465
7466 ;; The patterns that match these are at the end of this file.
7467
7468 (define_expand "divxf3"
7469   [(set (match_operand:XF 0 "register_operand" "")
7470         (div:XF (match_operand:XF 1 "register_operand" "")
7471                 (match_operand:XF 2 "register_operand" "")))]
7472   "TARGET_80387"
7473   "")
7474
7475 (define_expand "divdf3"
7476   [(set (match_operand:DF 0 "register_operand" "")
7477         (div:DF (match_operand:DF 1 "register_operand" "")
7478                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7479    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7480    "")
7481  
7482 (define_expand "divsf3"
7483   [(set (match_operand:SF 0 "register_operand" "")
7484         (div:SF (match_operand:SF 1 "register_operand" "")
7485                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7486   "TARGET_80387 || TARGET_SSE_MATH"
7487   "")
7488 \f
7489 ;; Remainder instructions.
7490
7491 (define_expand "divmoddi4"
7492   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7493                    (div:DI (match_operand:DI 1 "register_operand" "")
7494                            (match_operand:DI 2 "nonimmediate_operand" "")))
7495               (set (match_operand:DI 3 "register_operand" "")
7496                    (mod:DI (match_dup 1) (match_dup 2)))
7497               (clobber (reg:CC 17))])]
7498   "TARGET_64BIT"
7499   "")
7500
7501 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7502 ;; Penalize eax case slightly because it results in worse scheduling
7503 ;; of code.
7504 (define_insn "*divmoddi4_nocltd_rex64"
7505   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7506         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7507                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7508    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7509         (mod:DI (match_dup 2) (match_dup 3)))
7510    (clobber (reg:CC 17))]
7511   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7512   "#"
7513   [(set_attr "type" "multi")])
7514
7515 (define_insn "*divmoddi4_cltd_rex64"
7516   [(set (match_operand:DI 0 "register_operand" "=a")
7517         (div:DI (match_operand:DI 2 "register_operand" "a")
7518                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7519    (set (match_operand:DI 1 "register_operand" "=&d")
7520         (mod:DI (match_dup 2) (match_dup 3)))
7521    (clobber (reg:CC 17))]
7522   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7523   "#"
7524   [(set_attr "type" "multi")])
7525
7526 (define_insn "*divmoddi_noext_rex64"
7527   [(set (match_operand:DI 0 "register_operand" "=a")
7528         (div:DI (match_operand:DI 1 "register_operand" "0")
7529                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7530    (set (match_operand:DI 3 "register_operand" "=d")
7531         (mod:DI (match_dup 1) (match_dup 2)))
7532    (use (match_operand:DI 4 "register_operand" "3"))
7533    (clobber (reg:CC 17))]
7534   "TARGET_64BIT"
7535   "idiv{q}\t%2"
7536   [(set_attr "type" "idiv")
7537    (set_attr "mode" "DI")
7538    (set_attr "ppro_uops" "few")])
7539
7540 (define_split
7541   [(set (match_operand:DI 0 "register_operand" "")
7542         (div:DI (match_operand:DI 1 "register_operand" "")
7543                 (match_operand:DI 2 "nonimmediate_operand" "")))
7544    (set (match_operand:DI 3 "register_operand" "")
7545         (mod:DI (match_dup 1) (match_dup 2)))
7546    (clobber (reg:CC 17))]
7547   "TARGET_64BIT && reload_completed"
7548   [(parallel [(set (match_dup 3)
7549                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7550               (clobber (reg:CC 17))])
7551    (parallel [(set (match_dup 0)
7552                    (div:DI (reg:DI 0) (match_dup 2)))
7553               (set (match_dup 3)
7554                    (mod:DI (reg:DI 0) (match_dup 2)))
7555               (use (match_dup 3))
7556               (clobber (reg:CC 17))])]
7557 {
7558   /* Avoid use of cltd in favor of a mov+shift.  */
7559   if (!TARGET_USE_CLTD && !optimize_size)
7560     {
7561       if (true_regnum (operands[1]))
7562         emit_move_insn (operands[0], operands[1]);
7563       else
7564         emit_move_insn (operands[3], operands[1]);
7565       operands[4] = operands[3];
7566     }
7567   else
7568     {
7569       if (true_regnum (operands[1]))
7570         abort();
7571       operands[4] = operands[1];
7572     }
7573 })
7574
7575
7576 (define_expand "divmodsi4"
7577   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7578                    (div:SI (match_operand:SI 1 "register_operand" "")
7579                            (match_operand:SI 2 "nonimmediate_operand" "")))
7580               (set (match_operand:SI 3 "register_operand" "")
7581                    (mod:SI (match_dup 1) (match_dup 2)))
7582               (clobber (reg:CC 17))])]
7583   ""
7584   "")
7585
7586 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7587 ;; Penalize eax case slightly because it results in worse scheduling
7588 ;; of code.
7589 (define_insn "*divmodsi4_nocltd"
7590   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7591         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7592                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7593    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7594         (mod:SI (match_dup 2) (match_dup 3)))
7595    (clobber (reg:CC 17))]
7596   "!optimize_size && !TARGET_USE_CLTD"
7597   "#"
7598   [(set_attr "type" "multi")])
7599
7600 (define_insn "*divmodsi4_cltd"
7601   [(set (match_operand:SI 0 "register_operand" "=a")
7602         (div:SI (match_operand:SI 2 "register_operand" "a")
7603                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7604    (set (match_operand:SI 1 "register_operand" "=&d")
7605         (mod:SI (match_dup 2) (match_dup 3)))
7606    (clobber (reg:CC 17))]
7607   "optimize_size || TARGET_USE_CLTD"
7608   "#"
7609   [(set_attr "type" "multi")])
7610
7611 (define_insn "*divmodsi_noext"
7612   [(set (match_operand:SI 0 "register_operand" "=a")
7613         (div:SI (match_operand:SI 1 "register_operand" "0")
7614                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7615    (set (match_operand:SI 3 "register_operand" "=d")
7616         (mod:SI (match_dup 1) (match_dup 2)))
7617    (use (match_operand:SI 4 "register_operand" "3"))
7618    (clobber (reg:CC 17))]
7619   ""
7620   "idiv{l}\t%2"
7621   [(set_attr "type" "idiv")
7622    (set_attr "mode" "SI")
7623    (set_attr "ppro_uops" "few")])
7624
7625 (define_split
7626   [(set (match_operand:SI 0 "register_operand" "")
7627         (div:SI (match_operand:SI 1 "register_operand" "")
7628                 (match_operand:SI 2 "nonimmediate_operand" "")))
7629    (set (match_operand:SI 3 "register_operand" "")
7630         (mod:SI (match_dup 1) (match_dup 2)))
7631    (clobber (reg:CC 17))]
7632   "reload_completed"
7633   [(parallel [(set (match_dup 3)
7634                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7635               (clobber (reg:CC 17))])
7636    (parallel [(set (match_dup 0)
7637                    (div:SI (reg:SI 0) (match_dup 2)))
7638               (set (match_dup 3)
7639                    (mod:SI (reg:SI 0) (match_dup 2)))
7640               (use (match_dup 3))
7641               (clobber (reg:CC 17))])]
7642 {
7643   /* Avoid use of cltd in favor of a mov+shift.  */
7644   if (!TARGET_USE_CLTD && !optimize_size)
7645     {
7646       if (true_regnum (operands[1]))
7647         emit_move_insn (operands[0], operands[1]);
7648       else
7649         emit_move_insn (operands[3], operands[1]);
7650       operands[4] = operands[3];
7651     }
7652   else
7653     {
7654       if (true_regnum (operands[1]))
7655         abort();
7656       operands[4] = operands[1];
7657     }
7658 })
7659 ;; %%% Split me.
7660 (define_insn "divmodhi4"
7661   [(set (match_operand:HI 0 "register_operand" "=a")
7662         (div:HI (match_operand:HI 1 "register_operand" "0")
7663                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7664    (set (match_operand:HI 3 "register_operand" "=&d")
7665         (mod:HI (match_dup 1) (match_dup 2)))
7666    (clobber (reg:CC 17))]
7667   "TARGET_HIMODE_MATH"
7668   "cwtd\;idiv{w}\t%2"
7669   [(set_attr "type" "multi")
7670    (set_attr "length_immediate" "0")
7671    (set_attr "mode" "SI")])
7672
7673 (define_insn "udivmoddi4"
7674   [(set (match_operand:DI 0 "register_operand" "=a")
7675         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7676                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:DI 3 "register_operand" "=&d")
7678         (umod:DI (match_dup 1) (match_dup 2)))
7679    (clobber (reg:CC 17))]
7680   "TARGET_64BIT"
7681   "xor{q}\t%3, %3\;div{q}\t%2"
7682   [(set_attr "type" "multi")
7683    (set_attr "length_immediate" "0")
7684    (set_attr "mode" "DI")])
7685
7686 (define_insn "*udivmoddi4_noext"
7687   [(set (match_operand:DI 0 "register_operand" "=a")
7688         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7689                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7690    (set (match_operand:DI 3 "register_operand" "=d")
7691         (umod:DI (match_dup 1) (match_dup 2)))
7692    (use (match_dup 3))
7693    (clobber (reg:CC 17))]
7694   "TARGET_64BIT"
7695   "div{q}\t%2"
7696   [(set_attr "type" "idiv")
7697    (set_attr "ppro_uops" "few")
7698    (set_attr "mode" "DI")])
7699
7700 (define_split
7701   [(set (match_operand:DI 0 "register_operand" "")
7702         (udiv:DI (match_operand:DI 1 "register_operand" "")
7703                  (match_operand:DI 2 "nonimmediate_operand" "")))
7704    (set (match_operand:DI 3 "register_operand" "")
7705         (umod:DI (match_dup 1) (match_dup 2)))
7706    (clobber (reg:CC 17))]
7707   "TARGET_64BIT && reload_completed"
7708   [(set (match_dup 3) (const_int 0))
7709    (parallel [(set (match_dup 0)
7710                    (udiv:DI (match_dup 1) (match_dup 2)))
7711               (set (match_dup 3)
7712                    (umod:DI (match_dup 1) (match_dup 2)))
7713               (use (match_dup 3))
7714               (clobber (reg:CC 17))])]
7715   "")
7716
7717 (define_insn "udivmodsi4"
7718   [(set (match_operand:SI 0 "register_operand" "=a")
7719         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721    (set (match_operand:SI 3 "register_operand" "=&d")
7722         (umod:SI (match_dup 1) (match_dup 2)))
7723    (clobber (reg:CC 17))]
7724   ""
7725   "xor{l}\t%3, %3\;div{l}\t%2"
7726   [(set_attr "type" "multi")
7727    (set_attr "length_immediate" "0")
7728    (set_attr "mode" "SI")])
7729
7730 (define_insn "*udivmodsi4_noext"
7731   [(set (match_operand:SI 0 "register_operand" "=a")
7732         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734    (set (match_operand:SI 3 "register_operand" "=d")
7735         (umod:SI (match_dup 1) (match_dup 2)))
7736    (use (match_dup 3))
7737    (clobber (reg:CC 17))]
7738   ""
7739   "div{l}\t%2"
7740   [(set_attr "type" "idiv")
7741    (set_attr "ppro_uops" "few")
7742    (set_attr "mode" "SI")])
7743
7744 (define_split
7745   [(set (match_operand:SI 0 "register_operand" "")
7746         (udiv:SI (match_operand:SI 1 "register_operand" "")
7747                  (match_operand:SI 2 "nonimmediate_operand" "")))
7748    (set (match_operand:SI 3 "register_operand" "")
7749         (umod:SI (match_dup 1) (match_dup 2)))
7750    (clobber (reg:CC 17))]
7751   "reload_completed"
7752   [(set (match_dup 3) (const_int 0))
7753    (parallel [(set (match_dup 0)
7754                    (udiv:SI (match_dup 1) (match_dup 2)))
7755               (set (match_dup 3)
7756                    (umod:SI (match_dup 1) (match_dup 2)))
7757               (use (match_dup 3))
7758               (clobber (reg:CC 17))])]
7759   "")
7760
7761 (define_expand "udivmodhi4"
7762   [(set (match_dup 4) (const_int 0))
7763    (parallel [(set (match_operand:HI 0 "register_operand" "")
7764                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7765                             (match_operand:HI 2 "nonimmediate_operand" "")))
7766               (set (match_operand:HI 3 "register_operand" "")
7767                    (umod:HI (match_dup 1) (match_dup 2)))
7768               (use (match_dup 4))
7769               (clobber (reg:CC 17))])]
7770   "TARGET_HIMODE_MATH"
7771   "operands[4] = gen_reg_rtx (HImode);")
7772
7773 (define_insn "*udivmodhi_noext"
7774   [(set (match_operand:HI 0 "register_operand" "=a")
7775         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7776                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7777    (set (match_operand:HI 3 "register_operand" "=d")
7778         (umod:HI (match_dup 1) (match_dup 2)))
7779    (use (match_operand:HI 4 "register_operand" "3"))
7780    (clobber (reg:CC 17))]
7781   ""
7782   "div{w}\t%2"
7783   [(set_attr "type" "idiv")
7784    (set_attr "mode" "HI")
7785    (set_attr "ppro_uops" "few")])
7786
7787 ;; We can not use div/idiv for double division, because it causes
7788 ;; "division by zero" on the overflow and that's not what we expect
7789 ;; from truncate.  Because true (non truncating) double division is
7790 ;; never generated, we can't create this insn anyway.
7791 ;
7792 ;(define_insn ""
7793 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7794 ;       (truncate:SI
7795 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7796 ;                  (zero_extend:DI
7797 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7798 ;   (set (match_operand:SI 3 "register_operand" "=d")
7799 ;       (truncate:SI
7800 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7801 ;   (clobber (reg:CC 17))]
7802 ;  ""
7803 ;  "div{l}\t{%2, %0|%0, %2}"
7804 ;  [(set_attr "type" "idiv")
7805 ;   (set_attr "ppro_uops" "few")])
7806 \f
7807 ;;- Logical AND instructions
7808
7809 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7810 ;; Note that this excludes ah.
7811
7812 (define_insn "*testdi_1_rex64"
7813   [(set (reg 17)
7814         (compare
7815           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7816                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7817           (const_int 0)))]
7818   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7820   "@
7821    test{l}\t{%k1, %k0|%k0, %k1} 
7822    test{l}\t{%k1, %k0|%k0, %k1} 
7823    test{q}\t{%1, %0|%0, %1} 
7824    test{q}\t{%1, %0|%0, %1} 
7825    test{q}\t{%1, %0|%0, %1}"
7826   [(set_attr "type" "test")
7827    (set_attr "modrm" "0,1,0,1,1")
7828    (set_attr "mode" "SI,SI,DI,DI,DI")
7829    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7830
7831 (define_insn "testsi_1"
7832   [(set (reg 17)
7833         (compare
7834           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7835                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7836           (const_int 0)))]
7837   "ix86_match_ccmode (insn, CCNOmode)
7838    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7839   "test{l}\t{%1, %0|%0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "modrm" "0,1,1")
7842    (set_attr "mode" "SI")
7843    (set_attr "pent_pair" "uv,np,uv")])
7844
7845 (define_expand "testsi_ccno_1"
7846   [(set (reg:CCNO 17)
7847         (compare:CCNO
7848           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7849                   (match_operand:SI 1 "nonmemory_operand" ""))
7850           (const_int 0)))]
7851   ""
7852   "")
7853
7854 (define_insn "*testhi_1"
7855   [(set (reg 17)
7856         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7857                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7858                  (const_int 0)))]
7859   "ix86_match_ccmode (insn, CCNOmode)
7860    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7861   "test{w}\t{%1, %0|%0, %1}"
7862   [(set_attr "type" "test")
7863    (set_attr "modrm" "0,1,1")
7864    (set_attr "mode" "HI")
7865    (set_attr "pent_pair" "uv,np,uv")])
7866
7867 (define_expand "testqi_ccz_1"
7868   [(set (reg:CCZ 17)
7869         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7870                              (match_operand:QI 1 "nonmemory_operand" ""))
7871                  (const_int 0)))]
7872   ""
7873   "")
7874
7875 (define_insn "*testqi_1"
7876   [(set (reg 17)
7877         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7878                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7879                  (const_int 0)))]
7880   "ix86_match_ccmode (insn, CCNOmode)
7881    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7882 {
7883   if (which_alternative == 3)
7884     {
7885       if (GET_CODE (operands[1]) == CONST_INT
7886           && (INTVAL (operands[1]) & 0xffffff00))
7887         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888       return "test{l}\t{%1, %k0|%k0, %1}";
7889     }
7890   return "test{b}\t{%1, %0|%0, %1}";
7891 }
7892   [(set_attr "type" "test")
7893    (set_attr "modrm" "0,1,1,1")
7894    (set_attr "mode" "QI,QI,QI,SI")
7895    (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897 (define_expand "testqi_ext_ccno_0"
7898   [(set (reg:CCNO 17)
7899         (compare:CCNO
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "")
7903               (const_int 8)
7904               (const_int 8))
7905             (match_operand 1 "const_int_operand" ""))
7906           (const_int 0)))]
7907   ""
7908   "")
7909
7910 (define_insn "*testqi_ext_0"
7911   [(set (reg 17)
7912         (compare
7913           (and:SI
7914             (zero_extract:SI
7915               (match_operand 0 "ext_register_operand" "Q")
7916               (const_int 8)
7917               (const_int 8))
7918             (match_operand 1 "const_int_operand" "n"))
7919           (const_int 0)))]
7920   "ix86_match_ccmode (insn, CCNOmode)"
7921   "test{b}\t{%1, %h0|%h0, %1}"
7922   [(set_attr "type" "test")
7923    (set_attr "mode" "QI")
7924    (set_attr "length_immediate" "1")
7925    (set_attr "pent_pair" "np")])
7926
7927 (define_insn "*testqi_ext_1"
7928   [(set (reg 17)
7929         (compare
7930           (and:SI
7931             (zero_extract:SI
7932               (match_operand 0 "ext_register_operand" "Q")
7933               (const_int 8)
7934               (const_int 8))
7935             (zero_extend:SI
7936               (match_operand:QI 1 "general_operand" "Qm")))
7937           (const_int 0)))]
7938   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7939    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7940   "test{b}\t{%1, %h0|%h0, %1}"
7941   [(set_attr "type" "test")
7942    (set_attr "mode" "QI")])
7943
7944 (define_insn "*testqi_ext_1_rex64"
7945   [(set (reg 17)
7946         (compare
7947           (and:SI
7948             (zero_extract:SI
7949               (match_operand 0 "ext_register_operand" "Q")
7950               (const_int 8)
7951               (const_int 8))
7952             (zero_extend:SI
7953               (match_operand:QI 1 "register_operand" "Q")))
7954           (const_int 0)))]
7955   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7956   "test{b}\t{%1, %h0|%h0, %1}"
7957   [(set_attr "type" "test")
7958    (set_attr "mode" "QI")])
7959
7960 (define_insn "*testqi_ext_2"
7961   [(set (reg 17)
7962         (compare
7963           (and:SI
7964             (zero_extract:SI
7965               (match_operand 0 "ext_register_operand" "Q")
7966               (const_int 8)
7967               (const_int 8))
7968             (zero_extract:SI
7969               (match_operand 1 "ext_register_operand" "Q")
7970               (const_int 8)
7971               (const_int 8)))
7972           (const_int 0)))]
7973   "ix86_match_ccmode (insn, CCNOmode)"
7974   "test{b}\t{%h1, %h0|%h0, %h1}"
7975   [(set_attr "type" "test")
7976    (set_attr "mode" "QI")])
7977
7978 ;; Combine likes to form bit extractions for some tests.  Humor it.
7979 (define_insn "*testqi_ext_3"
7980   [(set (reg 17)
7981         (compare (zero_extract:SI
7982                    (match_operand 0 "nonimmediate_operand" "rm")
7983                    (match_operand:SI 1 "const_int_operand" "")
7984                    (match_operand:SI 2 "const_int_operand" ""))
7985                  (const_int 0)))]
7986   "ix86_match_ccmode (insn, CCNOmode)
7987    && (GET_MODE (operands[0]) == SImode
7988        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7989        || GET_MODE (operands[0]) == HImode
7990        || GET_MODE (operands[0]) == QImode)"
7991   "#")
7992
7993 (define_insn "*testqi_ext_3_rex64"
7994   [(set (reg 17)
7995         (compare (zero_extract:DI
7996                    (match_operand 0 "nonimmediate_operand" "rm")
7997                    (match_operand:DI 1 "const_int_operand" "")
7998                    (match_operand:DI 2 "const_int_operand" ""))
7999                  (const_int 0)))]
8000   "TARGET_64BIT
8001    && ix86_match_ccmode (insn, CCNOmode)
8002    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8003    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8004    /* Ensure that resulting mask is zero or sign extended operand.  */
8005    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8006        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8007            && INTVAL (operands[1]) > 32))
8008    && (GET_MODE (operands[0]) == SImode
8009        || GET_MODE (operands[0]) == DImode
8010        || GET_MODE (operands[0]) == HImode
8011        || GET_MODE (operands[0]) == QImode)"
8012   "#")
8013
8014 (define_split
8015   [(set (reg 17)
8016         (compare (zero_extract
8017                    (match_operand 0 "nonimmediate_operand" "")
8018                    (match_operand 1 "const_int_operand" "")
8019                    (match_operand 2 "const_int_operand" ""))
8020                  (const_int 0)))]
8021   "ix86_match_ccmode (insn, CCNOmode)"
8022   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8023 {
8024   HOST_WIDE_INT len = INTVAL (operands[1]);
8025   HOST_WIDE_INT pos = INTVAL (operands[2]);
8026   HOST_WIDE_INT mask;
8027   enum machine_mode mode, submode;
8028
8029   mode = GET_MODE (operands[0]);
8030   if (GET_CODE (operands[0]) == MEM)
8031     {
8032       /* ??? Combine likes to put non-volatile mem extractions in QImode
8033          no matter the size of the test.  So find a mode that works.  */
8034       if (! MEM_VOLATILE_P (operands[0]))
8035         {
8036           mode = smallest_mode_for_size (pos + len, MODE_INT);
8037           operands[0] = adjust_address (operands[0], mode, 0);
8038         }
8039     }
8040   else if (GET_CODE (operands[0]) == SUBREG
8041            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8042                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8043            && pos + len <= GET_MODE_BITSIZE (submode))
8044     {
8045       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8046       mode = submode;
8047       operands[0] = SUBREG_REG (operands[0]);
8048     }
8049   else if (mode == HImode && pos + len <= 8)
8050     {
8051       /* Small HImode tests can be converted to QImode.  */
8052       mode = QImode;
8053       operands[0] = gen_lowpart (QImode, operands[0]);
8054     }
8055
8056   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8057   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8058
8059   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8060 })
8061
8062 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8063 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8064 ;; this is relatively important trick.
8065 ;; Do the conversion only post-reload to avoid limiting of the register class
8066 ;; to QI regs.
8067 (define_split
8068   [(set (reg 17)
8069         (compare
8070           (and (match_operand 0 "register_operand" "")
8071                (match_operand 1 "const_int_operand" ""))
8072           (const_int 0)))]
8073    "reload_completed
8074     && QI_REG_P (operands[0])
8075     && ((ix86_match_ccmode (insn, CCZmode)
8076          && !(INTVAL (operands[1]) & ~(255 << 8)))
8077         || (ix86_match_ccmode (insn, CCNOmode)
8078             && !(INTVAL (operands[1]) & ~(127 << 8))))
8079     && GET_MODE (operands[0]) != QImode"
8080   [(set (reg:CCNO 17)
8081         (compare:CCNO
8082           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8083                   (match_dup 1))
8084           (const_int 0)))]
8085   "operands[0] = gen_lowpart (SImode, operands[0]);
8086    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8087
8088 (define_split
8089   [(set (reg 17)
8090         (compare
8091           (and (match_operand 0 "nonimmediate_operand" "")
8092                (match_operand 1 "const_int_operand" ""))
8093           (const_int 0)))]
8094    "reload_completed
8095     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8096     && ((ix86_match_ccmode (insn, CCZmode)
8097          && !(INTVAL (operands[1]) & ~255))
8098         || (ix86_match_ccmode (insn, CCNOmode)
8099             && !(INTVAL (operands[1]) & ~127)))
8100     && GET_MODE (operands[0]) != QImode"
8101   [(set (reg:CCNO 17)
8102         (compare:CCNO
8103           (and:QI (match_dup 0)
8104                   (match_dup 1))
8105           (const_int 0)))]
8106   "operands[0] = gen_lowpart (QImode, operands[0]);
8107    operands[1] = gen_lowpart (QImode, operands[1]);")
8108
8109
8110 ;; %%% This used to optimize known byte-wide and operations to memory,
8111 ;; and sometimes to QImode registers.  If this is considered useful,
8112 ;; it should be done with splitters.
8113
8114 (define_expand "anddi3"
8115   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8116         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8117                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8118    (clobber (reg:CC 17))]
8119   "TARGET_64BIT"
8120   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8121
8122 (define_insn "*anddi_1_rex64"
8123   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8124         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8125                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8126    (clobber (reg:CC 17))]
8127   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8128 {
8129   switch (get_attr_type (insn))
8130     {
8131     case TYPE_IMOVX:
8132       {
8133         enum machine_mode mode;
8134
8135         if (GET_CODE (operands[2]) != CONST_INT)
8136           abort ();
8137         if (INTVAL (operands[2]) == 0xff)
8138           mode = QImode;
8139         else if (INTVAL (operands[2]) == 0xffff)
8140           mode = HImode;
8141         else
8142           abort ();
8143         
8144         operands[1] = gen_lowpart (mode, operands[1]);
8145         if (mode == QImode)
8146           return "movz{bq|x}\t{%1,%0|%0, %1}";
8147         else
8148           return "movz{wq|x}\t{%1,%0|%0, %1}";
8149       }
8150
8151     default:
8152       if (! rtx_equal_p (operands[0], operands[1]))
8153         abort ();
8154       if (get_attr_mode (insn) == MODE_SI)
8155         return "and{l}\t{%k2, %k0|%k0, %k2}";
8156       else
8157         return "and{q}\t{%2, %0|%0, %2}";
8158     }
8159 }
8160   [(set_attr "type" "alu,alu,alu,imovx")
8161    (set_attr "length_immediate" "*,*,*,0")
8162    (set_attr "mode" "SI,DI,DI,DI")])
8163
8164 (define_insn "*anddi_2"
8165   [(set (reg 17)
8166         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8167                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8168                  (const_int 0)))
8169    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8170         (and:DI (match_dup 1) (match_dup 2)))]
8171   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8172    && ix86_binary_operator_ok (AND, DImode, operands)"
8173   "@
8174    and{l}\t{%k2, %k0|%k0, %k2} 
8175    and{q}\t{%2, %0|%0, %2} 
8176    and{q}\t{%2, %0|%0, %2}"
8177   [(set_attr "type" "alu")
8178    (set_attr "mode" "SI,DI,DI")])
8179
8180 (define_expand "andsi3"
8181   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8182         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8183                 (match_operand:SI 2 "general_operand" "")))
8184    (clobber (reg:CC 17))]
8185   ""
8186   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8187
8188 (define_insn "*andsi_1"
8189   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8190         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8191                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8192    (clobber (reg:CC 17))]
8193   "ix86_binary_operator_ok (AND, SImode, operands)"
8194 {
8195   switch (get_attr_type (insn))
8196     {
8197     case TYPE_IMOVX:
8198       {
8199         enum machine_mode mode;
8200
8201         if (GET_CODE (operands[2]) != CONST_INT)
8202           abort ();
8203         if (INTVAL (operands[2]) == 0xff)
8204           mode = QImode;
8205         else if (INTVAL (operands[2]) == 0xffff)
8206           mode = HImode;
8207         else
8208           abort ();
8209         
8210         operands[1] = gen_lowpart (mode, operands[1]);
8211         if (mode == QImode)
8212           return "movz{bl|x}\t{%1,%0|%0, %1}";
8213         else
8214           return "movz{wl|x}\t{%1,%0|%0, %1}";
8215       }
8216
8217     default:
8218       if (! rtx_equal_p (operands[0], operands[1]))
8219         abort ();
8220       return "and{l}\t{%2, %0|%0, %2}";
8221     }
8222 }
8223   [(set_attr "type" "alu,alu,imovx")
8224    (set_attr "length_immediate" "*,*,0")
8225    (set_attr "mode" "SI")])
8226
8227 (define_split
8228   [(set (match_operand 0 "register_operand" "")
8229         (and (match_dup 0)
8230              (const_int -65536)))
8231    (clobber (reg:CC 17))]
8232   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8233   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8234   "operands[1] = gen_lowpart (HImode, operands[0]);")
8235
8236 (define_split
8237   [(set (match_operand 0 "ext_register_operand" "")
8238         (and (match_dup 0)
8239              (const_int -256)))
8240    (clobber (reg:CC 17))]
8241   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8242   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8243   "operands[1] = gen_lowpart (QImode, operands[0]);")
8244
8245 (define_split
8246   [(set (match_operand 0 "ext_register_operand" "")
8247         (and (match_dup 0)
8248              (const_int -65281)))
8249    (clobber (reg:CC 17))]
8250   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8251   [(parallel [(set (zero_extract:SI (match_dup 0)
8252                                     (const_int 8)
8253                                     (const_int 8))
8254                    (xor:SI 
8255                      (zero_extract:SI (match_dup 0)
8256                                       (const_int 8)
8257                                       (const_int 8))
8258                      (zero_extract:SI (match_dup 0)
8259                                       (const_int 8)
8260                                       (const_int 8))))
8261               (clobber (reg:CC 17))])]
8262   "operands[0] = gen_lowpart (SImode, operands[0]);")
8263
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_1_zext"
8266   [(set (match_operand:DI 0 "register_operand" "=r")
8267         (zero_extend:DI
8268           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8269                   (match_operand:SI 2 "general_operand" "rim"))))
8270    (clobber (reg:CC 17))]
8271   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8272   "and{l}\t{%2, %k0|%k0, %2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "mode" "SI")])
8275
8276 (define_insn "*andsi_2"
8277   [(set (reg 17)
8278         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8279                          (match_operand:SI 2 "general_operand" "rim,ri"))
8280                  (const_int 0)))
8281    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8282         (and:SI (match_dup 1) (match_dup 2)))]
8283   "ix86_match_ccmode (insn, CCNOmode)
8284    && ix86_binary_operator_ok (AND, SImode, operands)"
8285   "and{l}\t{%2, %0|%0, %2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "mode" "SI")])
8288
8289 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8290 (define_insn "*andsi_2_zext"
8291   [(set (reg 17)
8292         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8293                          (match_operand:SI 2 "general_operand" "rim"))
8294                  (const_int 0)))
8295    (set (match_operand:DI 0 "register_operand" "=r")
8296         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8297   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8298    && ix86_binary_operator_ok (AND, SImode, operands)"
8299   "and{l}\t{%2, %k0|%k0, %2}"
8300   [(set_attr "type" "alu")
8301    (set_attr "mode" "SI")])
8302
8303 (define_expand "andhi3"
8304   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8305         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8306                 (match_operand:HI 2 "general_operand" "")))
8307    (clobber (reg:CC 17))]
8308   "TARGET_HIMODE_MATH"
8309   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8310
8311 (define_insn "*andhi_1"
8312   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8313         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8314                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8315    (clobber (reg:CC 17))]
8316   "ix86_binary_operator_ok (AND, HImode, operands)"
8317 {
8318   switch (get_attr_type (insn))
8319     {
8320     case TYPE_IMOVX:
8321       if (GET_CODE (operands[2]) != CONST_INT)
8322         abort ();
8323       if (INTVAL (operands[2]) == 0xff)
8324         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8325       abort ();
8326
8327     default:
8328       if (! rtx_equal_p (operands[0], operands[1]))
8329         abort ();
8330
8331       return "and{w}\t{%2, %0|%0, %2}";
8332     }
8333 }
8334   [(set_attr "type" "alu,alu,imovx")
8335    (set_attr "length_immediate" "*,*,0")
8336    (set_attr "mode" "HI,HI,SI")])
8337
8338 (define_insn "*andhi_2"
8339   [(set (reg 17)
8340         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8341                          (match_operand:HI 2 "general_operand" "rim,ri"))
8342                  (const_int 0)))
8343    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8344         (and:HI (match_dup 1) (match_dup 2)))]
8345   "ix86_match_ccmode (insn, CCNOmode)
8346    && ix86_binary_operator_ok (AND, HImode, operands)"
8347   "and{w}\t{%2, %0|%0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "mode" "HI")])
8350
8351 (define_expand "andqi3"
8352   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8353         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8354                 (match_operand:QI 2 "general_operand" "")))
8355    (clobber (reg:CC 17))]
8356   "TARGET_QIMODE_MATH"
8357   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8358
8359 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8360 (define_insn "*andqi_1"
8361   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8362         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8363                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8364    (clobber (reg:CC 17))]
8365   "ix86_binary_operator_ok (AND, QImode, operands)"
8366   "@
8367    and{b}\t{%2, %0|%0, %2}
8368    and{b}\t{%2, %0|%0, %2}
8369    and{l}\t{%k2, %k0|%k0, %k2}"
8370   [(set_attr "type" "alu")
8371    (set_attr "mode" "QI,QI,SI")])
8372
8373 (define_insn "*andqi_1_slp"
8374   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8375         (and:QI (match_dup 0)
8376                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8377    (clobber (reg:CC 17))]
8378   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8379    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8380   "and{b}\t{%1, %0|%0, %1}"
8381   [(set_attr "type" "alu1")
8382    (set_attr "mode" "QI")])
8383
8384 (define_insn "*andqi_2"
8385   [(set (reg 17)
8386         (compare (and:QI
8387                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8388                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8389                  (const_int 0)))
8390    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8391         (and:QI (match_dup 1) (match_dup 2)))]
8392   "ix86_match_ccmode (insn, CCNOmode)
8393    && ix86_binary_operator_ok (AND, QImode, operands)"
8394 {
8395   if (which_alternative == 2)
8396     {
8397       if (GET_CODE (operands[2]) == CONST_INT
8398           && (INTVAL (operands[2]) & 0xffffff00))
8399         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8400       return "and{l}\t{%2, %k0|%k0, %2}";
8401     }
8402   return "and{b}\t{%2, %0|%0, %2}";
8403 }
8404   [(set_attr "type" "alu")
8405    (set_attr "mode" "QI,QI,SI")])
8406
8407 (define_insn "*andqi_2_slp"
8408   [(set (reg 17)
8409         (compare (and:QI
8410                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8411                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8412                  (const_int 0)))
8413    (set (strict_low_part (match_dup 0))
8414         (and:QI (match_dup 0) (match_dup 1)))]
8415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8416    && ix86_match_ccmode (insn, CCNOmode)
8417    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8418   "and{b}\t{%1, %0|%0, %1}"
8419   [(set_attr "type" "alu1")
8420    (set_attr "mode" "QI")])
8421
8422 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8423 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8424 ;; for a QImode operand, which of course failed.
8425
8426 (define_insn "andqi_ext_0"
8427   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428                          (const_int 8)
8429                          (const_int 8))
8430         (and:SI 
8431           (zero_extract:SI
8432             (match_operand 1 "ext_register_operand" "0")
8433             (const_int 8)
8434             (const_int 8))
8435           (match_operand 2 "const_int_operand" "n")))
8436    (clobber (reg:CC 17))]
8437   ""
8438   "and{b}\t{%2, %h0|%h0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "length_immediate" "1")
8441    (set_attr "mode" "QI")])
8442
8443 ;; Generated by peephole translating test to and.  This shows up
8444 ;; often in fp comparisons.
8445
8446 (define_insn "*andqi_ext_0_cc"
8447   [(set (reg 17)
8448         (compare
8449           (and:SI
8450             (zero_extract:SI
8451               (match_operand 1 "ext_register_operand" "0")
8452               (const_int 8)
8453               (const_int 8))
8454             (match_operand 2 "const_int_operand" "n"))
8455           (const_int 0)))
8456    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457                          (const_int 8)
8458                          (const_int 8))
8459         (and:SI 
8460           (zero_extract:SI
8461             (match_dup 1)
8462             (const_int 8)
8463             (const_int 8))
8464           (match_dup 2)))]
8465   "ix86_match_ccmode (insn, CCNOmode)"
8466   "and{b}\t{%2, %h0|%h0, %2}"
8467   [(set_attr "type" "alu")
8468    (set_attr "length_immediate" "1")
8469    (set_attr "mode" "QI")])
8470
8471 (define_insn "*andqi_ext_1"
8472   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8473                          (const_int 8)
8474                          (const_int 8))
8475         (and:SI 
8476           (zero_extract:SI
8477             (match_operand 1 "ext_register_operand" "0")
8478             (const_int 8)
8479             (const_int 8))
8480           (zero_extend:SI
8481             (match_operand:QI 2 "general_operand" "Qm"))))
8482    (clobber (reg:CC 17))]
8483   "!TARGET_64BIT"
8484   "and{b}\t{%2, %h0|%h0, %2}"
8485   [(set_attr "type" "alu")
8486    (set_attr "length_immediate" "0")
8487    (set_attr "mode" "QI")])
8488
8489 (define_insn "*andqi_ext_1_rex64"
8490   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8491                          (const_int 8)
8492                          (const_int 8))
8493         (and:SI 
8494           (zero_extract:SI
8495             (match_operand 1 "ext_register_operand" "0")
8496             (const_int 8)
8497             (const_int 8))
8498           (zero_extend:SI
8499             (match_operand 2 "ext_register_operand" "Q"))))
8500    (clobber (reg:CC 17))]
8501   "TARGET_64BIT"
8502   "and{b}\t{%2, %h0|%h0, %2}"
8503   [(set_attr "type" "alu")
8504    (set_attr "length_immediate" "0")
8505    (set_attr "mode" "QI")])
8506
8507 (define_insn "*andqi_ext_2"
8508   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8509                          (const_int 8)
8510                          (const_int 8))
8511         (and:SI
8512           (zero_extract:SI
8513             (match_operand 1 "ext_register_operand" "%0")
8514             (const_int 8)
8515             (const_int 8))
8516           (zero_extract:SI
8517             (match_operand 2 "ext_register_operand" "Q")
8518             (const_int 8)
8519             (const_int 8))))
8520    (clobber (reg:CC 17))]
8521   ""
8522   "and{b}\t{%h2, %h0|%h0, %h2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "length_immediate" "0")
8525    (set_attr "mode" "QI")])
8526
8527 ;; Convert wide AND instructions with immediate operand to shorter QImode
8528 ;; equivalents when possible.
8529 ;; Don't do the splitting with memory operands, since it introduces risk
8530 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8531 ;; for size, but that can (should?) be handled by generic code instead.
8532 (define_split
8533   [(set (match_operand 0 "register_operand" "")
8534         (and (match_operand 1 "register_operand" "")
8535              (match_operand 2 "const_int_operand" "")))
8536    (clobber (reg:CC 17))]
8537    "reload_completed
8538     && QI_REG_P (operands[0])
8539     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8540     && !(~INTVAL (operands[2]) & ~(255 << 8))
8541     && GET_MODE (operands[0]) != QImode"
8542   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8543                    (and:SI (zero_extract:SI (match_dup 1)
8544                                             (const_int 8) (const_int 8))
8545                            (match_dup 2)))
8546               (clobber (reg:CC 17))])]
8547   "operands[0] = gen_lowpart (SImode, operands[0]);
8548    operands[1] = gen_lowpart (SImode, operands[1]);
8549    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8550
8551 ;; Since AND can be encoded with sign extended immediate, this is only
8552 ;; profitable when 7th bit is not set.
8553 (define_split
8554   [(set (match_operand 0 "register_operand" "")
8555         (and (match_operand 1 "general_operand" "")
8556              (match_operand 2 "const_int_operand" "")))
8557    (clobber (reg:CC 17))]
8558    "reload_completed
8559     && ANY_QI_REG_P (operands[0])
8560     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8561     && !(~INTVAL (operands[2]) & ~255)
8562     && !(INTVAL (operands[2]) & 128)
8563     && GET_MODE (operands[0]) != QImode"
8564   [(parallel [(set (strict_low_part (match_dup 0))
8565                    (and:QI (match_dup 1)
8566                            (match_dup 2)))
8567               (clobber (reg:CC 17))])]
8568   "operands[0] = gen_lowpart (QImode, operands[0]);
8569    operands[1] = gen_lowpart (QImode, operands[1]);
8570    operands[2] = gen_lowpart (QImode, operands[2]);")
8571 \f
8572 ;; Logical inclusive OR instructions
8573
8574 ;; %%% This used to optimize known byte-wide and operations to memory.
8575 ;; If this is considered useful, it should be done with splitters.
8576
8577 (define_expand "iordi3"
8578   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8579         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8580                 (match_operand:DI 2 "x86_64_general_operand" "")))
8581    (clobber (reg:CC 17))]
8582   "TARGET_64BIT"
8583   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8584
8585 (define_insn "*iordi_1_rex64"
8586   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8587         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8588                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8589    (clobber (reg:CC 17))]
8590   "TARGET_64BIT
8591    && ix86_binary_operator_ok (IOR, DImode, operands)"
8592   "or{q}\t{%2, %0|%0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "DI")])
8595
8596 (define_insn "*iordi_2_rex64"
8597   [(set (reg 17)
8598         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8599                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8600                  (const_int 0)))
8601    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8602         (ior:DI (match_dup 1) (match_dup 2)))]
8603   "TARGET_64BIT
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, DImode, operands)"
8606   "or{q}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "DI")])
8609
8610 (define_insn "*iordi_3_rex64"
8611   [(set (reg 17)
8612         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8613                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8614                  (const_int 0)))
8615    (clobber (match_scratch:DI 0 "=r"))]
8616   "TARGET_64BIT
8617    && ix86_match_ccmode (insn, CCNOmode)
8618    && ix86_binary_operator_ok (IOR, DImode, operands)"
8619   "or{q}\t{%2, %0|%0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "DI")])
8622
8623
8624 (define_expand "iorsi3"
8625   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8626         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8627                 (match_operand:SI 2 "general_operand" "")))
8628    (clobber (reg:CC 17))]
8629   ""
8630   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8631
8632 (define_insn "*iorsi_1"
8633   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8634         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8635                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8636    (clobber (reg:CC 17))]
8637   "ix86_binary_operator_ok (IOR, SImode, operands)"
8638   "or{l}\t{%2, %0|%0, %2}"
8639   [(set_attr "type" "alu")
8640    (set_attr "mode" "SI")])
8641
8642 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8643 (define_insn "*iorsi_1_zext"
8644   [(set (match_operand:DI 0 "register_operand" "=rm")
8645         (zero_extend:DI
8646           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8647                   (match_operand:SI 2 "general_operand" "rim"))))
8648    (clobber (reg:CC 17))]
8649   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8650   "or{l}\t{%2, %k0|%k0, %2}"
8651   [(set_attr "type" "alu")
8652    (set_attr "mode" "SI")])
8653
8654 (define_insn "*iorsi_1_zext_imm"
8655   [(set (match_operand:DI 0 "register_operand" "=rm")
8656         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8657                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8658    (clobber (reg:CC 17))]
8659   "TARGET_64BIT"
8660   "or{l}\t{%2, %k0|%k0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_2"
8665   [(set (reg 17)
8666         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8667                          (match_operand:SI 2 "general_operand" "rim,ri"))
8668                  (const_int 0)))
8669    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8670         (ior:SI (match_dup 1) (match_dup 2)))]
8671   "ix86_match_ccmode (insn, CCNOmode)
8672    && ix86_binary_operator_ok (IOR, SImode, operands)"
8673   "or{l}\t{%2, %0|%0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "SI")])
8676
8677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8678 ;; ??? Special case for immediate operand is missing - it is tricky.
8679 (define_insn "*iorsi_2_zext"
8680   [(set (reg 17)
8681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682                          (match_operand:SI 2 "general_operand" "rim"))
8683                  (const_int 0)))
8684    (set (match_operand:DI 0 "register_operand" "=r")
8685         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687    && ix86_binary_operator_ok (IOR, SImode, operands)"
8688   "or{l}\t{%2, %k0|%k0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "SI")])
8691
8692 (define_insn "*iorsi_2_zext_imm"
8693   [(set (reg 17)
8694         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8696                  (const_int 0)))
8697    (set (match_operand:DI 0 "register_operand" "=r")
8698         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8699   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8700    && ix86_binary_operator_ok (IOR, SImode, operands)"
8701   "or{l}\t{%2, %k0|%k0, %2}"
8702   [(set_attr "type" "alu")
8703    (set_attr "mode" "SI")])
8704
8705 (define_insn "*iorsi_3"
8706   [(set (reg 17)
8707         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8708                          (match_operand:SI 2 "general_operand" "rim"))
8709                  (const_int 0)))
8710    (clobber (match_scratch:SI 0 "=r"))]
8711   "ix86_match_ccmode (insn, CCNOmode)
8712    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8713   "or{l}\t{%2, %0|%0, %2}"
8714   [(set_attr "type" "alu")
8715    (set_attr "mode" "SI")])
8716
8717 (define_expand "iorhi3"
8718   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8719         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8720                 (match_operand:HI 2 "general_operand" "")))
8721    (clobber (reg:CC 17))]
8722   "TARGET_HIMODE_MATH"
8723   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8724
8725 (define_insn "*iorhi_1"
8726   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8727         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8728                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8729    (clobber (reg:CC 17))]
8730   "ix86_binary_operator_ok (IOR, HImode, operands)"
8731   "or{w}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "HI")])
8734
8735 (define_insn "*iorhi_2"
8736   [(set (reg 17)
8737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738                          (match_operand:HI 2 "general_operand" "rim,ri"))
8739                  (const_int 0)))
8740    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8741         (ior:HI (match_dup 1) (match_dup 2)))]
8742   "ix86_match_ccmode (insn, CCNOmode)
8743    && ix86_binary_operator_ok (IOR, HImode, operands)"
8744   "or{w}\t{%2, %0|%0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "mode" "HI")])
8747
8748 (define_insn "*iorhi_3"
8749   [(set (reg 17)
8750         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8751                          (match_operand:HI 2 "general_operand" "rim"))
8752                  (const_int 0)))
8753    (clobber (match_scratch:HI 0 "=r"))]
8754   "ix86_match_ccmode (insn, CCNOmode)
8755    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8756   "or{w}\t{%2, %0|%0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "mode" "HI")])
8759
8760 (define_expand "iorqi3"
8761   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8762         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8763                 (match_operand:QI 2 "general_operand" "")))
8764    (clobber (reg:CC 17))]
8765   "TARGET_QIMODE_MATH"
8766   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8767
8768 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8769 (define_insn "*iorqi_1"
8770   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8771         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8772                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8773    (clobber (reg:CC 17))]
8774   "ix86_binary_operator_ok (IOR, QImode, operands)"
8775   "@
8776    or{b}\t{%2, %0|%0, %2}
8777    or{b}\t{%2, %0|%0, %2}
8778    or{l}\t{%k2, %k0|%k0, %k2}"
8779   [(set_attr "type" "alu")
8780    (set_attr "mode" "QI,QI,SI")])
8781
8782 (define_insn "*iorqi_1_slp"
8783   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8784         (ior:QI (match_dup 0)
8785                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8786    (clobber (reg:CC 17))]
8787   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8789   "or{b}\t{%1, %0|%0, %1}"
8790   [(set_attr "type" "alu1")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_2"
8794   [(set (reg 17)
8795         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8796                          (match_operand:QI 2 "general_operand" "qim,qi"))
8797                  (const_int 0)))
8798    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8799         (ior:QI (match_dup 1) (match_dup 2)))]
8800   "ix86_match_ccmode (insn, CCNOmode)
8801    && ix86_binary_operator_ok (IOR, QImode, operands)"
8802   "or{b}\t{%2, %0|%0, %2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "mode" "QI")])
8805
8806 (define_insn "*iorqi_2_slp"
8807   [(set (reg 17)
8808         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8809                          (match_operand:QI 1 "general_operand" "qim,qi"))
8810                  (const_int 0)))
8811    (set (strict_low_part (match_dup 0))
8812         (ior:QI (match_dup 0) (match_dup 1)))]
8813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8814    && ix86_match_ccmode (insn, CCNOmode)
8815    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8816   "or{b}\t{%1, %0|%0, %1}"
8817   [(set_attr "type" "alu1")
8818    (set_attr "mode" "QI")])
8819
8820 (define_insn "*iorqi_3"
8821   [(set (reg 17)
8822         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8823                          (match_operand:QI 2 "general_operand" "qim"))
8824                  (const_int 0)))
8825    (clobber (match_scratch:QI 0 "=q"))]
8826   "ix86_match_ccmode (insn, CCNOmode)
8827    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8828   "or{b}\t{%2, %0|%0, %2}"
8829   [(set_attr "type" "alu")
8830    (set_attr "mode" "QI")])
8831
8832 (define_insn "iorqi_ext_0"
8833   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8834                          (const_int 8)
8835                          (const_int 8))
8836         (ior:SI 
8837           (zero_extract:SI
8838             (match_operand 1 "ext_register_operand" "0")
8839             (const_int 8)
8840             (const_int 8))
8841           (match_operand 2 "const_int_operand" "n")))
8842    (clobber (reg:CC 17))]
8843   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8844   "or{b}\t{%2, %h0|%h0, %2}"
8845   [(set_attr "type" "alu")
8846    (set_attr "length_immediate" "1")
8847    (set_attr "mode" "QI")])
8848
8849 (define_insn "*iorqi_ext_1"
8850   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8851                          (const_int 8)
8852                          (const_int 8))
8853         (ior:SI 
8854           (zero_extract:SI
8855             (match_operand 1 "ext_register_operand" "0")
8856             (const_int 8)
8857             (const_int 8))
8858           (zero_extend:SI
8859             (match_operand:QI 2 "general_operand" "Qm"))))
8860    (clobber (reg:CC 17))]
8861   "!TARGET_64BIT
8862    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8863   "or{b}\t{%2, %h0|%h0, %2}"
8864   [(set_attr "type" "alu")
8865    (set_attr "length_immediate" "0")
8866    (set_attr "mode" "QI")])
8867
8868 (define_insn "*iorqi_ext_1_rex64"
8869   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8870                          (const_int 8)
8871                          (const_int 8))
8872         (ior:SI 
8873           (zero_extract:SI
8874             (match_operand 1 "ext_register_operand" "0")
8875             (const_int 8)
8876             (const_int 8))
8877           (zero_extend:SI
8878             (match_operand 2 "ext_register_operand" "Q"))))
8879    (clobber (reg:CC 17))]
8880   "TARGET_64BIT
8881    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8882   "or{b}\t{%2, %h0|%h0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "length_immediate" "0")
8885    (set_attr "mode" "QI")])
8886
8887 (define_insn "*iorqi_ext_2"
8888   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8889                          (const_int 8)
8890                          (const_int 8))
8891         (ior:SI 
8892           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8893                            (const_int 8)
8894                            (const_int 8))
8895           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8896                            (const_int 8)
8897                            (const_int 8))))
8898    (clobber (reg:CC 17))]
8899   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8900   "ior{b}\t{%h2, %h0|%h0, %h2}"
8901   [(set_attr "type" "alu")
8902    (set_attr "length_immediate" "0")
8903    (set_attr "mode" "QI")])
8904
8905 (define_split
8906   [(set (match_operand 0 "register_operand" "")
8907         (ior (match_operand 1 "register_operand" "")
8908              (match_operand 2 "const_int_operand" "")))
8909    (clobber (reg:CC 17))]
8910    "reload_completed
8911     && QI_REG_P (operands[0])
8912     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8913     && !(INTVAL (operands[2]) & ~(255 << 8))
8914     && GET_MODE (operands[0]) != QImode"
8915   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8916                    (ior:SI (zero_extract:SI (match_dup 1)
8917                                             (const_int 8) (const_int 8))
8918                            (match_dup 2)))
8919               (clobber (reg:CC 17))])]
8920   "operands[0] = gen_lowpart (SImode, operands[0]);
8921    operands[1] = gen_lowpart (SImode, operands[1]);
8922    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8923
8924 ;; Since OR can be encoded with sign extended immediate, this is only
8925 ;; profitable when 7th bit is set.
8926 (define_split
8927   [(set (match_operand 0 "register_operand" "")
8928         (ior (match_operand 1 "general_operand" "")
8929              (match_operand 2 "const_int_operand" "")))
8930    (clobber (reg:CC 17))]
8931    "reload_completed
8932     && ANY_QI_REG_P (operands[0])
8933     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8934     && !(INTVAL (operands[2]) & ~255)
8935     && (INTVAL (operands[2]) & 128)
8936     && GET_MODE (operands[0]) != QImode"
8937   [(parallel [(set (strict_low_part (match_dup 0))
8938                    (ior:QI (match_dup 1)
8939                            (match_dup 2)))
8940               (clobber (reg:CC 17))])]
8941   "operands[0] = gen_lowpart (QImode, operands[0]);
8942    operands[1] = gen_lowpart (QImode, operands[1]);
8943    operands[2] = gen_lowpart (QImode, operands[2]);")
8944 \f
8945 ;; Logical XOR instructions
8946
8947 ;; %%% This used to optimize known byte-wide and operations to memory.
8948 ;; If this is considered useful, it should be done with splitters.
8949
8950 (define_expand "xordi3"
8951   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8952         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8953                 (match_operand:DI 2 "x86_64_general_operand" "")))
8954    (clobber (reg:CC 17))]
8955   "TARGET_64BIT"
8956   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8957
8958 (define_insn "*xordi_1_rex64"
8959   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8960         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8962    (clobber (reg:CC 17))]
8963   "TARGET_64BIT
8964    && ix86_binary_operator_ok (XOR, DImode, operands)"
8965   "@
8966    xor{q}\t{%2, %0|%0, %2} 
8967    xor{q}\t{%2, %0|%0, %2}"
8968   [(set_attr "type" "alu")
8969    (set_attr "mode" "DI,DI")])
8970
8971 (define_insn "*xordi_2_rex64"
8972   [(set (reg 17)
8973         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8974                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8975                  (const_int 0)))
8976    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8977         (xor:DI (match_dup 1) (match_dup 2)))]
8978   "TARGET_64BIT
8979    && ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, DImode, operands)"
8981   "@
8982    xor{q}\t{%2, %0|%0, %2} 
8983    xor{q}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "DI,DI")])
8986
8987 (define_insn "*xordi_3_rex64"
8988   [(set (reg 17)
8989         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8990                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8991                  (const_int 0)))
8992    (clobber (match_scratch:DI 0 "=r"))]
8993   "TARGET_64BIT
8994    && ix86_match_ccmode (insn, CCNOmode)
8995    && ix86_binary_operator_ok (XOR, DImode, operands)"
8996   "xor{q}\t{%2, %0|%0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "mode" "DI")])
8999
9000 (define_expand "xorsi3"
9001   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9002         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9003                 (match_operand:SI 2 "general_operand" "")))
9004    (clobber (reg:CC 17))]
9005   ""
9006   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9007
9008 (define_insn "*xorsi_1"
9009   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9010         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9011                 (match_operand:SI 2 "general_operand" "ri,rm")))
9012    (clobber (reg:CC 17))]
9013   "ix86_binary_operator_ok (XOR, SImode, operands)"
9014   "xor{l}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "SI")])
9017
9018 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9019 ;; Add speccase for immediates
9020 (define_insn "*xorsi_1_zext"
9021   [(set (match_operand:DI 0 "register_operand" "=r")
9022         (zero_extend:DI
9023           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024                   (match_operand:SI 2 "general_operand" "rim"))))
9025    (clobber (reg:CC 17))]
9026   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9027   "xor{l}\t{%2, %k0|%k0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "SI")])
9030
9031 (define_insn "*xorsi_1_zext_imm"
9032   [(set (match_operand:DI 0 "register_operand" "=r")
9033         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9034                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9035    (clobber (reg:CC 17))]
9036   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %k0|%k0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_2"
9042   [(set (reg 17)
9043         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9044                          (match_operand:SI 2 "general_operand" "rim,ri"))
9045                  (const_int 0)))
9046    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9047         (xor:SI (match_dup 1) (match_dup 2)))]
9048   "ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (XOR, SImode, operands)"
9050   "xor{l}\t{%2, %0|%0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9055 ;; ??? Special case for immediate operand is missing - it is tricky.
9056 (define_insn "*xorsi_2_zext"
9057   [(set (reg 17)
9058         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand:SI 2 "general_operand" "rim"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 (define_insn "*xorsi_2_zext_imm"
9070   [(set (reg 17)
9071         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9073                  (const_int 0)))
9074    (set (match_operand:DI 0 "register_operand" "=r")
9075         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9076   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9077    && ix86_binary_operator_ok (XOR, SImode, operands)"
9078   "xor{l}\t{%2, %k0|%k0, %2}"
9079   [(set_attr "type" "alu")
9080    (set_attr "mode" "SI")])
9081
9082 (define_insn "*xorsi_3"
9083   [(set (reg 17)
9084         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9085                          (match_operand:SI 2 "general_operand" "rim"))
9086                  (const_int 0)))
9087    (clobber (match_scratch:SI 0 "=r"))]
9088   "ix86_match_ccmode (insn, CCNOmode)
9089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9090   "xor{l}\t{%2, %0|%0, %2}"
9091   [(set_attr "type" "alu")
9092    (set_attr "mode" "SI")])
9093
9094 (define_expand "xorhi3"
9095   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9096         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9097                 (match_operand:HI 2 "general_operand" "")))
9098    (clobber (reg:CC 17))]
9099   "TARGET_HIMODE_MATH"
9100   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9101
9102 (define_insn "*xorhi_1"
9103   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9104         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9106    (clobber (reg:CC 17))]
9107   "ix86_binary_operator_ok (XOR, HImode, operands)"
9108   "xor{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9111
9112 (define_insn "*xorhi_2"
9113   [(set (reg 17)
9114         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115                          (match_operand:HI 2 "general_operand" "rim,ri"))
9116                  (const_int 0)))
9117    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9118         (xor:HI (match_dup 1) (match_dup 2)))]
9119   "ix86_match_ccmode (insn, CCNOmode)
9120    && ix86_binary_operator_ok (XOR, HImode, operands)"
9121   "xor{w}\t{%2, %0|%0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "HI")])
9124
9125 (define_insn "*xorhi_3"
9126   [(set (reg 17)
9127         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9128                          (match_operand:HI 2 "general_operand" "rim"))
9129                  (const_int 0)))
9130    (clobber (match_scratch:HI 0 "=r"))]
9131   "ix86_match_ccmode (insn, CCNOmode)
9132    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9133   "xor{w}\t{%2, %0|%0, %2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "mode" "HI")])
9136
9137 (define_expand "xorqi3"
9138   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9139         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9140                 (match_operand:QI 2 "general_operand" "")))
9141    (clobber (reg:CC 17))]
9142   "TARGET_QIMODE_MATH"
9143   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9144
9145 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9146 (define_insn "*xorqi_1"
9147   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9148         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9149                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9150    (clobber (reg:CC 17))]
9151   "ix86_binary_operator_ok (XOR, QImode, operands)"
9152   "@
9153    xor{b}\t{%2, %0|%0, %2}
9154    xor{b}\t{%2, %0|%0, %2}
9155    xor{l}\t{%k2, %k0|%k0, %k2}"
9156   [(set_attr "type" "alu")
9157    (set_attr "mode" "QI,QI,SI")])
9158
9159 (define_insn "*xorqi_1_slp"
9160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9161         (xor:QI (match_dup 0)
9162                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9163    (clobber (reg:CC 17))]
9164   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9166   "xor{b}\t{%1, %0|%0, %1}"
9167   [(set_attr "type" "alu1")
9168    (set_attr "mode" "QI")])
9169
9170 (define_insn "xorqi_ext_0"
9171   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9172                          (const_int 8)
9173                          (const_int 8))
9174         (xor:SI 
9175           (zero_extract:SI
9176             (match_operand 1 "ext_register_operand" "0")
9177             (const_int 8)
9178             (const_int 8))
9179           (match_operand 2 "const_int_operand" "n")))
9180    (clobber (reg:CC 17))]
9181   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9182   "xor{b}\t{%2, %h0|%h0, %2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "length_immediate" "1")
9185    (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_ext_1"
9188   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9189                          (const_int 8)
9190                          (const_int 8))
9191         (xor:SI 
9192           (zero_extract:SI
9193             (match_operand 1 "ext_register_operand" "0")
9194             (const_int 8)
9195             (const_int 8))
9196           (zero_extend:SI
9197             (match_operand:QI 2 "general_operand" "Qm"))))
9198    (clobber (reg:CC 17))]
9199   "!TARGET_64BIT
9200    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9201   "xor{b}\t{%2, %h0|%h0, %2}"
9202   [(set_attr "type" "alu")
9203    (set_attr "length_immediate" "0")
9204    (set_attr "mode" "QI")])
9205
9206 (define_insn "*xorqi_ext_1_rex64"
9207   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9208                          (const_int 8)
9209                          (const_int 8))
9210         (xor:SI 
9211           (zero_extract:SI
9212             (match_operand 1 "ext_register_operand" "0")
9213             (const_int 8)
9214             (const_int 8))
9215           (zero_extend:SI
9216             (match_operand 2 "ext_register_operand" "Q"))))
9217    (clobber (reg:CC 17))]
9218   "TARGET_64BIT
9219    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9220   "xor{b}\t{%2, %h0|%h0, %2}"
9221   [(set_attr "type" "alu")
9222    (set_attr "length_immediate" "0")
9223    (set_attr "mode" "QI")])
9224
9225 (define_insn "*xorqi_ext_2"
9226   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9227                          (const_int 8)
9228                          (const_int 8))
9229         (xor:SI 
9230           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9231                            (const_int 8)
9232                            (const_int 8))
9233           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9234                            (const_int 8)
9235                            (const_int 8))))
9236    (clobber (reg:CC 17))]
9237   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9238   "xor{b}\t{%h2, %h0|%h0, %h2}"
9239   [(set_attr "type" "alu")
9240    (set_attr "length_immediate" "0")
9241    (set_attr "mode" "QI")])
9242
9243 (define_insn "*xorqi_cc_1"
9244   [(set (reg 17)
9245         (compare
9246           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9247                   (match_operand:QI 2 "general_operand" "qim,qi"))
9248           (const_int 0)))
9249    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9250         (xor:QI (match_dup 1) (match_dup 2)))]
9251   "ix86_match_ccmode (insn, CCNOmode)
9252    && ix86_binary_operator_ok (XOR, QImode, operands)"
9253   "xor{b}\t{%2, %0|%0, %2}"
9254   [(set_attr "type" "alu")
9255    (set_attr "mode" "QI")])
9256
9257 (define_insn "*xorqi_2_slp"
9258   [(set (reg 17)
9259         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9260                          (match_operand:QI 1 "general_operand" "qim,qi"))
9261                  (const_int 0)))
9262    (set (strict_low_part (match_dup 0))
9263         (xor:QI (match_dup 0) (match_dup 1)))]
9264   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9265    && ix86_match_ccmode (insn, CCNOmode)
9266    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9267   "xor{b}\t{%1, %0|%0, %1}"
9268   [(set_attr "type" "alu1")
9269    (set_attr "mode" "QI")])
9270
9271 (define_insn "*xorqi_cc_2"
9272   [(set (reg 17)
9273         (compare
9274           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9275                   (match_operand:QI 2 "general_operand" "qim"))
9276           (const_int 0)))
9277    (clobber (match_scratch:QI 0 "=q"))]
9278   "ix86_match_ccmode (insn, CCNOmode)
9279    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9280   "xor{b}\t{%2, %0|%0, %2}"
9281   [(set_attr "type" "alu")
9282    (set_attr "mode" "QI")])
9283
9284 (define_insn "*xorqi_cc_ext_1"
9285   [(set (reg 17)
9286         (compare
9287           (xor:SI
9288             (zero_extract:SI
9289               (match_operand 1 "ext_register_operand" "0")
9290               (const_int 8)
9291               (const_int 8))
9292             (match_operand:QI 2 "general_operand" "qmn"))
9293           (const_int 0)))
9294    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9295                          (const_int 8)
9296                          (const_int 8))
9297         (xor:SI 
9298           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9299           (match_dup 2)))]
9300   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9301   "xor{b}\t{%2, %h0|%h0, %2}"
9302   [(set_attr "type" "alu")
9303    (set_attr "mode" "QI")])
9304
9305 (define_insn "*xorqi_cc_ext_1_rex64"
9306   [(set (reg 17)
9307         (compare
9308           (xor:SI
9309             (zero_extract:SI
9310               (match_operand 1 "ext_register_operand" "0")
9311               (const_int 8)
9312               (const_int 8))
9313             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9314           (const_int 0)))
9315    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9316                          (const_int 8)
9317                          (const_int 8))
9318         (xor:SI 
9319           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9320           (match_dup 2)))]
9321   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9322   "xor{b}\t{%2, %h0|%h0, %2}"
9323   [(set_attr "type" "alu")
9324    (set_attr "mode" "QI")])
9325
9326 (define_expand "xorqi_cc_ext_1"
9327   [(parallel [
9328      (set (reg:CCNO 17)
9329           (compare:CCNO
9330             (xor:SI
9331               (zero_extract:SI
9332                 (match_operand 1 "ext_register_operand" "")
9333                 (const_int 8)
9334                 (const_int 8))
9335               (match_operand:QI 2 "general_operand" ""))
9336             (const_int 0)))
9337      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9338                            (const_int 8)
9339                            (const_int 8))
9340           (xor:SI 
9341             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342             (match_dup 2)))])]
9343   ""
9344   "")
9345
9346 (define_split
9347   [(set (match_operand 0 "register_operand" "")
9348         (xor (match_operand 1 "register_operand" "")
9349              (match_operand 2 "const_int_operand" "")))
9350    (clobber (reg:CC 17))]
9351    "reload_completed
9352     && QI_REG_P (operands[0])
9353     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9354     && !(INTVAL (operands[2]) & ~(255 << 8))
9355     && GET_MODE (operands[0]) != QImode"
9356   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9357                    (xor:SI (zero_extract:SI (match_dup 1)
9358                                             (const_int 8) (const_int 8))
9359                            (match_dup 2)))
9360               (clobber (reg:CC 17))])]
9361   "operands[0] = gen_lowpart (SImode, operands[0]);
9362    operands[1] = gen_lowpart (SImode, operands[1]);
9363    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9364
9365 ;; Since XOR can be encoded with sign extended immediate, this is only
9366 ;; profitable when 7th bit is set.
9367 (define_split
9368   [(set (match_operand 0 "register_operand" "")
9369         (xor (match_operand 1 "general_operand" "")
9370              (match_operand 2 "const_int_operand" "")))
9371    (clobber (reg:CC 17))]
9372    "reload_completed
9373     && ANY_QI_REG_P (operands[0])
9374     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9375     && !(INTVAL (operands[2]) & ~255)
9376     && (INTVAL (operands[2]) & 128)
9377     && GET_MODE (operands[0]) != QImode"
9378   [(parallel [(set (strict_low_part (match_dup 0))
9379                    (xor:QI (match_dup 1)
9380                            (match_dup 2)))
9381               (clobber (reg:CC 17))])]
9382   "operands[0] = gen_lowpart (QImode, operands[0]);
9383    operands[1] = gen_lowpart (QImode, operands[1]);
9384    operands[2] = gen_lowpart (QImode, operands[2]);")
9385 \f
9386 ;; Negation instructions
9387
9388 (define_expand "negdi2"
9389   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9391               (clobber (reg:CC 17))])]
9392   ""
9393   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9394
9395 (define_insn "*negdi2_1"
9396   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9397         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9398    (clobber (reg:CC 17))]
9399   "!TARGET_64BIT
9400    && ix86_unary_operator_ok (NEG, DImode, operands)"
9401   "#")
9402
9403 (define_split
9404   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9405         (neg:DI (match_operand:DI 1 "general_operand" "")))
9406    (clobber (reg:CC 17))]
9407   "!TARGET_64BIT && reload_completed"
9408   [(parallel
9409     [(set (reg:CCZ 17)
9410           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9411      (set (match_dup 0) (neg:SI (match_dup 2)))])
9412    (parallel
9413     [(set (match_dup 1)
9414           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9415                             (match_dup 3))
9416                    (const_int 0)))
9417      (clobber (reg:CC 17))])
9418    (parallel
9419     [(set (match_dup 1)
9420           (neg:SI (match_dup 1)))
9421      (clobber (reg:CC 17))])]
9422   "split_di (operands+1, 1, operands+2, operands+3);
9423    split_di (operands+0, 1, operands+0, operands+1);")
9424
9425 (define_insn "*negdi2_1_rex64"
9426   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9428    (clobber (reg:CC 17))]
9429   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9430   "neg{q}\t%0"
9431   [(set_attr "type" "negnot")
9432    (set_attr "mode" "DI")])
9433
9434 ;; The problem with neg is that it does not perform (compare x 0),
9435 ;; it really performs (compare 0 x), which leaves us with the zero
9436 ;; flag being the only useful item.
9437
9438 (define_insn "*negdi2_cmpz_rex64"
9439   [(set (reg:CCZ 17)
9440         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9441                      (const_int 0)))
9442    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9443         (neg:DI (match_dup 1)))]
9444   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9445   "neg{q}\t%0"
9446   [(set_attr "type" "negnot")
9447    (set_attr "mode" "DI")])
9448
9449
9450 (define_expand "negsi2"
9451   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9452                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9453               (clobber (reg:CC 17))])]
9454   ""
9455   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9456
9457 (define_insn "*negsi2_1"
9458   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9459         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9460    (clobber (reg:CC 17))]
9461   "ix86_unary_operator_ok (NEG, SImode, operands)"
9462   "neg{l}\t%0"
9463   [(set_attr "type" "negnot")
9464    (set_attr "mode" "SI")])
9465
9466 ;; Combine is quite creative about this pattern.
9467 (define_insn "*negsi2_1_zext"
9468   [(set (match_operand:DI 0 "register_operand" "=r")
9469         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9470                                         (const_int 32)))
9471                      (const_int 32)))
9472    (clobber (reg:CC 17))]
9473   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9474   "neg{l}\t%k0"
9475   [(set_attr "type" "negnot")
9476    (set_attr "mode" "SI")])
9477
9478 ;; The problem with neg is that it does not perform (compare x 0),
9479 ;; it really performs (compare 0 x), which leaves us with the zero
9480 ;; flag being the only useful item.
9481
9482 (define_insn "*negsi2_cmpz"
9483   [(set (reg:CCZ 17)
9484         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9485                      (const_int 0)))
9486    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9487         (neg:SI (match_dup 1)))]
9488   "ix86_unary_operator_ok (NEG, SImode, operands)"
9489   "neg{l}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "SI")])
9492
9493 (define_insn "*negsi2_cmpz_zext"
9494   [(set (reg:CCZ 17)
9495         (compare:CCZ (lshiftrt:DI
9496                        (neg:DI (ashift:DI
9497                                  (match_operand:DI 1 "register_operand" "0")
9498                                  (const_int 32)))
9499                        (const_int 32))
9500                      (const_int 0)))
9501    (set (match_operand:DI 0 "register_operand" "=r")
9502         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9503                                         (const_int 32)))
9504                      (const_int 32)))]
9505   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9506   "neg{l}\t%k0"
9507   [(set_attr "type" "negnot")
9508    (set_attr "mode" "SI")])
9509
9510 (define_expand "neghi2"
9511   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9512                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9513               (clobber (reg:CC 17))])]
9514   "TARGET_HIMODE_MATH"
9515   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9516
9517 (define_insn "*neghi2_1"
9518   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9519         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9520    (clobber (reg:CC 17))]
9521   "ix86_unary_operator_ok (NEG, HImode, operands)"
9522   "neg{w}\t%0"
9523   [(set_attr "type" "negnot")
9524    (set_attr "mode" "HI")])
9525
9526 (define_insn "*neghi2_cmpz"
9527   [(set (reg:CCZ 17)
9528         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9529                      (const_int 0)))
9530    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9531         (neg:HI (match_dup 1)))]
9532   "ix86_unary_operator_ok (NEG, HImode, operands)"
9533   "neg{w}\t%0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "HI")])
9536
9537 (define_expand "negqi2"
9538   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9539                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9540               (clobber (reg:CC 17))])]
9541   "TARGET_QIMODE_MATH"
9542   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9543
9544 (define_insn "*negqi2_1"
9545   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9546         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9547    (clobber (reg:CC 17))]
9548   "ix86_unary_operator_ok (NEG, QImode, operands)"
9549   "neg{b}\t%0"
9550   [(set_attr "type" "negnot")
9551    (set_attr "mode" "QI")])
9552
9553 (define_insn "*negqi2_cmpz"
9554   [(set (reg:CCZ 17)
9555         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9556                      (const_int 0)))
9557    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9558         (neg:QI (match_dup 1)))]
9559   "ix86_unary_operator_ok (NEG, QImode, operands)"
9560   "neg{b}\t%0"
9561   [(set_attr "type" "negnot")
9562    (set_attr "mode" "QI")])
9563
9564 ;; Changing of sign for FP values is doable using integer unit too.
9565
9566 (define_expand "negsf2"
9567   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9568                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9569               (clobber (reg:CC 17))])]
9570   "TARGET_80387"
9571   "if (TARGET_SSE)
9572      {
9573        /* In case operand is in memory,  we will not use SSE.  */
9574        if (memory_operand (operands[0], VOIDmode)
9575            && rtx_equal_p (operands[0], operands[1]))
9576          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9577        else
9578         {
9579           /* Using SSE is tricky, since we need bitwise negation of -0
9580              in register.  */
9581           rtx reg = gen_reg_rtx (SFmode);
9582           rtx dest = operands[0];
9583           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9584
9585           operands[1] = force_reg (SFmode, operands[1]);
9586           operands[0] = force_reg (SFmode, operands[0]);
9587           reg = force_reg (V4SFmode,
9588                            gen_rtx_CONST_VECTOR (V4SFmode,
9589                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9590                                         CONST0_RTX (SFmode),
9591                                         CONST0_RTX (SFmode))));
9592           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9593           if (dest != operands[0])
9594             emit_move_insn (dest, operands[0]);
9595         }
9596        DONE;
9597      }
9598    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9599
9600 (define_insn "negsf2_memory"
9601   [(set (match_operand:SF 0 "memory_operand" "=m")
9602         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9603    (clobber (reg:CC 17))]
9604   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9605   "#")
9606
9607 (define_insn "negsf2_ifs"
9608   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9609         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9610    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9611    (clobber (reg:CC 17))]
9612   "TARGET_SSE
9613    && (reload_in_progress || reload_completed
9614        || (register_operand (operands[0], VOIDmode)
9615            && register_operand (operands[1], VOIDmode)))"
9616   "#")
9617
9618 (define_split
9619   [(set (match_operand:SF 0 "memory_operand" "")
9620         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9621    (use (match_operand:SF 2 "" ""))
9622    (clobber (reg:CC 17))]
9623   ""
9624   [(parallel [(set (match_dup 0)
9625                    (neg:SF (match_dup 1)))
9626               (clobber (reg:CC 17))])])
9627
9628 (define_split
9629   [(set (match_operand:SF 0 "register_operand" "")
9630         (neg:SF (match_operand:SF 1 "register_operand" "")))
9631    (use (match_operand:V4SF 2 "" ""))
9632    (clobber (reg:CC 17))]
9633   "reload_completed && !SSE_REG_P (operands[0])"
9634   [(parallel [(set (match_dup 0)
9635                    (neg:SF (match_dup 1)))
9636               (clobber (reg:CC 17))])])
9637
9638 (define_split
9639   [(set (match_operand:SF 0 "register_operand" "")
9640         (neg:SF (match_operand:SF 1 "register_operand" "")))
9641    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9642    (clobber (reg:CC 17))]
9643   "reload_completed && SSE_REG_P (operands[0])"
9644   [(set (subreg:TI (match_dup 0) 0)
9645         (xor:TI (match_dup 1)
9646                 (match_dup 2)))]
9647 {
9648   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9649   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9650   if (operands_match_p (operands[0], operands[2]))
9651     {
9652       rtx tmp;
9653       tmp = operands[1];
9654       operands[1] = operands[2];
9655       operands[2] = tmp;
9656     }
9657 })
9658
9659
9660 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9661 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9662 ;; to itself.
9663 (define_insn "*negsf2_if"
9664   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9665         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9666    (clobber (reg:CC 17))]
9667   "TARGET_80387 && !TARGET_SSE
9668    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9669   "#")
9670
9671 (define_split
9672   [(set (match_operand:SF 0 "fp_register_operand" "")
9673         (neg:SF (match_operand:SF 1 "register_operand" "")))
9674    (clobber (reg:CC 17))]
9675   "TARGET_80387 && reload_completed"
9676   [(set (match_dup 0)
9677         (neg:SF (match_dup 1)))]
9678   "")
9679
9680 (define_split
9681   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9682         (neg:SF (match_operand:SF 1 "register_operand" "")))
9683    (clobber (reg:CC 17))]
9684   "TARGET_80387 && reload_completed"
9685   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9686               (clobber (reg:CC 17))])]
9687   "operands[1] = gen_int_mode (0x80000000, SImode);
9688    operands[0] = gen_lowpart (SImode, operands[0]);")
9689
9690 (define_split
9691   [(set (match_operand 0 "memory_operand" "")
9692         (neg (match_operand 1 "memory_operand" "")))
9693    (clobber (reg:CC 17))]
9694   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9695   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9696               (clobber (reg:CC 17))])]
9697 {
9698   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9699
9700   if (GET_MODE (operands[1]) == XFmode)
9701     size = 10;
9702   operands[0] = adjust_address (operands[0], QImode, size - 1);
9703   operands[1] = gen_int_mode (0x80, QImode);
9704 })
9705
9706 (define_expand "negdf2"
9707   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9708                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9709               (clobber (reg:CC 17))])]
9710   "TARGET_80387"
9711   "if (TARGET_SSE2)
9712      {
9713        /* In case operand is in memory,  we will not use SSE.  */
9714        if (memory_operand (operands[0], VOIDmode)
9715            && rtx_equal_p (operands[0], operands[1]))
9716          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9717        else
9718         {
9719           /* Using SSE is tricky, since we need bitwise negation of -0
9720              in register.  */
9721           rtx reg;
9722 #if HOST_BITS_PER_WIDE_INT >= 64
9723           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9724 #else
9725           rtx imm = immed_double_const (0, 0x80000000, DImode);
9726 #endif
9727           rtx dest = operands[0];
9728
9729           operands[1] = force_reg (DFmode, operands[1]);
9730           operands[0] = force_reg (DFmode, operands[0]);
9731           imm = gen_lowpart (DFmode, imm);
9732           reg = force_reg (V2DFmode,
9733                            gen_rtx_CONST_VECTOR (V2DFmode,
9734                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9735           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9736           if (dest != operands[0])
9737             emit_move_insn (dest, operands[0]);
9738         }
9739        DONE;
9740      }
9741    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9742
9743 (define_insn "negdf2_memory"
9744   [(set (match_operand:DF 0 "memory_operand" "=m")
9745         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9746    (clobber (reg:CC 17))]
9747   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9748   "#")
9749
9750 (define_insn "negdf2_ifs"
9751   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9752         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9753    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9754    (clobber (reg:CC 17))]
9755   "!TARGET_64BIT && TARGET_SSE2
9756    && (reload_in_progress || reload_completed
9757        || (register_operand (operands[0], VOIDmode)
9758            && register_operand (operands[1], VOIDmode)))"
9759   "#")
9760
9761 (define_insn "*negdf2_ifs_rex64"
9762   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9763         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9764    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9765    (clobber (reg:CC 17))]
9766   "TARGET_64BIT && TARGET_SSE2
9767    && (reload_in_progress || reload_completed
9768        || (register_operand (operands[0], VOIDmode)
9769            && register_operand (operands[1], VOIDmode)))"
9770   "#")
9771
9772 (define_split
9773   [(set (match_operand:DF 0 "memory_operand" "")
9774         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9775    (use (match_operand:V2DF 2 "" ""))
9776    (clobber (reg:CC 17))]
9777   ""
9778   [(parallel [(set (match_dup 0)
9779                    (neg:DF (match_dup 1)))
9780               (clobber (reg:CC 17))])])
9781
9782 (define_split
9783   [(set (match_operand:DF 0 "register_operand" "")
9784         (neg:DF (match_operand:DF 1 "register_operand" "")))
9785    (use (match_operand:V2DF 2 "" ""))
9786    (clobber (reg:CC 17))]
9787   "reload_completed && !SSE_REG_P (operands[0])
9788    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9789   [(parallel [(set (match_dup 0)
9790                    (neg:DF (match_dup 1)))
9791               (clobber (reg:CC 17))])])
9792
9793 (define_split
9794   [(set (match_operand:DF 0 "register_operand" "")
9795         (neg:DF (match_operand:DF 1 "register_operand" "")))
9796    (use (match_operand:V2DF 2 "" ""))
9797    (clobber (reg:CC 17))]
9798   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9799   [(parallel [(set (match_dup 0)
9800                    (xor:DI (match_dup 1) (match_dup 2)))
9801               (clobber (reg:CC 17))])]
9802    "operands[0] = gen_lowpart (DImode, operands[0]);
9803     operands[1] = gen_lowpart (DImode, operands[1]);
9804     operands[2] = gen_lowpart (DImode, operands[2]);")
9805
9806 (define_split
9807   [(set (match_operand:DF 0 "register_operand" "")
9808         (neg:DF (match_operand:DF 1 "register_operand" "")))
9809    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9810    (clobber (reg:CC 17))]
9811   "reload_completed && SSE_REG_P (operands[0])"
9812   [(set (subreg:TI (match_dup 0) 0)
9813         (xor:TI (match_dup 1)
9814                 (match_dup 2)))]
9815 {
9816   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9817   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9818   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9819   /* Avoid possible reformatting on the operands.  */
9820   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9821     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9822   if (operands_match_p (operands[0], operands[2]))
9823     {
9824       rtx tmp;
9825       tmp = operands[1];
9826       operands[1] = operands[2];
9827       operands[2] = tmp;
9828     }
9829 })
9830
9831 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9832 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9833 ;; to itself.
9834 (define_insn "*negdf2_if"
9835   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9836         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9837    (clobber (reg:CC 17))]
9838   "!TARGET_64BIT && TARGET_80387
9839    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9840   "#")
9841
9842 ;; FIXME: We should to allow integer registers here.  Problem is that
9843 ;; we need another scratch register to get constant from.
9844 ;; Forcing constant to mem if no register available in peep2 should be
9845 ;; safe even for PIC mode, because of RIP relative addressing.
9846 (define_insn "*negdf2_if_rex64"
9847   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9848         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9849    (clobber (reg:CC 17))]
9850   "TARGET_64BIT && TARGET_80387
9851    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9852   "#")
9853
9854 (define_split
9855   [(set (match_operand:DF 0 "fp_register_operand" "")
9856         (neg:DF (match_operand:DF 1 "register_operand" "")))
9857    (clobber (reg:CC 17))]
9858   "TARGET_80387 && reload_completed"
9859   [(set (match_dup 0)
9860         (neg:DF (match_dup 1)))]
9861   "")
9862
9863 (define_split
9864   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9865         (neg:DF (match_operand:DF 1 "register_operand" "")))
9866    (clobber (reg:CC 17))]
9867   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9868   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9869               (clobber (reg:CC 17))])]
9870   "operands[4] = gen_int_mode (0x80000000, SImode);
9871    split_di (operands+0, 1, operands+2, operands+3);")
9872
9873 (define_expand "negxf2"
9874   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9875                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9876               (clobber (reg:CC 17))])]
9877   "TARGET_80387"
9878   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9879
9880 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9881 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9882 ;; to itself.
9883 (define_insn "*negxf2_if"
9884   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9885         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9886    (clobber (reg:CC 17))]
9887   "TARGET_80387
9888    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9889   "#")
9890
9891 (define_split
9892   [(set (match_operand:XF 0 "fp_register_operand" "")
9893         (neg:XF (match_operand:XF 1 "register_operand" "")))
9894    (clobber (reg:CC 17))]
9895   "TARGET_80387 && reload_completed"
9896   [(set (match_dup 0)
9897         (neg:XF (match_dup 1)))]
9898   "")
9899
9900 (define_split
9901   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9902         (neg:XF (match_operand:XF 1 "register_operand" "")))
9903    (clobber (reg:CC 17))]
9904   "TARGET_80387 && reload_completed"
9905   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9906               (clobber (reg:CC 17))])]
9907   "operands[1] = GEN_INT (0x8000);
9908    operands[0] = gen_rtx_REG (SImode,
9909                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9910
9911 ;; Conditionalize these after reload. If they matches before reload, we 
9912 ;; lose the clobber and ability to use integer instructions.
9913
9914 (define_insn "*negsf2_1"
9915   [(set (match_operand:SF 0 "register_operand" "=f")
9916         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9917   "TARGET_80387 && reload_completed"
9918   "fchs"
9919   [(set_attr "type" "fsgn")
9920    (set_attr "mode" "SF")
9921    (set_attr "ppro_uops" "few")])
9922
9923 (define_insn "*negdf2_1"
9924   [(set (match_operand:DF 0 "register_operand" "=f")
9925         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9926   "TARGET_80387 && reload_completed"
9927   "fchs"
9928   [(set_attr "type" "fsgn")
9929    (set_attr "mode" "DF")
9930    (set_attr "ppro_uops" "few")])
9931
9932 (define_insn "*negextendsfdf2"
9933   [(set (match_operand:DF 0 "register_operand" "=f")
9934         (neg:DF (float_extend:DF
9935                   (match_operand:SF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "DF")
9940    (set_attr "ppro_uops" "few")])
9941
9942 (define_insn "*negxf2_1"
9943   [(set (match_operand:XF 0 "register_operand" "=f")
9944         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9945   "TARGET_80387 && reload_completed"
9946   "fchs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "XF")
9949    (set_attr "ppro_uops" "few")])
9950
9951 (define_insn "*negextenddfxf2"
9952   [(set (match_operand:XF 0 "register_operand" "=f")
9953         (neg:XF (float_extend:XF
9954                   (match_operand:DF 1 "register_operand" "0"))))]
9955   "TARGET_80387"
9956   "fchs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "XF")
9959    (set_attr "ppro_uops" "few")])
9960
9961 (define_insn "*negextendsfxf2"
9962   [(set (match_operand:XF 0 "register_operand" "=f")
9963         (neg:XF (float_extend:XF
9964                   (match_operand:SF 1 "register_operand" "0"))))]
9965   "TARGET_80387"
9966   "fchs"
9967   [(set_attr "type" "fsgn")
9968    (set_attr "mode" "XF")
9969    (set_attr "ppro_uops" "few")])
9970 \f
9971 ;; Absolute value instructions
9972
9973 (define_expand "abssf2"
9974   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9975                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9976               (clobber (reg:CC 17))])]
9977   "TARGET_80387"
9978   "if (TARGET_SSE)
9979      {
9980        /* In case operand is in memory,  we will not use SSE.  */
9981        if (memory_operand (operands[0], VOIDmode)
9982            && rtx_equal_p (operands[0], operands[1]))
9983          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9984        else
9985         {
9986           /* Using SSE is tricky, since we need bitwise negation of -0
9987              in register.  */
9988           rtx reg = gen_reg_rtx (V4SFmode);
9989           rtx dest = operands[0];
9990           rtx imm;
9991
9992           operands[1] = force_reg (SFmode, operands[1]);
9993           operands[0] = force_reg (SFmode, operands[0]);
9994           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9995           reg = force_reg (V4SFmode,
9996                            gen_rtx_CONST_VECTOR (V4SFmode,
9997                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9998                                       CONST0_RTX (SFmode),
9999                                       CONST0_RTX (SFmode))));
10000           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10001           if (dest != operands[0])
10002             emit_move_insn (dest, operands[0]);
10003         }
10004        DONE;
10005      }
10006    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10007
10008 (define_insn "abssf2_memory"
10009   [(set (match_operand:SF 0 "memory_operand" "=m")
10010         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10011    (clobber (reg:CC 17))]
10012   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10013   "#")
10014
10015 (define_insn "abssf2_ifs"
10016   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10017         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10018    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10019    (clobber (reg:CC 17))]
10020   "TARGET_SSE
10021    && (reload_in_progress || reload_completed
10022        || (register_operand (operands[0], VOIDmode)
10023             && register_operand (operands[1], VOIDmode)))"
10024   "#")
10025
10026 (define_split
10027   [(set (match_operand:SF 0 "memory_operand" "")
10028         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10029    (use (match_operand:V4SF 2 "" ""))
10030    (clobber (reg:CC 17))]
10031   ""
10032   [(parallel [(set (match_dup 0)
10033                    (abs:SF (match_dup 1)))
10034               (clobber (reg:CC 17))])])
10035
10036 (define_split
10037   [(set (match_operand:SF 0 "register_operand" "")
10038         (abs:SF (match_operand:SF 1 "register_operand" "")))
10039    (use (match_operand:V4SF 2 "" ""))
10040    (clobber (reg:CC 17))]
10041   "reload_completed && !SSE_REG_P (operands[0])"
10042   [(parallel [(set (match_dup 0)
10043                    (abs:SF (match_dup 1)))
10044               (clobber (reg:CC 17))])])
10045
10046 (define_split
10047   [(set (match_operand:SF 0 "register_operand" "")
10048         (abs:SF (match_operand:SF 1 "register_operand" "")))
10049    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10050    (clobber (reg:CC 17))]
10051   "reload_completed && SSE_REG_P (operands[0])"
10052   [(set (subreg:TI (match_dup 0) 0)
10053         (and:TI (match_dup 1)
10054                 (match_dup 2)))]
10055 {
10056   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10057   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10058   if (operands_match_p (operands[0], operands[2]))
10059     {
10060       rtx tmp;
10061       tmp = operands[1];
10062       operands[1] = operands[2];
10063       operands[2] = tmp;
10064     }
10065 })
10066
10067 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10068 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10069 ;; to itself.
10070 (define_insn "*abssf2_if"
10071   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10072         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10073    (clobber (reg:CC 17))]
10074   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10075   "#")
10076
10077 (define_split
10078   [(set (match_operand:SF 0 "fp_register_operand" "")
10079         (abs:SF (match_operand:SF 1 "register_operand" "")))
10080    (clobber (reg:CC 17))]
10081   "TARGET_80387 && reload_completed"
10082   [(set (match_dup 0)
10083         (abs:SF (match_dup 1)))]
10084   "")
10085
10086 (define_split
10087   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10088         (abs:SF (match_operand:SF 1 "register_operand" "")))
10089    (clobber (reg:CC 17))]
10090   "TARGET_80387 && reload_completed"
10091   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10092               (clobber (reg:CC 17))])]
10093   "operands[1] = gen_int_mode (~0x80000000, SImode);
10094    operands[0] = gen_lowpart (SImode, operands[0]);")
10095
10096 (define_split
10097   [(set (match_operand 0 "memory_operand" "")
10098         (abs (match_operand 1 "memory_operand" "")))
10099    (clobber (reg:CC 17))]
10100   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10101   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10102               (clobber (reg:CC 17))])]
10103 {
10104   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10105
10106   if (GET_MODE (operands[1]) == XFmode)
10107     size = 10;
10108   operands[0] = adjust_address (operands[0], QImode, size - 1);
10109   operands[1] = gen_int_mode (~0x80, QImode);
10110 })
10111
10112 (define_expand "absdf2"
10113   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10114                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10115               (clobber (reg:CC 17))])]
10116   "TARGET_80387"
10117   "if (TARGET_SSE2)
10118      {
10119        /* In case operand is in memory,  we will not use SSE.  */
10120        if (memory_operand (operands[0], VOIDmode)
10121            && rtx_equal_p (operands[0], operands[1]))
10122          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10123        else
10124         {
10125           /* Using SSE is tricky, since we need bitwise negation of -0
10126              in register.  */
10127           rtx reg = gen_reg_rtx (V2DFmode);
10128 #if HOST_BITS_PER_WIDE_INT >= 64
10129           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10130 #else
10131           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10132 #endif
10133           rtx dest = operands[0];
10134
10135           operands[1] = force_reg (DFmode, operands[1]);
10136           operands[0] = force_reg (DFmode, operands[0]);
10137
10138           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10139           imm = gen_lowpart (DFmode, imm);
10140           reg = force_reg (V2DFmode,
10141                            gen_rtx_CONST_VECTOR (V2DFmode,
10142                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10143           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10144           if (dest != operands[0])
10145             emit_move_insn (dest, operands[0]);
10146         }
10147        DONE;
10148      }
10149    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10150
10151 (define_insn "absdf2_memory"
10152   [(set (match_operand:DF 0 "memory_operand" "=m")
10153         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10154    (clobber (reg:CC 17))]
10155   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10156   "#")
10157
10158 (define_insn "absdf2_ifs"
10159   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10160         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10161    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10162    (clobber (reg:CC 17))]
10163   "!TARGET_64BIT && TARGET_SSE2
10164    && (reload_in_progress || reload_completed
10165        || (register_operand (operands[0], VOIDmode)
10166            && register_operand (operands[1], VOIDmode)))"
10167   "#")
10168
10169 (define_insn "*absdf2_ifs_rex64"
10170   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10171         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10172    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10173    (clobber (reg:CC 17))]
10174   "TARGET_64BIT && TARGET_SSE2
10175    && (reload_in_progress || reload_completed
10176        || (register_operand (operands[0], VOIDmode)
10177            && register_operand (operands[1], VOIDmode)))"
10178   "#")
10179
10180 (define_split
10181   [(set (match_operand:DF 0 "memory_operand" "")
10182         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10183    (use (match_operand:V2DF 2 "" ""))
10184    (clobber (reg:CC 17))]
10185   ""
10186   [(parallel [(set (match_dup 0)
10187                    (abs:DF (match_dup 1)))
10188               (clobber (reg:CC 17))])])
10189
10190 (define_split
10191   [(set (match_operand:DF 0 "register_operand" "")
10192         (abs:DF (match_operand:DF 1 "register_operand" "")))
10193    (use (match_operand:V2DF 2 "" ""))
10194    (clobber (reg:CC 17))]
10195   "reload_completed && !SSE_REG_P (operands[0])"
10196   [(parallel [(set (match_dup 0)
10197                    (abs:DF (match_dup 1)))
10198               (clobber (reg:CC 17))])])
10199
10200 (define_split
10201   [(set (match_operand:DF 0 "register_operand" "")
10202         (abs:DF (match_operand:DF 1 "register_operand" "")))
10203    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10204    (clobber (reg:CC 17))]
10205   "reload_completed && SSE_REG_P (operands[0])"
10206   [(set (subreg:TI (match_dup 0) 0)
10207         (and:TI (match_dup 1)
10208                 (match_dup 2)))]
10209 {
10210   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10211   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10212   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10213   /* Avoid possible reformatting on the operands.  */
10214   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10215     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10216   if (operands_match_p (operands[0], operands[2]))
10217     {
10218       rtx tmp;
10219       tmp = operands[1];
10220       operands[1] = operands[2];
10221       operands[2] = tmp;
10222     }
10223 })
10224
10225
10226 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10227 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10228 ;; to itself.
10229 (define_insn "*absdf2_if"
10230   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10231         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10232    (clobber (reg:CC 17))]
10233   "!TARGET_64BIT && TARGET_80387
10234    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10235   "#")
10236
10237 ;; FIXME: We should to allow integer registers here.  Problem is that
10238 ;; we need another scratch register to get constant from.
10239 ;; Forcing constant to mem if no register available in peep2 should be
10240 ;; safe even for PIC mode, because of RIP relative addressing.
10241 (define_insn "*absdf2_if_rex64"
10242   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10243         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10244    (clobber (reg:CC 17))]
10245   "TARGET_64BIT && TARGET_80387
10246    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10247   "#")
10248
10249 (define_split
10250   [(set (match_operand:DF 0 "fp_register_operand" "")
10251         (abs:DF (match_operand:DF 1 "register_operand" "")))
10252    (clobber (reg:CC 17))]
10253   "TARGET_80387 && reload_completed"
10254   [(set (match_dup 0)
10255         (abs:DF (match_dup 1)))]
10256   "")
10257
10258 (define_split
10259   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10260         (abs:DF (match_operand:DF 1 "register_operand" "")))
10261    (clobber (reg:CC 17))]
10262   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10263   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10264               (clobber (reg:CC 17))])]
10265   "operands[4] = gen_int_mode (~0x80000000, SImode);
10266    split_di (operands+0, 1, operands+2, operands+3);")
10267
10268 (define_expand "absxf2"
10269   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10270                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10271               (clobber (reg:CC 17))])]
10272   "TARGET_80387"
10273   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10274
10275 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10276 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10277 ;; to itself.
10278 (define_insn "*absxf2_if"
10279   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10280         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10281    (clobber (reg:CC 17))]
10282   "TARGET_80387
10283    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10284   "#")
10285
10286 (define_split
10287   [(set (match_operand:XF 0 "fp_register_operand" "")
10288         (abs:XF (match_operand:XF 1 "register_operand" "")))
10289    (clobber (reg:CC 17))]
10290   "TARGET_80387 && reload_completed"
10291   [(set (match_dup 0)
10292         (abs:XF (match_dup 1)))]
10293   "")
10294
10295 (define_split
10296   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10297         (abs:XF (match_operand:XF 1 "register_operand" "")))
10298    (clobber (reg:CC 17))]
10299   "TARGET_80387 && reload_completed"
10300   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10301               (clobber (reg:CC 17))])]
10302   "operands[1] = GEN_INT (~0x8000);
10303    operands[0] = gen_rtx_REG (SImode,
10304                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10305
10306 (define_insn "*abssf2_1"
10307   [(set (match_operand:SF 0 "register_operand" "=f")
10308         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10309   "TARGET_80387 && reload_completed"
10310   "fabs"
10311   [(set_attr "type" "fsgn")
10312    (set_attr "mode" "SF")])
10313
10314 (define_insn "*absdf2_1"
10315   [(set (match_operand:DF 0 "register_operand" "=f")
10316         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10317   "TARGET_80387 && reload_completed"
10318   "fabs"
10319   [(set_attr "type" "fsgn")
10320    (set_attr "mode" "DF")])
10321
10322 (define_insn "*absextendsfdf2"
10323   [(set (match_operand:DF 0 "register_operand" "=f")
10324         (abs:DF (float_extend:DF
10325                   (match_operand:SF 1 "register_operand" "0"))))]
10326   "TARGET_80387"
10327   "fabs"
10328   [(set_attr "type" "fsgn")
10329    (set_attr "mode" "DF")])
10330
10331 (define_insn "*absxf2_1"
10332   [(set (match_operand:XF 0 "register_operand" "=f")
10333         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10334   "TARGET_80387 && reload_completed"
10335   "fabs"
10336   [(set_attr "type" "fsgn")
10337    (set_attr "mode" "DF")])
10338
10339 (define_insn "*absextenddfxf2"
10340   [(set (match_operand:XF 0 "register_operand" "=f")
10341         (abs:XF (float_extend:XF
10342           (match_operand:DF 1 "register_operand" "0"))))]
10343   "TARGET_80387"
10344   "fabs"
10345   [(set_attr "type" "fsgn")
10346    (set_attr "mode" "XF")])
10347
10348 (define_insn "*absextendsfxf2"
10349   [(set (match_operand:XF 0 "register_operand" "=f")
10350         (abs:XF (float_extend:XF
10351           (match_operand:SF 1 "register_operand" "0"))))]
10352   "TARGET_80387"
10353   "fabs"
10354   [(set_attr "type" "fsgn")
10355    (set_attr "mode" "XF")])
10356 \f
10357 ;; One complement instructions
10358
10359 (define_expand "one_cmpldi2"
10360   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10361         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10362   "TARGET_64BIT"
10363   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10364
10365 (define_insn "*one_cmpldi2_1_rex64"
10366   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10367         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10368   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10369   "not{q}\t%0"
10370   [(set_attr "type" "negnot")
10371    (set_attr "mode" "DI")])
10372
10373 (define_insn "*one_cmpldi2_2_rex64"
10374   [(set (reg 17)
10375         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10376                  (const_int 0)))
10377    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10378         (not:DI (match_dup 1)))]
10379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10380    && ix86_unary_operator_ok (NOT, DImode, operands)"
10381   "#"
10382   [(set_attr "type" "alu1")
10383    (set_attr "mode" "DI")])
10384
10385 (define_split
10386   [(set (reg 17)
10387         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10388                  (const_int 0)))
10389    (set (match_operand:DI 0 "nonimmediate_operand" "")
10390         (not:DI (match_dup 1)))]
10391   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10392   [(parallel [(set (reg:CCNO 17)
10393                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10394                                  (const_int 0)))
10395               (set (match_dup 0)
10396                    (xor:DI (match_dup 1) (const_int -1)))])]
10397   "")
10398
10399 (define_expand "one_cmplsi2"
10400   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10401         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10402   ""
10403   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10404
10405 (define_insn "*one_cmplsi2_1"
10406   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10407         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10408   "ix86_unary_operator_ok (NOT, SImode, operands)"
10409   "not{l}\t%0"
10410   [(set_attr "type" "negnot")
10411    (set_attr "mode" "SI")])
10412
10413 ;; ??? Currently never generated - xor is used instead.
10414 (define_insn "*one_cmplsi2_1_zext"
10415   [(set (match_operand:DI 0 "register_operand" "=r")
10416         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10417   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10418   "not{l}\t%k0"
10419   [(set_attr "type" "negnot")
10420    (set_attr "mode" "SI")])
10421
10422 (define_insn "*one_cmplsi2_2"
10423   [(set (reg 17)
10424         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10425                  (const_int 0)))
10426    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10427         (not:SI (match_dup 1)))]
10428   "ix86_match_ccmode (insn, CCNOmode)
10429    && ix86_unary_operator_ok (NOT, SImode, operands)"
10430   "#"
10431   [(set_attr "type" "alu1")
10432    (set_attr "mode" "SI")])
10433
10434 (define_split
10435   [(set (reg 17)
10436         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10437                  (const_int 0)))
10438    (set (match_operand:SI 0 "nonimmediate_operand" "")
10439         (not:SI (match_dup 1)))]
10440   "ix86_match_ccmode (insn, CCNOmode)"
10441   [(parallel [(set (reg:CCNO 17)
10442                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10443                                  (const_int 0)))
10444               (set (match_dup 0)
10445                    (xor:SI (match_dup 1) (const_int -1)))])]
10446   "")
10447
10448 ;; ??? Currently never generated - xor is used instead.
10449 (define_insn "*one_cmplsi2_2_zext"
10450   [(set (reg 17)
10451         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10452                  (const_int 0)))
10453    (set (match_operand:DI 0 "register_operand" "=r")
10454         (zero_extend:DI (not:SI (match_dup 1))))]
10455   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10456    && ix86_unary_operator_ok (NOT, SImode, operands)"
10457   "#"
10458   [(set_attr "type" "alu1")
10459    (set_attr "mode" "SI")])
10460
10461 (define_split
10462   [(set (reg 17)
10463         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10464                  (const_int 0)))
10465    (set (match_operand:DI 0 "register_operand" "")
10466         (zero_extend:DI (not:SI (match_dup 1))))]
10467   "ix86_match_ccmode (insn, CCNOmode)"
10468   [(parallel [(set (reg:CCNO 17)
10469                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10470                                  (const_int 0)))
10471               (set (match_dup 0)
10472                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10473   "")
10474
10475 (define_expand "one_cmplhi2"
10476   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10477         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10478   "TARGET_HIMODE_MATH"
10479   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10480
10481 (define_insn "*one_cmplhi2_1"
10482   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10483         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10484   "ix86_unary_operator_ok (NOT, HImode, operands)"
10485   "not{w}\t%0"
10486   [(set_attr "type" "negnot")
10487    (set_attr "mode" "HI")])
10488
10489 (define_insn "*one_cmplhi2_2"
10490   [(set (reg 17)
10491         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10492                  (const_int 0)))
10493    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10494         (not:HI (match_dup 1)))]
10495   "ix86_match_ccmode (insn, CCNOmode)
10496    && ix86_unary_operator_ok (NEG, HImode, operands)"
10497   "#"
10498   [(set_attr "type" "alu1")
10499    (set_attr "mode" "HI")])
10500
10501 (define_split
10502   [(set (reg 17)
10503         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10504                  (const_int 0)))
10505    (set (match_operand:HI 0 "nonimmediate_operand" "")
10506         (not:HI (match_dup 1)))]
10507   "ix86_match_ccmode (insn, CCNOmode)"
10508   [(parallel [(set (reg:CCNO 17)
10509                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10510                                  (const_int 0)))
10511               (set (match_dup 0)
10512                    (xor:HI (match_dup 1) (const_int -1)))])]
10513   "")
10514
10515 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10516 (define_expand "one_cmplqi2"
10517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519   "TARGET_QIMODE_MATH"
10520   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10521
10522 (define_insn "*one_cmplqi2_1"
10523   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525   "ix86_unary_operator_ok (NOT, QImode, operands)"
10526   "@
10527    not{b}\t%0
10528    not{l}\t%k0"
10529   [(set_attr "type" "negnot")
10530    (set_attr "mode" "QI,SI")])
10531
10532 (define_insn "*one_cmplqi2_2"
10533   [(set (reg 17)
10534         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10535                  (const_int 0)))
10536    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537         (not:QI (match_dup 1)))]
10538   "ix86_match_ccmode (insn, CCNOmode)
10539    && ix86_unary_operator_ok (NOT, QImode, operands)"
10540   "#"
10541   [(set_attr "type" "alu1")
10542    (set_attr "mode" "QI")])
10543
10544 (define_split
10545   [(set (reg 17)
10546         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10547                  (const_int 0)))
10548    (set (match_operand:QI 0 "nonimmediate_operand" "")
10549         (not:QI (match_dup 1)))]
10550   "ix86_match_ccmode (insn, CCNOmode)"
10551   [(parallel [(set (reg:CCNO 17)
10552                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10553                                  (const_int 0)))
10554               (set (match_dup 0)
10555                    (xor:QI (match_dup 1) (const_int -1)))])]
10556   "")
10557 \f
10558 ;; Arithmetic shift instructions
10559
10560 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10561 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10562 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10563 ;; from the assembler input.
10564 ;;
10565 ;; This instruction shifts the target reg/mem as usual, but instead of
10566 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10567 ;; is a left shift double, bits are taken from the high order bits of
10568 ;; reg, else if the insn is a shift right double, bits are taken from the
10569 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10570 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10571 ;;
10572 ;; Since sh[lr]d does not change the `reg' operand, that is done
10573 ;; separately, making all shifts emit pairs of shift double and normal
10574 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10575 ;; support a 63 bit shift, each shift where the count is in a reg expands
10576 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10577 ;;
10578 ;; If the shift count is a constant, we need never emit more than one
10579 ;; shift pair, instead using moves and sign extension for counts greater
10580 ;; than 31.
10581
10582 (define_expand "ashldi3"
10583   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10584                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10585                               (match_operand:QI 2 "nonmemory_operand" "")))
10586               (clobber (reg:CC 17))])]
10587   ""
10588 {
10589   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10590     {
10591       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10592       DONE;
10593     }
10594   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10595   DONE;
10596 })
10597
10598 (define_insn "*ashldi3_1_rex64"
10599   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10600         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10601                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10602    (clobber (reg:CC 17))]
10603   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10604 {
10605   switch (get_attr_type (insn))
10606     {
10607     case TYPE_ALU:
10608       if (operands[2] != const1_rtx)
10609         abort ();
10610       if (!rtx_equal_p (operands[0], operands[1]))
10611         abort ();
10612       return "add{q}\t{%0, %0|%0, %0}";
10613
10614     case TYPE_LEA:
10615       if (GET_CODE (operands[2]) != CONST_INT
10616           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10617         abort ();
10618       operands[1] = gen_rtx_MULT (DImode, operands[1],
10619                                   GEN_INT (1 << INTVAL (operands[2])));
10620       return "lea{q}\t{%a1, %0|%0, %a1}";
10621
10622     default:
10623       if (REG_P (operands[2]))
10624         return "sal{q}\t{%b2, %0|%0, %b2}";
10625       else if (GET_CODE (operands[2]) == CONST_INT
10626                && INTVAL (operands[2]) == 1
10627                && (TARGET_SHIFT1 || optimize_size))
10628         return "sal{q}\t%0";
10629       else
10630         return "sal{q}\t{%2, %0|%0, %2}";
10631     }
10632 }
10633   [(set (attr "type")
10634      (cond [(eq_attr "alternative" "1")
10635               (const_string "lea")
10636             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10637                           (const_int 0))
10638                       (match_operand 0 "register_operand" ""))
10639                  (match_operand 2 "const1_operand" ""))
10640               (const_string "alu")
10641            ]
10642            (const_string "ishift")))
10643    (set_attr "mode" "DI")])
10644
10645 ;; Convert lea to the lea pattern to avoid flags dependency.
10646 (define_split
10647   [(set (match_operand:DI 0 "register_operand" "")
10648         (ashift:DI (match_operand:DI 1 "register_operand" "")
10649                    (match_operand:QI 2 "immediate_operand" "")))
10650    (clobber (reg:CC 17))]
10651   "TARGET_64BIT && reload_completed
10652    && true_regnum (operands[0]) != true_regnum (operands[1])"
10653   [(set (match_dup 0)
10654         (mult:DI (match_dup 1)
10655                  (match_dup 2)))]
10656   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10657
10658 ;; This pattern can't accept a variable shift count, since shifts by
10659 ;; zero don't affect the flags.  We assume that shifts by constant
10660 ;; zero are optimized away.
10661 (define_insn "*ashldi3_cmp_rex64"
10662   [(set (reg 17)
10663         (compare
10664           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10665                      (match_operand:QI 2 "immediate_operand" "e"))
10666           (const_int 0)))
10667    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10668         (ashift:DI (match_dup 1) (match_dup 2)))]
10669   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10670    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10671 {
10672   switch (get_attr_type (insn))
10673     {
10674     case TYPE_ALU:
10675       if (operands[2] != const1_rtx)
10676         abort ();
10677       return "add{q}\t{%0, %0|%0, %0}";
10678
10679     default:
10680       if (REG_P (operands[2]))
10681         return "sal{q}\t{%b2, %0|%0, %b2}";
10682       else if (GET_CODE (operands[2]) == CONST_INT
10683                && INTVAL (operands[2]) == 1
10684                && (TARGET_SHIFT1 || optimize_size))
10685         return "sal{q}\t%0";
10686       else
10687         return "sal{q}\t{%2, %0|%0, %2}";
10688     }
10689 }
10690   [(set (attr "type")
10691      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10692                           (const_int 0))
10693                       (match_operand 0 "register_operand" ""))
10694                  (match_operand 2 "const1_operand" ""))
10695               (const_string "alu")
10696            ]
10697            (const_string "ishift")))
10698    (set_attr "mode" "DI")])
10699
10700 (define_insn "ashldi3_1"
10701   [(set (match_operand:DI 0 "register_operand" "=r")
10702         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10703                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10704    (clobber (match_scratch:SI 3 "=&r"))
10705    (clobber (reg:CC 17))]
10706   "!TARGET_64BIT && TARGET_CMOVE"
10707   "#"
10708   [(set_attr "type" "multi")])
10709
10710 (define_insn "*ashldi3_2"
10711   [(set (match_operand:DI 0 "register_operand" "=r")
10712         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10713                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10714    (clobber (reg:CC 17))]
10715   "!TARGET_64BIT"
10716   "#"
10717   [(set_attr "type" "multi")])
10718
10719 (define_split
10720   [(set (match_operand:DI 0 "register_operand" "")
10721         (ashift:DI (match_operand:DI 1 "register_operand" "")
10722                    (match_operand:QI 2 "nonmemory_operand" "")))
10723    (clobber (match_scratch:SI 3 ""))
10724    (clobber (reg:CC 17))]
10725   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10726   [(const_int 0)]
10727   "ix86_split_ashldi (operands, operands[3]); DONE;")
10728
10729 (define_split
10730   [(set (match_operand:DI 0 "register_operand" "")
10731         (ashift:DI (match_operand:DI 1 "register_operand" "")
10732                    (match_operand:QI 2 "nonmemory_operand" "")))
10733    (clobber (reg:CC 17))]
10734   "!TARGET_64BIT && reload_completed"
10735   [(const_int 0)]
10736   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10737
10738 (define_insn "x86_shld_1"
10739   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10740         (ior:SI (ashift:SI (match_dup 0)
10741                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10742                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10743                   (minus:QI (const_int 32) (match_dup 2)))))
10744    (clobber (reg:CC 17))]
10745   ""
10746   "@
10747    shld{l}\t{%2, %1, %0|%0, %1, %2}
10748    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10749   [(set_attr "type" "ishift")
10750    (set_attr "prefix_0f" "1")
10751    (set_attr "mode" "SI")
10752    (set_attr "pent_pair" "np")
10753    (set_attr "athlon_decode" "vector")
10754    (set_attr "ppro_uops" "few")])
10755
10756 (define_expand "x86_shift_adj_1"
10757   [(set (reg:CCZ 17)
10758         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10759                              (const_int 32))
10760                      (const_int 0)))
10761    (set (match_operand:SI 0 "register_operand" "")
10762         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10763                          (match_operand:SI 1 "register_operand" "")
10764                          (match_dup 0)))
10765    (set (match_dup 1)
10766         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10767                          (match_operand:SI 3 "register_operand" "r")
10768                          (match_dup 1)))]
10769   "TARGET_CMOVE"
10770   "")
10771
10772 (define_expand "x86_shift_adj_2"
10773   [(use (match_operand:SI 0 "register_operand" ""))
10774    (use (match_operand:SI 1 "register_operand" ""))
10775    (use (match_operand:QI 2 "register_operand" ""))]
10776   ""
10777 {
10778   rtx label = gen_label_rtx ();
10779   rtx tmp;
10780
10781   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10782
10783   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10784   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10785   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10786                               gen_rtx_LABEL_REF (VOIDmode, label),
10787                               pc_rtx);
10788   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10789   JUMP_LABEL (tmp) = label;
10790
10791   emit_move_insn (operands[0], operands[1]);
10792   emit_move_insn (operands[1], const0_rtx);
10793
10794   emit_label (label);
10795   LABEL_NUSES (label) = 1;
10796
10797   DONE;
10798 })
10799
10800 (define_expand "ashlsi3"
10801   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10802         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10803                    (match_operand:QI 2 "nonmemory_operand" "")))
10804    (clobber (reg:CC 17))]
10805   ""
10806   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10807
10808 (define_insn "*ashlsi3_1"
10809   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10810         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10811                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10812    (clobber (reg:CC 17))]
10813   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10814 {
10815   switch (get_attr_type (insn))
10816     {
10817     case TYPE_ALU:
10818       if (operands[2] != const1_rtx)
10819         abort ();
10820       if (!rtx_equal_p (operands[0], operands[1]))
10821         abort ();
10822       return "add{l}\t{%0, %0|%0, %0}";
10823
10824     case TYPE_LEA:
10825       return "#";
10826
10827     default:
10828       if (REG_P (operands[2]))
10829         return "sal{l}\t{%b2, %0|%0, %b2}";
10830       else if (GET_CODE (operands[2]) == CONST_INT
10831                && INTVAL (operands[2]) == 1
10832                && (TARGET_SHIFT1 || optimize_size))
10833         return "sal{l}\t%0";
10834       else
10835         return "sal{l}\t{%2, %0|%0, %2}";
10836     }
10837 }
10838   [(set (attr "type")
10839      (cond [(eq_attr "alternative" "1")
10840               (const_string "lea")
10841             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842                           (const_int 0))
10843                       (match_operand 0 "register_operand" ""))
10844                  (match_operand 2 "const1_operand" ""))
10845               (const_string "alu")
10846            ]
10847            (const_string "ishift")))
10848    (set_attr "mode" "SI")])
10849
10850 ;; Convert lea to the lea pattern to avoid flags dependency.
10851 (define_split
10852   [(set (match_operand 0 "register_operand" "")
10853         (ashift (match_operand 1 "index_register_operand" "")
10854                 (match_operand:QI 2 "const_int_operand" "")))
10855    (clobber (reg:CC 17))]
10856   "reload_completed
10857    && true_regnum (operands[0]) != true_regnum (operands[1])"
10858   [(const_int 0)]
10859 {
10860   rtx pat;
10861   operands[0] = gen_lowpart (SImode, operands[0]);
10862   operands[1] = gen_lowpart (Pmode, operands[1]);
10863   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10864   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10865   if (Pmode != SImode)
10866     pat = gen_rtx_SUBREG (SImode, pat, 0);
10867   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10868   DONE;
10869 })
10870
10871 ;; Rare case of shifting RSP is handled by generating move and shift
10872 (define_split
10873   [(set (match_operand 0 "register_operand" "")
10874         (ashift (match_operand 1 "register_operand" "")
10875                 (match_operand:QI 2 "const_int_operand" "")))
10876    (clobber (reg:CC 17))]
10877   "reload_completed
10878    && true_regnum (operands[0]) != true_regnum (operands[1])"
10879   [(const_int 0)]
10880 {
10881   rtx pat, clob;
10882   emit_move_insn (operands[1], operands[0]);
10883   pat = gen_rtx_SET (VOIDmode, operands[0],
10884                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10885                                      operands[0], operands[2]));
10886   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10887   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10888   DONE;
10889 })
10890
10891 (define_insn "*ashlsi3_1_zext"
10892   [(set (match_operand:DI 0 "register_operand" "=r,r")
10893         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10894                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10895    (clobber (reg:CC 17))]
10896   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10897 {
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       if (operands[2] != const1_rtx)
10902         abort ();
10903       return "add{l}\t{%k0, %k0|%k0, %k0}";
10904
10905     case TYPE_LEA:
10906       return "#";
10907
10908     default:
10909       if (REG_P (operands[2]))
10910         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10911       else if (GET_CODE (operands[2]) == CONST_INT
10912                && INTVAL (operands[2]) == 1
10913                && (TARGET_SHIFT1 || optimize_size))
10914         return "sal{l}\t%k0";
10915       else
10916         return "sal{l}\t{%2, %k0|%k0, %2}";
10917     }
10918 }
10919   [(set (attr "type")
10920      (cond [(eq_attr "alternative" "1")
10921               (const_string "lea")
10922             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10923                      (const_int 0))
10924                  (match_operand 2 "const1_operand" ""))
10925               (const_string "alu")
10926            ]
10927            (const_string "ishift")))
10928    (set_attr "mode" "SI")])
10929
10930 ;; Convert lea to the lea pattern to avoid flags dependency.
10931 (define_split
10932   [(set (match_operand:DI 0 "register_operand" "")
10933         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10934                                 (match_operand:QI 2 "const_int_operand" ""))))
10935    (clobber (reg:CC 17))]
10936   "TARGET_64BIT && reload_completed
10937    && true_regnum (operands[0]) != true_regnum (operands[1])"
10938   [(set (match_dup 0) (zero_extend:DI
10939                         (subreg:SI (mult:SI (match_dup 1)
10940                                             (match_dup 2)) 0)))]
10941 {
10942   operands[1] = gen_lowpart (Pmode, operands[1]);
10943   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10944 })
10945
10946 ;; This pattern can't accept a variable shift count, since shifts by
10947 ;; zero don't affect the flags.  We assume that shifts by constant
10948 ;; zero are optimized away.
10949 (define_insn "*ashlsi3_cmp"
10950   [(set (reg 17)
10951         (compare
10952           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10953                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10954           (const_int 0)))
10955    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10956         (ashift:SI (match_dup 1) (match_dup 2)))]
10957   "ix86_match_ccmode (insn, CCGOCmode)
10958    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10959 {
10960   switch (get_attr_type (insn))
10961     {
10962     case TYPE_ALU:
10963       if (operands[2] != const1_rtx)
10964         abort ();
10965       return "add{l}\t{%0, %0|%0, %0}";
10966
10967     default:
10968       if (REG_P (operands[2]))
10969         return "sal{l}\t{%b2, %0|%0, %b2}";
10970       else if (GET_CODE (operands[2]) == CONST_INT
10971                && INTVAL (operands[2]) == 1
10972                && (TARGET_SHIFT1 || optimize_size))
10973         return "sal{l}\t%0";
10974       else
10975         return "sal{l}\t{%2, %0|%0, %2}";
10976     }
10977 }
10978   [(set (attr "type")
10979      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "SI")])
10987
10988 (define_insn "*ashlsi3_cmp_zext"
10989   [(set (reg 17)
10990         (compare
10991           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10992                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10993           (const_int 0)))
10994    (set (match_operand:DI 0 "register_operand" "=r")
10995         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10996   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10997    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10998 {
10999   switch (get_attr_type (insn))
11000     {
11001     case TYPE_ALU:
11002       if (operands[2] != const1_rtx)
11003         abort ();
11004       return "add{l}\t{%k0, %k0|%k0, %k0}";
11005
11006     default:
11007       if (REG_P (operands[2]))
11008         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11009       else if (GET_CODE (operands[2]) == CONST_INT
11010                && INTVAL (operands[2]) == 1
11011                && (TARGET_SHIFT1 || optimize_size))
11012         return "sal{l}\t%k0";
11013       else
11014         return "sal{l}\t{%2, %k0|%k0, %2}";
11015     }
11016 }
11017   [(set (attr "type")
11018      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11019                      (const_int 0))
11020                  (match_operand 2 "const1_operand" ""))
11021               (const_string "alu")
11022            ]
11023            (const_string "ishift")))
11024    (set_attr "mode" "SI")])
11025
11026 (define_expand "ashlhi3"
11027   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11028         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11029                    (match_operand:QI 2 "nonmemory_operand" "")))
11030    (clobber (reg:CC 17))]
11031   "TARGET_HIMODE_MATH"
11032   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11033
11034 (define_insn "*ashlhi3_1_lea"
11035   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11036         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11037                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11038    (clobber (reg:CC 17))]
11039   "!TARGET_PARTIAL_REG_STALL
11040    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11041 {
11042   switch (get_attr_type (insn))
11043     {
11044     case TYPE_LEA:
11045       return "#";
11046     case TYPE_ALU:
11047       if (operands[2] != const1_rtx)
11048         abort ();
11049       return "add{w}\t{%0, %0|%0, %0}";
11050
11051     default:
11052       if (REG_P (operands[2]))
11053         return "sal{w}\t{%b2, %0|%0, %b2}";
11054       else if (GET_CODE (operands[2]) == CONST_INT
11055                && INTVAL (operands[2]) == 1
11056                && (TARGET_SHIFT1 || optimize_size))
11057         return "sal{w}\t%0";
11058       else
11059         return "sal{w}\t{%2, %0|%0, %2}";
11060     }
11061 }
11062   [(set (attr "type")
11063      (cond [(eq_attr "alternative" "1")
11064               (const_string "lea")
11065             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066                           (const_int 0))
11067                       (match_operand 0 "register_operand" ""))
11068                  (match_operand 2 "const1_operand" ""))
11069               (const_string "alu")
11070            ]
11071            (const_string "ishift")))
11072    (set_attr "mode" "HI,SI")])
11073
11074 (define_insn "*ashlhi3_1"
11075   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11076         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11077                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11078    (clobber (reg:CC 17))]
11079   "TARGET_PARTIAL_REG_STALL
11080    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11081 {
11082   switch (get_attr_type (insn))
11083     {
11084     case TYPE_ALU:
11085       if (operands[2] != const1_rtx)
11086         abort ();
11087       return "add{w}\t{%0, %0|%0, %0}";
11088
11089     default:
11090       if (REG_P (operands[2]))
11091         return "sal{w}\t{%b2, %0|%0, %b2}";
11092       else if (GET_CODE (operands[2]) == CONST_INT
11093                && INTVAL (operands[2]) == 1
11094                && (TARGET_SHIFT1 || optimize_size))
11095         return "sal{w}\t%0";
11096       else
11097         return "sal{w}\t{%2, %0|%0, %2}";
11098     }
11099 }
11100   [(set (attr "type")
11101      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102                           (const_int 0))
11103                       (match_operand 0 "register_operand" ""))
11104                  (match_operand 2 "const1_operand" ""))
11105               (const_string "alu")
11106            ]
11107            (const_string "ishift")))
11108    (set_attr "mode" "HI")])
11109
11110 ;; This pattern can't accept a variable shift count, since shifts by
11111 ;; zero don't affect the flags.  We assume that shifts by constant
11112 ;; zero are optimized away.
11113 (define_insn "*ashlhi3_cmp"
11114   [(set (reg 17)
11115         (compare
11116           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11117                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11118           (const_int 0)))
11119    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11120         (ashift:HI (match_dup 1) (match_dup 2)))]
11121   "ix86_match_ccmode (insn, CCGOCmode)
11122    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11123 {
11124   switch (get_attr_type (insn))
11125     {
11126     case TYPE_ALU:
11127       if (operands[2] != const1_rtx)
11128         abort ();
11129       return "add{w}\t{%0, %0|%0, %0}";
11130
11131     default:
11132       if (REG_P (operands[2]))
11133         return "sal{w}\t{%b2, %0|%0, %b2}";
11134       else if (GET_CODE (operands[2]) == CONST_INT
11135                && INTVAL (operands[2]) == 1
11136                && (TARGET_SHIFT1 || optimize_size))
11137         return "sal{w}\t%0";
11138       else
11139         return "sal{w}\t{%2, %0|%0, %2}";
11140     }
11141 }
11142   [(set (attr "type")
11143      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11144                           (const_int 0))
11145                       (match_operand 0 "register_operand" ""))
11146                  (match_operand 2 "const1_operand" ""))
11147               (const_string "alu")
11148            ]
11149            (const_string "ishift")))
11150    (set_attr "mode" "HI")])
11151
11152 (define_expand "ashlqi3"
11153   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11154         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11155                    (match_operand:QI 2 "nonmemory_operand" "")))
11156    (clobber (reg:CC 17))]
11157   "TARGET_QIMODE_MATH"
11158   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11159
11160 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11161
11162 (define_insn "*ashlqi3_1_lea"
11163   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11164         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11165                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11166    (clobber (reg:CC 17))]
11167   "!TARGET_PARTIAL_REG_STALL
11168    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11169 {
11170   switch (get_attr_type (insn))
11171     {
11172     case TYPE_LEA:
11173       return "#";
11174     case TYPE_ALU:
11175       if (operands[2] != const1_rtx)
11176         abort ();
11177       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11178         return "add{l}\t{%k0, %k0|%k0, %k0}";
11179       else
11180         return "add{b}\t{%0, %0|%0, %0}";
11181
11182     default:
11183       if (REG_P (operands[2]))
11184         {
11185           if (get_attr_mode (insn) == MODE_SI)
11186             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11187           else
11188             return "sal{b}\t{%b2, %0|%0, %b2}";
11189         }
11190       else if (GET_CODE (operands[2]) == CONST_INT
11191                && INTVAL (operands[2]) == 1
11192                && (TARGET_SHIFT1 || optimize_size))
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t%0";
11196           else
11197             return "sal{b}\t%0";
11198         }
11199       else
11200         {
11201           if (get_attr_mode (insn) == MODE_SI)
11202             return "sal{l}\t{%2, %k0|%k0, %2}";
11203           else
11204             return "sal{b}\t{%2, %0|%0, %2}";
11205         }
11206     }
11207 }
11208   [(set (attr "type")
11209      (cond [(eq_attr "alternative" "2")
11210               (const_string "lea")
11211             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11212                           (const_int 0))
11213                       (match_operand 0 "register_operand" ""))
11214                  (match_operand 2 "const1_operand" ""))
11215               (const_string "alu")
11216            ]
11217            (const_string "ishift")))
11218    (set_attr "mode" "QI,SI,SI")])
11219
11220 (define_insn "*ashlqi3_1"
11221   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11222         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11223                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11224    (clobber (reg:CC 17))]
11225   "TARGET_PARTIAL_REG_STALL
11226    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11227 {
11228   switch (get_attr_type (insn))
11229     {
11230     case TYPE_ALU:
11231       if (operands[2] != const1_rtx)
11232         abort ();
11233       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11234         return "add{l}\t{%k0, %k0|%k0, %k0}";
11235       else
11236         return "add{b}\t{%0, %0|%0, %0}";
11237
11238     default:
11239       if (REG_P (operands[2]))
11240         {
11241           if (get_attr_mode (insn) == MODE_SI)
11242             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11243           else
11244             return "sal{b}\t{%b2, %0|%0, %b2}";
11245         }
11246       else if (GET_CODE (operands[2]) == CONST_INT
11247                && INTVAL (operands[2]) == 1
11248                && (TARGET_SHIFT1 || optimize_size))
11249         {
11250           if (get_attr_mode (insn) == MODE_SI)
11251             return "sal{l}\t%0";
11252           else
11253             return "sal{b}\t%0";
11254         }
11255       else
11256         {
11257           if (get_attr_mode (insn) == MODE_SI)
11258             return "sal{l}\t{%2, %k0|%k0, %2}";
11259           else
11260             return "sal{b}\t{%2, %0|%0, %2}";
11261         }
11262     }
11263 }
11264   [(set (attr "type")
11265      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11266                           (const_int 0))
11267                       (match_operand 0 "register_operand" ""))
11268                  (match_operand 2 "const1_operand" ""))
11269               (const_string "alu")
11270            ]
11271            (const_string "ishift")))
11272    (set_attr "mode" "QI,SI")])
11273
11274 ;; This pattern can't accept a variable shift count, since shifts by
11275 ;; zero don't affect the flags.  We assume that shifts by constant
11276 ;; zero are optimized away.
11277 (define_insn "*ashlqi3_cmp"
11278   [(set (reg 17)
11279         (compare
11280           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11281                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11282           (const_int 0)))
11283    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11284         (ashift:QI (match_dup 1) (match_dup 2)))]
11285   "ix86_match_ccmode (insn, CCGOCmode)
11286    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11287 {
11288   switch (get_attr_type (insn))
11289     {
11290     case TYPE_ALU:
11291       if (operands[2] != const1_rtx)
11292         abort ();
11293       return "add{b}\t{%0, %0|%0, %0}";
11294
11295     default:
11296       if (REG_P (operands[2]))
11297         return "sal{b}\t{%b2, %0|%0, %b2}";
11298       else if (GET_CODE (operands[2]) == CONST_INT
11299                && INTVAL (operands[2]) == 1
11300                && (TARGET_SHIFT1 || optimize_size))
11301         return "sal{b}\t%0";
11302       else
11303         return "sal{b}\t{%2, %0|%0, %2}";
11304     }
11305 }
11306   [(set (attr "type")
11307      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11308                           (const_int 0))
11309                       (match_operand 0 "register_operand" ""))
11310                  (match_operand 2 "const1_operand" ""))
11311               (const_string "alu")
11312            ]
11313            (const_string "ishift")))
11314    (set_attr "mode" "QI")])
11315
11316 ;; See comment above `ashldi3' about how this works.
11317
11318 (define_expand "ashrdi3"
11319   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11320                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11321                                 (match_operand:QI 2 "nonmemory_operand" "")))
11322               (clobber (reg:CC 17))])]
11323   ""
11324 {
11325   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11326     {
11327       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11328       DONE;
11329     }
11330   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11331   DONE;
11332 })
11333
11334 (define_insn "ashrdi3_63_rex64"
11335   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11336         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11337                      (match_operand:DI 2 "const_int_operand" "i,i")))
11338    (clobber (reg:CC 17))]
11339   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11340    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11341   "@
11342    {cqto|cqo}
11343    sar{q}\t{%2, %0|%0, %2}"
11344   [(set_attr "type" "imovx,ishift")
11345    (set_attr "prefix_0f" "0,*")
11346    (set_attr "length_immediate" "0,*")
11347    (set_attr "modrm" "0,1")
11348    (set_attr "mode" "DI")])
11349
11350 (define_insn "*ashrdi3_1_one_bit_rex64"
11351   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11352         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11353                      (match_operand:QI 2 "const1_operand" "")))
11354    (clobber (reg:CC 17))]
11355   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11356    && (TARGET_SHIFT1 || optimize_size)"
11357   "sar{q}\t%0"
11358   [(set_attr "type" "ishift")
11359    (set (attr "length") 
11360      (if_then_else (match_operand:DI 0 "register_operand" "") 
11361         (const_string "2")
11362         (const_string "*")))])
11363
11364 (define_insn "*ashrdi3_1_rex64"
11365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11366         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11367                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11368    (clobber (reg:CC 17))]
11369   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370   "@
11371    sar{q}\t{%2, %0|%0, %2}
11372    sar{q}\t{%b2, %0|%0, %b2}"
11373   [(set_attr "type" "ishift")
11374    (set_attr "mode" "DI")])
11375
11376 ;; This pattern can't accept a variable shift count, since shifts by
11377 ;; zero don't affect the flags.  We assume that shifts by constant
11378 ;; zero are optimized away.
11379 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11380   [(set (reg 17)
11381         (compare
11382           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11383                        (match_operand:QI 2 "const1_operand" ""))
11384           (const_int 0)))
11385    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11386         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11387   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11388    && (TARGET_SHIFT1 || optimize_size)
11389    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11390   "sar{q}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand:DI 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11396
11397 ;; This pattern can't accept a variable shift count, since shifts by
11398 ;; zero don't affect the flags.  We assume that shifts by constant
11399 ;; zero are optimized away.
11400 (define_insn "*ashrdi3_cmp_rex64"
11401   [(set (reg 17)
11402         (compare
11403           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404                        (match_operand:QI 2 "const_int_operand" "n"))
11405           (const_int 0)))
11406    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11407         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11408   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11409    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11410   "sar{q}\t{%2, %0|%0, %2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "DI")])
11413
11414
11415 (define_insn "ashrdi3_1"
11416   [(set (match_operand:DI 0 "register_operand" "=r")
11417         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11418                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11419    (clobber (match_scratch:SI 3 "=&r"))
11420    (clobber (reg:CC 17))]
11421   "!TARGET_64BIT && TARGET_CMOVE"
11422   "#"
11423   [(set_attr "type" "multi")])
11424
11425 (define_insn "*ashrdi3_2"
11426   [(set (match_operand:DI 0 "register_operand" "=r")
11427         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11428                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11429    (clobber (reg:CC 17))]
11430   "!TARGET_64BIT"
11431   "#"
11432   [(set_attr "type" "multi")])
11433
11434 (define_split
11435   [(set (match_operand:DI 0 "register_operand" "")
11436         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11437                      (match_operand:QI 2 "nonmemory_operand" "")))
11438    (clobber (match_scratch:SI 3 ""))
11439    (clobber (reg:CC 17))]
11440   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11441   [(const_int 0)]
11442   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11443
11444 (define_split
11445   [(set (match_operand:DI 0 "register_operand" "")
11446         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11447                      (match_operand:QI 2 "nonmemory_operand" "")))
11448    (clobber (reg:CC 17))]
11449   "!TARGET_64BIT && reload_completed"
11450   [(const_int 0)]
11451   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11452
11453 (define_insn "x86_shrd_1"
11454   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11455         (ior:SI (ashiftrt:SI (match_dup 0)
11456                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11457                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11458                   (minus:QI (const_int 32) (match_dup 2)))))
11459    (clobber (reg:CC 17))]
11460   ""
11461   "@
11462    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11463    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11464   [(set_attr "type" "ishift")
11465    (set_attr "prefix_0f" "1")
11466    (set_attr "pent_pair" "np")
11467    (set_attr "ppro_uops" "few")
11468    (set_attr "mode" "SI")])
11469
11470 (define_expand "x86_shift_adj_3"
11471   [(use (match_operand:SI 0 "register_operand" ""))
11472    (use (match_operand:SI 1 "register_operand" ""))
11473    (use (match_operand:QI 2 "register_operand" ""))]
11474   ""
11475 {
11476   rtx label = gen_label_rtx ();
11477   rtx tmp;
11478
11479   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11480
11481   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11482   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11483   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11484                               gen_rtx_LABEL_REF (VOIDmode, label),
11485                               pc_rtx);
11486   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11487   JUMP_LABEL (tmp) = label;
11488
11489   emit_move_insn (operands[0], operands[1]);
11490   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11491
11492   emit_label (label);
11493   LABEL_NUSES (label) = 1;
11494
11495   DONE;
11496 })
11497
11498 (define_insn "ashrsi3_31"
11499   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11500         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11501                      (match_operand:SI 2 "const_int_operand" "i,i")))
11502    (clobber (reg:CC 17))]
11503   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11504    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11505   "@
11506    {cltd|cdq}
11507    sar{l}\t{%2, %0|%0, %2}"
11508   [(set_attr "type" "imovx,ishift")
11509    (set_attr "prefix_0f" "0,*")
11510    (set_attr "length_immediate" "0,*")
11511    (set_attr "modrm" "0,1")
11512    (set_attr "mode" "SI")])
11513
11514 (define_insn "*ashrsi3_31_zext"
11515   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11516         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11517                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11518    (clobber (reg:CC 17))]
11519   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11520    && INTVAL (operands[2]) == 31
11521    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11522   "@
11523    {cltd|cdq}
11524    sar{l}\t{%2, %k0|%k0, %2}"
11525   [(set_attr "type" "imovx,ishift")
11526    (set_attr "prefix_0f" "0,*")
11527    (set_attr "length_immediate" "0,*")
11528    (set_attr "modrm" "0,1")
11529    (set_attr "mode" "SI")])
11530
11531 (define_expand "ashrsi3"
11532   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11533         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11534                      (match_operand:QI 2 "nonmemory_operand" "")))
11535    (clobber (reg:CC 17))]
11536   ""
11537   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11538
11539 (define_insn "*ashrsi3_1_one_bit"
11540   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11541         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11542                      (match_operand:QI 2 "const1_operand" "")))
11543    (clobber (reg:CC 17))]
11544   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11545    && (TARGET_SHIFT1 || optimize_size)"
11546   "sar{l}\t%0"
11547   [(set_attr "type" "ishift")
11548    (set (attr "length") 
11549      (if_then_else (match_operand:SI 0 "register_operand" "") 
11550         (const_string "2")
11551         (const_string "*")))])
11552
11553 (define_insn "*ashrsi3_1_one_bit_zext"
11554   [(set (match_operand:DI 0 "register_operand" "=r")
11555         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11556                                      (match_operand:QI 2 "const1_operand" ""))))
11557    (clobber (reg:CC 17))]
11558   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11559    && (TARGET_SHIFT1 || optimize_size)"
11560   "sar{l}\t%k0"
11561   [(set_attr "type" "ishift")
11562    (set_attr "length" "2")])
11563
11564 (define_insn "*ashrsi3_1"
11565   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11566         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11567                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11568    (clobber (reg:CC 17))]
11569   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570   "@
11571    sar{l}\t{%2, %0|%0, %2}
11572    sar{l}\t{%b2, %0|%0, %b2}"
11573   [(set_attr "type" "ishift")
11574    (set_attr "mode" "SI")])
11575
11576 (define_insn "*ashrsi3_1_zext"
11577   [(set (match_operand:DI 0 "register_operand" "=r,r")
11578         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11579                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11580    (clobber (reg:CC 17))]
11581   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11582   "@
11583    sar{l}\t{%2, %k0|%k0, %2}
11584    sar{l}\t{%b2, %k0|%k0, %b2}"
11585   [(set_attr "type" "ishift")
11586    (set_attr "mode" "SI")])
11587
11588 ;; This pattern can't accept a variable shift count, since shifts by
11589 ;; zero don't affect the flags.  We assume that shifts by constant
11590 ;; zero are optimized away.
11591 (define_insn "*ashrsi3_one_bit_cmp"
11592   [(set (reg 17)
11593         (compare
11594           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595                        (match_operand:QI 2 "const1_operand" ""))
11596           (const_int 0)))
11597    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11598         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11599   "ix86_match_ccmode (insn, CCGOCmode)
11600    && (TARGET_SHIFT1 || optimize_size)
11601    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602   "sar{l}\t%0"
11603   [(set_attr "type" "ishift")
11604    (set (attr "length") 
11605      (if_then_else (match_operand:SI 0 "register_operand" "") 
11606         (const_string "2")
11607         (const_string "*")))])
11608
11609 (define_insn "*ashrsi3_one_bit_cmp_zext"
11610   [(set (reg 17)
11611         (compare
11612           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11613                        (match_operand:QI 2 "const1_operand" ""))
11614           (const_int 0)))
11615    (set (match_operand:DI 0 "register_operand" "=r")
11616         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11617   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11618    && (TARGET_SHIFT1 || optimize_size)
11619    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620   "sar{l}\t%k0"
11621   [(set_attr "type" "ishift")
11622    (set_attr "length" "2")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_cmp"
11628   [(set (reg 17)
11629         (compare
11630           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11632           (const_int 0)))
11633    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635   "ix86_match_ccmode (insn, CCGOCmode)
11636    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637   "sar{l}\t{%2, %0|%0, %2}"
11638   [(set_attr "type" "ishift")
11639    (set_attr "mode" "SI")])
11640
11641 (define_insn "*ashrsi3_cmp_zext"
11642   [(set (reg 17)
11643         (compare
11644           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "register_operand" "=r")
11648         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11651   "sar{l}\t{%2, %k0|%k0, %2}"
11652   [(set_attr "type" "ishift")
11653    (set_attr "mode" "SI")])
11654
11655 (define_expand "ashrhi3"
11656   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11657         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11658                      (match_operand:QI 2 "nonmemory_operand" "")))
11659    (clobber (reg:CC 17))]
11660   "TARGET_HIMODE_MATH"
11661   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11662
11663 (define_insn "*ashrhi3_1_one_bit"
11664   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11665         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666                      (match_operand:QI 2 "const1_operand" "")))
11667    (clobber (reg:CC 17))]
11668   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11669    && (TARGET_SHIFT1 || optimize_size)"
11670   "sar{w}\t%0"
11671   [(set_attr "type" "ishift")
11672    (set (attr "length") 
11673      (if_then_else (match_operand 0 "register_operand" "") 
11674         (const_string "2")
11675         (const_string "*")))])
11676
11677 (define_insn "*ashrhi3_1"
11678   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11679         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11680                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11681    (clobber (reg:CC 17))]
11682   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11683   "@
11684    sar{w}\t{%2, %0|%0, %2}
11685    sar{w}\t{%b2, %0|%0, %b2}"
11686   [(set_attr "type" "ishift")
11687    (set_attr "mode" "HI")])
11688
11689 ;; This pattern can't accept a variable shift count, since shifts by
11690 ;; zero don't affect the flags.  We assume that shifts by constant
11691 ;; zero are optimized away.
11692 (define_insn "*ashrhi3_one_bit_cmp"
11693   [(set (reg 17)
11694         (compare
11695           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11696                        (match_operand:QI 2 "const1_operand" ""))
11697           (const_int 0)))
11698    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11699         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11700   "ix86_match_ccmode (insn, CCGOCmode)
11701    && (TARGET_SHIFT1 || optimize_size)
11702    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703   "sar{w}\t%0"
11704   [(set_attr "type" "ishift")
11705    (set (attr "length") 
11706      (if_then_else (match_operand 0 "register_operand" "") 
11707         (const_string "2")
11708         (const_string "*")))])
11709
11710 ;; This pattern can't accept a variable shift count, since shifts by
11711 ;; zero don't affect the flags.  We assume that shifts by constant
11712 ;; zero are optimized away.
11713 (define_insn "*ashrhi3_cmp"
11714   [(set (reg 17)
11715         (compare
11716           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11718           (const_int 0)))
11719    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11721   "ix86_match_ccmode (insn, CCGOCmode)
11722    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723   "sar{w}\t{%2, %0|%0, %2}"
11724   [(set_attr "type" "ishift")
11725    (set_attr "mode" "HI")])
11726
11727 (define_expand "ashrqi3"
11728   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11729         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11730                      (match_operand:QI 2 "nonmemory_operand" "")))
11731    (clobber (reg:CC 17))]
11732   "TARGET_QIMODE_MATH"
11733   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11734
11735 (define_insn "*ashrqi3_1_one_bit"
11736   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11737         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11738                      (match_operand:QI 2 "const1_operand" "")))
11739    (clobber (reg:CC 17))]
11740   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11741    && (TARGET_SHIFT1 || optimize_size)"
11742   "sar{b}\t%0"
11743   [(set_attr "type" "ishift")
11744    (set (attr "length") 
11745      (if_then_else (match_operand 0 "register_operand" "") 
11746         (const_string "2")
11747         (const_string "*")))])
11748
11749 (define_insn "*ashrqi3_1_one_bit_slp"
11750   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11751         (ashiftrt:QI (match_dup 0)
11752                      (match_operand:QI 1 "const1_operand" "")))
11753    (clobber (reg:CC 17))]
11754   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11755    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11756    && (TARGET_SHIFT1 || optimize_size)"
11757   "sar{b}\t%0"
11758   [(set_attr "type" "ishift1")
11759    (set (attr "length") 
11760      (if_then_else (match_operand 0 "register_operand" "") 
11761         (const_string "2")
11762         (const_string "*")))])
11763
11764 (define_insn "*ashrqi3_1"
11765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11766         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11767                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11768    (clobber (reg:CC 17))]
11769   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11770   "@
11771    sar{b}\t{%2, %0|%0, %2}
11772    sar{b}\t{%b2, %0|%0, %b2}"
11773   [(set_attr "type" "ishift")
11774    (set_attr "mode" "QI")])
11775
11776 (define_insn "*ashrqi3_1_slp"
11777   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11778         (ashiftrt:QI (match_dup 0)
11779                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11780    (clobber (reg:CC 17))]
11781   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11782    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11783   "@
11784    sar{b}\t{%1, %0|%0, %1}
11785    sar{b}\t{%b1, %0|%0, %b1}"
11786   [(set_attr "type" "ishift1")
11787    (set_attr "mode" "QI")])
11788
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags.  We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashrqi3_one_bit_cmp"
11793   [(set (reg 17)
11794         (compare
11795           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11796                        (match_operand:QI 2 "const1_operand" "I"))
11797           (const_int 0)))
11798    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11799         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11800   "ix86_match_ccmode (insn, CCGOCmode)
11801    && (TARGET_SHIFT1 || optimize_size)
11802    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11803   "sar{b}\t%0"
11804   [(set_attr "type" "ishift")
11805    (set (attr "length") 
11806      (if_then_else (match_operand 0 "register_operand" "") 
11807         (const_string "2")
11808         (const_string "*")))])
11809
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags.  We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*ashrqi3_cmp"
11814   [(set (reg 17)
11815         (compare
11816           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11817                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11818           (const_int 0)))
11819    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11820         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11821   "ix86_match_ccmode (insn, CCGOCmode)
11822    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11823   "sar{b}\t{%2, %0|%0, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "QI")])
11826 \f
11827 ;; Logical shift instructions
11828
11829 ;; See comment above `ashldi3' about how this works.
11830
11831 (define_expand "lshrdi3"
11832   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11833                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11834                                 (match_operand:QI 2 "nonmemory_operand" "")))
11835               (clobber (reg:CC 17))])]
11836   ""
11837 {
11838   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11839     {
11840       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11841       DONE;
11842     }
11843   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11844   DONE;
11845 })
11846
11847 (define_insn "*lshrdi3_1_one_bit_rex64"
11848   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11849         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const1_operand" "")))
11851    (clobber (reg:CC 17))]
11852   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11853    && (TARGET_SHIFT1 || optimize_size)"
11854   "shr{q}\t%0"
11855   [(set_attr "type" "ishift")
11856    (set (attr "length") 
11857      (if_then_else (match_operand:DI 0 "register_operand" "") 
11858         (const_string "2")
11859         (const_string "*")))])
11860
11861 (define_insn "*lshrdi3_1_rex64"
11862   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11863         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11864                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11865    (clobber (reg:CC 17))]
11866   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11867   "@
11868    shr{q}\t{%2, %0|%0, %2}
11869    shr{q}\t{%b2, %0|%0, %b2}"
11870   [(set_attr "type" "ishift")
11871    (set_attr "mode" "DI")])
11872
11873 ;; This pattern can't accept a variable shift count, since shifts by
11874 ;; zero don't affect the flags.  We assume that shifts by constant
11875 ;; zero are optimized away.
11876 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11877   [(set (reg 17)
11878         (compare
11879           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11880                        (match_operand:QI 2 "const1_operand" ""))
11881           (const_int 0)))
11882    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11883         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11884   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11885    && (TARGET_SHIFT1 || optimize_size)
11886    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11887   "shr{q}\t%0"
11888   [(set_attr "type" "ishift")
11889    (set (attr "length") 
11890      (if_then_else (match_operand:DI 0 "register_operand" "") 
11891         (const_string "2")
11892         (const_string "*")))])
11893
11894 ;; This pattern can't accept a variable shift count, since shifts by
11895 ;; zero don't affect the flags.  We assume that shifts by constant
11896 ;; zero are optimized away.
11897 (define_insn "*lshrdi3_cmp_rex64"
11898   [(set (reg 17)
11899         (compare
11900           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901                        (match_operand:QI 2 "const_int_operand" "e"))
11902           (const_int 0)))
11903    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11904         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11905   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11906    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11907   "shr{q}\t{%2, %0|%0, %2}"
11908   [(set_attr "type" "ishift")
11909    (set_attr "mode" "DI")])
11910
11911 (define_insn "lshrdi3_1"
11912   [(set (match_operand:DI 0 "register_operand" "=r")
11913         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11914                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11915    (clobber (match_scratch:SI 3 "=&r"))
11916    (clobber (reg:CC 17))]
11917   "!TARGET_64BIT && TARGET_CMOVE"
11918   "#"
11919   [(set_attr "type" "multi")])
11920
11921 (define_insn "*lshrdi3_2"
11922   [(set (match_operand:DI 0 "register_operand" "=r")
11923         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11924                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11925    (clobber (reg:CC 17))]
11926   "!TARGET_64BIT"
11927   "#"
11928   [(set_attr "type" "multi")])
11929
11930 (define_split 
11931   [(set (match_operand:DI 0 "register_operand" "")
11932         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11933                      (match_operand:QI 2 "nonmemory_operand" "")))
11934    (clobber (match_scratch:SI 3 ""))
11935    (clobber (reg:CC 17))]
11936   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11937   [(const_int 0)]
11938   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11939
11940 (define_split 
11941   [(set (match_operand:DI 0 "register_operand" "")
11942         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11943                      (match_operand:QI 2 "nonmemory_operand" "")))
11944    (clobber (reg:CC 17))]
11945   "!TARGET_64BIT && reload_completed"
11946   [(const_int 0)]
11947   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11948
11949 (define_expand "lshrsi3"
11950   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11951         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11952                      (match_operand:QI 2 "nonmemory_operand" "")))
11953    (clobber (reg:CC 17))]
11954   ""
11955   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11956
11957 (define_insn "*lshrsi3_1_one_bit"
11958   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11959         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11960                      (match_operand:QI 2 "const1_operand" "")))
11961    (clobber (reg:CC 17))]
11962   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11963    && (TARGET_SHIFT1 || optimize_size)"
11964   "shr{l}\t%0"
11965   [(set_attr "type" "ishift")
11966    (set (attr "length") 
11967      (if_then_else (match_operand:SI 0 "register_operand" "") 
11968         (const_string "2")
11969         (const_string "*")))])
11970
11971 (define_insn "*lshrsi3_1_one_bit_zext"
11972   [(set (match_operand:DI 0 "register_operand" "=r")
11973         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11974                      (match_operand:QI 2 "const1_operand" "")))
11975    (clobber (reg:CC 17))]
11976   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11977    && (TARGET_SHIFT1 || optimize_size)"
11978   "shr{l}\t%k0"
11979   [(set_attr "type" "ishift")
11980    (set_attr "length" "2")])
11981
11982 (define_insn "*lshrsi3_1"
11983   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11984         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11985                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986    (clobber (reg:CC 17))]
11987   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11988   "@
11989    shr{l}\t{%2, %0|%0, %2}
11990    shr{l}\t{%b2, %0|%0, %b2}"
11991   [(set_attr "type" "ishift")
11992    (set_attr "mode" "SI")])
11993
11994 (define_insn "*lshrsi3_1_zext"
11995   [(set (match_operand:DI 0 "register_operand" "=r,r")
11996         (zero_extend:DI
11997           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11998                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11999    (clobber (reg:CC 17))]
12000   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12001   "@
12002    shr{l}\t{%2, %k0|%k0, %2}
12003    shr{l}\t{%b2, %k0|%k0, %b2}"
12004   [(set_attr "type" "ishift")
12005    (set_attr "mode" "SI")])
12006
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags.  We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*lshrsi3_one_bit_cmp"
12011   [(set (reg 17)
12012         (compare
12013           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12014                        (match_operand:QI 2 "const1_operand" ""))
12015           (const_int 0)))
12016    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12017         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12018   "ix86_match_ccmode (insn, CCGOCmode)
12019    && (TARGET_SHIFT1 || optimize_size)
12020    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12021   "shr{l}\t%0"
12022   [(set_attr "type" "ishift")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 (define_insn "*lshrsi3_cmp_one_bit_zext"
12029   [(set (reg 17)
12030         (compare
12031           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032                        (match_operand:QI 2 "const1_operand" ""))
12033           (const_int 0)))
12034    (set (match_operand:DI 0 "register_operand" "=r")
12035         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12036   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037    && (TARGET_SHIFT1 || optimize_size)
12038    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039   "shr{l}\t%k0"
12040   [(set_attr "type" "ishift")
12041    (set_attr "length" "2")])
12042
12043 ;; This pattern can't accept a variable shift count, since shifts by
12044 ;; zero don't affect the flags.  We assume that shifts by constant
12045 ;; zero are optimized away.
12046 (define_insn "*lshrsi3_cmp"
12047   [(set (reg 17)
12048         (compare
12049           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12050                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12051           (const_int 0)))
12052    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12053         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12054   "ix86_match_ccmode (insn, CCGOCmode)
12055    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12056   "shr{l}\t{%2, %0|%0, %2}"
12057   [(set_attr "type" "ishift")
12058    (set_attr "mode" "SI")])
12059
12060 (define_insn "*lshrsi3_cmp_zext"
12061   [(set (reg 17)
12062         (compare
12063           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12064                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12065           (const_int 0)))
12066    (set (match_operand:DI 0 "register_operand" "=r")
12067         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12068   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12069    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070   "shr{l}\t{%2, %k0|%k0, %2}"
12071   [(set_attr "type" "ishift")
12072    (set_attr "mode" "SI")])
12073
12074 (define_expand "lshrhi3"
12075   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12076         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12077                      (match_operand:QI 2 "nonmemory_operand" "")))
12078    (clobber (reg:CC 17))]
12079   "TARGET_HIMODE_MATH"
12080   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12081
12082 (define_insn "*lshrhi3_1_one_bit"
12083   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12084         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085                      (match_operand:QI 2 "const1_operand" "")))
12086    (clobber (reg:CC 17))]
12087   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12088    && (TARGET_SHIFT1 || optimize_size)"
12089   "shr{w}\t%0"
12090   [(set_attr "type" "ishift")
12091    (set (attr "length") 
12092      (if_then_else (match_operand 0 "register_operand" "") 
12093         (const_string "2")
12094         (const_string "*")))])
12095
12096 (define_insn "*lshrhi3_1"
12097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12098         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12099                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12100    (clobber (reg:CC 17))]
12101   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102   "@
12103    shr{w}\t{%2, %0|%0, %2}
12104    shr{w}\t{%b2, %0|%0, %b2}"
12105   [(set_attr "type" "ishift")
12106    (set_attr "mode" "HI")])
12107
12108 ;; This pattern can't accept a variable shift count, since shifts by
12109 ;; zero don't affect the flags.  We assume that shifts by constant
12110 ;; zero are optimized away.
12111 (define_insn "*lshrhi3_one_bit_cmp"
12112   [(set (reg 17)
12113         (compare
12114           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12115                        (match_operand:QI 2 "const1_operand" ""))
12116           (const_int 0)))
12117    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12118         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12119   "ix86_match_ccmode (insn, CCGOCmode)
12120    && (TARGET_SHIFT1 || optimize_size)
12121    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12122   "shr{w}\t%0"
12123   [(set_attr "type" "ishift")
12124    (set (attr "length") 
12125      (if_then_else (match_operand:SI 0 "register_operand" "") 
12126         (const_string "2")
12127         (const_string "*")))])
12128
12129 ;; This pattern can't accept a variable shift count, since shifts by
12130 ;; zero don't affect the flags.  We assume that shifts by constant
12131 ;; zero are optimized away.
12132 (define_insn "*lshrhi3_cmp"
12133   [(set (reg 17)
12134         (compare
12135           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12137           (const_int 0)))
12138    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12139         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12140   "ix86_match_ccmode (insn, CCGOCmode)
12141    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142   "shr{w}\t{%2, %0|%0, %2}"
12143   [(set_attr "type" "ishift")
12144    (set_attr "mode" "HI")])
12145
12146 (define_expand "lshrqi3"
12147   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12148         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12149                      (match_operand:QI 2 "nonmemory_operand" "")))
12150    (clobber (reg:CC 17))]
12151   "TARGET_QIMODE_MATH"
12152   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12153
12154 (define_insn "*lshrqi3_1_one_bit"
12155   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12156         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12157                      (match_operand:QI 2 "const1_operand" "")))
12158    (clobber (reg:CC 17))]
12159   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12160    && (TARGET_SHIFT1 || optimize_size)"
12161   "shr{b}\t%0"
12162   [(set_attr "type" "ishift")
12163    (set (attr "length") 
12164      (if_then_else (match_operand 0 "register_operand" "") 
12165         (const_string "2")
12166         (const_string "*")))])
12167
12168 (define_insn "*lshrqi3_1_one_bit_slp"
12169   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12170         (lshiftrt:QI (match_dup 0)
12171                      (match_operand:QI 1 "const1_operand" "")))
12172    (clobber (reg:CC 17))]
12173   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12174    && (TARGET_SHIFT1 || optimize_size)"
12175   "shr{b}\t%0"
12176   [(set_attr "type" "ishift1")
12177    (set (attr "length") 
12178      (if_then_else (match_operand 0 "register_operand" "") 
12179         (const_string "2")
12180         (const_string "*")))])
12181
12182 (define_insn "*lshrqi3_1"
12183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12184         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12185                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12186    (clobber (reg:CC 17))]
12187   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12188   "@
12189    shr{b}\t{%2, %0|%0, %2}
12190    shr{b}\t{%b2, %0|%0, %b2}"
12191   [(set_attr "type" "ishift")
12192    (set_attr "mode" "QI")])
12193
12194 (define_insn "*lshrqi3_1_slp"
12195   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12196         (lshiftrt:QI (match_dup 0)
12197                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12198    (clobber (reg:CC 17))]
12199   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12200    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12201   "@
12202    shr{b}\t{%1, %0|%0, %1}
12203    shr{b}\t{%b1, %0|%0, %b1}"
12204   [(set_attr "type" "ishift1")
12205    (set_attr "mode" "QI")])
12206
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags.  We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*lshrqi2_one_bit_cmp"
12211   [(set (reg 17)
12212         (compare
12213           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12214                        (match_operand:QI 2 "const1_operand" ""))
12215           (const_int 0)))
12216    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12217         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12218   "ix86_match_ccmode (insn, CCGOCmode)
12219    && (TARGET_SHIFT1 || optimize_size)
12220    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12221   "shr{b}\t%0"
12222   [(set_attr "type" "ishift")
12223    (set (attr "length") 
12224      (if_then_else (match_operand:SI 0 "register_operand" "") 
12225         (const_string "2")
12226         (const_string "*")))])
12227
12228 ;; This pattern can't accept a variable shift count, since shifts by
12229 ;; zero don't affect the flags.  We assume that shifts by constant
12230 ;; zero are optimized away.
12231 (define_insn "*lshrqi2_cmp"
12232   [(set (reg 17)
12233         (compare
12234           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12236           (const_int 0)))
12237    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12238         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12239   "ix86_match_ccmode (insn, CCGOCmode)
12240    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12241   "shr{b}\t{%2, %0|%0, %2}"
12242   [(set_attr "type" "ishift")
12243    (set_attr "mode" "QI")])
12244 \f
12245 ;; Rotate instructions
12246
12247 (define_expand "rotldi3"
12248   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12249         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12250                    (match_operand:QI 2 "nonmemory_operand" "")))
12251    (clobber (reg:CC 17))]
12252   "TARGET_64BIT"
12253   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12254
12255 (define_insn "*rotlsi3_1_one_bit_rex64"
12256   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12257         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12258                    (match_operand:QI 2 "const1_operand" "")))
12259    (clobber (reg:CC 17))]
12260   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12261    && (TARGET_SHIFT1 || optimize_size)"
12262   "rol{q}\t%0"
12263   [(set_attr "type" "rotate")
12264    (set (attr "length") 
12265      (if_then_else (match_operand:DI 0 "register_operand" "") 
12266         (const_string "2")
12267         (const_string "*")))])
12268
12269 (define_insn "*rotldi3_1_rex64"
12270   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12271         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12272                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12273    (clobber (reg:CC 17))]
12274   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12275   "@
12276    rol{q}\t{%2, %0|%0, %2}
12277    rol{q}\t{%b2, %0|%0, %b2}"
12278   [(set_attr "type" "rotate")
12279    (set_attr "mode" "DI")])
12280
12281 (define_expand "rotlsi3"
12282   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12283         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12284                    (match_operand:QI 2 "nonmemory_operand" "")))
12285    (clobber (reg:CC 17))]
12286   ""
12287   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12288
12289 (define_insn "*rotlsi3_1_one_bit"
12290   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12291         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12292                    (match_operand:QI 2 "const1_operand" "")))
12293    (clobber (reg:CC 17))]
12294   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12295    && (TARGET_SHIFT1 || optimize_size)"
12296   "rol{l}\t%0"
12297   [(set_attr "type" "rotate")
12298    (set (attr "length") 
12299      (if_then_else (match_operand:SI 0 "register_operand" "") 
12300         (const_string "2")
12301         (const_string "*")))])
12302
12303 (define_insn "*rotlsi3_1_one_bit_zext"
12304   [(set (match_operand:DI 0 "register_operand" "=r")
12305         (zero_extend:DI
12306           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12307                      (match_operand:QI 2 "const1_operand" ""))))
12308    (clobber (reg:CC 17))]
12309   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12310    && (TARGET_SHIFT1 || optimize_size)"
12311   "rol{l}\t%k0"
12312   [(set_attr "type" "rotate")
12313    (set_attr "length" "2")])
12314
12315 (define_insn "*rotlsi3_1"
12316   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12317         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12318                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12319    (clobber (reg:CC 17))]
12320   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12321   "@
12322    rol{l}\t{%2, %0|%0, %2}
12323    rol{l}\t{%b2, %0|%0, %b2}"
12324   [(set_attr "type" "rotate")
12325    (set_attr "mode" "SI")])
12326
12327 (define_insn "*rotlsi3_1_zext"
12328   [(set (match_operand:DI 0 "register_operand" "=r,r")
12329         (zero_extend:DI
12330           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12331                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12332    (clobber (reg:CC 17))]
12333   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12334   "@
12335    rol{l}\t{%2, %k0|%k0, %2}
12336    rol{l}\t{%b2, %k0|%k0, %b2}"
12337   [(set_attr "type" "rotate")
12338    (set_attr "mode" "SI")])
12339
12340 (define_expand "rotlhi3"
12341   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12342         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12343                    (match_operand:QI 2 "nonmemory_operand" "")))
12344    (clobber (reg:CC 17))]
12345   "TARGET_HIMODE_MATH"
12346   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12347
12348 (define_insn "*rotlhi3_1_one_bit"
12349   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12350         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351                    (match_operand:QI 2 "const1_operand" "")))
12352    (clobber (reg:CC 17))]
12353   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12354    && (TARGET_SHIFT1 || optimize_size)"
12355   "rol{w}\t%0"
12356   [(set_attr "type" "rotate")
12357    (set (attr "length") 
12358      (if_then_else (match_operand 0 "register_operand" "") 
12359         (const_string "2")
12360         (const_string "*")))])
12361
12362 (define_insn "*rotlhi3_1"
12363   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12364         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12365                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12366    (clobber (reg:CC 17))]
12367   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12368   "@
12369    rol{w}\t{%2, %0|%0, %2}
12370    rol{w}\t{%b2, %0|%0, %b2}"
12371   [(set_attr "type" "rotate")
12372    (set_attr "mode" "HI")])
12373
12374 (define_expand "rotlqi3"
12375   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12376         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12377                    (match_operand:QI 2 "nonmemory_operand" "")))
12378    (clobber (reg:CC 17))]
12379   "TARGET_QIMODE_MATH"
12380   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12381
12382 (define_insn "*rotlqi3_1_one_bit_slp"
12383   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12384         (rotate:QI (match_dup 0)
12385                    (match_operand:QI 1 "const1_operand" "")))
12386    (clobber (reg:CC 17))]
12387   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12388    && (TARGET_SHIFT1 || optimize_size)"
12389   "rol{b}\t%0"
12390   [(set_attr "type" "rotate1")
12391    (set (attr "length") 
12392      (if_then_else (match_operand 0 "register_operand" "") 
12393         (const_string "2")
12394         (const_string "*")))])
12395
12396 (define_insn "*rotlqi3_1_one_bit"
12397   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12398         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12399                    (match_operand:QI 2 "const1_operand" "")))
12400    (clobber (reg:CC 17))]
12401   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12402    && (TARGET_SHIFT1 || optimize_size)"
12403   "rol{b}\t%0"
12404   [(set_attr "type" "rotate")
12405    (set (attr "length") 
12406      (if_then_else (match_operand 0 "register_operand" "") 
12407         (const_string "2")
12408         (const_string "*")))])
12409
12410 (define_insn "*rotlqi3_1_slp"
12411   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12412         (rotate:QI (match_dup 0)
12413                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12414    (clobber (reg:CC 17))]
12415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12416    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12417   "@
12418    rol{b}\t{%1, %0|%0, %1}
12419    rol{b}\t{%b1, %0|%0, %b1}"
12420   [(set_attr "type" "rotate1")
12421    (set_attr "mode" "QI")])
12422
12423 (define_insn "*rotlqi3_1"
12424   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12425         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12426                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12427    (clobber (reg:CC 17))]
12428   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12429   "@
12430    rol{b}\t{%2, %0|%0, %2}
12431    rol{b}\t{%b2, %0|%0, %b2}"
12432   [(set_attr "type" "rotate")
12433    (set_attr "mode" "QI")])
12434
12435 (define_expand "rotrdi3"
12436   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12437         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12438                      (match_operand:QI 2 "nonmemory_operand" "")))
12439    (clobber (reg:CC 17))]
12440   "TARGET_64BIT"
12441   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12442
12443 (define_insn "*rotrdi3_1_one_bit_rex64"
12444   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12445         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12446                      (match_operand:QI 2 "const1_operand" "")))
12447    (clobber (reg:CC 17))]
12448   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12449    && (TARGET_SHIFT1 || optimize_size)"
12450   "ror{q}\t%0"
12451   [(set_attr "type" "rotate")
12452    (set (attr "length") 
12453      (if_then_else (match_operand:DI 0 "register_operand" "") 
12454         (const_string "2")
12455         (const_string "*")))])
12456
12457 (define_insn "*rotrdi3_1_rex64"
12458   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12459         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12460                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12461    (clobber (reg:CC 17))]
12462   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12463   "@
12464    ror{q}\t{%2, %0|%0, %2}
12465    ror{q}\t{%b2, %0|%0, %b2}"
12466   [(set_attr "type" "rotate")
12467    (set_attr "mode" "DI")])
12468
12469 (define_expand "rotrsi3"
12470   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12471         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12472                      (match_operand:QI 2 "nonmemory_operand" "")))
12473    (clobber (reg:CC 17))]
12474   ""
12475   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12476
12477 (define_insn "*rotrsi3_1_one_bit"
12478   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12479         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12480                      (match_operand:QI 2 "const1_operand" "")))
12481    (clobber (reg:CC 17))]
12482   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12483    && (TARGET_SHIFT1 || optimize_size)"
12484   "ror{l}\t%0"
12485   [(set_attr "type" "rotate")
12486    (set (attr "length") 
12487      (if_then_else (match_operand:SI 0 "register_operand" "") 
12488         (const_string "2")
12489         (const_string "*")))])
12490
12491 (define_insn "*rotrsi3_1_one_bit_zext"
12492   [(set (match_operand:DI 0 "register_operand" "=r")
12493         (zero_extend:DI
12494           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12495                        (match_operand:QI 2 "const1_operand" ""))))
12496    (clobber (reg:CC 17))]
12497   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12498    && (TARGET_SHIFT1 || optimize_size)"
12499   "ror{l}\t%k0"
12500   [(set_attr "type" "rotate")
12501    (set (attr "length") 
12502      (if_then_else (match_operand:SI 0 "register_operand" "") 
12503         (const_string "2")
12504         (const_string "*")))])
12505
12506 (define_insn "*rotrsi3_1"
12507   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12508         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12509                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12510    (clobber (reg:CC 17))]
12511   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12512   "@
12513    ror{l}\t{%2, %0|%0, %2}
12514    ror{l}\t{%b2, %0|%0, %b2}"
12515   [(set_attr "type" "rotate")
12516    (set_attr "mode" "SI")])
12517
12518 (define_insn "*rotrsi3_1_zext"
12519   [(set (match_operand:DI 0 "register_operand" "=r,r")
12520         (zero_extend:DI
12521           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12522                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12523    (clobber (reg:CC 17))]
12524   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12525   "@
12526    ror{l}\t{%2, %k0|%k0, %2}
12527    ror{l}\t{%b2, %k0|%k0, %b2}"
12528   [(set_attr "type" "rotate")
12529    (set_attr "mode" "SI")])
12530
12531 (define_expand "rotrhi3"
12532   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12533         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12534                      (match_operand:QI 2 "nonmemory_operand" "")))
12535    (clobber (reg:CC 17))]
12536   "TARGET_HIMODE_MATH"
12537   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12538
12539 (define_insn "*rotrhi3_one_bit"
12540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12541         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12542                      (match_operand:QI 2 "const1_operand" "")))
12543    (clobber (reg:CC 17))]
12544   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12545    && (TARGET_SHIFT1 || optimize_size)"
12546   "ror{w}\t%0"
12547   [(set_attr "type" "rotate")
12548    (set (attr "length") 
12549      (if_then_else (match_operand 0 "register_operand" "") 
12550         (const_string "2")
12551         (const_string "*")))])
12552
12553 (define_insn "*rotrhi3"
12554   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12555         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12556                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12557    (clobber (reg:CC 17))]
12558   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12559   "@
12560    ror{w}\t{%2, %0|%0, %2}
12561    ror{w}\t{%b2, %0|%0, %b2}"
12562   [(set_attr "type" "rotate")
12563    (set_attr "mode" "HI")])
12564
12565 (define_expand "rotrqi3"
12566   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12567         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12568                      (match_operand:QI 2 "nonmemory_operand" "")))
12569    (clobber (reg:CC 17))]
12570   "TARGET_QIMODE_MATH"
12571   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12572
12573 (define_insn "*rotrqi3_1_one_bit"
12574   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12575         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12576                      (match_operand:QI 2 "const1_operand" "")))
12577    (clobber (reg:CC 17))]
12578   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12579    && (TARGET_SHIFT1 || optimize_size)"
12580   "ror{b}\t%0"
12581   [(set_attr "type" "rotate")
12582    (set (attr "length") 
12583      (if_then_else (match_operand 0 "register_operand" "") 
12584         (const_string "2")
12585         (const_string "*")))])
12586
12587 (define_insn "*rotrqi3_1_one_bit_slp"
12588   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12589         (rotatert:QI (match_dup 0)
12590                      (match_operand:QI 1 "const1_operand" "")))
12591    (clobber (reg:CC 17))]
12592   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12593    && (TARGET_SHIFT1 || optimize_size)"
12594   "ror{b}\t%0"
12595   [(set_attr "type" "rotate1")
12596    (set (attr "length") 
12597      (if_then_else (match_operand 0 "register_operand" "") 
12598         (const_string "2")
12599         (const_string "*")))])
12600
12601 (define_insn "*rotrqi3_1"
12602   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12603         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12604                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12605    (clobber (reg:CC 17))]
12606   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12607   "@
12608    ror{b}\t{%2, %0|%0, %2}
12609    ror{b}\t{%b2, %0|%0, %b2}"
12610   [(set_attr "type" "rotate")
12611    (set_attr "mode" "QI")])
12612
12613 (define_insn "*rotrqi3_1_slp"
12614   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12615         (rotatert:QI (match_dup 0)
12616                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12617    (clobber (reg:CC 17))]
12618   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12619    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12620   "@
12621    ror{b}\t{%1, %0|%0, %1}
12622    ror{b}\t{%b1, %0|%0, %b1}"
12623   [(set_attr "type" "rotate1")
12624    (set_attr "mode" "QI")])
12625 \f
12626 ;; Bit set / bit test instructions
12627
12628 (define_expand "extv"
12629   [(set (match_operand:SI 0 "register_operand" "")
12630         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12631                          (match_operand:SI 2 "immediate_operand" "")
12632                          (match_operand:SI 3 "immediate_operand" "")))]
12633   ""
12634 {
12635   /* Handle extractions from %ah et al.  */
12636   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12637     FAIL;
12638
12639   /* From mips.md: extract_bit_field doesn't verify that our source
12640      matches the predicate, so check it again here.  */
12641   if (! register_operand (operands[1], VOIDmode))
12642     FAIL;
12643 })
12644
12645 (define_expand "extzv"
12646   [(set (match_operand:SI 0 "register_operand" "")
12647         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12648                          (match_operand:SI 2 "immediate_operand" "")
12649                          (match_operand:SI 3 "immediate_operand" "")))]
12650   ""
12651 {
12652   /* Handle extractions from %ah et al.  */
12653   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12654     FAIL;
12655
12656   /* From mips.md: extract_bit_field doesn't verify that our source
12657      matches the predicate, so check it again here.  */
12658   if (! register_operand (operands[1], VOIDmode))
12659     FAIL;
12660 })
12661
12662 (define_expand "insv"
12663   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12664                       (match_operand 1 "immediate_operand" "")
12665                       (match_operand 2 "immediate_operand" ""))
12666         (match_operand 3 "register_operand" ""))]
12667   ""
12668 {
12669   /* Handle extractions from %ah et al.  */
12670   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12671     FAIL;
12672
12673   /* From mips.md: insert_bit_field doesn't verify that our source
12674      matches the predicate, so check it again here.  */
12675   if (! register_operand (operands[0], VOIDmode))
12676     FAIL;
12677
12678   if (TARGET_64BIT)
12679     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12680   else
12681     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12682
12683   DONE;
12684 })
12685
12686 ;; %%% bts, btr, btc, bt.
12687 \f
12688 ;; Store-flag instructions.
12689
12690 ;; For all sCOND expanders, also expand the compare or test insn that
12691 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12692
12693 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12694 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12695 ;; way, which can later delete the movzx if only QImode is needed.
12696
12697 (define_expand "seq"
12698   [(set (match_operand:QI 0 "register_operand" "")
12699         (eq:QI (reg:CC 17) (const_int 0)))]
12700   ""
12701   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12702
12703 (define_expand "sne"
12704   [(set (match_operand:QI 0 "register_operand" "")
12705         (ne:QI (reg:CC 17) (const_int 0)))]
12706   ""
12707   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12708
12709 (define_expand "sgt"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (gt:QI (reg:CC 17) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sgtu"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (gtu:QI (reg:CC 17) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "slt"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (lt:QI (reg:CC 17) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sltu"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (ltu:QI (reg:CC 17) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "sge"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (ge:QI (reg:CC 17) (const_int 0)))]
12736   ""
12737   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sgeu"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (geu:QI (reg:CC 17) (const_int 0)))]
12742   ""
12743   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "sle"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (le:QI (reg:CC 17) (const_int 0)))]
12748   ""
12749   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "sleu"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (leu:QI (reg:CC 17) (const_int 0)))]
12754   ""
12755   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12756
12757 (define_expand "sunordered"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (unordered:QI (reg:CC 17) (const_int 0)))]
12760   "TARGET_80387 || TARGET_SSE"
12761   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12762
12763 (define_expand "sordered"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (ordered:QI (reg:CC 17) (const_int 0)))]
12766   "TARGET_80387"
12767   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12768
12769 (define_expand "suneq"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (uneq:QI (reg:CC 17) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12774
12775 (define_expand "sunge"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (unge:QI (reg:CC 17) (const_int 0)))]
12778   "TARGET_80387 || TARGET_SSE"
12779   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12780
12781 (define_expand "sungt"
12782   [(set (match_operand:QI 0 "register_operand" "")
12783         (ungt:QI (reg:CC 17) (const_int 0)))]
12784   "TARGET_80387 || TARGET_SSE"
12785   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12786
12787 (define_expand "sunle"
12788   [(set (match_operand:QI 0 "register_operand" "")
12789         (unle:QI (reg:CC 17) (const_int 0)))]
12790   "TARGET_80387 || TARGET_SSE"
12791   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12792
12793 (define_expand "sunlt"
12794   [(set (match_operand:QI 0 "register_operand" "")
12795         (unlt:QI (reg:CC 17) (const_int 0)))]
12796   "TARGET_80387 || TARGET_SSE"
12797   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12798
12799 (define_expand "sltgt"
12800   [(set (match_operand:QI 0 "register_operand" "")
12801         (ltgt:QI (reg:CC 17) (const_int 0)))]
12802   "TARGET_80387 || TARGET_SSE"
12803   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12804
12805 (define_insn "*setcc_1"
12806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12807         (match_operator:QI 1 "ix86_comparison_operator"
12808           [(reg 17) (const_int 0)]))]
12809   ""
12810   "set%C1\t%0"
12811   [(set_attr "type" "setcc")
12812    (set_attr "mode" "QI")])
12813
12814 (define_insn "setcc_2"
12815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12816         (match_operator:QI 1 "ix86_comparison_operator"
12817           [(reg 17) (const_int 0)]))]
12818   ""
12819   "set%C1\t%0"
12820   [(set_attr "type" "setcc")
12821    (set_attr "mode" "QI")])
12822
12823 ;; In general it is not safe to assume too much about CCmode registers,
12824 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12825 ;; conditions this is safe on x86, so help combine not create
12826 ;;
12827 ;;      seta    %al
12828 ;;      testb   %al, %al
12829 ;;      sete    %al
12830
12831 (define_split 
12832   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833         (ne:QI (match_operator 1 "ix86_comparison_operator"
12834                  [(reg 17) (const_int 0)])
12835             (const_int 0)))]
12836   ""
12837   [(set (match_dup 0) (match_dup 1))]
12838 {
12839   PUT_MODE (operands[1], QImode);
12840 })
12841
12842 (define_split 
12843   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12844         (ne:QI (match_operator 1 "ix86_comparison_operator"
12845                  [(reg 17) (const_int 0)])
12846             (const_int 0)))]
12847   ""
12848   [(set (match_dup 0) (match_dup 1))]
12849 {
12850   PUT_MODE (operands[1], QImode);
12851 })
12852
12853 (define_split 
12854   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12855         (eq:QI (match_operator 1 "ix86_comparison_operator"
12856                  [(reg 17) (const_int 0)])
12857             (const_int 0)))]
12858   ""
12859   [(set (match_dup 0) (match_dup 1))]
12860 {
12861   rtx new_op1 = copy_rtx (operands[1]);
12862   operands[1] = new_op1;
12863   PUT_MODE (new_op1, QImode);
12864   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12865                                         GET_MODE (XEXP (new_op1, 0))));
12866
12867   /* Make sure that (a) the CCmode we have for the flags is strong
12868      enough for the reversed compare or (b) we have a valid FP compare.  */
12869   if (! ix86_comparison_operator (new_op1, VOIDmode))
12870     FAIL;
12871 })
12872
12873 (define_split 
12874   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12875         (eq:QI (match_operator 1 "ix86_comparison_operator"
12876                  [(reg 17) (const_int 0)])
12877             (const_int 0)))]
12878   ""
12879   [(set (match_dup 0) (match_dup 1))]
12880 {
12881   rtx new_op1 = copy_rtx (operands[1]);
12882   operands[1] = new_op1;
12883   PUT_MODE (new_op1, QImode);
12884   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12885                                         GET_MODE (XEXP (new_op1, 0))));
12886
12887   /* Make sure that (a) the CCmode we have for the flags is strong
12888      enough for the reversed compare or (b) we have a valid FP compare.  */
12889   if (! ix86_comparison_operator (new_op1, VOIDmode))
12890     FAIL;
12891 })
12892
12893 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12894 ;; subsequent logical operations are used to imitate conditional moves.
12895 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12896 ;; it directly.  Further holding this value in pseudo register might bring
12897 ;; problem in implicit normalization in spill code.
12898 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12899 ;; instructions after reload by splitting the conditional move patterns.
12900
12901 (define_insn "*sse_setccsf"
12902   [(set (match_operand:SF 0 "register_operand" "=x")
12903         (match_operator:SF 1 "sse_comparison_operator"
12904           [(match_operand:SF 2 "register_operand" "0")
12905            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12906   "TARGET_SSE && reload_completed"
12907   "cmp%D1ss\t{%3, %0|%0, %3}"
12908   [(set_attr "type" "ssecmp")
12909    (set_attr "mode" "SF")])
12910
12911 (define_insn "*sse_setccdf"
12912   [(set (match_operand:DF 0 "register_operand" "=Y")
12913         (match_operator:DF 1 "sse_comparison_operator"
12914           [(match_operand:DF 2 "register_operand" "0")
12915            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12916   "TARGET_SSE2 && reload_completed"
12917   "cmp%D1sd\t{%3, %0|%0, %3}"
12918   [(set_attr "type" "ssecmp")
12919    (set_attr "mode" "DF")])
12920 \f
12921 ;; Basic conditional jump instructions.
12922 ;; We ignore the overflow flag for signed branch instructions.
12923
12924 ;; For all bCOND expanders, also expand the compare or test insn that
12925 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12926
12927 (define_expand "beq"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (EQ, operands[0]); DONE;")
12934
12935 (define_expand "bne"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (NE, operands[0]); DONE;")
12942
12943 (define_expand "bgt"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (GT, operands[0]); DONE;")
12950
12951 (define_expand "bgtu"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GTU, operands[0]); DONE;")
12958
12959 (define_expand "blt"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (LT, operands[0]); DONE;")
12966
12967 (define_expand "bltu"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LTU, operands[0]); DONE;")
12974
12975 (define_expand "bge"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (GE, operands[0]); DONE;")
12982
12983 (define_expand "bgeu"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   ""
12989   "ix86_expand_branch (GEU, operands[0]); DONE;")
12990
12991 (define_expand "ble"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   ""
12997   "ix86_expand_branch (LE, operands[0]); DONE;")
12998
12999 (define_expand "bleu"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   ""
13005   "ix86_expand_branch (LEU, operands[0]); DONE;")
13006
13007 (define_expand "bunordered"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13014
13015 (define_expand "bordered"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13022
13023 (define_expand "buneq"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13030
13031 (define_expand "bunge"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE"
13037   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13038
13039 (define_expand "bungt"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE"
13045   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13046
13047 (define_expand "bunle"
13048   [(set (pc)
13049         (if_then_else (match_dup 1)
13050                       (label_ref (match_operand 0 "" ""))
13051                       (pc)))]
13052   "TARGET_80387 || TARGET_SSE"
13053   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13054
13055 (define_expand "bunlt"
13056   [(set (pc)
13057         (if_then_else (match_dup 1)
13058                       (label_ref (match_operand 0 "" ""))
13059                       (pc)))]
13060   "TARGET_80387 || TARGET_SSE"
13061   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13062
13063 (define_expand "bltgt"
13064   [(set (pc)
13065         (if_then_else (match_dup 1)
13066                       (label_ref (match_operand 0 "" ""))
13067                       (pc)))]
13068   "TARGET_80387 || TARGET_SSE"
13069   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13070
13071 (define_insn "*jcc_1"
13072   [(set (pc)
13073         (if_then_else (match_operator 1 "ix86_comparison_operator"
13074                                       [(reg 17) (const_int 0)])
13075                       (label_ref (match_operand 0 "" ""))
13076                       (pc)))]
13077   ""
13078   "%+j%C1\t%l0"
13079   [(set_attr "type" "ibr")
13080    (set_attr "modrm" "0")
13081    (set (attr "length")
13082            (if_then_else (and (ge (minus (match_dup 0) (pc))
13083                                   (const_int -126))
13084                               (lt (minus (match_dup 0) (pc))
13085                                   (const_int 128)))
13086              (const_int 2)
13087              (const_int 6)))])
13088
13089 (define_insn "*jcc_2"
13090   [(set (pc)
13091         (if_then_else (match_operator 1 "ix86_comparison_operator"
13092                                       [(reg 17) (const_int 0)])
13093                       (pc)
13094                       (label_ref (match_operand 0 "" ""))))]
13095   ""
13096   "%+j%c1\t%l0"
13097   [(set_attr "type" "ibr")
13098    (set_attr "modrm" "0")
13099    (set (attr "length")
13100            (if_then_else (and (ge (minus (match_dup 0) (pc))
13101                                   (const_int -126))
13102                               (lt (minus (match_dup 0) (pc))
13103                                   (const_int 128)))
13104              (const_int 2)
13105              (const_int 6)))])
13106
13107 ;; In general it is not safe to assume too much about CCmode registers,
13108 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13109 ;; conditions this is safe on x86, so help combine not create
13110 ;;
13111 ;;      seta    %al
13112 ;;      testb   %al, %al
13113 ;;      je      Lfoo
13114
13115 (define_split 
13116   [(set (pc)
13117         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13118                                       [(reg 17) (const_int 0)])
13119                           (const_int 0))
13120                       (label_ref (match_operand 1 "" ""))
13121                       (pc)))]
13122   ""
13123   [(set (pc)
13124         (if_then_else (match_dup 0)
13125                       (label_ref (match_dup 1))
13126                       (pc)))]
13127 {
13128   PUT_MODE (operands[0], VOIDmode);
13129 })
13130   
13131 (define_split 
13132   [(set (pc)
13133         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13134                                       [(reg 17) (const_int 0)])
13135                           (const_int 0))
13136                       (label_ref (match_operand 1 "" ""))
13137                       (pc)))]
13138   ""
13139   [(set (pc)
13140         (if_then_else (match_dup 0)
13141                       (label_ref (match_dup 1))
13142                       (pc)))]
13143 {
13144   rtx new_op0 = copy_rtx (operands[0]);
13145   operands[0] = new_op0;
13146   PUT_MODE (new_op0, VOIDmode);
13147   PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13148                                         GET_MODE (XEXP (new_op0, 0))));
13149
13150   /* Make sure that (a) the CCmode we have for the flags is strong
13151      enough for the reversed compare or (b) we have a valid FP compare.  */
13152   if (! ix86_comparison_operator (new_op0, VOIDmode))
13153     FAIL;
13154 })
13155
13156 ;; Define combination compare-and-branch fp compare instructions to use
13157 ;; during early optimization.  Splitting the operation apart early makes
13158 ;; for bad code when we want to reverse the operation.
13159
13160 (define_insn "*fp_jcc_1"
13161   [(set (pc)
13162         (if_then_else (match_operator 0 "comparison_operator"
13163                         [(match_operand 1 "register_operand" "f")
13164                          (match_operand 2 "register_operand" "f")])
13165           (label_ref (match_operand 3 "" ""))
13166           (pc)))
13167    (clobber (reg:CCFP 18))
13168    (clobber (reg:CCFP 17))]
13169   "TARGET_CMOVE && TARGET_80387
13170    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13171    && FLOAT_MODE_P (GET_MODE (operands[1]))
13172    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13173    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13174   "#")
13175
13176 (define_insn "*fp_jcc_1_sse"
13177   [(set (pc)
13178         (if_then_else (match_operator 0 "comparison_operator"
13179                         [(match_operand 1 "register_operand" "f#x,x#f")
13180                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13181           (label_ref (match_operand 3 "" ""))
13182           (pc)))
13183    (clobber (reg:CCFP 18))
13184    (clobber (reg:CCFP 17))]
13185   "TARGET_80387
13186    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13187    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13188    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13189   "#")
13190
13191 (define_insn "*fp_jcc_1_sse_only"
13192   [(set (pc)
13193         (if_then_else (match_operator 0 "comparison_operator"
13194                         [(match_operand 1 "register_operand" "x")
13195                          (match_operand 2 "nonimmediate_operand" "xm")])
13196           (label_ref (match_operand 3 "" ""))
13197           (pc)))
13198    (clobber (reg:CCFP 18))
13199    (clobber (reg:CCFP 17))]
13200   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13201    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13203   "#")
13204
13205 (define_insn "*fp_jcc_2"
13206   [(set (pc)
13207         (if_then_else (match_operator 0 "comparison_operator"
13208                         [(match_operand 1 "register_operand" "f")
13209                          (match_operand 2 "register_operand" "f")])
13210           (pc)
13211           (label_ref (match_operand 3 "" ""))))
13212    (clobber (reg:CCFP 18))
13213    (clobber (reg:CCFP 17))]
13214   "TARGET_CMOVE && TARGET_80387
13215    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13216    && FLOAT_MODE_P (GET_MODE (operands[1]))
13217    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13218    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13219   "#")
13220
13221 (define_insn "*fp_jcc_2_sse"
13222   [(set (pc)
13223         (if_then_else (match_operator 0 "comparison_operator"
13224                         [(match_operand 1 "register_operand" "f#x,x#f")
13225                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13226           (pc)
13227           (label_ref (match_operand 3 "" ""))))
13228    (clobber (reg:CCFP 18))
13229    (clobber (reg:CCFP 17))]
13230   "TARGET_80387
13231    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13232    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13234   "#")
13235
13236 (define_insn "*fp_jcc_2_sse_only"
13237   [(set (pc)
13238         (if_then_else (match_operator 0 "comparison_operator"
13239                         [(match_operand 1 "register_operand" "x")
13240                          (match_operand 2 "nonimmediate_operand" "xm")])
13241           (pc)
13242           (label_ref (match_operand 3 "" ""))))
13243    (clobber (reg:CCFP 18))
13244    (clobber (reg:CCFP 17))]
13245   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13246    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248   "#")
13249
13250 (define_insn "*fp_jcc_3"
13251   [(set (pc)
13252         (if_then_else (match_operator 0 "comparison_operator"
13253                         [(match_operand 1 "register_operand" "f")
13254                          (match_operand 2 "nonimmediate_operand" "fm")])
13255           (label_ref (match_operand 3 "" ""))
13256           (pc)))
13257    (clobber (reg:CCFP 18))
13258    (clobber (reg:CCFP 17))
13259    (clobber (match_scratch:HI 4 "=a"))]
13260   "TARGET_80387
13261    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13262    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13264    && SELECT_CC_MODE (GET_CODE (operands[0]),
13265                       operands[1], operands[2]) == CCFPmode
13266    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267   "#")
13268
13269 (define_insn "*fp_jcc_4"
13270   [(set (pc)
13271         (if_then_else (match_operator 0 "comparison_operator"
13272                         [(match_operand 1 "register_operand" "f")
13273                          (match_operand 2 "nonimmediate_operand" "fm")])
13274           (pc)
13275           (label_ref (match_operand 3 "" ""))))
13276    (clobber (reg:CCFP 18))
13277    (clobber (reg:CCFP 17))
13278    (clobber (match_scratch:HI 4 "=a"))]
13279   "TARGET_80387
13280    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13281    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13283    && SELECT_CC_MODE (GET_CODE (operands[0]),
13284                       operands[1], operands[2]) == CCFPmode
13285    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13286   "#")
13287
13288 (define_insn "*fp_jcc_5"
13289   [(set (pc)
13290         (if_then_else (match_operator 0 "comparison_operator"
13291                         [(match_operand 1 "register_operand" "f")
13292                          (match_operand 2 "register_operand" "f")])
13293           (label_ref (match_operand 3 "" ""))
13294           (pc)))
13295    (clobber (reg:CCFP 18))
13296    (clobber (reg:CCFP 17))
13297    (clobber (match_scratch:HI 4 "=a"))]
13298   "TARGET_80387
13299    && FLOAT_MODE_P (GET_MODE (operands[1]))
13300    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13301    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13302   "#")
13303
13304 (define_insn "*fp_jcc_6"
13305   [(set (pc)
13306         (if_then_else (match_operator 0 "comparison_operator"
13307                         [(match_operand 1 "register_operand" "f")
13308                          (match_operand 2 "register_operand" "f")])
13309           (pc)
13310           (label_ref (match_operand 3 "" ""))))
13311    (clobber (reg:CCFP 18))
13312    (clobber (reg:CCFP 17))
13313    (clobber (match_scratch:HI 4 "=a"))]
13314   "TARGET_80387
13315    && FLOAT_MODE_P (GET_MODE (operands[1]))
13316    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13317    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318   "#")
13319
13320 (define_split
13321   [(set (pc)
13322         (if_then_else (match_operator 0 "comparison_operator"
13323                         [(match_operand 1 "register_operand" "")
13324                          (match_operand 2 "nonimmediate_operand" "")])
13325           (match_operand 3 "" "")
13326           (match_operand 4 "" "")))
13327    (clobber (reg:CCFP 18))
13328    (clobber (reg:CCFP 17))]
13329   "reload_completed"
13330   [(const_int 0)]
13331 {
13332   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13333                         operands[3], operands[4], NULL_RTX);
13334   DONE;
13335 })
13336
13337 (define_split
13338   [(set (pc)
13339         (if_then_else (match_operator 0 "comparison_operator"
13340                         [(match_operand 1 "register_operand" "")
13341                          (match_operand 2 "nonimmediate_operand" "")])
13342           (match_operand 3 "" "")
13343           (match_operand 4 "" "")))
13344    (clobber (reg:CCFP 18))
13345    (clobber (reg:CCFP 17))
13346    (clobber (match_scratch:HI 5 "=a"))]
13347   "reload_completed"
13348   [(set (pc)
13349         (if_then_else (match_dup 6)
13350           (match_dup 3)
13351           (match_dup 4)))]
13352 {
13353   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13354                         operands[3], operands[4], operands[5]);
13355   DONE;
13356 })
13357 \f
13358 ;; Unconditional and other jump instructions
13359
13360 (define_insn "jump"
13361   [(set (pc)
13362         (label_ref (match_operand 0 "" "")))]
13363   ""
13364   "jmp\t%l0"
13365   [(set_attr "type" "ibr")
13366    (set (attr "length")
13367            (if_then_else (and (ge (minus (match_dup 0) (pc))
13368                                   (const_int -126))
13369                               (lt (minus (match_dup 0) (pc))
13370                                   (const_int 128)))
13371              (const_int 2)
13372              (const_int 5)))
13373    (set_attr "modrm" "0")])
13374
13375 (define_expand "indirect_jump"
13376   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13377   ""
13378   "")
13379
13380 (define_insn "*indirect_jump"
13381   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13382   "!TARGET_64BIT"
13383   "jmp\t%A0"
13384   [(set_attr "type" "ibr")
13385    (set_attr "length_immediate" "0")])
13386
13387 (define_insn "*indirect_jump_rtx64"
13388   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13389   "TARGET_64BIT"
13390   "jmp\t%A0"
13391   [(set_attr "type" "ibr")
13392    (set_attr "length_immediate" "0")])
13393
13394 (define_expand "tablejump"
13395   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13396               (use (label_ref (match_operand 1 "" "")))])]
13397   ""
13398 {
13399   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13400      relative.  Convert the relative address to an absolute address.  */
13401   if (flag_pic)
13402     {
13403       rtx op0, op1;
13404       enum rtx_code code;
13405
13406       if (TARGET_64BIT)
13407         {
13408           code = PLUS;
13409           op0 = operands[0];
13410           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13411         }
13412       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13413         {
13414           code = PLUS;
13415           op0 = operands[0];
13416           op1 = pic_offset_table_rtx;
13417         }
13418       else
13419         {
13420           code = MINUS;
13421           op0 = pic_offset_table_rtx;
13422           op1 = operands[0];
13423         }
13424
13425       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13426                                          OPTAB_DIRECT);
13427     }
13428 })
13429
13430 (define_insn "*tablejump_1"
13431   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13432    (use (label_ref (match_operand 1 "" "")))]
13433   "!TARGET_64BIT"
13434   "jmp\t%A0"
13435   [(set_attr "type" "ibr")
13436    (set_attr "length_immediate" "0")])
13437
13438 (define_insn "*tablejump_1_rtx64"
13439   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13440    (use (label_ref (match_operand 1 "" "")))]
13441   "TARGET_64BIT"
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13445 \f
13446 ;; Loop instruction
13447 ;;
13448 ;; This is all complicated by the fact that since this is a jump insn
13449 ;; we must handle our own reloads.
13450
13451 (define_expand "doloop_end"
13452   [(use (match_operand 0 "" ""))        ; loop pseudo
13453    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13454    (use (match_operand 2 "" ""))        ; max iterations
13455    (use (match_operand 3 "" ""))        ; loop level 
13456    (use (match_operand 4 "" ""))]       ; label
13457   "!TARGET_64BIT && TARGET_USE_LOOP"
13458   "                                 
13459 {
13460   /* Only use cloop on innermost loops.  */
13461   if (INTVAL (operands[3]) > 1)
13462     FAIL;
13463   if (GET_MODE (operands[0]) != SImode)
13464     FAIL;
13465   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13466                                            operands[0]));
13467   DONE;
13468 }")
13469
13470 (define_insn "doloop_end_internal"
13471   [(set (pc)
13472         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13473                           (const_int 1))
13474                       (label_ref (match_operand 0 "" ""))
13475                       (pc)))
13476    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13477         (plus:SI (match_dup 1)
13478                  (const_int -1)))
13479    (clobber (match_scratch:SI 3 "=X,X,r"))
13480    (clobber (reg:CC 17))]
13481   "!TARGET_64BIT && TARGET_USE_LOOP"
13482 {
13483   if (which_alternative != 0)
13484     return "#";
13485   if (get_attr_length (insn) == 2)
13486     return "%+loop\t%l0";
13487   else
13488     return "dec{l}\t%1\;%+jne\t%l0";
13489 }
13490   [(set_attr "ppro_uops" "many")
13491    (set (attr "length")
13492         (if_then_else (and (eq_attr "alternative" "0")
13493                            (and (ge (minus (match_dup 0) (pc))
13494                                     (const_int -126))
13495                                 (lt (minus (match_dup 0) (pc))
13496                                     (const_int 128))))
13497                       (const_int 2)
13498                       (const_int 16)))
13499    ;; We don't know the type before shorten branches.  Optimistically expect
13500    ;; the loop instruction to match.
13501    (set (attr "type") (const_string "ibr"))])
13502
13503 (define_split
13504   [(set (pc)
13505         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13506                           (const_int 1))
13507                       (match_operand 0 "" "")
13508                       (pc)))
13509    (set (match_dup 1)
13510         (plus:SI (match_dup 1)
13511                  (const_int -1)))
13512    (clobber (match_scratch:SI 2 ""))
13513    (clobber (reg:CC 17))]
13514   "!TARGET_64BIT && TARGET_USE_LOOP
13515    && reload_completed
13516    && REGNO (operands[1]) != 2"
13517   [(parallel [(set (reg:CCZ 17)
13518                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13519                                  (const_int 0)))
13520               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13521    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13522                            (match_dup 0)
13523                            (pc)))]
13524   "")
13525   
13526 (define_split
13527   [(set (pc)
13528         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13529                           (const_int 1))
13530                       (match_operand 0 "" "")
13531                       (pc)))
13532    (set (match_operand:SI 2 "nonimmediate_operand" "")
13533         (plus:SI (match_dup 1)
13534                  (const_int -1)))
13535    (clobber (match_scratch:SI 3 ""))
13536    (clobber (reg:CC 17))]
13537   "!TARGET_64BIT && TARGET_USE_LOOP
13538    && reload_completed
13539    && (! REG_P (operands[2])
13540        || ! rtx_equal_p (operands[1], operands[2]))"
13541   [(set (match_dup 3) (match_dup 1))
13542    (parallel [(set (reg:CCZ 17)
13543                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13544                                 (const_int 0)))
13545               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13546    (set (match_dup 2) (match_dup 3))
13547    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13548                            (match_dup 0)
13549                            (pc)))]
13550   "")
13551
13552 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13553
13554 (define_peephole2
13555   [(set (reg 17) (match_operand 0 "" ""))
13556    (set (match_operand:QI 1 "register_operand" "")
13557         (match_operator:QI 2 "ix86_comparison_operator"
13558           [(reg 17) (const_int 0)]))
13559    (set (match_operand 3 "q_regs_operand" "")
13560         (zero_extend (match_dup 1)))]
13561   "(peep2_reg_dead_p (3, operands[1])
13562     || operands_match_p (operands[1], operands[3]))
13563    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13564   [(set (match_dup 4) (match_dup 0))
13565    (set (strict_low_part (match_dup 5))
13566         (match_dup 2))]
13567 {
13568   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13569   operands[5] = gen_lowpart (QImode, operands[3]);
13570   ix86_expand_clear (operands[3]);
13571 })
13572
13573 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13574
13575 (define_peephole2
13576   [(set (reg 17) (match_operand 0 "" ""))
13577    (set (match_operand:QI 1 "register_operand" "")
13578         (match_operator:QI 2 "ix86_comparison_operator"
13579           [(reg 17) (const_int 0)]))
13580    (parallel [(set (match_operand 3 "q_regs_operand" "")
13581                    (zero_extend (match_dup 1)))
13582               (clobber (reg:CC 17))])]
13583   "(peep2_reg_dead_p (3, operands[1])
13584     || operands_match_p (operands[1], operands[3]))
13585    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13586   [(set (match_dup 4) (match_dup 0))
13587    (set (strict_low_part (match_dup 5))
13588         (match_dup 2))]
13589 {
13590   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13591   operands[5] = gen_lowpart (QImode, operands[3]);
13592   ix86_expand_clear (operands[3]);
13593 })
13594 \f
13595 ;; Call instructions.
13596
13597 ;; The predicates normally associated with named expanders are not properly
13598 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13599 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13600
13601 ;; Call subroutine returning no value.
13602
13603 (define_expand "call_pop"
13604   [(parallel [(call (match_operand:QI 0 "" "")
13605                     (match_operand:SI 1 "" ""))
13606               (set (reg:SI 7)
13607                    (plus:SI (reg:SI 7)
13608                             (match_operand:SI 3 "" "")))])]
13609   "!TARGET_64BIT"
13610 {
13611   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13612   DONE;
13613 })
13614
13615 (define_insn "*call_pop_0"
13616   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13617          (match_operand:SI 1 "" ""))
13618    (set (reg:SI 7) (plus:SI (reg:SI 7)
13619                             (match_operand:SI 2 "immediate_operand" "")))]
13620   "!TARGET_64BIT"
13621 {
13622   if (SIBLING_CALL_P (insn))
13623     return "jmp\t%P0";
13624   else
13625     return "call\t%P0";
13626 }
13627   [(set_attr "type" "call")])
13628   
13629 (define_insn "*call_pop_1"
13630   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13631          (match_operand:SI 1 "" ""))
13632    (set (reg:SI 7) (plus:SI (reg:SI 7)
13633                             (match_operand:SI 2 "immediate_operand" "i")))]
13634   "!TARGET_64BIT"
13635 {
13636   if (constant_call_address_operand (operands[0], Pmode))
13637     {
13638       if (SIBLING_CALL_P (insn))
13639         return "jmp\t%P0";
13640       else
13641         return "call\t%P0";
13642     }
13643   if (SIBLING_CALL_P (insn))
13644     return "jmp\t%A0";
13645   else
13646     return "call\t%A0";
13647 }
13648   [(set_attr "type" "call")])
13649
13650 (define_expand "call"
13651   [(call (match_operand:QI 0 "" "")
13652          (match_operand 1 "" ""))
13653    (use (match_operand 2 "" ""))]
13654   ""
13655 {
13656   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13657   DONE;
13658 })
13659
13660 (define_expand "sibcall"
13661   [(call (match_operand:QI 0 "" "")
13662          (match_operand 1 "" ""))
13663    (use (match_operand 2 "" ""))]
13664   ""
13665 {
13666   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13667   DONE;
13668 })
13669
13670 (define_insn "*call_0"
13671   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13672          (match_operand 1 "" ""))]
13673   ""
13674 {
13675   if (SIBLING_CALL_P (insn))
13676     return "jmp\t%P0";
13677   else
13678     return "call\t%P0";
13679 }
13680   [(set_attr "type" "call")])
13681
13682 (define_insn "*call_1"
13683   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13684          (match_operand 1 "" ""))]
13685   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13686 {
13687   if (constant_call_address_operand (operands[0], QImode))
13688     return "call\t%P0";
13689   return "call\t%A0";
13690 }
13691   [(set_attr "type" "call")])
13692
13693 (define_insn "*sibcall_1"
13694   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13695          (match_operand 1 "" ""))]
13696   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13697 {
13698   if (constant_call_address_operand (operands[0], QImode))
13699     return "jmp\t%P0";
13700   return "jmp\t%A0";
13701 }
13702   [(set_attr "type" "call")])
13703
13704 (define_insn "*call_1_rex64"
13705   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13706          (match_operand 1 "" ""))]
13707   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13708 {
13709   if (constant_call_address_operand (operands[0], QImode))
13710     return "call\t%P0";
13711   return "call\t%A0";
13712 }
13713   [(set_attr "type" "call")])
13714
13715 (define_insn "*sibcall_1_rex64"
13716   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13717          (match_operand 1 "" ""))]
13718   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13719   "jmp\t%P0"
13720   [(set_attr "type" "call")])
13721
13722 (define_insn "*sibcall_1_rex64_v"
13723   [(call (mem:QI (reg:DI 40))
13724          (match_operand 0 "" ""))]
13725   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13726   "jmp\t*%%r11"
13727   [(set_attr "type" "call")])
13728
13729
13730 ;; Call subroutine, returning value in operand 0
13731
13732 (define_expand "call_value_pop"
13733   [(parallel [(set (match_operand 0 "" "")
13734                    (call (match_operand:QI 1 "" "")
13735                          (match_operand:SI 2 "" "")))
13736               (set (reg:SI 7)
13737                    (plus:SI (reg:SI 7)
13738                             (match_operand:SI 4 "" "")))])]
13739   "!TARGET_64BIT"
13740 {
13741   ix86_expand_call (operands[0], operands[1], operands[2],
13742                     operands[3], operands[4], 0);
13743   DONE;
13744 })
13745
13746 (define_expand "call_value"
13747   [(set (match_operand 0 "" "")
13748         (call (match_operand:QI 1 "" "")
13749               (match_operand:SI 2 "" "")))
13750    (use (match_operand:SI 3 "" ""))]
13751   ;; Operand 2 not used on the i386.
13752   ""
13753 {
13754   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13755   DONE;
13756 })
13757
13758 (define_expand "sibcall_value"
13759   [(set (match_operand 0 "" "")
13760         (call (match_operand:QI 1 "" "")
13761               (match_operand:SI 2 "" "")))
13762    (use (match_operand:SI 3 "" ""))]
13763   ;; Operand 2 not used on the i386.
13764   ""
13765 {
13766   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13767   DONE;
13768 })
13769
13770 ;; Call subroutine returning any type.
13771
13772 (define_expand "untyped_call"
13773   [(parallel [(call (match_operand 0 "" "")
13774                     (const_int 0))
13775               (match_operand 1 "" "")
13776               (match_operand 2 "" "")])]
13777   ""
13778 {
13779   int i;
13780
13781   /* In order to give reg-stack an easier job in validating two
13782      coprocessor registers as containing a possible return value,
13783      simply pretend the untyped call returns a complex long double
13784      value.  */
13785
13786   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13787                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13788                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13789                     NULL, 0);
13790
13791   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13792     {
13793       rtx set = XVECEXP (operands[2], 0, i);
13794       emit_move_insn (SET_DEST (set), SET_SRC (set));
13795     }
13796
13797   /* The optimizer does not know that the call sets the function value
13798      registers we stored in the result block.  We avoid problems by
13799      claiming that all hard registers are used and clobbered at this
13800      point.  */
13801   emit_insn (gen_blockage (const0_rtx));
13802
13803   DONE;
13804 })
13805 \f
13806 ;; Prologue and epilogue instructions
13807
13808 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13809 ;; all of memory.  This blocks insns from being moved across this point.
13810
13811 (define_insn "blockage"
13812   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13813   ""
13814   ""
13815   [(set_attr "length" "0")])
13816
13817 ;; Insn emitted into the body of a function to return from a function.
13818 ;; This is only done if the function's epilogue is known to be simple.
13819 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13820
13821 (define_expand "return"
13822   [(return)]
13823   "ix86_can_use_return_insn_p ()"
13824 {
13825   if (current_function_pops_args)
13826     {
13827       rtx popc = GEN_INT (current_function_pops_args);
13828       emit_jump_insn (gen_return_pop_internal (popc));
13829       DONE;
13830     }
13831 })
13832
13833 (define_insn "return_internal"
13834   [(return)]
13835   "reload_completed"
13836   "ret"
13837   [(set_attr "length" "1")
13838    (set_attr "length_immediate" "0")
13839    (set_attr "modrm" "0")])
13840
13841 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13842 ;; instruction Athlon and K8 have.
13843
13844 (define_insn "return_internal_long"
13845   [(return)
13846    (unspec [(const_int 0)] UNSPEC_REP)]
13847   "reload_completed"
13848   "rep {;} ret"
13849   [(set_attr "length" "1")
13850    (set_attr "length_immediate" "0")
13851    (set_attr "prefix_rep" "1")
13852    (set_attr "modrm" "0")])
13853
13854 (define_insn "return_pop_internal"
13855   [(return)
13856    (use (match_operand:SI 0 "const_int_operand" ""))]
13857   "reload_completed"
13858   "ret\t%0"
13859   [(set_attr "length" "3")
13860    (set_attr "length_immediate" "2")
13861    (set_attr "modrm" "0")])
13862
13863 (define_insn "return_indirect_internal"
13864   [(return)
13865    (use (match_operand:SI 0 "register_operand" "r"))]
13866   "reload_completed"
13867   "jmp\t%A0"
13868   [(set_attr "type" "ibr")
13869    (set_attr "length_immediate" "0")])
13870
13871 (define_insn "nop"
13872   [(const_int 0)]
13873   ""
13874   "nop"
13875   [(set_attr "length" "1")
13876    (set_attr "length_immediate" "0")
13877    (set_attr "modrm" "0")
13878    (set_attr "ppro_uops" "one")])
13879
13880 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13881 ;; branch prediction penalty for the third jump in a 16-byte
13882 ;; block on K8.
13883
13884 (define_insn "align"
13885   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13886   ""
13887 {
13888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13889   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13890 #else
13891   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13892      The align insn is used to avoid 3 jump instructions in the row to improve
13893      branch prediction and the benefits hardly outweight the cost of extra 8
13894      nops on the average inserted by full alignment pseudo operation.  */
13895 #endif
13896   return "";
13897 }
13898   [(set_attr "length" "16")])
13899
13900 (define_expand "prologue"
13901   [(const_int 1)]
13902   ""
13903   "ix86_expand_prologue (); DONE;")
13904
13905 (define_insn "set_got"
13906   [(set (match_operand:SI 0 "register_operand" "=r")
13907         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13908    (clobber (reg:CC 17))]
13909   "!TARGET_64BIT"
13910   { return output_set_got (operands[0]); }
13911   [(set_attr "type" "multi")
13912    (set_attr "length" "12")])
13913
13914 (define_expand "epilogue"
13915   [(const_int 1)]
13916   ""
13917   "ix86_expand_epilogue (1); DONE;")
13918
13919 (define_expand "sibcall_epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (0); DONE;")
13923
13924 (define_expand "eh_return"
13925   [(use (match_operand 0 "register_operand" ""))]
13926   ""
13927 {
13928   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13929
13930   /* Tricky bit: we write the address of the handler to which we will
13931      be returning into someone else's stack frame, one word below the
13932      stack address we wish to restore.  */
13933   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13934   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13935   tmp = gen_rtx_MEM (Pmode, tmp);
13936   emit_move_insn (tmp, ra);
13937
13938   if (Pmode == SImode)
13939     emit_insn (gen_eh_return_si (sa));
13940   else
13941     emit_insn (gen_eh_return_di (sa));
13942   emit_barrier ();
13943   DONE;
13944 })
13945
13946 (define_insn_and_split "eh_return_si"
13947   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13948                     UNSPECV_EH_RETURN)]
13949   "!TARGET_64BIT"
13950   "#"
13951   "reload_completed"
13952   [(const_int 1)]
13953   "ix86_expand_epilogue (2); DONE;")
13954
13955 (define_insn_and_split "eh_return_di"
13956   [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13957                     UNSPECV_EH_RETURN)]
13958   "TARGET_64BIT"
13959   "#"
13960   "reload_completed"
13961   [(const_int 1)]
13962   "ix86_expand_epilogue (2); DONE;")
13963
13964 (define_insn "leave"
13965   [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13966    (set (reg:SI 6) (mem:SI (reg:SI 6)))
13967    (clobber (mem:BLK (scratch)))]
13968   "!TARGET_64BIT"
13969   "leave"
13970   [(set_attr "type" "leave")])
13971
13972 (define_insn "leave_rex64"
13973   [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13974    (set (reg:DI 6) (mem:DI (reg:DI 6)))
13975    (clobber (mem:BLK (scratch)))]
13976   "TARGET_64BIT"
13977   "leave"
13978   [(set_attr "type" "leave")])
13979 \f
13980 (define_expand "ffssi2"
13981   [(parallel
13982      [(set (match_operand:SI 0 "register_operand" "") 
13983            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13984       (clobber (match_scratch:SI 2 ""))
13985       (clobber (reg:CC 17))])]
13986   ""
13987   "")
13988
13989 (define_insn_and_split "*ffs_cmove"
13990   [(set (match_operand:SI 0 "register_operand" "=r") 
13991         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13992    (clobber (match_scratch:SI 2 "=&r"))
13993    (clobber (reg:CC 17))]
13994   "TARGET_CMOVE"
13995   "#"
13996   "&& reload_completed"
13997   [(set (match_dup 2) (const_int -1))
13998    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13999               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14000    (set (match_dup 0) (if_then_else:SI
14001                         (eq (reg:CCZ 17) (const_int 0))
14002                         (match_dup 2)
14003                         (match_dup 0)))
14004    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14005               (clobber (reg:CC 17))])]
14006   "")
14007
14008 (define_insn_and_split "*ffs_no_cmove"
14009   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14010         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14011    (clobber (match_scratch:SI 2 "=&q"))
14012    (clobber (reg:CC 17))]
14013   ""
14014   "#"
14015   "reload_completed"
14016   [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14017               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14018    (set (strict_low_part (match_dup 3))
14019         (eq:QI (reg:CCZ 17) (const_int 0)))
14020    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14021               (clobber (reg:CC 17))])
14022    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14023               (clobber (reg:CC 17))])
14024    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14025               (clobber (reg:CC 17))])]
14026 {
14027   operands[3] = gen_lowpart (QImode, operands[2]);
14028   ix86_expand_clear (operands[2]);
14029 })
14030
14031 (define_insn "*ffssi_1"
14032   [(set (reg:CCZ 17)
14033         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14034                      (const_int 0)))
14035    (set (match_operand:SI 0 "register_operand" "=r")
14036         (ctz:SI (match_dup 1)))]
14037   ""
14038   "bsf{l}\t{%1, %0|%0, %1}"
14039   [(set_attr "prefix_0f" "1")
14040    (set_attr "ppro_uops" "few")])
14041
14042 (define_insn "ctzsi2"
14043   [(set (match_operand:SI 0 "register_operand" "=r")
14044         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14045    (clobber (reg:CC 17))]
14046   ""
14047   "bsf{l}\t{%1, %0|%0, %1}"
14048   [(set_attr "prefix_0f" "1")
14049    (set_attr "ppro_uops" "few")])
14050
14051 (define_expand "clzsi2"
14052   [(parallel
14053      [(set (match_operand:SI 0 "register_operand" "")
14054            (minus:SI (const_int 31)
14055                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14056       (clobber (reg:CC 17))])
14057    (parallel
14058      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14059       (clobber (reg:CC 17))])]
14060   ""
14061   "")
14062
14063 (define_insn "*bsr"
14064   [(set (match_operand:SI 0 "register_operand" "=r")
14065         (minus:SI (const_int 31)
14066                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14067    (clobber (reg:CC 17))]
14068   ""
14069   "bsr{l}\t{%1, %0|%0, %1}"
14070   [(set_attr "prefix_0f" "1")
14071    (set_attr "ppro_uops" "few")])
14072 \f
14073 ;; Thread-local storage patterns for ELF.
14074 ;;
14075 ;; Note that these code sequences must appear exactly as shown
14076 ;; in order to allow linker relaxation.
14077
14078 (define_insn "*tls_global_dynamic_32_gnu"
14079   [(set (match_operand:SI 0 "register_operand" "=a")
14080         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14081                     (match_operand:SI 2 "tls_symbolic_operand" "")
14082                     (match_operand:SI 3 "call_insn_operand" "")]
14083                     UNSPEC_TLS_GD))
14084    (clobber (match_scratch:SI 4 "=d"))
14085    (clobber (match_scratch:SI 5 "=c"))
14086    (clobber (reg:CC 17))]
14087   "!TARGET_64BIT && TARGET_GNU_TLS"
14088   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14089   [(set_attr "type" "multi")
14090    (set_attr "length" "12")])
14091
14092 (define_insn "*tls_global_dynamic_32_sun"
14093   [(set (match_operand:SI 0 "register_operand" "=a")
14094         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14095                     (match_operand:SI 2 "tls_symbolic_operand" "")
14096                     (match_operand:SI 3 "call_insn_operand" "")]
14097                     UNSPEC_TLS_GD))
14098    (clobber (match_scratch:SI 4 "=d"))
14099    (clobber (match_scratch:SI 5 "=c"))
14100    (clobber (reg:CC 17))]
14101   "!TARGET_64BIT && TARGET_SUN_TLS"
14102   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14103         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14104   [(set_attr "type" "multi")
14105    (set_attr "length" "14")])
14106
14107 (define_expand "tls_global_dynamic_32"
14108   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14109                    (unspec:SI
14110                     [(match_dup 2)
14111                      (match_operand:SI 1 "tls_symbolic_operand" "")
14112                      (match_dup 3)]
14113                     UNSPEC_TLS_GD))
14114               (clobber (match_scratch:SI 4 ""))
14115               (clobber (match_scratch:SI 5 ""))
14116               (clobber (reg:CC 17))])]
14117   ""
14118 {
14119   if (flag_pic)
14120     operands[2] = pic_offset_table_rtx;
14121   else
14122     {
14123       operands[2] = gen_reg_rtx (Pmode);
14124       emit_insn (gen_set_got (operands[2]));
14125     }
14126   operands[3] = ix86_tls_get_addr ();
14127 })
14128
14129 (define_insn "*tls_global_dynamic_64"
14130   [(set (match_operand:DI 0 "register_operand" "=a")
14131         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14132                       (match_operand:DI 3 "" "")))
14133    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14134               UNSPEC_TLS_GD)]
14135   "TARGET_64BIT"
14136   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14137   [(set_attr "type" "multi")
14138    (set_attr "length" "16")])
14139
14140 (define_expand "tls_global_dynamic_64"
14141   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14142                    (call (mem:QI (match_dup 2)) (const_int 0)))
14143               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14144                          UNSPEC_TLS_GD)])]
14145   ""
14146 {
14147   operands[2] = ix86_tls_get_addr ();
14148 })
14149
14150 (define_insn "*tls_local_dynamic_base_32_gnu"
14151   [(set (match_operand:SI 0 "register_operand" "=a")
14152         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153                     (match_operand:SI 2 "call_insn_operand" "")]
14154                    UNSPEC_TLS_LD_BASE))
14155    (clobber (match_scratch:SI 3 "=d"))
14156    (clobber (match_scratch:SI 4 "=c"))
14157    (clobber (reg:CC 17))]
14158   "!TARGET_64BIT && TARGET_GNU_TLS"
14159   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14160   [(set_attr "type" "multi")
14161    (set_attr "length" "11")])
14162
14163 (define_insn "*tls_local_dynamic_base_32_sun"
14164   [(set (match_operand:SI 0 "register_operand" "=a")
14165         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14166                     (match_operand:SI 2 "call_insn_operand" "")]
14167                    UNSPEC_TLS_LD_BASE))
14168    (clobber (match_scratch:SI 3 "=d"))
14169    (clobber (match_scratch:SI 4 "=c"))
14170    (clobber (reg:CC 17))]
14171   "!TARGET_64BIT && TARGET_SUN_TLS"
14172   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14173         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14174   [(set_attr "type" "multi")
14175    (set_attr "length" "13")])
14176
14177 (define_expand "tls_local_dynamic_base_32"
14178   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14179                    (unspec:SI [(match_dup 1) (match_dup 2)]
14180                               UNSPEC_TLS_LD_BASE))
14181               (clobber (match_scratch:SI 3 ""))
14182               (clobber (match_scratch:SI 4 ""))
14183               (clobber (reg:CC 17))])]
14184   ""
14185 {
14186   if (flag_pic)
14187     operands[1] = pic_offset_table_rtx;
14188   else
14189     {
14190       operands[1] = gen_reg_rtx (Pmode);
14191       emit_insn (gen_set_got (operands[1]));
14192     }
14193   operands[2] = ix86_tls_get_addr ();
14194 })
14195
14196 (define_insn "*tls_local_dynamic_base_64"
14197   [(set (match_operand:DI 0 "register_operand" "=a")
14198         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14199                       (match_operand:DI 2 "" "")))
14200    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14201   "TARGET_64BIT"
14202   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14203   [(set_attr "type" "multi")
14204    (set_attr "length" "12")])
14205
14206 (define_expand "tls_local_dynamic_base_64"
14207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14208                    (call (mem:QI (match_dup 1)) (const_int 0)))
14209               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14210   ""
14211 {
14212   operands[1] = ix86_tls_get_addr ();
14213 })
14214
14215 ;; Local dynamic of a single variable is a lose.  Show combine how
14216 ;; to convert that back to global dynamic.
14217
14218 (define_insn_and_split "*tls_local_dynamic_32_once"
14219   [(set (match_operand:SI 0 "register_operand" "=a")
14220         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14221                              (match_operand:SI 2 "call_insn_operand" "")]
14222                             UNSPEC_TLS_LD_BASE)
14223                  (const:SI (unspec:SI
14224                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14225                             UNSPEC_DTPOFF))))
14226    (clobber (match_scratch:SI 4 "=d"))
14227    (clobber (match_scratch:SI 5 "=c"))
14228    (clobber (reg:CC 17))]
14229   ""
14230   "#"
14231   ""
14232   [(parallel [(set (match_dup 0)
14233                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14234                               UNSPEC_TLS_GD))
14235               (clobber (match_dup 4))
14236               (clobber (match_dup 5))
14237               (clobber (reg:CC 17))])]
14238   "")
14239
14240 ;; Load and add the thread base pointer from %gs:0.
14241
14242 (define_insn "*load_tp_si"
14243   [(set (match_operand:SI 0 "register_operand" "=r")
14244         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14245   "!TARGET_64BIT"
14246   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14247   [(set_attr "type" "imov")
14248    (set_attr "modrm" "0")
14249    (set_attr "length" "7")
14250    (set_attr "memory" "load")
14251    (set_attr "imm_disp" "false")])
14252
14253 (define_insn "*add_tp_si"
14254   [(set (match_operand:SI 0 "register_operand" "=r")
14255         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14256                  (match_operand:SI 1 "register_operand" "0")))
14257    (clobber (reg:CC 17))]
14258   "!TARGET_64BIT"
14259   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14260   [(set_attr "type" "alu")
14261    (set_attr "modrm" "0")
14262    (set_attr "length" "7")
14263    (set_attr "memory" "load")
14264    (set_attr "imm_disp" "false")])
14265
14266 (define_insn "*load_tp_di"
14267   [(set (match_operand:DI 0 "register_operand" "=r")
14268         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14269   "TARGET_64BIT"
14270   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14271   [(set_attr "type" "imov")
14272    (set_attr "modrm" "0")
14273    (set_attr "length" "7")
14274    (set_attr "memory" "load")
14275    (set_attr "imm_disp" "false")])
14276
14277 (define_insn "*add_tp_di"
14278   [(set (match_operand:DI 0 "register_operand" "=r")
14279         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14280                  (match_operand:DI 1 "register_operand" "0")))
14281    (clobber (reg:CC 17))]
14282   "TARGET_64BIT"
14283   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14284   [(set_attr "type" "alu")
14285    (set_attr "modrm" "0")
14286    (set_attr "length" "7")
14287    (set_attr "memory" "load")
14288    (set_attr "imm_disp" "false")])
14289 \f
14290 ;; These patterns match the binary 387 instructions for addM3, subM3,
14291 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14292 ;; SFmode.  The first is the normal insn, the second the same insn but
14293 ;; with one operand a conversion, and the third the same insn but with
14294 ;; the other operand a conversion.  The conversion may be SFmode or
14295 ;; SImode if the target mode DFmode, but only SImode if the target mode
14296 ;; is SFmode.
14297
14298 ;; Gcc is slightly more smart about handling normal two address instructions
14299 ;; so use special patterns for add and mull.
14300 (define_insn "*fop_sf_comm_nosse"
14301   [(set (match_operand:SF 0 "register_operand" "=f")
14302         (match_operator:SF 3 "binary_fp_operator"
14303                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14304                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14305   "TARGET_80387 && !TARGET_SSE_MATH
14306    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14307    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14308   "* return output_387_binary_op (insn, operands);"
14309   [(set (attr "type") 
14310         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14311            (const_string "fmul")
14312            (const_string "fop")))
14313    (set_attr "mode" "SF")])
14314
14315 (define_insn "*fop_sf_comm"
14316   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14317         (match_operator:SF 3 "binary_fp_operator"
14318                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14319                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14320   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14321    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14323   "* return output_387_binary_op (insn, operands);"
14324   [(set (attr "type") 
14325         (if_then_else (eq_attr "alternative" "1")
14326            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14327               (const_string "ssemul")
14328               (const_string "sseadd"))
14329            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14330               (const_string "fmul")
14331               (const_string "fop"))))
14332    (set_attr "mode" "SF")])
14333
14334 (define_insn "*fop_sf_comm_sse"
14335   [(set (match_operand:SF 0 "register_operand" "=x")
14336         (match_operator:SF 3 "binary_fp_operator"
14337                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14338                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14339   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14341   "* return output_387_binary_op (insn, operands);"
14342   [(set (attr "type") 
14343         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14344            (const_string "ssemul")
14345            (const_string "sseadd")))
14346    (set_attr "mode" "SF")])
14347
14348 (define_insn "*fop_df_comm_nosse"
14349   [(set (match_operand:DF 0 "register_operand" "=f")
14350         (match_operator:DF 3 "binary_fp_operator"
14351                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14352                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14353   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14354    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14355    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14356   "* return output_387_binary_op (insn, operands);"
14357   [(set (attr "type") 
14358         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14359            (const_string "fmul")
14360            (const_string "fop")))
14361    (set_attr "mode" "DF")])
14362
14363 (define_insn "*fop_df_comm"
14364   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14365         (match_operator:DF 3 "binary_fp_operator"
14366                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14367                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14368   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14369    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14370    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14371   "* return output_387_binary_op (insn, operands);"
14372   [(set (attr "type") 
14373         (if_then_else (eq_attr "alternative" "1")
14374            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14375               (const_string "ssemul")
14376               (const_string "sseadd"))
14377            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14378               (const_string "fmul")
14379               (const_string "fop"))))
14380    (set_attr "mode" "DF")])
14381
14382 (define_insn "*fop_df_comm_sse"
14383   [(set (match_operand:DF 0 "register_operand" "=Y")
14384         (match_operator:DF 3 "binary_fp_operator"
14385                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14386                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14387   "TARGET_SSE2 && TARGET_SSE_MATH
14388    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14390   "* return output_387_binary_op (insn, operands);"
14391   [(set (attr "type") 
14392         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14393            (const_string "ssemul")
14394            (const_string "sseadd")))
14395    (set_attr "mode" "DF")])
14396
14397 (define_insn "*fop_xf_comm"
14398   [(set (match_operand:XF 0 "register_operand" "=f")
14399         (match_operator:XF 3 "binary_fp_operator"
14400                         [(match_operand:XF 1 "register_operand" "%0")
14401                          (match_operand:XF 2 "register_operand" "f")]))]
14402   "TARGET_80387
14403    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14404   "* return output_387_binary_op (insn, operands);"
14405   [(set (attr "type") 
14406         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14407            (const_string "fmul")
14408            (const_string "fop")))
14409    (set_attr "mode" "XF")])
14410
14411 (define_insn "*fop_sf_1_nosse"
14412   [(set (match_operand:SF 0 "register_operand" "=f,f")
14413         (match_operator:SF 3 "binary_fp_operator"
14414                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14415                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14416   "TARGET_80387 && !TARGET_SSE_MATH
14417    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14418    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14419   "* return output_387_binary_op (insn, operands);"
14420   [(set (attr "type") 
14421         (cond [(match_operand:SF 3 "mult_operator" "") 
14422                  (const_string "fmul")
14423                (match_operand:SF 3 "div_operator" "") 
14424                  (const_string "fdiv")
14425               ]
14426               (const_string "fop")))
14427    (set_attr "mode" "SF")])
14428
14429 (define_insn "*fop_sf_1"
14430   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14431         (match_operator:SF 3 "binary_fp_operator"
14432                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14433                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14434   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14435    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14436    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14437   "* return output_387_binary_op (insn, operands);"
14438   [(set (attr "type") 
14439         (cond [(and (eq_attr "alternative" "2")
14440                     (match_operand:SF 3 "mult_operator" ""))
14441                  (const_string "ssemul")
14442                (and (eq_attr "alternative" "2")
14443                     (match_operand:SF 3 "div_operator" ""))
14444                  (const_string "ssediv")
14445                (eq_attr "alternative" "2")
14446                  (const_string "sseadd")
14447                (match_operand:SF 3 "mult_operator" "") 
14448                  (const_string "fmul")
14449                (match_operand:SF 3 "div_operator" "") 
14450                  (const_string "fdiv")
14451               ]
14452               (const_string "fop")))
14453    (set_attr "mode" "SF")])
14454
14455 (define_insn "*fop_sf_1_sse"
14456   [(set (match_operand:SF 0 "register_operand" "=x")
14457         (match_operator:SF 3 "binary_fp_operator"
14458                         [(match_operand:SF 1 "register_operand" "0")
14459                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14460   "TARGET_SSE_MATH
14461    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14462   "* return output_387_binary_op (insn, operands);"
14463   [(set (attr "type") 
14464         (cond [(match_operand:SF 3 "mult_operator" "")
14465                  (const_string "ssemul")
14466                (match_operand:SF 3 "div_operator" "")
14467                  (const_string "ssediv")
14468               ]
14469               (const_string "sseadd")))
14470    (set_attr "mode" "SF")])
14471
14472 ;; ??? Add SSE splitters for these!
14473 (define_insn "*fop_sf_2"
14474   [(set (match_operand:SF 0 "register_operand" "=f,f")
14475         (match_operator:SF 3 "binary_fp_operator"
14476           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14477            (match_operand:SF 2 "register_operand" "0,0")]))]
14478   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14479   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (cond [(match_operand:SF 3 "mult_operator" "") 
14482                  (const_string "fmul")
14483                (match_operand:SF 3 "div_operator" "") 
14484                  (const_string "fdiv")
14485               ]
14486               (const_string "fop")))
14487    (set_attr "fp_int_src" "true")
14488    (set_attr "ppro_uops" "many")
14489    (set_attr "mode" "SI")])
14490
14491 (define_insn "*fop_sf_3"
14492   [(set (match_operand:SF 0 "register_operand" "=f,f")
14493         (match_operator:SF 3 "binary_fp_operator"
14494           [(match_operand:SF 1 "register_operand" "0,0")
14495            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14496   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14497   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14498   [(set (attr "type") 
14499         (cond [(match_operand:SF 3 "mult_operator" "") 
14500                  (const_string "fmul")
14501                (match_operand:SF 3 "div_operator" "") 
14502                  (const_string "fdiv")
14503               ]
14504               (const_string "fop")))
14505    (set_attr "fp_int_src" "true")
14506    (set_attr "ppro_uops" "many")
14507    (set_attr "mode" "SI")])
14508
14509 (define_insn "*fop_df_1_nosse"
14510   [(set (match_operand:DF 0 "register_operand" "=f,f")
14511         (match_operator:DF 3 "binary_fp_operator"
14512                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14513                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14514   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14515    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14516    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14517   "* return output_387_binary_op (insn, operands);"
14518   [(set (attr "type") 
14519         (cond [(match_operand:DF 3 "mult_operator" "") 
14520                  (const_string "fmul")
14521                (match_operand:DF 3 "div_operator" "")
14522                  (const_string "fdiv")
14523               ]
14524               (const_string "fop")))
14525    (set_attr "mode" "DF")])
14526
14527
14528 (define_insn "*fop_df_1"
14529   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14530         (match_operator:DF 3 "binary_fp_operator"
14531                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14532                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14533   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14534    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14535    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14536   "* return output_387_binary_op (insn, operands);"
14537   [(set (attr "type") 
14538         (cond [(and (eq_attr "alternative" "2")
14539                     (match_operand:SF 3 "mult_operator" ""))
14540                  (const_string "ssemul")
14541                (and (eq_attr "alternative" "2")
14542                     (match_operand:SF 3 "div_operator" ""))
14543                  (const_string "ssediv")
14544                (eq_attr "alternative" "2")
14545                  (const_string "sseadd")
14546                (match_operand:DF 3 "mult_operator" "") 
14547                  (const_string "fmul")
14548                (match_operand:DF 3 "div_operator" "") 
14549                  (const_string "fdiv")
14550               ]
14551               (const_string "fop")))
14552    (set_attr "mode" "DF")])
14553
14554 (define_insn "*fop_df_1_sse"
14555   [(set (match_operand:DF 0 "register_operand" "=Y")
14556         (match_operator:DF 3 "binary_fp_operator"
14557                         [(match_operand:DF 1 "register_operand" "0")
14558                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14559   "TARGET_SSE2 && TARGET_SSE_MATH
14560    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14561   "* return output_387_binary_op (insn, operands);"
14562   [(set_attr "mode" "DF")
14563    (set (attr "type") 
14564         (cond [(match_operand:SF 3 "mult_operator" "")
14565                  (const_string "ssemul")
14566                (match_operand:SF 3 "div_operator" "")
14567                  (const_string "ssediv")
14568               ]
14569               (const_string "sseadd")))])
14570
14571 ;; ??? Add SSE splitters for these!
14572 (define_insn "*fop_df_2"
14573   [(set (match_operand:DF 0 "register_operand" "=f,f")
14574         (match_operator:DF 3 "binary_fp_operator"
14575            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14576             (match_operand:DF 2 "register_operand" "0,0")]))]
14577   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14578   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14579   [(set (attr "type") 
14580         (cond [(match_operand:DF 3 "mult_operator" "") 
14581                  (const_string "fmul")
14582                (match_operand:DF 3 "div_operator" "") 
14583                  (const_string "fdiv")
14584               ]
14585               (const_string "fop")))
14586    (set_attr "fp_int_src" "true")
14587    (set_attr "ppro_uops" "many")
14588    (set_attr "mode" "SI")])
14589
14590 (define_insn "*fop_df_3"
14591   [(set (match_operand:DF 0 "register_operand" "=f,f")
14592         (match_operator:DF 3 "binary_fp_operator"
14593            [(match_operand:DF 1 "register_operand" "0,0")
14594             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14595   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14596   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14597   [(set (attr "type") 
14598         (cond [(match_operand:DF 3 "mult_operator" "") 
14599                  (const_string "fmul")
14600                (match_operand:DF 3 "div_operator" "") 
14601                  (const_string "fdiv")
14602               ]
14603               (const_string "fop")))
14604    (set_attr "fp_int_src" "true")
14605    (set_attr "ppro_uops" "many")
14606    (set_attr "mode" "SI")])
14607
14608 (define_insn "*fop_df_4"
14609   [(set (match_operand:DF 0 "register_operand" "=f,f")
14610         (match_operator:DF 3 "binary_fp_operator"
14611            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14612             (match_operand:DF 2 "register_operand" "0,f")]))]
14613   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14614    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14615   "* return output_387_binary_op (insn, operands);"
14616   [(set (attr "type") 
14617         (cond [(match_operand:DF 3 "mult_operator" "") 
14618                  (const_string "fmul")
14619                (match_operand:DF 3 "div_operator" "") 
14620                  (const_string "fdiv")
14621               ]
14622               (const_string "fop")))
14623    (set_attr "mode" "SF")])
14624
14625 (define_insn "*fop_df_5"
14626   [(set (match_operand:DF 0 "register_operand" "=f,f")
14627         (match_operator:DF 3 "binary_fp_operator"
14628           [(match_operand:DF 1 "register_operand" "0,f")
14629            (float_extend:DF
14630             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14631   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14632   "* return output_387_binary_op (insn, operands);"
14633   [(set (attr "type") 
14634         (cond [(match_operand:DF 3 "mult_operator" "") 
14635                  (const_string "fmul")
14636                (match_operand:DF 3 "div_operator" "") 
14637                  (const_string "fdiv")
14638               ]
14639               (const_string "fop")))
14640    (set_attr "mode" "SF")])
14641
14642 (define_insn "*fop_df_6"
14643   [(set (match_operand:DF 0 "register_operand" "=f,f")
14644         (match_operator:DF 3 "binary_fp_operator"
14645           [(float_extend:DF
14646             (match_operand:SF 1 "register_operand" "0,f"))
14647            (float_extend:DF
14648             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14649   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14650   "* return output_387_binary_op (insn, operands);"
14651   [(set (attr "type") 
14652         (cond [(match_operand:DF 3 "mult_operator" "") 
14653                  (const_string "fmul")
14654                (match_operand:DF 3 "div_operator" "") 
14655                  (const_string "fdiv")
14656               ]
14657               (const_string "fop")))
14658    (set_attr "mode" "SF")])
14659
14660 (define_insn "*fop_xf_1"
14661   [(set (match_operand:XF 0 "register_operand" "=f,f")
14662         (match_operator:XF 3 "binary_fp_operator"
14663                         [(match_operand:XF 1 "register_operand" "0,f")
14664                          (match_operand:XF 2 "register_operand" "f,0")]))]
14665   "TARGET_80387
14666    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14667   "* return output_387_binary_op (insn, operands);"
14668   [(set (attr "type") 
14669         (cond [(match_operand:XF 3 "mult_operator" "") 
14670                  (const_string "fmul")
14671                (match_operand:XF 3 "div_operator" "") 
14672                  (const_string "fdiv")
14673               ]
14674               (const_string "fop")))
14675    (set_attr "mode" "XF")])
14676
14677 (define_insn "*fop_xf_2"
14678   [(set (match_operand:XF 0 "register_operand" "=f,f")
14679         (match_operator:XF 3 "binary_fp_operator"
14680            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14681             (match_operand:XF 2 "register_operand" "0,0")]))]
14682   "TARGET_80387 && TARGET_USE_FIOP"
14683   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14684   [(set (attr "type") 
14685         (cond [(match_operand:XF 3 "mult_operator" "") 
14686                  (const_string "fmul")
14687                (match_operand:XF 3 "div_operator" "") 
14688                  (const_string "fdiv")
14689               ]
14690               (const_string "fop")))
14691    (set_attr "fp_int_src" "true")
14692    (set_attr "mode" "SI")
14693    (set_attr "ppro_uops" "many")])
14694
14695 (define_insn "*fop_xf_3"
14696   [(set (match_operand:XF 0 "register_operand" "=f,f")
14697         (match_operator:XF 3 "binary_fp_operator"
14698           [(match_operand:XF 1 "register_operand" "0,0")
14699            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14700   "TARGET_80387 && TARGET_USE_FIOP"
14701   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14702   [(set (attr "type") 
14703         (cond [(match_operand:XF 3 "mult_operator" "") 
14704                  (const_string "fmul")
14705                (match_operand:XF 3 "div_operator" "") 
14706                  (const_string "fdiv")
14707               ]
14708               (const_string "fop")))
14709    (set_attr "fp_int_src" "true")
14710    (set_attr "mode" "SI")
14711    (set_attr "ppro_uops" "many")])
14712
14713 (define_insn "*fop_xf_4"
14714   [(set (match_operand:XF 0 "register_operand" "=f,f")
14715         (match_operator:XF 3 "binary_fp_operator"
14716            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14717             (match_operand:XF 2 "register_operand" "0,f")]))]
14718   "TARGET_80387"
14719   "* return output_387_binary_op (insn, operands);"
14720   [(set (attr "type") 
14721         (cond [(match_operand:XF 3 "mult_operator" "") 
14722                  (const_string "fmul")
14723                (match_operand:XF 3 "div_operator" "") 
14724                  (const_string "fdiv")
14725               ]
14726               (const_string "fop")))
14727    (set_attr "mode" "SF")])
14728
14729 (define_insn "*fop_xf_5"
14730   [(set (match_operand:XF 0 "register_operand" "=f,f")
14731         (match_operator:XF 3 "binary_fp_operator"
14732           [(match_operand:XF 1 "register_operand" "0,f")
14733            (float_extend:XF
14734             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14735   "TARGET_80387"
14736   "* return output_387_binary_op (insn, operands);"
14737   [(set (attr "type") 
14738         (cond [(match_operand:XF 3 "mult_operator" "") 
14739                  (const_string "fmul")
14740                (match_operand:XF 3 "div_operator" "") 
14741                  (const_string "fdiv")
14742               ]
14743               (const_string "fop")))
14744    (set_attr "mode" "SF")])
14745
14746 (define_insn "*fop_xf_6"
14747   [(set (match_operand:XF 0 "register_operand" "=f,f")
14748         (match_operator:XF 3 "binary_fp_operator"
14749           [(float_extend:XF
14750             (match_operand 1 "register_operand" "0,f"))
14751            (float_extend:XF
14752             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14753   "TARGET_80387"
14754   "* return output_387_binary_op (insn, operands);"
14755   [(set (attr "type") 
14756         (cond [(match_operand:XF 3 "mult_operator" "") 
14757                  (const_string "fmul")
14758                (match_operand:XF 3 "div_operator" "") 
14759                  (const_string "fdiv")
14760               ]
14761               (const_string "fop")))
14762    (set_attr "mode" "SF")])
14763
14764 (define_split
14765   [(set (match_operand 0 "register_operand" "")
14766         (match_operator 3 "binary_fp_operator"
14767            [(float (match_operand:SI 1 "register_operand" ""))
14768             (match_operand 2 "register_operand" "")]))]
14769   "TARGET_80387 && reload_completed
14770    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14771   [(const_int 0)]
14772
14773   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14774   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14775   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14776                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14777                                           GET_MODE (operands[3]),
14778                                           operands[4],
14779                                           operands[2])));
14780   ix86_free_from_memory (GET_MODE (operands[1]));
14781   DONE;
14782 })
14783
14784 (define_split
14785   [(set (match_operand 0 "register_operand" "")
14786         (match_operator 3 "binary_fp_operator"
14787            [(match_operand 1 "register_operand" "")
14788             (float (match_operand:SI 2 "register_operand" ""))]))]
14789   "TARGET_80387 && reload_completed
14790    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14791   [(const_int 0)]
14792 {
14793   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14794   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14795   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14796                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14797                                           GET_MODE (operands[3]),
14798                                           operands[1],
14799                                           operands[4])));
14800   ix86_free_from_memory (GET_MODE (operands[2]));
14801   DONE;
14802 })
14803 \f
14804 ;; FPU special functions.
14805
14806 (define_expand "sqrtsf2"
14807   [(set (match_operand:SF 0 "register_operand" "")
14808         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14809   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14810 {
14811   if (!TARGET_SSE_MATH)
14812     operands[1] = force_reg (SFmode, operands[1]);
14813 })
14814
14815 (define_insn "sqrtsf2_1"
14816   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14817         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14818   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14819    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14820   "@
14821    fsqrt
14822    sqrtss\t{%1, %0|%0, %1}"
14823   [(set_attr "type" "fpspc,sse")
14824    (set_attr "mode" "SF,SF")
14825    (set_attr "athlon_decode" "direct,*")])
14826
14827 (define_insn "sqrtsf2_1_sse_only"
14828   [(set (match_operand:SF 0 "register_operand" "=x")
14829         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14830   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14831   "sqrtss\t{%1, %0|%0, %1}"
14832   [(set_attr "type" "sse")
14833    (set_attr "mode" "SF")
14834    (set_attr "athlon_decode" "*")])
14835
14836 (define_insn "sqrtsf2_i387"
14837   [(set (match_operand:SF 0 "register_operand" "=f")
14838         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14839   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14840    && !TARGET_SSE_MATH"
14841   "fsqrt"
14842   [(set_attr "type" "fpspc")
14843    (set_attr "mode" "SF")
14844    (set_attr "athlon_decode" "direct")])
14845
14846 (define_expand "sqrtdf2"
14847   [(set (match_operand:DF 0 "register_operand" "")
14848         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14849   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14850    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14851 {
14852   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14853     operands[1] = force_reg (DFmode, operands[1]);
14854 })
14855
14856 (define_insn "sqrtdf2_1"
14857   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14858         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14859   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14860    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14861   "@
14862    fsqrt
14863    sqrtsd\t{%1, %0|%0, %1}"
14864   [(set_attr "type" "fpspc,sse")
14865    (set_attr "mode" "DF,DF")
14866    (set_attr "athlon_decode" "direct,*")])
14867
14868 (define_insn "sqrtdf2_1_sse_only"
14869   [(set (match_operand:DF 0 "register_operand" "=Y")
14870         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14871   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14872   "sqrtsd\t{%1, %0|%0, %1}"
14873   [(set_attr "type" "sse")
14874    (set_attr "mode" "DF")
14875    (set_attr "athlon_decode" "*")])
14876
14877 (define_insn "sqrtdf2_i387"
14878   [(set (match_operand:DF 0 "register_operand" "=f")
14879         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14880   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14881    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14882   "fsqrt"
14883   [(set_attr "type" "fpspc")
14884    (set_attr "mode" "DF")
14885    (set_attr "athlon_decode" "direct")])
14886
14887 (define_insn "*sqrtextendsfdf2"
14888   [(set (match_operand:DF 0 "register_operand" "=f")
14889         (sqrt:DF (float_extend:DF
14890                   (match_operand:SF 1 "register_operand" "0"))))]
14891   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14892    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14893   "fsqrt"
14894   [(set_attr "type" "fpspc")
14895    (set_attr "mode" "DF")
14896    (set_attr "athlon_decode" "direct")])
14897
14898 (define_insn "sqrtxf2"
14899   [(set (match_operand:XF 0 "register_operand" "=f")
14900         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14901   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14902    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14903   "fsqrt"
14904   [(set_attr "type" "fpspc")
14905    (set_attr "mode" "XF")
14906    (set_attr "athlon_decode" "direct")])
14907
14908 (define_insn "*sqrtextenddfxf2"
14909   [(set (match_operand:XF 0 "register_operand" "=f")
14910         (sqrt:XF (float_extend:XF
14911                   (match_operand:DF 1 "register_operand" "0"))))]
14912   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14913   "fsqrt"
14914   [(set_attr "type" "fpspc")
14915    (set_attr "mode" "XF")
14916    (set_attr "athlon_decode" "direct")])
14917
14918 (define_insn "*sqrtextendsfxf2"
14919   [(set (match_operand:XF 0 "register_operand" "=f")
14920         (sqrt:XF (float_extend:XF
14921                   (match_operand:SF 1 "register_operand" "0"))))]
14922   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14923   "fsqrt"
14924   [(set_attr "type" "fpspc")
14925    (set_attr "mode" "XF")
14926    (set_attr "athlon_decode" "direct")])
14927
14928 (define_insn "sindf2"
14929   [(set (match_operand:DF 0 "register_operand" "=f")
14930         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14931   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14932    && flag_unsafe_math_optimizations"
14933   "fsin"
14934   [(set_attr "type" "fpspc")
14935    (set_attr "mode" "DF")])
14936
14937 (define_insn "sinsf2"
14938   [(set (match_operand:SF 0 "register_operand" "=f")
14939         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14941    && flag_unsafe_math_optimizations"
14942   "fsin"
14943   [(set_attr "type" "fpspc")
14944    (set_attr "mode" "SF")])
14945
14946 (define_insn "*sinextendsfdf2"
14947   [(set (match_operand:DF 0 "register_operand" "=f")
14948         (unspec:DF [(float_extend:DF
14949                      (match_operand:SF 1 "register_operand" "0"))]
14950                    UNSPEC_SIN))]
14951   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14952    && flag_unsafe_math_optimizations"
14953   "fsin"
14954   [(set_attr "type" "fpspc")
14955    (set_attr "mode" "DF")])
14956
14957 (define_insn "sinxf2"
14958   [(set (match_operand:XF 0 "register_operand" "=f")
14959         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14960   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14961    && flag_unsafe_math_optimizations"
14962   "fsin"
14963   [(set_attr "type" "fpspc")
14964    (set_attr "mode" "XF")])
14965
14966 (define_insn "cosdf2"
14967   [(set (match_operand:DF 0 "register_operand" "=f")
14968         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14969   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14970    && flag_unsafe_math_optimizations"
14971   "fcos"
14972   [(set_attr "type" "fpspc")
14973    (set_attr "mode" "DF")])
14974
14975 (define_insn "cossf2"
14976   [(set (match_operand:SF 0 "register_operand" "=f")
14977         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14978   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14979    && flag_unsafe_math_optimizations"
14980   "fcos"
14981   [(set_attr "type" "fpspc")
14982    (set_attr "mode" "SF")])
14983
14984 (define_insn "*cosextendsfdf2"
14985   [(set (match_operand:DF 0 "register_operand" "=f")
14986         (unspec:DF [(float_extend:DF
14987                      (match_operand:SF 1 "register_operand" "0"))]
14988                    UNSPEC_COS))]
14989   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14990    && flag_unsafe_math_optimizations"
14991   "fcos"
14992   [(set_attr "type" "fpspc")
14993    (set_attr "mode" "DF")])
14994
14995 (define_insn "cosxf2"
14996   [(set (match_operand:XF 0 "register_operand" "=f")
14997         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14998   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14999    && flag_unsafe_math_optimizations"
15000   "fcos"
15001   [(set_attr "type" "fpspc")
15002    (set_attr "mode" "XF")])
15003
15004 (define_insn "atan2df3_1"
15005   [(set (match_operand:DF 0 "register_operand" "=f")
15006         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15007                     (match_operand:DF 1 "register_operand" "u")]
15008                    UNSPEC_FPATAN))
15009    (clobber (match_scratch:DF 3 "=1"))]
15010   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15011    && flag_unsafe_math_optimizations"
15012   "fpatan"
15013   [(set_attr "type" "fpspc")
15014    (set_attr "mode" "DF")])
15015
15016 (define_expand "atan2df3"
15017   [(use (match_operand:DF 0 "register_operand" "=f"))
15018    (use (match_operand:DF 2 "register_operand" "0"))
15019    (use (match_operand:DF 1 "register_operand" "u"))]
15020   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15021    && flag_unsafe_math_optimizations"
15022 {
15023   rtx copy = gen_reg_rtx (DFmode);
15024   emit_move_insn (copy, operands[1]);
15025   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15026   DONE;
15027 })
15028
15029 (define_insn "atan2sf3_1"
15030   [(set (match_operand:SF 0 "register_operand" "=f")
15031         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15032                     (match_operand:SF 1 "register_operand" "u")]
15033                    UNSPEC_FPATAN))
15034    (clobber (match_scratch:SF 3 "=1"))]
15035   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15036    && flag_unsafe_math_optimizations"
15037   "fpatan"
15038   [(set_attr "type" "fpspc")
15039    (set_attr "mode" "SF")])
15040
15041 (define_expand "atan2sf3"
15042   [(use (match_operand:SF 0 "register_operand" "=f"))
15043    (use (match_operand:SF 2 "register_operand" "0"))
15044    (use (match_operand:SF 1 "register_operand" "u"))]
15045   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15046    && flag_unsafe_math_optimizations"
15047 {
15048   rtx copy = gen_reg_rtx (SFmode);
15049   emit_move_insn (copy, operands[1]);
15050   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15051   DONE;
15052 })
15053
15054 (define_insn "atan2xf3_1"
15055   [(set (match_operand:XF 0 "register_operand" "=f")
15056         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15057                     (match_operand:XF 1 "register_operand" "u")]
15058                    UNSPEC_FPATAN))
15059    (clobber (match_scratch:XF 3 "=1"))]
15060   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15061    && flag_unsafe_math_optimizations"
15062   "fpatan"
15063   [(set_attr "type" "fpspc")
15064    (set_attr "mode" "XF")])
15065
15066 (define_expand "atan2xf3"
15067   [(use (match_operand:XF 0 "register_operand" "=f"))
15068    (use (match_operand:XF 2 "register_operand" "0"))
15069    (use (match_operand:XF 1 "register_operand" "u"))]
15070   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15071    && flag_unsafe_math_optimizations"
15072 {
15073   rtx copy = gen_reg_rtx (XFmode);
15074   emit_move_insn (copy, operands[1]);
15075   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15076   DONE;
15077 })
15078
15079 (define_insn "*fyl2x_sfxf3"
15080   [(set (match_operand:SF 0 "register_operand" "=f")
15081          (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15082                      (match_operand:XF 1 "register_operand" "u")]
15083                     UNSPEC_FYL2X))
15084    (clobber (match_scratch:SF 3 "=1"))]
15085   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15086    && flag_unsafe_math_optimizations"
15087   "fyl2x"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "SF")])
15090
15091 (define_insn "*fyl2x_dfxf3"
15092   [(set (match_operand:DF 0 "register_operand" "=f")
15093          (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15094                      (match_operand:XF 1 "register_operand" "u")]
15095                     UNSPEC_FYL2X))
15096    (clobber (match_scratch:DF 3 "=1"))]
15097   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15098    && flag_unsafe_math_optimizations"
15099   "fyl2x"
15100   [(set_attr "type" "fpspc")
15101    (set_attr "mode" "DF")])
15102
15103 (define_insn "*fyl2x_xf3"
15104   [(set (match_operand:XF 0 "register_operand" "=f")
15105         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15106                     (match_operand:XF 1 "register_operand" "u")]
15107                    UNSPEC_FYL2X))
15108    (clobber (match_scratch:XF 3 "=1"))]
15109   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15110    && flag_unsafe_math_optimizations"
15111   "fyl2x"
15112   [(set_attr "type" "fpspc")
15113    (set_attr "mode" "XF")])
15114
15115 (define_expand "logsf2"
15116   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15117                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
15118                                (match_dup 2)] UNSPEC_FYL2X))
15119               (clobber (match_scratch:SF 3 ""))])]
15120   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15121    && flag_unsafe_math_optimizations"
15122 {
15123   rtx temp;
15124
15125   operands[2] = gen_reg_rtx (XFmode);
15126   temp = standard_80387_constant_rtx (4); /* fldln2 */
15127   emit_move_insn (operands[2], temp);
15128 })
15129
15130 (define_expand "logdf2"
15131   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15132                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
15133                                (match_dup 2)] UNSPEC_FYL2X))
15134               (clobber (match_scratch:DF 3 ""))])]
15135   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15136    && flag_unsafe_math_optimizations"
15137 {
15138   rtx temp;
15139
15140   operands[2] = gen_reg_rtx (XFmode);
15141   temp = standard_80387_constant_rtx (4); /* fldln2 */
15142   emit_move_insn (operands[2], temp);
15143 })
15144
15145 (define_expand "logxf2"
15146   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15147                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15148                                (match_dup 2)] UNSPEC_FYL2X))
15149               (clobber (match_scratch:XF 3 ""))])]
15150   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15151    && flag_unsafe_math_optimizations"
15152 {
15153   rtx temp;
15154
15155   operands[2] = gen_reg_rtx (XFmode);
15156   temp = standard_80387_constant_rtx (4); /* fldln2 */
15157   emit_move_insn (operands[2], temp);
15158 })
15159
15160 (define_insn "*fscale_sfxf3"
15161   [(set (match_operand:SF 0 "register_operand" "=f")
15162          (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15163                      (match_operand:XF 1 "register_operand" "u")]
15164                     UNSPEC_FSCALE))
15165    (clobber (match_scratch:SF 3 "=1"))]
15166   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15167    && flag_unsafe_math_optimizations"
15168   "fscale\;fstp\t%y1"
15169   [(set_attr "type" "fpspc")
15170    (set_attr "mode" "SF")])
15171
15172 (define_insn "*fscale_dfxf3"
15173   [(set (match_operand:DF 0 "register_operand" "=f")
15174          (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15175                      (match_operand:XF 1 "register_operand" "u")]
15176                     UNSPEC_FSCALE))
15177    (clobber (match_scratch:DF 3 "=1"))]
15178   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15179    && flag_unsafe_math_optimizations"
15180   "fscale\;fstp\t%y1"
15181   [(set_attr "type" "fpspc")
15182    (set_attr "mode" "DF")])
15183
15184 (define_insn "*fscale_xf3"
15185   [(set (match_operand:XF 0 "register_operand" "=f")
15186         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15187                     (match_operand:XF 1 "register_operand" "u")]
15188                    UNSPEC_FSCALE))
15189    (clobber (match_scratch:XF 3 "=1"))]
15190   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15191    && flag_unsafe_math_optimizations"
15192   "fscale\;fstp\t%y1"
15193   [(set_attr "type" "fpspc")
15194    (set_attr "mode" "XF")])
15195
15196 (define_insn "*frndintxf2"
15197   [(set (match_operand:XF 0 "register_operand" "=f")
15198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15199          UNSPEC_FRNDINT))]
15200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15201    && flag_unsafe_math_optimizations"
15202   "frndint"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "XF")])
15205
15206 (define_insn "*f2xm1xf2"
15207   [(set (match_operand:XF 0 "register_operand" "=f")
15208         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15209          UNSPEC_F2XM1))]
15210   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15211    && flag_unsafe_math_optimizations"
15212   "f2xm1"
15213   [(set_attr "type" "fpspc")
15214    (set_attr "mode" "XF")])
15215
15216 (define_expand "expsf2"
15217   [(set (match_dup 2)
15218         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15219    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15220    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15221    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15222    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15223    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15224    (parallel [(set (match_operand:SF 0 "register_operand" "")
15225                    (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15226               (clobber (match_scratch:SF 5 ""))])]
15227   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15228    && flag_unsafe_math_optimizations"
15229 {
15230   rtx temp;
15231   int i;
15232
15233   for (i=2; i<10; i++)
15234     operands[i] = gen_reg_rtx (XFmode);
15235   temp = standard_80387_constant_rtx (5); /* fldl2e */
15236   emit_move_insn (operands[3], temp);
15237   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15238 })
15239
15240 (define_expand "expdf2"
15241   [(set (match_dup 2)
15242         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15243    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15244    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15245    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15246    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15247    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15248    (parallel [(set (match_operand:DF 0 "register_operand" "")
15249                    (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15250               (clobber (match_scratch:DF 5 ""))])]
15251   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252    && flag_unsafe_math_optimizations"
15253 {
15254   rtx temp;
15255   int i;
15256
15257   for (i=2; i<10; i++)
15258     operands[i] = gen_reg_rtx (XFmode);
15259   temp = standard_80387_constant_rtx (5); /* fldl2e */
15260   emit_move_insn (operands[3], temp);
15261   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15262 })
15263
15264 (define_expand "expxf2"
15265   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15266                                (match_dup 2)))
15267    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15268    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15269    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15270    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15271    (parallel [(set (match_operand:XF 0 "register_operand" "")
15272                    (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15273               (clobber (match_scratch:XF 5 ""))])]
15274   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15275    && flag_unsafe_math_optimizations"
15276 {
15277   rtx temp;
15278   int i;
15279
15280   for (i=2; i<9; i++)
15281     operands[i] = gen_reg_rtx (XFmode);
15282   temp = standard_80387_constant_rtx (5); /* fldl2e */
15283   emit_move_insn (operands[2], temp);
15284   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15285 })
15286
15287 (define_expand "atansf2"
15288   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15289                    (unspec:SF [(match_dup 2)
15290                                (match_operand:SF 1 "register_operand" "")]
15291                     UNSPEC_FPATAN))
15292               (clobber (match_scratch:SF 3 ""))])]
15293   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15294    && flag_unsafe_math_optimizations"
15295 {
15296   operands[2] = gen_reg_rtx (SFmode);
15297   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15298 })
15299
15300 (define_expand "atandf2"
15301   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15302                    (unspec:DF [(match_dup 2)
15303                                (match_operand:DF 1 "register_operand" "")]
15304                     UNSPEC_FPATAN))
15305               (clobber (match_scratch:DF 3 ""))])]
15306   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15307    && flag_unsafe_math_optimizations"
15308 {
15309   operands[2] = gen_reg_rtx (DFmode);
15310   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15311 })
15312
15313 (define_expand "atanxf2"
15314   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15315                    (unspec:XF [(match_dup 2)
15316                                (match_operand:XF 1 "register_operand" "")]
15317                     UNSPEC_FPATAN))
15318               (clobber (match_scratch:XF 3 ""))])]
15319   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15320    && flag_unsafe_math_optimizations"
15321 {
15322   operands[2] = gen_reg_rtx (XFmode);
15323   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15324 })
15325 \f
15326 ;; Block operation instructions
15327
15328 (define_insn "cld"
15329  [(set (reg:SI 19) (const_int 0))]
15330  ""
15331  "cld"
15332   [(set_attr "type" "cld")])
15333
15334 (define_expand "movstrsi"
15335   [(use (match_operand:BLK 0 "memory_operand" ""))
15336    (use (match_operand:BLK 1 "memory_operand" ""))
15337    (use (match_operand:SI 2 "nonmemory_operand" ""))
15338    (use (match_operand:SI 3 "const_int_operand" ""))]
15339   "! optimize_size"
15340 {
15341  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15342    DONE;
15343  else
15344    FAIL;
15345 })
15346
15347 (define_expand "movstrdi"
15348   [(use (match_operand:BLK 0 "memory_operand" ""))
15349    (use (match_operand:BLK 1 "memory_operand" ""))
15350    (use (match_operand:DI 2 "nonmemory_operand" ""))
15351    (use (match_operand:DI 3 "const_int_operand" ""))]
15352   "TARGET_64BIT"
15353 {
15354  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15355    DONE;
15356  else
15357    FAIL;
15358 })
15359
15360 ;; Most CPUs don't like single string operations
15361 ;; Handle this case here to simplify previous expander.
15362
15363 (define_expand "strmov"
15364   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15365    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15366    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15367               (clobber (reg:CC 17))])
15368    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15369               (clobber (reg:CC 17))])]
15370   ""
15371 {
15372   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15373
15374   /* If .md ever supports :P for Pmode, these can be directly
15375      in the pattern above.  */
15376   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15377   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15378
15379   if (TARGET_SINGLE_STRINGOP || optimize_size)
15380     {
15381       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15382                                       operands[2], operands[3],
15383                                       operands[5], operands[6]));
15384       DONE;
15385     }
15386
15387   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15388 })
15389
15390 (define_expand "strmov_singleop"
15391   [(parallel [(set (match_operand 1 "memory_operand" "")
15392                    (match_operand 3 "memory_operand" ""))
15393               (set (match_operand 0 "register_operand" "")
15394                    (match_operand 4 "" ""))
15395               (set (match_operand 2 "register_operand" "")
15396                    (match_operand 5 "" ""))
15397               (use (reg:SI 19))])]
15398   "TARGET_SINGLE_STRINGOP || optimize_size"
15399   "")
15400
15401 (define_insn "*strmovdi_rex_1"
15402   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15403         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15404    (set (match_operand:DI 0 "register_operand" "=D")
15405         (plus:DI (match_dup 2)
15406                  (const_int 8)))
15407    (set (match_operand:DI 1 "register_operand" "=S")
15408         (plus:DI (match_dup 3)
15409                  (const_int 8)))
15410    (use (reg:SI 19))]
15411   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15412   "movsq"
15413   [(set_attr "type" "str")
15414    (set_attr "mode" "DI")
15415    (set_attr "memory" "both")])
15416
15417 (define_insn "*strmovsi_1"
15418   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15419         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15420    (set (match_operand:SI 0 "register_operand" "=D")
15421         (plus:SI (match_dup 2)
15422                  (const_int 4)))
15423    (set (match_operand:SI 1 "register_operand" "=S")
15424         (plus:SI (match_dup 3)
15425                  (const_int 4)))
15426    (use (reg:SI 19))]
15427   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15428   "{movsl|movsd}"
15429   [(set_attr "type" "str")
15430    (set_attr "mode" "SI")
15431    (set_attr "memory" "both")])
15432
15433 (define_insn "*strmovsi_rex_1"
15434   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15435         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15436    (set (match_operand:DI 0 "register_operand" "=D")
15437         (plus:DI (match_dup 2)
15438                  (const_int 4)))
15439    (set (match_operand:DI 1 "register_operand" "=S")
15440         (plus:DI (match_dup 3)
15441                  (const_int 4)))
15442    (use (reg:SI 19))]
15443   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15444   "{movsl|movsd}"
15445   [(set_attr "type" "str")
15446    (set_attr "mode" "SI")
15447    (set_attr "memory" "both")])
15448
15449 (define_insn "*strmovhi_1"
15450   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15451         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15452    (set (match_operand:SI 0 "register_operand" "=D")
15453         (plus:SI (match_dup 2)
15454                  (const_int 2)))
15455    (set (match_operand:SI 1 "register_operand" "=S")
15456         (plus:SI (match_dup 3)
15457                  (const_int 2)))
15458    (use (reg:SI 19))]
15459   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15460   "movsw"
15461   [(set_attr "type" "str")
15462    (set_attr "memory" "both")
15463    (set_attr "mode" "HI")])
15464
15465 (define_insn "*strmovhi_rex_1"
15466   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15467         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15468    (set (match_operand:DI 0 "register_operand" "=D")
15469         (plus:DI (match_dup 2)
15470                  (const_int 2)))
15471    (set (match_operand:DI 1 "register_operand" "=S")
15472         (plus:DI (match_dup 3)
15473                  (const_int 2)))
15474    (use (reg:SI 19))]
15475   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15476   "movsw"
15477   [(set_attr "type" "str")
15478    (set_attr "memory" "both")
15479    (set_attr "mode" "HI")])
15480
15481 (define_insn "*strmovqi_1"
15482   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15483         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15484    (set (match_operand:SI 0 "register_operand" "=D")
15485         (plus:SI (match_dup 2)
15486                  (const_int 1)))
15487    (set (match_operand:SI 1 "register_operand" "=S")
15488         (plus:SI (match_dup 3)
15489                  (const_int 1)))
15490    (use (reg:SI 19))]
15491   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15492   "movsb"
15493   [(set_attr "type" "str")
15494    (set_attr "memory" "both")
15495    (set_attr "mode" "QI")])
15496
15497 (define_insn "*strmovqi_rex_1"
15498   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15499         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15500    (set (match_operand:DI 0 "register_operand" "=D")
15501         (plus:DI (match_dup 2)
15502                  (const_int 1)))
15503    (set (match_operand:DI 1 "register_operand" "=S")
15504         (plus:DI (match_dup 3)
15505                  (const_int 1)))
15506    (use (reg:SI 19))]
15507   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15508   "movsb"
15509   [(set_attr "type" "str")
15510    (set_attr "memory" "both")
15511    (set_attr "mode" "QI")])
15512
15513 (define_expand "rep_mov"
15514   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15515               (set (match_operand 0 "register_operand" "")
15516                    (match_operand 5 "" ""))
15517               (set (match_operand 2 "register_operand" "")
15518                    (match_operand 6 "" ""))
15519               (set (match_operand 1 "memory_operand" "")
15520                    (match_operand 3 "memory_operand" ""))
15521               (use (match_dup 4))
15522               (use (reg:SI 19))])]
15523   ""
15524   "")
15525
15526 (define_insn "*rep_movdi_rex64"
15527   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15528    (set (match_operand:DI 0 "register_operand" "=D") 
15529         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15530                             (const_int 3))
15531                  (match_operand:DI 3 "register_operand" "0")))
15532    (set (match_operand:DI 1 "register_operand" "=S") 
15533         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15534                  (match_operand:DI 4 "register_operand" "1")))
15535    (set (mem:BLK (match_dup 3))
15536         (mem:BLK (match_dup 4)))
15537    (use (match_dup 5))
15538    (use (reg:SI 19))]
15539   "TARGET_64BIT"
15540   "{rep\;movsq|rep movsq}"
15541   [(set_attr "type" "str")
15542    (set_attr "prefix_rep" "1")
15543    (set_attr "memory" "both")
15544    (set_attr "mode" "DI")])
15545
15546 (define_insn "*rep_movsi"
15547   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15548    (set (match_operand:SI 0 "register_operand" "=D") 
15549         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15550                             (const_int 2))
15551                  (match_operand:SI 3 "register_operand" "0")))
15552    (set (match_operand:SI 1 "register_operand" "=S") 
15553         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15554                  (match_operand:SI 4 "register_operand" "1")))
15555    (set (mem:BLK (match_dup 3))
15556         (mem:BLK (match_dup 4)))
15557    (use (match_dup 5))
15558    (use (reg:SI 19))]
15559   "!TARGET_64BIT"
15560   "{rep\;movsl|rep movsd}"
15561   [(set_attr "type" "str")
15562    (set_attr "prefix_rep" "1")
15563    (set_attr "memory" "both")
15564    (set_attr "mode" "SI")])
15565
15566 (define_insn "*rep_movsi_rex64"
15567   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15568    (set (match_operand:DI 0 "register_operand" "=D") 
15569         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15570                             (const_int 2))
15571                  (match_operand:DI 3 "register_operand" "0")))
15572    (set (match_operand:DI 1 "register_operand" "=S") 
15573         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15574                  (match_operand:DI 4 "register_operand" "1")))
15575    (set (mem:BLK (match_dup 3))
15576         (mem:BLK (match_dup 4)))
15577    (use (match_dup 5))
15578    (use (reg:SI 19))]
15579   "TARGET_64BIT"
15580   "{rep\;movsl|rep movsd}"
15581   [(set_attr "type" "str")
15582    (set_attr "prefix_rep" "1")
15583    (set_attr "memory" "both")
15584    (set_attr "mode" "SI")])
15585
15586 (define_insn "*rep_movqi"
15587   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15588    (set (match_operand:SI 0 "register_operand" "=D") 
15589         (plus:SI (match_operand:SI 3 "register_operand" "0")
15590                  (match_operand:SI 5 "register_operand" "2")))
15591    (set (match_operand:SI 1 "register_operand" "=S") 
15592         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15593    (set (mem:BLK (match_dup 3))
15594         (mem:BLK (match_dup 4)))
15595    (use (match_dup 5))
15596    (use (reg:SI 19))]
15597   "!TARGET_64BIT"
15598   "{rep\;movsb|rep movsb}"
15599   [(set_attr "type" "str")
15600    (set_attr "prefix_rep" "1")
15601    (set_attr "memory" "both")
15602    (set_attr "mode" "SI")])
15603
15604 (define_insn "*rep_movqi_rex64"
15605   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15606    (set (match_operand:DI 0 "register_operand" "=D") 
15607         (plus:DI (match_operand:DI 3 "register_operand" "0")
15608                  (match_operand:DI 5 "register_operand" "2")))
15609    (set (match_operand:DI 1 "register_operand" "=S") 
15610         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15611    (set (mem:BLK (match_dup 3))
15612         (mem:BLK (match_dup 4)))
15613    (use (match_dup 5))
15614    (use (reg:SI 19))]
15615   "TARGET_64BIT"
15616   "{rep\;movsb|rep movsb}"
15617   [(set_attr "type" "str")
15618    (set_attr "prefix_rep" "1")
15619    (set_attr "memory" "both")
15620    (set_attr "mode" "SI")])
15621
15622 (define_expand "clrstrsi"
15623    [(use (match_operand:BLK 0 "memory_operand" ""))
15624     (use (match_operand:SI 1 "nonmemory_operand" ""))
15625     (use (match_operand 2 "const_int_operand" ""))]
15626   ""
15627 {
15628  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15629    DONE;
15630  else
15631    FAIL;
15632 })
15633
15634 (define_expand "clrstrdi"
15635    [(use (match_operand:BLK 0 "memory_operand" ""))
15636     (use (match_operand:DI 1 "nonmemory_operand" ""))
15637     (use (match_operand 2 "const_int_operand" ""))]
15638   "TARGET_64BIT"
15639 {
15640  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15641    DONE;
15642  else
15643    FAIL;
15644 })
15645
15646 ;; Most CPUs don't like single string operations
15647 ;; Handle this case here to simplify previous expander.
15648
15649 (define_expand "strset"
15650   [(set (match_operand 1 "memory_operand" "")
15651         (match_operand 2 "register_operand" ""))
15652    (parallel [(set (match_operand 0 "register_operand" "")
15653                    (match_dup 3))
15654               (clobber (reg:CC 17))])]
15655   ""
15656 {
15657   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15658     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15659
15660   /* If .md ever supports :P for Pmode, this can be directly
15661      in the pattern above.  */
15662   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15663                               GEN_INT (GET_MODE_SIZE (GET_MODE
15664                                                       (operands[2]))));
15665   if (TARGET_SINGLE_STRINGOP || optimize_size)
15666     {
15667       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15668                                       operands[3]));
15669       DONE;
15670     }
15671 })
15672
15673 (define_expand "strset_singleop"
15674   [(parallel [(set (match_operand 1 "memory_operand" "")
15675                    (match_operand 2 "register_operand" ""))
15676               (set (match_operand 0 "register_operand" "")
15677                    (match_operand 3 "" ""))
15678               (use (reg:SI 19))])]
15679   "TARGET_SINGLE_STRINGOP || optimize_size"
15680   "")
15681
15682 (define_insn "*strsetdi_rex_1"
15683   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15684         (match_operand:SI 2 "register_operand" "a"))
15685    (set (match_operand:DI 0 "register_operand" "=D")
15686         (plus:DI (match_dup 1)
15687                  (const_int 8)))
15688    (use (reg:SI 19))]
15689   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15690   "stosq"
15691   [(set_attr "type" "str")
15692    (set_attr "memory" "store")
15693    (set_attr "mode" "DI")])
15694
15695 (define_insn "*strsetsi_1"
15696   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15697         (match_operand:SI 2 "register_operand" "a"))
15698    (set (match_operand:SI 0 "register_operand" "=D")
15699         (plus:SI (match_dup 1)
15700                  (const_int 4)))
15701    (use (reg:SI 19))]
15702   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15703   "{stosl|stosd}"
15704   [(set_attr "type" "str")
15705    (set_attr "memory" "store")
15706    (set_attr "mode" "SI")])
15707
15708 (define_insn "*strsetsi_rex_1"
15709   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15710         (match_operand:SI 2 "register_operand" "a"))
15711    (set (match_operand:DI 0 "register_operand" "=D")
15712         (plus:DI (match_dup 1)
15713                  (const_int 4)))
15714    (use (reg:SI 19))]
15715   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15716   "{stosl|stosd}"
15717   [(set_attr "type" "str")
15718    (set_attr "memory" "store")
15719    (set_attr "mode" "SI")])
15720
15721 (define_insn "*strsethi_1"
15722   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15723         (match_operand:HI 2 "register_operand" "a"))
15724    (set (match_operand:SI 0 "register_operand" "=D")
15725         (plus:SI (match_dup 1)
15726                  (const_int 2)))
15727    (use (reg:SI 19))]
15728   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15729   "stosw"
15730   [(set_attr "type" "str")
15731    (set_attr "memory" "store")
15732    (set_attr "mode" "HI")])
15733
15734 (define_insn "*strsethi_rex_1"
15735   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15736         (match_operand:HI 2 "register_operand" "a"))
15737    (set (match_operand:DI 0 "register_operand" "=D")
15738         (plus:DI (match_dup 1)
15739                  (const_int 2)))
15740    (use (reg:SI 19))]
15741   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15742   "stosw"
15743   [(set_attr "type" "str")
15744    (set_attr "memory" "store")
15745    (set_attr "mode" "HI")])
15746
15747 (define_insn "*strsetqi_1"
15748   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15749         (match_operand:QI 2 "register_operand" "a"))
15750    (set (match_operand:SI 0 "register_operand" "=D")
15751         (plus:SI (match_dup 1)
15752                  (const_int 1)))
15753    (use (reg:SI 19))]
15754   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15755   "stosb"
15756   [(set_attr "type" "str")
15757    (set_attr "memory" "store")
15758    (set_attr "mode" "QI")])
15759
15760 (define_insn "*strsetqi_rex_1"
15761   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15762         (match_operand:QI 2 "register_operand" "a"))
15763    (set (match_operand:DI 0 "register_operand" "=D")
15764         (plus:DI (match_dup 1)
15765                  (const_int 1)))
15766    (use (reg:SI 19))]
15767   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15768   "stosb"
15769   [(set_attr "type" "str")
15770    (set_attr "memory" "store")
15771    (set_attr "mode" "QI")])
15772
15773 (define_expand "rep_stos"
15774   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15775               (set (match_operand 0 "register_operand" "")
15776                    (match_operand 4 "" ""))
15777               (set (match_operand 2 "memory_operand" "") (const_int 0))
15778               (use (match_operand 3 "register_operand" ""))
15779               (use (match_dup 1))
15780               (use (reg:SI 19))])]
15781   ""
15782   "")
15783
15784 (define_insn "*rep_stosdi_rex64"
15785   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15786    (set (match_operand:DI 0 "register_operand" "=D") 
15787         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15788                             (const_int 3))
15789                  (match_operand:DI 3 "register_operand" "0")))
15790    (set (mem:BLK (match_dup 3))
15791         (const_int 0))
15792    (use (match_operand:DI 2 "register_operand" "a"))
15793    (use (match_dup 4))
15794    (use (reg:SI 19))]
15795   "TARGET_64BIT"
15796   "{rep\;stosq|rep stosq}"
15797   [(set_attr "type" "str")
15798    (set_attr "prefix_rep" "1")
15799    (set_attr "memory" "store")
15800    (set_attr "mode" "DI")])
15801
15802 (define_insn "*rep_stossi"
15803   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15804    (set (match_operand:SI 0 "register_operand" "=D") 
15805         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15806                             (const_int 2))
15807                  (match_operand:SI 3 "register_operand" "0")))
15808    (set (mem:BLK (match_dup 3))
15809         (const_int 0))
15810    (use (match_operand:SI 2 "register_operand" "a"))
15811    (use (match_dup 4))
15812    (use (reg:SI 19))]
15813   "!TARGET_64BIT"
15814   "{rep\;stosl|rep stosd}"
15815   [(set_attr "type" "str")
15816    (set_attr "prefix_rep" "1")
15817    (set_attr "memory" "store")
15818    (set_attr "mode" "SI")])
15819
15820 (define_insn "*rep_stossi_rex64"
15821   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15822    (set (match_operand:DI 0 "register_operand" "=D") 
15823         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15824                             (const_int 2))
15825                  (match_operand:DI 3 "register_operand" "0")))
15826    (set (mem:BLK (match_dup 3))
15827         (const_int 0))
15828    (use (match_operand:SI 2 "register_operand" "a"))
15829    (use (match_dup 4))
15830    (use (reg:SI 19))]
15831   "TARGET_64BIT"
15832   "{rep\;stosl|rep stosd}"
15833   [(set_attr "type" "str")
15834    (set_attr "prefix_rep" "1")
15835    (set_attr "memory" "store")
15836    (set_attr "mode" "SI")])
15837
15838 (define_insn "*rep_stosqi"
15839   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15840    (set (match_operand:SI 0 "register_operand" "=D") 
15841         (plus:SI (match_operand:SI 3 "register_operand" "0")
15842                  (match_operand:SI 4 "register_operand" "1")))
15843    (set (mem:BLK (match_dup 3))
15844         (const_int 0))
15845    (use (match_operand:QI 2 "register_operand" "a"))
15846    (use (match_dup 4))
15847    (use (reg:SI 19))]
15848   "!TARGET_64BIT"
15849   "{rep\;stosb|rep stosb}"
15850   [(set_attr "type" "str")
15851    (set_attr "prefix_rep" "1")
15852    (set_attr "memory" "store")
15853    (set_attr "mode" "QI")])
15854
15855 (define_insn "*rep_stosqi_rex64"
15856   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15857    (set (match_operand:DI 0 "register_operand" "=D") 
15858         (plus:DI (match_operand:DI 3 "register_operand" "0")
15859                  (match_operand:DI 4 "register_operand" "1")))
15860    (set (mem:BLK (match_dup 3))
15861         (const_int 0))
15862    (use (match_operand:QI 2 "register_operand" "a"))
15863    (use (match_dup 4))
15864    (use (reg:SI 19))]
15865   "TARGET_64BIT"
15866   "{rep\;stosb|rep stosb}"
15867   [(set_attr "type" "str")
15868    (set_attr "prefix_rep" "1")
15869    (set_attr "memory" "store")
15870    (set_attr "mode" "QI")])
15871
15872 (define_expand "cmpstrsi"
15873   [(set (match_operand:SI 0 "register_operand" "")
15874         (compare:SI (match_operand:BLK 1 "general_operand" "")
15875                     (match_operand:BLK 2 "general_operand" "")))
15876    (use (match_operand 3 "general_operand" ""))
15877    (use (match_operand 4 "immediate_operand" ""))]
15878   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15879 {
15880   rtx addr1, addr2, out, outlow, count, countreg, align;
15881
15882   /* Can't use this if the user has appropriated esi or edi.  */
15883   if (global_regs[4] || global_regs[5])
15884     FAIL;
15885
15886   out = operands[0];
15887   if (GET_CODE (out) != REG)
15888     out = gen_reg_rtx (SImode);
15889
15890   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15891   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15892   if (addr1 != XEXP (operands[1], 0))
15893     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15894   if (addr2 != XEXP (operands[2], 0))
15895     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15896
15897   count = operands[3];
15898   countreg = ix86_zero_extend_to_Pmode (count);
15899
15900   /* %%% Iff we are testing strict equality, we can use known alignment
15901      to good advantage.  This may be possible with combine, particularly
15902      once cc0 is dead.  */
15903   align = operands[4];
15904
15905   emit_insn (gen_cld ());
15906   if (GET_CODE (count) == CONST_INT)
15907     {
15908       if (INTVAL (count) == 0)
15909         {
15910           emit_move_insn (operands[0], const0_rtx);
15911           DONE;
15912         }
15913       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15914                                     operands[1], operands[2]));
15915     }
15916   else
15917     {
15918       if (TARGET_64BIT)
15919         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15920       else
15921         emit_insn (gen_cmpsi_1 (countreg, countreg));
15922       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15923                                  operands[1], operands[2]));
15924     }
15925
15926   outlow = gen_lowpart (QImode, out);
15927   emit_insn (gen_cmpintqi (outlow));
15928   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15929
15930   if (operands[0] != out)
15931     emit_move_insn (operands[0], out);
15932
15933   DONE;
15934 })
15935
15936 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15937
15938 (define_expand "cmpintqi"
15939   [(set (match_dup 1)
15940         (gtu:QI (reg:CC 17) (const_int 0)))
15941    (set (match_dup 2)
15942         (ltu:QI (reg:CC 17) (const_int 0)))
15943    (parallel [(set (match_operand:QI 0 "register_operand" "")
15944                    (minus:QI (match_dup 1)
15945                              (match_dup 2)))
15946               (clobber (reg:CC 17))])]
15947   ""
15948   "operands[1] = gen_reg_rtx (QImode);
15949    operands[2] = gen_reg_rtx (QImode);")
15950
15951 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15952 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15953
15954 (define_expand "cmpstrqi_nz_1"
15955   [(parallel [(set (reg:CC 17)
15956                    (compare:CC (match_operand 4 "memory_operand" "")
15957                                (match_operand 5 "memory_operand" "")))
15958               (use (match_operand 2 "register_operand" ""))
15959               (use (match_operand:SI 3 "immediate_operand" ""))
15960               (use (reg:SI 19))
15961               (clobber (match_operand 0 "register_operand" ""))
15962               (clobber (match_operand 1 "register_operand" ""))
15963               (clobber (match_dup 2))])]
15964   ""
15965   "")
15966
15967 (define_insn "*cmpstrqi_nz_1"
15968   [(set (reg:CC 17)
15969         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15970                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15971    (use (match_operand:SI 6 "register_operand" "2"))
15972    (use (match_operand:SI 3 "immediate_operand" "i"))
15973    (use (reg:SI 19))
15974    (clobber (match_operand:SI 0 "register_operand" "=S"))
15975    (clobber (match_operand:SI 1 "register_operand" "=D"))
15976    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15977   "!TARGET_64BIT"
15978   "repz{\;| }cmpsb"
15979   [(set_attr "type" "str")
15980    (set_attr "mode" "QI")
15981    (set_attr "prefix_rep" "1")])
15982
15983 (define_insn "*cmpstrqi_nz_rex_1"
15984   [(set (reg:CC 17)
15985         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15986                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15987    (use (match_operand:DI 6 "register_operand" "2"))
15988    (use (match_operand:SI 3 "immediate_operand" "i"))
15989    (use (reg:SI 19))
15990    (clobber (match_operand:DI 0 "register_operand" "=S"))
15991    (clobber (match_operand:DI 1 "register_operand" "=D"))
15992    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15993   "TARGET_64BIT"
15994   "repz{\;| }cmpsb"
15995   [(set_attr "type" "str")
15996    (set_attr "mode" "QI")
15997    (set_attr "prefix_rep" "1")])
15998
15999 ;; The same, but the count is not known to not be zero.
16000
16001 (define_expand "cmpstrqi_1"
16002   [(parallel [(set (reg:CC 17)
16003                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16004                                      (const_int 0))
16005                   (compare:CC (match_operand 4 "memory_operand" "")
16006                               (match_operand 5 "memory_operand" ""))
16007                   (const_int 0)))
16008               (use (match_operand:SI 3 "immediate_operand" ""))
16009               (use (reg:CC 17))
16010               (use (reg:SI 19))
16011               (clobber (match_operand 0 "register_operand" ""))
16012               (clobber (match_operand 1 "register_operand" ""))
16013               (clobber (match_dup 2))])]
16014   ""
16015   "")
16016
16017 (define_insn "*cmpstrqi_1"
16018   [(set (reg:CC 17)
16019         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16020                              (const_int 0))
16021           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16022                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16023           (const_int 0)))
16024    (use (match_operand:SI 3 "immediate_operand" "i"))
16025    (use (reg:CC 17))
16026    (use (reg:SI 19))
16027    (clobber (match_operand:SI 0 "register_operand" "=S"))
16028    (clobber (match_operand:SI 1 "register_operand" "=D"))
16029    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16030   "!TARGET_64BIT"
16031   "repz{\;| }cmpsb"
16032   [(set_attr "type" "str")
16033    (set_attr "mode" "QI")
16034    (set_attr "prefix_rep" "1")])
16035
16036 (define_insn "*cmpstrqi_rex_1"
16037   [(set (reg:CC 17)
16038         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16039                              (const_int 0))
16040           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16041                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16042           (const_int 0)))
16043    (use (match_operand:SI 3 "immediate_operand" "i"))
16044    (use (reg:CC 17))
16045    (use (reg:SI 19))
16046    (clobber (match_operand:DI 0 "register_operand" "=S"))
16047    (clobber (match_operand:DI 1 "register_operand" "=D"))
16048    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16049   "TARGET_64BIT"
16050   "repz{\;| }cmpsb"
16051   [(set_attr "type" "str")
16052    (set_attr "mode" "QI")
16053    (set_attr "prefix_rep" "1")])
16054
16055 (define_expand "strlensi"
16056   [(set (match_operand:SI 0 "register_operand" "")
16057         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16058                     (match_operand:QI 2 "immediate_operand" "")
16059                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16060   ""
16061 {
16062  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16063    DONE;
16064  else
16065    FAIL;
16066 })
16067
16068 (define_expand "strlendi"
16069   [(set (match_operand:DI 0 "register_operand" "")
16070         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16071                     (match_operand:QI 2 "immediate_operand" "")
16072                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16073   ""
16074 {
16075  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16076    DONE;
16077  else
16078    FAIL;
16079 })
16080
16081 (define_expand "strlenqi_1"
16082   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16083               (use (reg:SI 19))
16084               (clobber (match_operand 1 "register_operand" ""))
16085               (clobber (reg:CC 17))])]
16086   ""
16087   "")
16088
16089 (define_insn "*strlenqi_1"
16090   [(set (match_operand:SI 0 "register_operand" "=&c")
16091         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16092                     (match_operand:QI 2 "register_operand" "a")
16093                     (match_operand:SI 3 "immediate_operand" "i")
16094                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16095    (use (reg:SI 19))
16096    (clobber (match_operand:SI 1 "register_operand" "=D"))
16097    (clobber (reg:CC 17))]
16098   "!TARGET_64BIT"
16099   "repnz{\;| }scasb"
16100   [(set_attr "type" "str")
16101    (set_attr "mode" "QI")
16102    (set_attr "prefix_rep" "1")])
16103
16104 (define_insn "*strlenqi_rex_1"
16105   [(set (match_operand:DI 0 "register_operand" "=&c")
16106         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16107                     (match_operand:QI 2 "register_operand" "a")
16108                     (match_operand:DI 3 "immediate_operand" "i")
16109                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16110    (use (reg:SI 19))
16111    (clobber (match_operand:DI 1 "register_operand" "=D"))
16112    (clobber (reg:CC 17))]
16113   "TARGET_64BIT"
16114   "repnz{\;| }scasb"
16115   [(set_attr "type" "str")
16116    (set_attr "mode" "QI")
16117    (set_attr "prefix_rep" "1")])
16118
16119 ;; Peephole optimizations to clean up after cmpstr*.  This should be
16120 ;; handled in combine, but it is not currently up to the task.
16121 ;; When used for their truth value, the cmpstr* expanders generate
16122 ;; code like this:
16123 ;;
16124 ;;   repz cmpsb
16125 ;;   seta       %al
16126 ;;   setb       %dl
16127 ;;   cmpb       %al, %dl
16128 ;;   jcc        label
16129 ;;
16130 ;; The intermediate three instructions are unnecessary.
16131
16132 ;; This one handles cmpstr*_nz_1...
16133 (define_peephole2
16134   [(parallel[
16135      (set (reg:CC 17)
16136           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16137                       (mem:BLK (match_operand 5 "register_operand" ""))))
16138      (use (match_operand 6 "register_operand" ""))
16139      (use (match_operand:SI 3 "immediate_operand" ""))
16140      (use (reg:SI 19))
16141      (clobber (match_operand 0 "register_operand" ""))
16142      (clobber (match_operand 1 "register_operand" ""))
16143      (clobber (match_operand 2 "register_operand" ""))])
16144    (set (match_operand:QI 7 "register_operand" "")
16145         (gtu:QI (reg:CC 17) (const_int 0)))
16146    (set (match_operand:QI 8 "register_operand" "")
16147         (ltu:QI (reg:CC 17) (const_int 0)))
16148    (set (reg 17)
16149         (compare (match_dup 7) (match_dup 8)))
16150   ]
16151   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16152   [(parallel[
16153      (set (reg:CC 17)
16154           (compare:CC (mem:BLK (match_dup 4))
16155                       (mem:BLK (match_dup 5))))
16156      (use (match_dup 6))
16157      (use (match_dup 3))
16158      (use (reg:SI 19))
16159      (clobber (match_dup 0))
16160      (clobber (match_dup 1))
16161      (clobber (match_dup 2))])]
16162   "")
16163
16164 ;; ...and this one handles cmpstr*_1.
16165 (define_peephole2
16166   [(parallel[
16167      (set (reg:CC 17)
16168           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16169                                (const_int 0))
16170             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16171                         (mem:BLK (match_operand 5 "register_operand" "")))
16172             (const_int 0)))
16173      (use (match_operand:SI 3 "immediate_operand" ""))
16174      (use (reg:CC 17))
16175      (use (reg:SI 19))
16176      (clobber (match_operand 0 "register_operand" ""))
16177      (clobber (match_operand 1 "register_operand" ""))
16178      (clobber (match_operand 2 "register_operand" ""))])
16179    (set (match_operand:QI 7 "register_operand" "")
16180         (gtu:QI (reg:CC 17) (const_int 0)))
16181    (set (match_operand:QI 8 "register_operand" "")
16182         (ltu:QI (reg:CC 17) (const_int 0)))
16183    (set (reg 17)
16184         (compare (match_dup 7) (match_dup 8)))
16185   ]
16186   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16187   [(parallel[
16188      (set (reg:CC 17)
16189           (if_then_else:CC (ne (match_dup 6)
16190                                (const_int 0))
16191             (compare:CC (mem:BLK (match_dup 4))
16192                         (mem:BLK (match_dup 5)))
16193             (const_int 0)))
16194      (use (match_dup 3))
16195      (use (reg:CC 17))
16196      (use (reg:SI 19))
16197      (clobber (match_dup 0))
16198      (clobber (match_dup 1))
16199      (clobber (match_dup 2))])]
16200   "")
16201
16202
16203 \f
16204 ;; Conditional move instructions.
16205
16206 (define_expand "movdicc"
16207   [(set (match_operand:DI 0 "register_operand" "")
16208         (if_then_else:DI (match_operand 1 "comparison_operator" "")
16209                          (match_operand:DI 2 "general_operand" "")
16210                          (match_operand:DI 3 "general_operand" "")))]
16211   "TARGET_64BIT"
16212   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16213
16214 (define_insn "x86_movdicc_0_m1_rex64"
16215   [(set (match_operand:DI 0 "register_operand" "=r")
16216         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16217           (const_int -1)
16218           (const_int 0)))
16219    (clobber (reg:CC 17))]
16220   "TARGET_64BIT"
16221   "sbb{q}\t%0, %0"
16222   ; Since we don't have the proper number of operands for an alu insn,
16223   ; fill in all the blanks.
16224   [(set_attr "type" "alu")
16225    (set_attr "pent_pair" "pu")
16226    (set_attr "memory" "none")
16227    (set_attr "imm_disp" "false")
16228    (set_attr "mode" "DI")
16229    (set_attr "length_immediate" "0")])
16230
16231 (define_insn "movdicc_c_rex64"
16232   [(set (match_operand:DI 0 "register_operand" "=r,r")
16233         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
16234                                 [(reg 17) (const_int 0)])
16235                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16236                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16237   "TARGET_64BIT && TARGET_CMOVE
16238    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16239   "@
16240    cmov%O2%C1\t{%2, %0|%0, %2}
16241    cmov%O2%c1\t{%3, %0|%0, %3}"
16242   [(set_attr "type" "icmov")
16243    (set_attr "mode" "DI")])
16244
16245 (define_expand "movsicc"
16246   [(set (match_operand:SI 0 "register_operand" "")
16247         (if_then_else:SI (match_operand 1 "comparison_operator" "")
16248                          (match_operand:SI 2 "general_operand" "")
16249                          (match_operand:SI 3 "general_operand" "")))]
16250   ""
16251   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16252
16253 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16254 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16255 ;; So just document what we're doing explicitly.
16256
16257 (define_insn "x86_movsicc_0_m1"
16258   [(set (match_operand:SI 0 "register_operand" "=r")
16259         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16260           (const_int -1)
16261           (const_int 0)))
16262    (clobber (reg:CC 17))]
16263   ""
16264   "sbb{l}\t%0, %0"
16265   ; Since we don't have the proper number of operands for an alu insn,
16266   ; fill in all the blanks.
16267   [(set_attr "type" "alu")
16268    (set_attr "pent_pair" "pu")
16269    (set_attr "memory" "none")
16270    (set_attr "imm_disp" "false")
16271    (set_attr "mode" "SI")
16272    (set_attr "length_immediate" "0")])
16273
16274 (define_insn "*movsicc_noc"
16275   [(set (match_operand:SI 0 "register_operand" "=r,r")
16276         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
16277                                 [(reg 17) (const_int 0)])
16278                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16279                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16280   "TARGET_CMOVE
16281    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16282   "@
16283    cmov%O2%C1\t{%2, %0|%0, %2}
16284    cmov%O2%c1\t{%3, %0|%0, %3}"
16285   [(set_attr "type" "icmov")
16286    (set_attr "mode" "SI")])
16287
16288 (define_expand "movhicc"
16289   [(set (match_operand:HI 0 "register_operand" "")
16290         (if_then_else:HI (match_operand 1 "comparison_operator" "")
16291                          (match_operand:HI 2 "general_operand" "")
16292                          (match_operand:HI 3 "general_operand" "")))]
16293   "TARGET_HIMODE_MATH"
16294   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16295
16296 (define_insn "*movhicc_noc"
16297   [(set (match_operand:HI 0 "register_operand" "=r,r")
16298         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
16299                                 [(reg 17) (const_int 0)])
16300                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16301                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16302   "TARGET_CMOVE
16303    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16304   "@
16305    cmov%O2%C1\t{%2, %0|%0, %2}
16306    cmov%O2%c1\t{%3, %0|%0, %3}"
16307   [(set_attr "type" "icmov")
16308    (set_attr "mode" "HI")])
16309
16310 (define_expand "movqicc"
16311   [(set (match_operand:QI 0 "register_operand" "")
16312         (if_then_else:QI (match_operand 1 "comparison_operator" "")
16313                          (match_operand:QI 2 "general_operand" "")
16314                          (match_operand:QI 3 "general_operand" "")))]
16315   "TARGET_QIMODE_MATH"
16316   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16317
16318 (define_insn_and_split "*movqicc_noc"
16319   [(set (match_operand:QI 0 "register_operand" "=r,r")
16320         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16321                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16322                       (match_operand:QI 2 "register_operand" "r,0")
16323                       (match_operand:QI 3 "register_operand" "0,r")))]
16324   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16325   "#"
16326   "&& reload_completed"
16327   [(set (match_dup 0)
16328         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16329                       (match_dup 2)
16330                       (match_dup 3)))]
16331   "operands[0] = gen_lowpart (SImode, operands[0]);
16332    operands[2] = gen_lowpart (SImode, operands[2]);
16333    operands[3] = gen_lowpart (SImode, operands[3]);"
16334   [(set_attr "type" "icmov")
16335    (set_attr "mode" "SI")])
16336
16337 (define_expand "movsfcc"
16338   [(set (match_operand:SF 0 "register_operand" "")
16339         (if_then_else:SF (match_operand 1 "comparison_operator" "")
16340                          (match_operand:SF 2 "register_operand" "")
16341                          (match_operand:SF 3 "register_operand" "")))]
16342   "TARGET_CMOVE"
16343   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16344
16345 (define_insn "*movsfcc_1"
16346   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16347         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
16348                                 [(reg 17) (const_int 0)])
16349                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16350                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16351   "TARGET_CMOVE
16352    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16353   "@
16354    fcmov%F1\t{%2, %0|%0, %2}
16355    fcmov%f1\t{%3, %0|%0, %3}
16356    cmov%O2%C1\t{%2, %0|%0, %2}
16357    cmov%O2%c1\t{%3, %0|%0, %3}"
16358   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16359    (set_attr "mode" "SF,SF,SI,SI")])
16360
16361 (define_expand "movdfcc"
16362   [(set (match_operand:DF 0 "register_operand" "")
16363         (if_then_else:DF (match_operand 1 "comparison_operator" "")
16364                          (match_operand:DF 2 "register_operand" "")
16365                          (match_operand:DF 3 "register_operand" "")))]
16366   "TARGET_CMOVE"
16367   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16368
16369 (define_insn "*movdfcc_1"
16370   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16371         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16372                                 [(reg 17) (const_int 0)])
16373                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16374                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16375   "!TARGET_64BIT && TARGET_CMOVE
16376    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16377   "@
16378    fcmov%F1\t{%2, %0|%0, %2}
16379    fcmov%f1\t{%3, %0|%0, %3}
16380    #
16381    #"
16382   [(set_attr "type" "fcmov,fcmov,multi,multi")
16383    (set_attr "mode" "DF")])
16384
16385 (define_insn "*movdfcc_1_rex64"
16386   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16387         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16388                                 [(reg 17) (const_int 0)])
16389                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16390                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16391   "TARGET_64BIT && TARGET_CMOVE
16392    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16393   "@
16394    fcmov%F1\t{%2, %0|%0, %2}
16395    fcmov%f1\t{%3, %0|%0, %3}
16396    cmov%O2%C1\t{%2, %0|%0, %2}
16397    cmov%O2%c1\t{%3, %0|%0, %3}"
16398   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16399    (set_attr "mode" "DF")])
16400
16401 (define_split
16402   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16403         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16404                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16405                       (match_operand:DF 2 "nonimmediate_operand" "")
16406                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16407   "!TARGET_64BIT && reload_completed"
16408   [(set (match_dup 2)
16409         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16410                       (match_dup 5)
16411                       (match_dup 7)))
16412    (set (match_dup 3)
16413         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16414                       (match_dup 6)
16415                       (match_dup 8)))]
16416   "split_di (operands+2, 1, operands+5, operands+6);
16417    split_di (operands+3, 1, operands+7, operands+8);
16418    split_di (operands, 1, operands+2, operands+3);")
16419
16420 (define_expand "movxfcc"
16421   [(set (match_operand:XF 0 "register_operand" "")
16422         (if_then_else:XF (match_operand 1 "comparison_operator" "")
16423                          (match_operand:XF 2 "register_operand" "")
16424                          (match_operand:XF 3 "register_operand" "")))]
16425   "TARGET_CMOVE"
16426   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16427
16428 (define_insn "*movxfcc_1"
16429   [(set (match_operand:XF 0 "register_operand" "=f,f")
16430         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16431                                 [(reg 17) (const_int 0)])
16432                       (match_operand:XF 2 "register_operand" "f,0")
16433                       (match_operand:XF 3 "register_operand" "0,f")))]
16434   "TARGET_CMOVE"
16435   "@
16436    fcmov%F1\t{%2, %0|%0, %2}
16437    fcmov%f1\t{%3, %0|%0, %3}"
16438   [(set_attr "type" "fcmov")
16439    (set_attr "mode" "XF")])
16440
16441 (define_expand "minsf3"
16442   [(parallel [
16443      (set (match_operand:SF 0 "register_operand" "")
16444           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16445                                (match_operand:SF 2 "nonimmediate_operand" ""))
16446                            (match_dup 1)
16447                            (match_dup 2)))
16448      (clobber (reg:CC 17))])]
16449   "TARGET_SSE"
16450   "")
16451
16452 (define_insn "*minsf"
16453   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16454         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16455                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16456                          (match_dup 1)
16457                          (match_dup 2)))
16458    (clobber (reg:CC 17))]
16459   "TARGET_SSE && TARGET_IEEE_FP"
16460   "#")
16461
16462 (define_insn "*minsf_nonieee"
16463   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16464         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16465                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16466                          (match_dup 1)
16467                          (match_dup 2)))
16468    (clobber (reg:CC 17))]
16469   "TARGET_SSE && !TARGET_IEEE_FP
16470    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16471   "#")
16472
16473 (define_split
16474   [(set (match_operand:SF 0 "register_operand" "")
16475         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16476                              (match_operand:SF 2 "nonimmediate_operand" ""))
16477                          (match_operand:SF 3 "register_operand" "")
16478                          (match_operand:SF 4 "nonimmediate_operand" "")))
16479    (clobber (reg:CC 17))]
16480   "SSE_REG_P (operands[0]) && reload_completed
16481    && ((operands_match_p (operands[1], operands[3])
16482         && operands_match_p (operands[2], operands[4]))
16483        || (operands_match_p (operands[1], operands[4])
16484            && operands_match_p (operands[2], operands[3])))"
16485   [(set (match_dup 0)
16486         (if_then_else:SF (lt (match_dup 1)
16487                              (match_dup 2))
16488                          (match_dup 1)
16489                          (match_dup 2)))])
16490
16491 ;; Conditional addition patterns
16492 (define_expand "addqicc"
16493   [(match_operand:QI 0 "register_operand" "")
16494    (match_operand 1 "comparison_operator" "")
16495    (match_operand:QI 2 "register_operand" "")
16496    (match_operand:QI 3 "const_int_operand" "")]
16497   ""
16498   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16499
16500 (define_expand "addhicc"
16501   [(match_operand:HI 0 "register_operand" "")
16502    (match_operand 1 "comparison_operator" "")
16503    (match_operand:HI 2 "register_operand" "")
16504    (match_operand:HI 3 "const_int_operand" "")]
16505   ""
16506   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16507
16508 (define_expand "addsicc"
16509   [(match_operand:SI 0 "register_operand" "")
16510    (match_operand 1 "comparison_operator" "")
16511    (match_operand:SI 2 "register_operand" "")
16512    (match_operand:SI 3 "const_int_operand" "")]
16513   ""
16514   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16515
16516 (define_expand "adddicc"
16517   [(match_operand:DI 0 "register_operand" "")
16518    (match_operand 1 "comparison_operator" "")
16519    (match_operand:DI 2 "register_operand" "")
16520    (match_operand:DI 3 "const_int_operand" "")]
16521   "TARGET_64BIT"
16522   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16523
16524 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16525
16526 (define_split
16527   [(set (match_operand:SF 0 "fp_register_operand" "")
16528         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16529                              (match_operand:SF 2 "register_operand" ""))
16530                          (match_operand:SF 3 "register_operand" "")
16531                          (match_operand:SF 4 "register_operand" "")))
16532    (clobber (reg:CC 17))]
16533   "reload_completed
16534    && ((operands_match_p (operands[1], operands[3])
16535         && operands_match_p (operands[2], operands[4]))
16536        || (operands_match_p (operands[1], operands[4])
16537            && operands_match_p (operands[2], operands[3])))"
16538   [(set (reg:CCFP 17)
16539         (compare:CCFP (match_dup 2)
16540                       (match_dup 1)))
16541    (set (match_dup 0)
16542         (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16543                          (match_dup 1)
16544                          (match_dup 2)))])
16545
16546 (define_insn "*minsf_sse"
16547   [(set (match_operand:SF 0 "register_operand" "=x")
16548         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16549                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16550                          (match_dup 1)
16551                          (match_dup 2)))]
16552   "TARGET_SSE && reload_completed"
16553   "minss\t{%2, %0|%0, %2}"
16554   [(set_attr "type" "sse")
16555    (set_attr "mode" "SF")])
16556
16557 (define_expand "mindf3"
16558   [(parallel [
16559      (set (match_operand:DF 0 "register_operand" "")
16560           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16561                                (match_operand:DF 2 "nonimmediate_operand" ""))
16562                            (match_dup 1)
16563                            (match_dup 2)))
16564      (clobber (reg:CC 17))])]
16565   "TARGET_SSE2 && TARGET_SSE_MATH"
16566   "#")
16567
16568 (define_insn "*mindf"
16569   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16570         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16571                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16572                          (match_dup 1)
16573                          (match_dup 2)))
16574    (clobber (reg:CC 17))]
16575   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16576   "#")
16577
16578 (define_insn "*mindf_nonieee"
16579   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16580         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16581                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16582                          (match_dup 1)
16583                          (match_dup 2)))
16584    (clobber (reg:CC 17))]
16585   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16586    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16587   "#")
16588
16589 (define_split
16590   [(set (match_operand:DF 0 "register_operand" "")
16591         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16592                              (match_operand:DF 2 "nonimmediate_operand" ""))
16593                          (match_operand:DF 3 "register_operand" "")
16594                          (match_operand:DF 4 "nonimmediate_operand" "")))
16595    (clobber (reg:CC 17))]
16596   "SSE_REG_P (operands[0]) && reload_completed
16597    && ((operands_match_p (operands[1], operands[3])
16598         && operands_match_p (operands[2], operands[4]))
16599        || (operands_match_p (operands[1], operands[4])
16600            && operands_match_p (operands[2], operands[3])))"
16601   [(set (match_dup 0)
16602         (if_then_else:DF (lt (match_dup 1)
16603                              (match_dup 2))
16604                          (match_dup 1)
16605                          (match_dup 2)))])
16606
16607 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16608 (define_split
16609   [(set (match_operand:DF 0 "fp_register_operand" "")
16610         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16611                              (match_operand:DF 2 "register_operand" ""))
16612                          (match_operand:DF 3 "register_operand" "")
16613                          (match_operand:DF 4 "register_operand" "")))
16614    (clobber (reg:CC 17))]
16615   "reload_completed
16616    && ((operands_match_p (operands[1], operands[3])
16617         && operands_match_p (operands[2], operands[4]))
16618        || (operands_match_p (operands[1], operands[4])
16619            && operands_match_p (operands[2], operands[3])))"
16620   [(set (reg:CCFP 17)
16621         (compare:CCFP (match_dup 2)
16622                       (match_dup 1)))
16623    (set (match_dup 0)
16624         (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16625                          (match_dup 1)
16626                          (match_dup 2)))])
16627
16628 (define_insn "*mindf_sse"
16629   [(set (match_operand:DF 0 "register_operand" "=Y")
16630         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16631                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16632                          (match_dup 1)
16633                          (match_dup 2)))]
16634   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16635   "minsd\t{%2, %0|%0, %2}"
16636   [(set_attr "type" "sse")
16637    (set_attr "mode" "DF")])
16638
16639 (define_expand "maxsf3"
16640   [(parallel [
16641      (set (match_operand:SF 0 "register_operand" "")
16642           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16643                                (match_operand:SF 2 "nonimmediate_operand" ""))
16644                            (match_dup 1)
16645                            (match_dup 2)))
16646      (clobber (reg:CC 17))])]
16647   "TARGET_SSE"
16648   "#")
16649
16650 (define_insn "*maxsf"
16651   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16652         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16653                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16654                          (match_dup 1)
16655                          (match_dup 2)))
16656    (clobber (reg:CC 17))]
16657   "TARGET_SSE && TARGET_IEEE_FP"
16658   "#")
16659
16660 (define_insn "*maxsf_nonieee"
16661   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16662         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16663                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16664                          (match_dup 1)
16665                          (match_dup 2)))
16666    (clobber (reg:CC 17))]
16667   "TARGET_SSE && !TARGET_IEEE_FP
16668    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16669   "#")
16670
16671 (define_split
16672   [(set (match_operand:SF 0 "register_operand" "")
16673         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16674                              (match_operand:SF 2 "nonimmediate_operand" ""))
16675                          (match_operand:SF 3 "register_operand" "")
16676                          (match_operand:SF 4 "nonimmediate_operand" "")))
16677    (clobber (reg:CC 17))]
16678   "SSE_REG_P (operands[0]) && reload_completed
16679    && ((operands_match_p (operands[1], operands[3])
16680         && operands_match_p (operands[2], operands[4]))
16681        || (operands_match_p (operands[1], operands[4])
16682            && operands_match_p (operands[2], operands[3])))"
16683   [(set (match_dup 0)
16684         (if_then_else:SF (gt (match_dup 1)
16685                              (match_dup 2))
16686                          (match_dup 1)
16687                          (match_dup 2)))])
16688
16689 (define_split
16690   [(set (match_operand:SF 0 "fp_register_operand" "")
16691         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16692                              (match_operand:SF 2 "register_operand" ""))
16693                          (match_operand:SF 3 "register_operand" "")
16694                          (match_operand:SF 4 "register_operand" "")))
16695    (clobber (reg:CC 17))]
16696   "reload_completed
16697    && ((operands_match_p (operands[1], operands[3])
16698         && operands_match_p (operands[2], operands[4]))
16699        || (operands_match_p (operands[1], operands[4])
16700            && operands_match_p (operands[2], operands[3])))"
16701   [(set (reg:CCFP 17)
16702         (compare:CCFP (match_dup 1)
16703                       (match_dup 2)))
16704    (set (match_dup 0)
16705         (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16706                          (match_dup 1)
16707                          (match_dup 2)))])
16708
16709 (define_insn "*maxsf_sse"
16710   [(set (match_operand:SF 0 "register_operand" "=x")
16711         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16712                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16713                          (match_dup 1)
16714                          (match_dup 2)))]
16715   "TARGET_SSE && reload_completed"
16716   "maxss\t{%2, %0|%0, %2}"
16717   [(set_attr "type" "sse")
16718    (set_attr "mode" "SF")])
16719
16720 (define_expand "maxdf3"
16721   [(parallel [
16722      (set (match_operand:DF 0 "register_operand" "")
16723           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16724                                (match_operand:DF 2 "nonimmediate_operand" ""))
16725                            (match_dup 1)
16726                            (match_dup 2)))
16727      (clobber (reg:CC 17))])]
16728   "TARGET_SSE2 && TARGET_SSE_MATH"
16729   "#")
16730
16731 (define_insn "*maxdf"
16732   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16733         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16734                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16735                          (match_dup 1)
16736                          (match_dup 2)))
16737    (clobber (reg:CC 17))]
16738   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16739   "#")
16740
16741 (define_insn "*maxdf_nonieee"
16742   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16743         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16744                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16745                          (match_dup 1)
16746                          (match_dup 2)))
16747    (clobber (reg:CC 17))]
16748   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16749    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16750   "#")
16751
16752 (define_split
16753   [(set (match_operand:DF 0 "register_operand" "")
16754         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16755                              (match_operand:DF 2 "nonimmediate_operand" ""))
16756                          (match_operand:DF 3 "register_operand" "")
16757                          (match_operand:DF 4 "nonimmediate_operand" "")))
16758    (clobber (reg:CC 17))]
16759   "SSE_REG_P (operands[0]) && reload_completed
16760    && ((operands_match_p (operands[1], operands[3])
16761         && operands_match_p (operands[2], operands[4]))
16762        || (operands_match_p (operands[1], operands[4])
16763            && operands_match_p (operands[2], operands[3])))"
16764   [(set (match_dup 0)
16765         (if_then_else:DF (gt (match_dup 1)
16766                              (match_dup 2))
16767                          (match_dup 1)
16768                          (match_dup 2)))])
16769
16770 (define_split
16771   [(set (match_operand:DF 0 "fp_register_operand" "")
16772         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16773                              (match_operand:DF 2 "register_operand" ""))
16774                          (match_operand:DF 3 "register_operand" "")
16775                          (match_operand:DF 4 "register_operand" "")))
16776    (clobber (reg:CC 17))]
16777   "reload_completed
16778    && ((operands_match_p (operands[1], operands[3])
16779         && operands_match_p (operands[2], operands[4]))
16780        || (operands_match_p (operands[1], operands[4])
16781            && operands_match_p (operands[2], operands[3])))"
16782   [(set (reg:CCFP 17)
16783         (compare:CCFP (match_dup 1)
16784                       (match_dup 2)))
16785    (set (match_dup 0)
16786         (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16787                          (match_dup 1)
16788                          (match_dup 2)))])
16789
16790 (define_insn "*maxdf_sse"
16791   [(set (match_operand:DF 0 "register_operand" "=Y")
16792         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16793                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16794                          (match_dup 1)
16795                          (match_dup 2)))]
16796   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16797   "maxsd\t{%2, %0|%0, %2}"
16798   [(set_attr "type" "sse")
16799    (set_attr "mode" "DF")])
16800 \f
16801 ;; Misc patterns (?)
16802
16803 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16804 ;; Otherwise there will be nothing to keep
16805 ;; 
16806 ;; [(set (reg ebp) (reg esp))]
16807 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16808 ;;  (clobber (eflags)]
16809 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16810 ;;
16811 ;; in proper program order.
16812 (define_insn "pro_epilogue_adjust_stack_1"
16813   [(set (match_operand:SI 0 "register_operand" "=r,r")
16814         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16815                  (match_operand:SI 2 "immediate_operand" "i,i")))
16816    (clobber (reg:CC 17))
16817    (clobber (mem:BLK (scratch)))]
16818   "!TARGET_64BIT"
16819 {
16820   switch (get_attr_type (insn))
16821     {
16822     case TYPE_IMOV:
16823       return "mov{l}\t{%1, %0|%0, %1}";
16824
16825     case TYPE_ALU:
16826       if (GET_CODE (operands[2]) == CONST_INT
16827           && (INTVAL (operands[2]) == 128
16828               || (INTVAL (operands[2]) < 0
16829                   && INTVAL (operands[2]) != -128)))
16830         {
16831           operands[2] = GEN_INT (-INTVAL (operands[2]));
16832           return "sub{l}\t{%2, %0|%0, %2}";
16833         }
16834       return "add{l}\t{%2, %0|%0, %2}";
16835
16836     case TYPE_LEA:
16837       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16838       return "lea{l}\t{%a2, %0|%0, %a2}";
16839
16840     default:
16841       abort ();
16842     }
16843 }
16844   [(set (attr "type")
16845         (cond [(eq_attr "alternative" "0")
16846                  (const_string "alu")
16847                (match_operand:SI 2 "const0_operand" "")
16848                  (const_string "imov")
16849               ]
16850               (const_string "lea")))
16851    (set_attr "mode" "SI")])
16852
16853 (define_insn "pro_epilogue_adjust_stack_rex64"
16854   [(set (match_operand:DI 0 "register_operand" "=r,r")
16855         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16856                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16857    (clobber (reg:CC 17))
16858    (clobber (mem:BLK (scratch)))]
16859   "TARGET_64BIT"
16860 {
16861   switch (get_attr_type (insn))
16862     {
16863     case TYPE_IMOV:
16864       return "mov{q}\t{%1, %0|%0, %1}";
16865
16866     case TYPE_ALU:
16867       if (GET_CODE (operands[2]) == CONST_INT
16868           /* Avoid overflows.  */
16869           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16870           && (INTVAL (operands[2]) == 128
16871               || (INTVAL (operands[2]) < 0
16872                   && INTVAL (operands[2]) != -128)))
16873         {
16874           operands[2] = GEN_INT (-INTVAL (operands[2]));
16875           return "sub{q}\t{%2, %0|%0, %2}";
16876         }
16877       return "add{q}\t{%2, %0|%0, %2}";
16878
16879     case TYPE_LEA:
16880       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16881       return "lea{q}\t{%a2, %0|%0, %a2}";
16882
16883     default:
16884       abort ();
16885     }
16886 }
16887   [(set (attr "type")
16888         (cond [(eq_attr "alternative" "0")
16889                  (const_string "alu")
16890                (match_operand:DI 2 "const0_operand" "")
16891                  (const_string "imov")
16892               ]
16893               (const_string "lea")))
16894    (set_attr "mode" "DI")])
16895
16896 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16897   [(set (match_operand:DI 0 "register_operand" "=r,r")
16898         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16899                  (match_operand:DI 3 "immediate_operand" "i,i")))
16900    (use (match_operand:DI 2 "register_operand" "r,r"))
16901    (clobber (reg:CC 17))
16902    (clobber (mem:BLK (scratch)))]
16903   "TARGET_64BIT"
16904 {
16905   switch (get_attr_type (insn))
16906     {
16907     case TYPE_ALU:
16908       return "add{q}\t{%2, %0|%0, %2}";
16909
16910     case TYPE_LEA:
16911       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16912       return "lea{q}\t{%a2, %0|%0, %a2}";
16913
16914     default:
16915       abort ();
16916     }
16917 }
16918   [(set_attr "type" "alu,lea")
16919    (set_attr "mode" "DI")])
16920
16921 ;; Placeholder for the conditional moves.  This one is split either to SSE
16922 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
16923 ;; fact is that compares supported by the cmp??ss instructions are exactly
16924 ;; swapped of those supported by cmove sequence.
16925 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16926 ;; supported by i387 comparisons and we do need to emit two conditional moves
16927 ;; in tandem.
16928
16929 (define_insn "sse_movsfcc"
16930   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16931         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16932                         [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16933                          (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16934                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16935                       (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16936    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16937    (clobber (reg:CC 17))]
16938   "TARGET_SSE
16939    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16940    /* Avoid combine from being smart and converting min/max
16941       instruction patterns into conditional moves.  */
16942    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16943         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16944        || !rtx_equal_p (operands[4], operands[2])
16945        || !rtx_equal_p (operands[5], operands[3]))
16946    && (!TARGET_IEEE_FP
16947        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16948   "#")
16949
16950 (define_insn "sse_movsfcc_eq"
16951   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16952         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16953                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16954                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16955                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16956    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16957    (clobber (reg:CC 17))]
16958   "TARGET_SSE
16959    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16960   "#")
16961
16962 (define_insn "sse_movdfcc"
16963   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
16964         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16965                         [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
16966                          (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
16967                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
16968                       (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
16969    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16970    (clobber (reg:CC 17))]
16971   "TARGET_SSE2
16972    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16973    /* Avoid combine from being smart and converting min/max
16974       instruction patterns into conditional moves.  */
16975    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16976         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16977        || !rtx_equal_p (operands[4], operands[2])
16978        || !rtx_equal_p (operands[5], operands[3]))
16979    && (!TARGET_IEEE_FP
16980        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16981   "#")
16982
16983 (define_insn "sse_movdfcc_eq"
16984   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16985         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16986                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16987                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16988                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16989    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16990    (clobber (reg:CC 17))]
16991   "TARGET_SSE
16992    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16993   "#")
16994
16995 ;; For non-sse moves just expand the usual cmove sequence.
16996 (define_split
16997   [(set (match_operand 0 "register_operand" "")
16998         (if_then_else (match_operator 1 "comparison_operator"
16999                         [(match_operand 4 "nonimmediate_operand" "")
17000                          (match_operand 5 "register_operand" "")])
17001                       (match_operand 2 "nonimmediate_operand" "")
17002                       (match_operand 3 "nonimmediate_operand" "")))
17003    (clobber (match_operand 6 "" ""))
17004    (clobber (reg:CC 17))]
17005   "!SSE_REG_P (operands[0]) && reload_completed
17006    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17007   [(const_int 0)]
17008 {
17009    ix86_compare_op0 = operands[5];
17010    ix86_compare_op1 = operands[4];
17011    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17012                                  VOIDmode, operands[5], operands[4]);
17013    ix86_expand_fp_movcc (operands);
17014    DONE;
17015 })
17016
17017 ;; Split SSE based conditional move into sequence:
17018 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
17019 ;; and   op2, op0   -  zero op2 if comparison was false
17020 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
17021 ;; or    op2, op0   -  get the nonzero one into the result.
17022 (define_split
17023   [(set (match_operand 0 "register_operand" "")
17024         (if_then_else (match_operator 1 "sse_comparison_operator"
17025                         [(match_operand 4 "register_operand" "")
17026                          (match_operand 5 "nonimmediate_operand" "")])
17027                       (match_operand 2 "register_operand" "")
17028                       (match_operand 3 "register_operand" "")))
17029    (clobber (match_operand 6 "" ""))
17030    (clobber (reg:CC 17))]
17031   "SSE_REG_P (operands[0]) && reload_completed"
17032   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17033    (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17034                                             (subreg:TI (match_dup 4) 0)))
17035    (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17036                                             (subreg:TI (match_dup 3) 0)))
17037    (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17038                                             (subreg:TI (match_dup 7) 0)))]
17039 {
17040   if (GET_MODE (operands[2]) == DFmode
17041       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17042     {
17043       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17044       emit_insn (gen_sse2_unpcklpd (op, op, op));
17045       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17046       emit_insn (gen_sse2_unpcklpd (op, op, op));
17047     }
17048
17049   /* If op2 == op3, op3 would be clobbered before it is used.  */
17050   if (operands_match_p (operands[2], operands[3]))
17051     {
17052       emit_move_insn (operands[0], operands[2]);
17053       DONE;
17054     }
17055
17056   PUT_MODE (operands[1], GET_MODE (operands[0]));
17057   if (operands_match_p (operands[0], operands[4]))
17058     operands[6] = operands[4], operands[7] = operands[2];
17059   else
17060     operands[6] = operands[2], operands[7] = operands[4];
17061 })
17062
17063 ;; Special case of conditional move we can handle effectively.
17064 ;; Do not brother with the integer/floating point case, since these are
17065 ;; bot considerably slower, unlike in the generic case.
17066 (define_insn "*sse_movsfcc_const0_1"
17067   [(set (match_operand:SF 0 "register_operand" "=&x")
17068         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17069                         [(match_operand:SF 4 "register_operand" "0")
17070                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17071                       (match_operand:SF 2 "register_operand" "x")
17072                       (match_operand:SF 3 "const0_operand" "X")))]
17073   "TARGET_SSE"
17074   "#")
17075
17076 (define_insn "*sse_movsfcc_const0_2"
17077   [(set (match_operand:SF 0 "register_operand" "=&x")
17078         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17079                         [(match_operand:SF 4 "register_operand" "0")
17080                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17081                       (match_operand:SF 2 "const0_operand" "X")
17082                       (match_operand:SF 3 "register_operand" "x")))]
17083   "TARGET_SSE"
17084   "#")
17085
17086 (define_insn "*sse_movsfcc_const0_3"
17087   [(set (match_operand:SF 0 "register_operand" "=&x")
17088         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17089                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17090                          (match_operand:SF 5 "register_operand" "0")])
17091                       (match_operand:SF 2 "register_operand" "x")
17092                       (match_operand:SF 3 "const0_operand" "X")))]
17093   "TARGET_SSE"
17094   "#")
17095
17096 (define_insn "*sse_movsfcc_const0_4"
17097   [(set (match_operand:SF 0 "register_operand" "=&x")
17098         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17099                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17100                          (match_operand:SF 5 "register_operand" "0")])
17101                       (match_operand:SF 2 "const0_operand" "X")
17102                       (match_operand:SF 3 "register_operand" "x")))]
17103   "TARGET_SSE"
17104   "#")
17105
17106 (define_insn "*sse_movdfcc_const0_1"
17107   [(set (match_operand:DF 0 "register_operand" "=&Y")
17108         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17109                         [(match_operand:DF 4 "register_operand" "0")
17110                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17111                       (match_operand:DF 2 "register_operand" "Y")
17112                       (match_operand:DF 3 "const0_operand" "X")))]
17113   "TARGET_SSE2"
17114   "#")
17115
17116 (define_insn "*sse_movdfcc_const0_2"
17117   [(set (match_operand:DF 0 "register_operand" "=&Y")
17118         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17119                         [(match_operand:DF 4 "register_operand" "0")
17120                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17121                       (match_operand:DF 2 "const0_operand" "X")
17122                       (match_operand:DF 3 "register_operand" "Y")))]
17123   "TARGET_SSE2"
17124   "#")
17125
17126 (define_insn "*sse_movdfcc_const0_3"
17127   [(set (match_operand:DF 0 "register_operand" "=&Y")
17128         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17129                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17130                          (match_operand:DF 5 "register_operand" "0")])
17131                       (match_operand:DF 2 "register_operand" "Y")
17132                       (match_operand:DF 3 "const0_operand" "X")))]
17133   "TARGET_SSE2"
17134   "#")
17135
17136 (define_insn "*sse_movdfcc_const0_4"
17137   [(set (match_operand:DF 0 "register_operand" "=&Y")
17138         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17139                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17140                          (match_operand:DF 5 "register_operand" "0")])
17141                       (match_operand:DF 2 "const0_operand" "X")
17142                       (match_operand:DF 3 "register_operand" "Y")))]
17143   "TARGET_SSE2"
17144   "#")
17145
17146 (define_split
17147   [(set (match_operand 0 "register_operand" "")
17148         (if_then_else (match_operator 1 "comparison_operator"
17149                         [(match_operand 4 "nonimmediate_operand" "")
17150                          (match_operand 5 "nonimmediate_operand" "")])
17151                       (match_operand 2 "nonmemory_operand" "")
17152                       (match_operand 3 "nonmemory_operand" "")))]
17153   "SSE_REG_P (operands[0]) && reload_completed
17154    && (const0_operand (operands[2], GET_MODE (operands[0]))
17155        || const0_operand (operands[3], GET_MODE (operands[0])))"
17156   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17157    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17158                                             (match_dup 7)))]
17159 {
17160   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17161       && GET_MODE (operands[2]) == DFmode)
17162     {
17163       if (REG_P (operands[2]))
17164         {
17165           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17166           emit_insn (gen_sse2_unpcklpd (op, op, op));
17167         }
17168       if (REG_P (operands[3]))
17169         {
17170           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17171           emit_insn (gen_sse2_unpcklpd (op, op, op));
17172         }
17173     }
17174   PUT_MODE (operands[1], GET_MODE (operands[0]));
17175   if (!sse_comparison_operator (operands[1], VOIDmode)
17176       || !rtx_equal_p (operands[0], operands[4]))
17177     {
17178       rtx tmp = operands[5];
17179       operands[5] = operands[4];
17180       operands[4] = tmp;
17181       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17182     }
17183   if (!rtx_equal_p (operands[0], operands[4]))
17184     abort ();
17185   if (const0_operand (operands[2], GET_MODE (operands[0])))
17186     {
17187       operands[7] = operands[3];
17188       operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17189                                                          0));
17190     }
17191   else
17192     {
17193       operands[7] = operands[2];
17194       operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17195     }
17196   operands[7] = simplify_gen_subreg (TImode, operands[7],
17197                                      GET_MODE (operands[7]), 0);
17198 })
17199
17200 (define_expand "allocate_stack_worker"
17201   [(match_operand:SI 0 "register_operand" "")]
17202   "TARGET_STACK_PROBE"
17203 {
17204   if (reload_completed)
17205     {
17206       if (TARGET_64BIT)
17207         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17208       else
17209         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17210     }
17211   else
17212     {
17213       if (TARGET_64BIT)
17214         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17215       else
17216         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17217     }
17218   DONE;
17219 })
17220
17221 (define_insn "allocate_stack_worker_1"
17222   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17223     UNSPECV_STACK_PROBE)
17224    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17225    (clobber (match_scratch:SI 1 "=0"))
17226    (clobber (reg:CC 17))]
17227   "!TARGET_64BIT && TARGET_STACK_PROBE"
17228   "call\t__alloca"
17229   [(set_attr "type" "multi")
17230    (set_attr "length" "5")])
17231
17232 (define_expand "allocate_stack_worker_postreload"
17233   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17234                                     UNSPECV_STACK_PROBE)
17235               (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17236               (clobber (match_dup 0))
17237               (clobber (reg:CC 17))])]
17238   ""
17239   "")
17240
17241 (define_insn "allocate_stack_worker_rex64"
17242   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17243     UNSPECV_STACK_PROBE)
17244    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17245    (clobber (match_scratch:DI 1 "=0"))
17246    (clobber (reg:CC 17))]
17247   "TARGET_64BIT && TARGET_STACK_PROBE"
17248   "call\t__alloca"
17249   [(set_attr "type" "multi")
17250    (set_attr "length" "5")])
17251
17252 (define_expand "allocate_stack_worker_rex64_postreload"
17253   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17254                                     UNSPECV_STACK_PROBE)
17255               (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17256               (clobber (match_dup 0))
17257               (clobber (reg:CC 17))])]
17258   ""
17259   "")
17260
17261 (define_expand "allocate_stack"
17262   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17263                    (minus:SI (reg:SI 7)
17264                              (match_operand:SI 1 "general_operand" "")))
17265               (clobber (reg:CC 17))])
17266    (parallel [(set (reg:SI 7)
17267                    (minus:SI (reg:SI 7) (match_dup 1)))
17268               (clobber (reg:CC 17))])]
17269   "TARGET_STACK_PROBE"
17270 {
17271 #ifdef CHECK_STACK_LIMIT
17272   if (GET_CODE (operands[1]) == CONST_INT
17273       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17274     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17275                            operands[1]));
17276   else 
17277 #endif
17278     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17279                                                             operands[1])));
17280
17281   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17282   DONE;
17283 })
17284
17285 (define_expand "builtin_setjmp_receiver"
17286   [(label_ref (match_operand 0 "" ""))]
17287   "!TARGET_64BIT && flag_pic"
17288 {
17289   emit_insn (gen_set_got (pic_offset_table_rtx));
17290   DONE;
17291 })
17292 \f
17293 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17294
17295 (define_split
17296   [(set (match_operand 0 "register_operand" "")
17297         (match_operator 3 "promotable_binary_operator"
17298            [(match_operand 1 "register_operand" "")
17299             (match_operand 2 "aligned_operand" "")]))
17300    (clobber (reg:CC 17))]
17301   "! TARGET_PARTIAL_REG_STALL && reload_completed
17302    && ((GET_MODE (operands[0]) == HImode 
17303         && ((!optimize_size && !TARGET_FAST_PREFIX)
17304             || GET_CODE (operands[2]) != CONST_INT
17305             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17306        || (GET_MODE (operands[0]) == QImode 
17307            && (TARGET_PROMOTE_QImode || optimize_size)))"
17308   [(parallel [(set (match_dup 0)
17309                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17310               (clobber (reg:CC 17))])]
17311   "operands[0] = gen_lowpart (SImode, operands[0]);
17312    operands[1] = gen_lowpart (SImode, operands[1]);
17313    if (GET_CODE (operands[3]) != ASHIFT)
17314      operands[2] = gen_lowpart (SImode, operands[2]);
17315    PUT_MODE (operands[3], SImode);")
17316
17317 ; Promote the QImode tests, as i386 has encoding of the AND
17318 ; instruction with 32-bit sign-extended immediate and thus the
17319 ; instruction size is unchanged, except in the %eax case for
17320 ; which it is increased by one byte, hence the ! optimize_size.
17321 (define_split
17322   [(set (reg 17)
17323         (compare (and (match_operand 1 "aligned_operand" "")
17324                       (match_operand 2 "const_int_operand" ""))
17325                  (const_int 0)))
17326    (set (match_operand 0 "register_operand" "")
17327         (and (match_dup 1) (match_dup 2)))]
17328   "! TARGET_PARTIAL_REG_STALL && reload_completed
17329    /* Ensure that the operand will remain sign-extended immediate.  */
17330    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17331    && ! optimize_size
17332    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17333        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17334   [(parallel [(set (reg:CCNO 17)
17335                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17336                                  (const_int 0)))
17337               (set (match_dup 0)
17338                    (and:SI (match_dup 1) (match_dup 2)))])]
17339   "operands[2]
17340      = gen_int_mode (INTVAL (operands[2])
17341                      & GET_MODE_MASK (GET_MODE (operands[0])),
17342                      SImode);
17343    operands[0] = gen_lowpart (SImode, operands[0]);
17344    operands[1] = gen_lowpart (SImode, operands[1]);")
17345
17346 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17347 ; the TEST instruction with 32-bit sign-extended immediate and thus
17348 ; the instruction size would at least double, which is not what we
17349 ; want even with ! optimize_size.
17350 (define_split
17351   [(set (reg 17)
17352         (compare (and (match_operand:HI 0 "aligned_operand" "")
17353                       (match_operand:HI 1 "const_int_operand" ""))
17354                  (const_int 0)))]
17355   "! TARGET_PARTIAL_REG_STALL && reload_completed
17356    /* Ensure that the operand will remain sign-extended immediate.  */
17357    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17358    && ! TARGET_FAST_PREFIX
17359    && ! optimize_size"
17360   [(set (reg:CCNO 17)
17361         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17362                       (const_int 0)))]
17363   "operands[1]
17364      = gen_int_mode (INTVAL (operands[1])
17365                      & GET_MODE_MASK (GET_MODE (operands[0])),
17366                      SImode);
17367    operands[0] = gen_lowpart (SImode, operands[0]);")
17368
17369 (define_split
17370   [(set (match_operand 0 "register_operand" "")
17371         (neg (match_operand 1 "register_operand" "")))
17372    (clobber (reg:CC 17))]
17373   "! TARGET_PARTIAL_REG_STALL && reload_completed
17374    && (GET_MODE (operands[0]) == HImode
17375        || (GET_MODE (operands[0]) == QImode 
17376            && (TARGET_PROMOTE_QImode || optimize_size)))"
17377   [(parallel [(set (match_dup 0)
17378                    (neg:SI (match_dup 1)))
17379               (clobber (reg:CC 17))])]
17380   "operands[0] = gen_lowpart (SImode, operands[0]);
17381    operands[1] = gen_lowpart (SImode, operands[1]);")
17382
17383 (define_split
17384   [(set (match_operand 0 "register_operand" "")
17385         (not (match_operand 1 "register_operand" "")))]
17386   "! TARGET_PARTIAL_REG_STALL && reload_completed
17387    && (GET_MODE (operands[0]) == HImode
17388        || (GET_MODE (operands[0]) == QImode 
17389            && (TARGET_PROMOTE_QImode || optimize_size)))"
17390   [(set (match_dup 0)
17391         (not:SI (match_dup 1)))]
17392   "operands[0] = gen_lowpart (SImode, operands[0]);
17393    operands[1] = gen_lowpart (SImode, operands[1]);")
17394
17395 (define_split 
17396   [(set (match_operand 0 "register_operand" "")
17397         (if_then_else (match_operator 1 "comparison_operator" 
17398                                 [(reg 17) (const_int 0)])
17399                       (match_operand 2 "register_operand" "")
17400                       (match_operand 3 "register_operand" "")))]
17401   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17402    && (GET_MODE (operands[0]) == HImode
17403        || (GET_MODE (operands[0]) == QImode 
17404            && (TARGET_PROMOTE_QImode || optimize_size)))"
17405   [(set (match_dup 0)
17406         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17407   "operands[0] = gen_lowpart (SImode, operands[0]);
17408    operands[2] = gen_lowpart (SImode, operands[2]);
17409    operands[3] = gen_lowpart (SImode, operands[3]);")
17410                         
17411 \f
17412 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17413 ;; transform a complex memory operation into two memory to register operations.
17414
17415 ;; Don't push memory operands
17416 (define_peephole2
17417   [(set (match_operand:SI 0 "push_operand" "")
17418         (match_operand:SI 1 "memory_operand" ""))
17419    (match_scratch:SI 2 "r")]
17420   "! optimize_size && ! TARGET_PUSH_MEMORY"
17421   [(set (match_dup 2) (match_dup 1))
17422    (set (match_dup 0) (match_dup 2))]
17423   "")
17424
17425 (define_peephole2
17426   [(set (match_operand:DI 0 "push_operand" "")
17427         (match_operand:DI 1 "memory_operand" ""))
17428    (match_scratch:DI 2 "r")]
17429   "! optimize_size && ! TARGET_PUSH_MEMORY"
17430   [(set (match_dup 2) (match_dup 1))
17431    (set (match_dup 0) (match_dup 2))]
17432   "")
17433
17434 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17435 ;; SImode pushes.
17436 (define_peephole2
17437   [(set (match_operand:SF 0 "push_operand" "")
17438         (match_operand:SF 1 "memory_operand" ""))
17439    (match_scratch:SF 2 "r")]
17440   "! optimize_size && ! TARGET_PUSH_MEMORY"
17441   [(set (match_dup 2) (match_dup 1))
17442    (set (match_dup 0) (match_dup 2))]
17443   "")
17444
17445 (define_peephole2
17446   [(set (match_operand:HI 0 "push_operand" "")
17447         (match_operand:HI 1 "memory_operand" ""))
17448    (match_scratch:HI 2 "r")]
17449   "! optimize_size && ! TARGET_PUSH_MEMORY"
17450   [(set (match_dup 2) (match_dup 1))
17451    (set (match_dup 0) (match_dup 2))]
17452   "")
17453
17454 (define_peephole2
17455   [(set (match_operand:QI 0 "push_operand" "")
17456         (match_operand:QI 1 "memory_operand" ""))
17457    (match_scratch:QI 2 "q")]
17458   "! optimize_size && ! TARGET_PUSH_MEMORY"
17459   [(set (match_dup 2) (match_dup 1))
17460    (set (match_dup 0) (match_dup 2))]
17461   "")
17462
17463 ;; Don't move an immediate directly to memory when the instruction
17464 ;; gets too big.
17465 (define_peephole2
17466   [(match_scratch:SI 1 "r")
17467    (set (match_operand:SI 0 "memory_operand" "")
17468         (const_int 0))]
17469   "! optimize_size
17470    && ! TARGET_USE_MOV0
17471    && TARGET_SPLIT_LONG_MOVES
17472    && get_attr_length (insn) >= ix86_cost->large_insn
17473    && peep2_regno_dead_p (0, FLAGS_REG)"
17474   [(parallel [(set (match_dup 1) (const_int 0))
17475               (clobber (reg:CC 17))])
17476    (set (match_dup 0) (match_dup 1))]
17477   "")
17478
17479 (define_peephole2
17480   [(match_scratch:HI 1 "r")
17481    (set (match_operand:HI 0 "memory_operand" "")
17482         (const_int 0))]
17483   "! optimize_size
17484    && ! TARGET_USE_MOV0
17485    && TARGET_SPLIT_LONG_MOVES
17486    && get_attr_length (insn) >= ix86_cost->large_insn
17487    && peep2_regno_dead_p (0, FLAGS_REG)"
17488   [(parallel [(set (match_dup 2) (const_int 0))
17489               (clobber (reg:CC 17))])
17490    (set (match_dup 0) (match_dup 1))]
17491   "operands[2] = gen_lowpart (SImode, operands[1]);")
17492
17493 (define_peephole2
17494   [(match_scratch:QI 1 "q")
17495    (set (match_operand:QI 0 "memory_operand" "")
17496         (const_int 0))]
17497   "! optimize_size
17498    && ! TARGET_USE_MOV0
17499    && TARGET_SPLIT_LONG_MOVES
17500    && get_attr_length (insn) >= ix86_cost->large_insn
17501    && peep2_regno_dead_p (0, FLAGS_REG)"
17502   [(parallel [(set (match_dup 2) (const_int 0))
17503               (clobber (reg:CC 17))])
17504    (set (match_dup 0) (match_dup 1))]
17505   "operands[2] = gen_lowpart (SImode, operands[1]);")
17506
17507 (define_peephole2
17508   [(match_scratch:SI 2 "r")
17509    (set (match_operand:SI 0 "memory_operand" "")
17510         (match_operand:SI 1 "immediate_operand" ""))]
17511   "! optimize_size
17512    && get_attr_length (insn) >= ix86_cost->large_insn
17513    && TARGET_SPLIT_LONG_MOVES"
17514   [(set (match_dup 2) (match_dup 1))
17515    (set (match_dup 0) (match_dup 2))]
17516   "")
17517
17518 (define_peephole2
17519   [(match_scratch:HI 2 "r")
17520    (set (match_operand:HI 0 "memory_operand" "")
17521         (match_operand:HI 1 "immediate_operand" ""))]
17522   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17523   && TARGET_SPLIT_LONG_MOVES"
17524   [(set (match_dup 2) (match_dup 1))
17525    (set (match_dup 0) (match_dup 2))]
17526   "")
17527
17528 (define_peephole2
17529   [(match_scratch:QI 2 "q")
17530    (set (match_operand:QI 0 "memory_operand" "")
17531         (match_operand:QI 1 "immediate_operand" ""))]
17532   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17533   && TARGET_SPLIT_LONG_MOVES"
17534   [(set (match_dup 2) (match_dup 1))
17535    (set (match_dup 0) (match_dup 2))]
17536   "")
17537
17538 ;; Don't compare memory with zero, load and use a test instead.
17539 (define_peephole2
17540   [(set (reg 17)
17541         (compare (match_operand:SI 0 "memory_operand" "")
17542                  (const_int 0)))
17543    (match_scratch:SI 3 "r")]
17544   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17545   [(set (match_dup 3) (match_dup 0))
17546    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17547   "")
17548
17549 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17550 ;; Don't split NOTs with a displacement operand, because resulting XOR
17551 ;; will not be pairable anyway.
17552 ;;
17553 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17554 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17555 ;; so this split helps here as well.
17556 ;;
17557 ;; Note: Can't do this as a regular split because we can't get proper
17558 ;; lifetime information then.
17559
17560 (define_peephole2
17561   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17562         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17563   "!optimize_size
17564    && peep2_regno_dead_p (0, FLAGS_REG)
17565    && ((TARGET_PENTIUM 
17566         && (GET_CODE (operands[0]) != MEM
17567             || !memory_displacement_operand (operands[0], SImode)))
17568        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17569   [(parallel [(set (match_dup 0)
17570                    (xor:SI (match_dup 1) (const_int -1)))
17571               (clobber (reg:CC 17))])]
17572   "")
17573
17574 (define_peephole2
17575   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17576         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17577   "!optimize_size
17578    && peep2_regno_dead_p (0, FLAGS_REG)
17579    && ((TARGET_PENTIUM 
17580         && (GET_CODE (operands[0]) != MEM
17581             || !memory_displacement_operand (operands[0], HImode)))
17582        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17583   [(parallel [(set (match_dup 0)
17584                    (xor:HI (match_dup 1) (const_int -1)))
17585               (clobber (reg:CC 17))])]
17586   "")
17587
17588 (define_peephole2
17589   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17590         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17591   "!optimize_size
17592    && peep2_regno_dead_p (0, FLAGS_REG)
17593    && ((TARGET_PENTIUM 
17594         && (GET_CODE (operands[0]) != MEM
17595             || !memory_displacement_operand (operands[0], QImode)))
17596        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17597   [(parallel [(set (match_dup 0)
17598                    (xor:QI (match_dup 1) (const_int -1)))
17599               (clobber (reg:CC 17))])]
17600   "")
17601
17602 ;; Non pairable "test imm, reg" instructions can be translated to
17603 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17604 ;; byte opcode instead of two, have a short form for byte operands),
17605 ;; so do it for other CPUs as well.  Given that the value was dead,
17606 ;; this should not create any new dependencies.  Pass on the sub-word
17607 ;; versions if we're concerned about partial register stalls.
17608
17609 (define_peephole2
17610   [(set (reg 17)
17611         (compare (and:SI (match_operand:SI 0 "register_operand" "")
17612                          (match_operand:SI 1 "immediate_operand" ""))
17613                  (const_int 0)))]
17614   "ix86_match_ccmode (insn, CCNOmode)
17615    && (true_regnum (operands[0]) != 0
17616        || (GET_CODE (operands[1]) == CONST_INT
17617            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17618    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17619   [(parallel
17620      [(set (reg:CCNO 17)
17621            (compare:CCNO (and:SI (match_dup 0)
17622                                  (match_dup 1))
17623                          (const_int 0)))
17624       (set (match_dup 0)
17625            (and:SI (match_dup 0) (match_dup 1)))])]
17626   "")
17627
17628 ;; We don't need to handle HImode case, because it will be promoted to SImode
17629 ;; on ! TARGET_PARTIAL_REG_STALL
17630
17631 (define_peephole2
17632   [(set (reg 17)
17633         (compare (and:QI (match_operand:QI 0 "register_operand" "")
17634                          (match_operand:QI 1 "immediate_operand" ""))
17635                  (const_int 0)))]
17636   "! TARGET_PARTIAL_REG_STALL
17637    && ix86_match_ccmode (insn, CCNOmode)
17638    && true_regnum (operands[0]) != 0
17639    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17640   [(parallel
17641      [(set (reg:CCNO 17)
17642            (compare:CCNO (and:QI (match_dup 0)
17643                                  (match_dup 1))
17644                          (const_int 0)))
17645       (set (match_dup 0)
17646            (and:QI (match_dup 0) (match_dup 1)))])]
17647   "")
17648
17649 (define_peephole2
17650   [(set (reg 17)
17651         (compare
17652           (and:SI
17653             (zero_extract:SI
17654               (match_operand 0 "ext_register_operand" "")
17655               (const_int 8)
17656               (const_int 8))
17657             (match_operand 1 "const_int_operand" ""))
17658           (const_int 0)))]
17659   "! TARGET_PARTIAL_REG_STALL
17660    && ix86_match_ccmode (insn, CCNOmode)
17661    && true_regnum (operands[0]) != 0
17662    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17663   [(parallel [(set (reg:CCNO 17)
17664                    (compare:CCNO
17665                        (and:SI
17666                          (zero_extract:SI
17667                          (match_dup 0)
17668                          (const_int 8)
17669                          (const_int 8))
17670                         (match_dup 1))
17671                    (const_int 0)))
17672               (set (zero_extract:SI (match_dup 0)
17673                                     (const_int 8)
17674                                     (const_int 8))
17675                    (and:SI 
17676                      (zero_extract:SI
17677                        (match_dup 0)
17678                        (const_int 8)
17679                        (const_int 8))
17680                      (match_dup 1)))])]
17681   "")
17682
17683 ;; Don't do logical operations with memory inputs.
17684 (define_peephole2
17685   [(match_scratch:SI 2 "r")
17686    (parallel [(set (match_operand:SI 0 "register_operand" "")
17687                    (match_operator:SI 3 "arith_or_logical_operator"
17688                      [(match_dup 0)
17689                       (match_operand:SI 1 "memory_operand" "")]))
17690               (clobber (reg:CC 17))])]
17691   "! optimize_size && ! TARGET_READ_MODIFY"
17692   [(set (match_dup 2) (match_dup 1))
17693    (parallel [(set (match_dup 0)
17694                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17695               (clobber (reg:CC 17))])]
17696   "")
17697
17698 (define_peephole2
17699   [(match_scratch:SI 2 "r")
17700    (parallel [(set (match_operand:SI 0 "register_operand" "")
17701                    (match_operator:SI 3 "arith_or_logical_operator"
17702                      [(match_operand:SI 1 "memory_operand" "")
17703                       (match_dup 0)]))
17704               (clobber (reg:CC 17))])]
17705   "! optimize_size && ! TARGET_READ_MODIFY"
17706   [(set (match_dup 2) (match_dup 1))
17707    (parallel [(set (match_dup 0)
17708                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17709               (clobber (reg:CC 17))])]
17710   "")
17711
17712 ; Don't do logical operations with memory outputs
17713 ;
17714 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17715 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17716 ; the same decoder scheduling characteristics as the original.
17717
17718 (define_peephole2
17719   [(match_scratch:SI 2 "r")
17720    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17721                    (match_operator:SI 3 "arith_or_logical_operator"
17722                      [(match_dup 0)
17723                       (match_operand:SI 1 "nonmemory_operand" "")]))
17724               (clobber (reg:CC 17))])]
17725   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17726   [(set (match_dup 2) (match_dup 0))
17727    (parallel [(set (match_dup 2)
17728                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17729               (clobber (reg:CC 17))])
17730    (set (match_dup 0) (match_dup 2))]
17731   "")
17732
17733 (define_peephole2
17734   [(match_scratch:SI 2 "r")
17735    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17736                    (match_operator:SI 3 "arith_or_logical_operator"
17737                      [(match_operand:SI 1 "nonmemory_operand" "")
17738                       (match_dup 0)]))
17739               (clobber (reg:CC 17))])]
17740   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17741   [(set (match_dup 2) (match_dup 0))
17742    (parallel [(set (match_dup 2)
17743                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17744               (clobber (reg:CC 17))])
17745    (set (match_dup 0) (match_dup 2))]
17746   "")
17747
17748 ;; Attempt to always use XOR for zeroing registers.
17749 (define_peephole2
17750   [(set (match_operand 0 "register_operand" "")
17751         (const_int 0))]
17752   "(GET_MODE (operands[0]) == QImode
17753     || GET_MODE (operands[0]) == HImode
17754     || GET_MODE (operands[0]) == SImode
17755     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17756    && (! TARGET_USE_MOV0 || optimize_size)
17757    && peep2_regno_dead_p (0, FLAGS_REG)"
17758   [(parallel [(set (match_dup 0) (const_int 0))
17759               (clobber (reg:CC 17))])]
17760   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17761                               operands[0]);")
17762
17763 (define_peephole2
17764   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17765         (const_int 0))]
17766   "(GET_MODE (operands[0]) == QImode
17767     || GET_MODE (operands[0]) == HImode)
17768    && (! TARGET_USE_MOV0 || optimize_size)
17769    && peep2_regno_dead_p (0, FLAGS_REG)"
17770   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17771               (clobber (reg:CC 17))])])
17772
17773 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17774 (define_peephole2
17775   [(set (match_operand 0 "register_operand" "")
17776         (const_int -1))]
17777   "(GET_MODE (operands[0]) == HImode
17778     || GET_MODE (operands[0]) == SImode 
17779     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17780    && (optimize_size || TARGET_PENTIUM)
17781    && peep2_regno_dead_p (0, FLAGS_REG)"
17782   [(parallel [(set (match_dup 0) (const_int -1))
17783               (clobber (reg:CC 17))])]
17784   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17785                               operands[0]);")
17786
17787 ;; Attempt to convert simple leas to adds. These can be created by
17788 ;; move expanders.
17789 (define_peephole2
17790   [(set (match_operand:SI 0 "register_operand" "")
17791         (plus:SI (match_dup 0)
17792                  (match_operand:SI 1 "nonmemory_operand" "")))]
17793   "peep2_regno_dead_p (0, FLAGS_REG)"
17794   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17795               (clobber (reg:CC 17))])]
17796   "")
17797
17798 (define_peephole2
17799   [(set (match_operand:SI 0 "register_operand" "")
17800         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17801                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17802   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17803   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17804               (clobber (reg:CC 17))])]
17805   "operands[2] = gen_lowpart (SImode, operands[2]);")
17806
17807 (define_peephole2
17808   [(set (match_operand:DI 0 "register_operand" "")
17809         (plus:DI (match_dup 0)
17810                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17811   "peep2_regno_dead_p (0, FLAGS_REG)"
17812   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17813               (clobber (reg:CC 17))])]
17814   "")
17815
17816 (define_peephole2
17817   [(set (match_operand:SI 0 "register_operand" "")
17818         (mult:SI (match_dup 0)
17819                  (match_operand:SI 1 "const_int_operand" "")))]
17820   "exact_log2 (INTVAL (operands[1])) >= 0
17821    && peep2_regno_dead_p (0, FLAGS_REG)"
17822   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17823               (clobber (reg:CC 17))])]
17824   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17825
17826 (define_peephole2
17827   [(set (match_operand:DI 0 "register_operand" "")
17828         (mult:DI (match_dup 0)
17829                  (match_operand:DI 1 "const_int_operand" "")))]
17830   "exact_log2 (INTVAL (operands[1])) >= 0
17831    && peep2_regno_dead_p (0, FLAGS_REG)"
17832   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17833               (clobber (reg:CC 17))])]
17834   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17835
17836 (define_peephole2
17837   [(set (match_operand:SI 0 "register_operand" "")
17838         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17839                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17840   "exact_log2 (INTVAL (operands[2])) >= 0
17841    && REGNO (operands[0]) == REGNO (operands[1])
17842    && peep2_regno_dead_p (0, FLAGS_REG)"
17843   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17844               (clobber (reg:CC 17))])]
17845   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17846
17847 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17848 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17849 ;; many CPUs it is also faster, since special hardware to avoid esp
17850 ;; dependencies is present.
17851
17852 ;; While some of these conversions may be done using splitters, we use peepholes
17853 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17854
17855 ;; Convert prologue esp subtractions to push.
17856 ;; We need register to push.  In order to keep verify_flow_info happy we have
17857 ;; two choices
17858 ;; - use scratch and clobber it in order to avoid dependencies
17859 ;; - use already live register
17860 ;; We can't use the second way right now, since there is no reliable way how to
17861 ;; verify that given register is live.  First choice will also most likely in
17862 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17863 ;; call clobbered registers are dead.  We may want to use base pointer as an
17864 ;; alternative when no register is available later.
17865
17866 (define_peephole2
17867   [(match_scratch:SI 0 "r")
17868    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17869               (clobber (reg:CC 17))
17870               (clobber (mem:BLK (scratch)))])]
17871   "optimize_size || !TARGET_SUB_ESP_4"
17872   [(clobber (match_dup 0))
17873    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17874               (clobber (mem:BLK (scratch)))])])
17875
17876 (define_peephole2
17877   [(match_scratch:SI 0 "r")
17878    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17879               (clobber (reg:CC 17))
17880               (clobber (mem:BLK (scratch)))])]
17881   "optimize_size || !TARGET_SUB_ESP_8"
17882   [(clobber (match_dup 0))
17883    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17884    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17885               (clobber (mem:BLK (scratch)))])])
17886
17887 ;; Convert esp subtractions to push.
17888 (define_peephole2
17889   [(match_scratch:SI 0 "r")
17890    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17891               (clobber (reg:CC 17))])]
17892   "optimize_size || !TARGET_SUB_ESP_4"
17893   [(clobber (match_dup 0))
17894    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17895
17896 (define_peephole2
17897   [(match_scratch:SI 0 "r")
17898    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17899               (clobber (reg:CC 17))])]
17900   "optimize_size || !TARGET_SUB_ESP_8"
17901   [(clobber (match_dup 0))
17902    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17903    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17904
17905 ;; Convert epilogue deallocator to pop.
17906 (define_peephole2
17907   [(match_scratch:SI 0 "r")
17908    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17909               (clobber (reg:CC 17))
17910               (clobber (mem:BLK (scratch)))])]
17911   "optimize_size || !TARGET_ADD_ESP_4"
17912   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17913               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17914               (clobber (mem:BLK (scratch)))])]
17915   "")
17916
17917 ;; Two pops case is tricky, since pop causes dependency on destination register.
17918 ;; We use two registers if available.
17919 (define_peephole2
17920   [(match_scratch:SI 0 "r")
17921    (match_scratch:SI 1 "r")
17922    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17923               (clobber (reg:CC 17))
17924               (clobber (mem:BLK (scratch)))])]
17925   "optimize_size || !TARGET_ADD_ESP_8"
17926   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17927               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17928               (clobber (mem:BLK (scratch)))])
17929    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17930               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17931   "")
17932
17933 (define_peephole2
17934   [(match_scratch:SI 0 "r")
17935    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17936               (clobber (reg:CC 17))
17937               (clobber (mem:BLK (scratch)))])]
17938   "optimize_size"
17939   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17940               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17941               (clobber (mem:BLK (scratch)))])
17942    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17943               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17944   "")
17945
17946 ;; Convert esp additions to pop.
17947 (define_peephole2
17948   [(match_scratch:SI 0 "r")
17949    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17950               (clobber (reg:CC 17))])]
17951   ""
17952   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17953               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17954   "")
17955
17956 ;; Two pops case is tricky, since pop causes dependency on destination register.
17957 ;; We use two registers if available.
17958 (define_peephole2
17959   [(match_scratch:SI 0 "r")
17960    (match_scratch:SI 1 "r")
17961    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17962               (clobber (reg:CC 17))])]
17963   ""
17964   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17965               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17966    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17967               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17968   "")
17969
17970 (define_peephole2
17971   [(match_scratch:SI 0 "r")
17972    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17973               (clobber (reg:CC 17))])]
17974   "optimize_size"
17975   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17976               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17977    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17978               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17979   "")
17980 \f
17981 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17982 ;; required and register dies.
17983 (define_peephole2
17984   [(set (reg 17)
17985         (compare (match_operand:SI 0 "register_operand" "")
17986                  (match_operand:SI 1 "incdec_operand" "")))]
17987   "ix86_match_ccmode (insn, CCGCmode)
17988    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17989   [(parallel [(set (reg:CCGC 17)
17990                    (compare:CCGC (match_dup 0)
17991                                  (match_dup 1)))
17992               (clobber (match_dup 0))])]
17993   "")
17994
17995 (define_peephole2
17996   [(set (reg 17)
17997         (compare (match_operand:HI 0 "register_operand" "")
17998                  (match_operand:HI 1 "incdec_operand" "")))]
17999   "ix86_match_ccmode (insn, CCGCmode)
18000    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18001   [(parallel [(set (reg:CCGC 17)
18002                    (compare:CCGC (match_dup 0)
18003                                  (match_dup 1)))
18004               (clobber (match_dup 0))])]
18005   "")
18006
18007 (define_peephole2
18008   [(set (reg 17)
18009         (compare (match_operand:QI 0 "register_operand" "")
18010                  (match_operand:QI 1 "incdec_operand" "")))]
18011   "ix86_match_ccmode (insn, CCGCmode)
18012    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18013   [(parallel [(set (reg:CCGC 17)
18014                    (compare:CCGC (match_dup 0)
18015                                  (match_dup 1)))
18016               (clobber (match_dup 0))])]
18017   "")
18018
18019 ;; Convert compares with 128 to shorter add -128
18020 (define_peephole2
18021   [(set (reg 17)
18022         (compare (match_operand:SI 0 "register_operand" "")
18023                  (const_int 128)))]
18024   "ix86_match_ccmode (insn, CCGCmode)
18025    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18026   [(parallel [(set (reg:CCGC 17)
18027                    (compare:CCGC (match_dup 0)
18028                                  (const_int 128)))
18029               (clobber (match_dup 0))])]
18030   "")
18031
18032 (define_peephole2
18033   [(set (reg 17)
18034         (compare (match_operand:HI 0 "register_operand" "")
18035                  (const_int 128)))]
18036   "ix86_match_ccmode (insn, CCGCmode)
18037    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18038   [(parallel [(set (reg:CCGC 17)
18039                    (compare:CCGC (match_dup 0)
18040                                  (const_int 128)))
18041               (clobber (match_dup 0))])]
18042   "")
18043 \f
18044 (define_peephole2
18045   [(match_scratch:DI 0 "r")
18046    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18047               (clobber (reg:CC 17))
18048               (clobber (mem:BLK (scratch)))])]
18049   "optimize_size || !TARGET_SUB_ESP_4"
18050   [(clobber (match_dup 0))
18051    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18052               (clobber (mem:BLK (scratch)))])])
18053
18054 (define_peephole2
18055   [(match_scratch:DI 0 "r")
18056    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18057               (clobber (reg:CC 17))
18058               (clobber (mem:BLK (scratch)))])]
18059   "optimize_size || !TARGET_SUB_ESP_8"
18060   [(clobber (match_dup 0))
18061    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18062    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18063               (clobber (mem:BLK (scratch)))])])
18064
18065 ;; Convert esp subtractions to push.
18066 (define_peephole2
18067   [(match_scratch:DI 0 "r")
18068    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18069               (clobber (reg:CC 17))])]
18070   "optimize_size || !TARGET_SUB_ESP_4"
18071   [(clobber (match_dup 0))
18072    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18073
18074 (define_peephole2
18075   [(match_scratch:DI 0 "r")
18076    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18077               (clobber (reg:CC 17))])]
18078   "optimize_size || !TARGET_SUB_ESP_8"
18079   [(clobber (match_dup 0))
18080    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18081    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18082
18083 ;; Convert epilogue deallocator to pop.
18084 (define_peephole2
18085   [(match_scratch:DI 0 "r")
18086    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18087               (clobber (reg:CC 17))
18088               (clobber (mem:BLK (scratch)))])]
18089   "optimize_size || !TARGET_ADD_ESP_4"
18090   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18091               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18092               (clobber (mem:BLK (scratch)))])]
18093   "")
18094
18095 ;; Two pops case is tricky, since pop causes dependency on destination register.
18096 ;; We use two registers if available.
18097 (define_peephole2
18098   [(match_scratch:DI 0 "r")
18099    (match_scratch:DI 1 "r")
18100    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18101               (clobber (reg:CC 17))
18102               (clobber (mem:BLK (scratch)))])]
18103   "optimize_size || !TARGET_ADD_ESP_8"
18104   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18105               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18106               (clobber (mem:BLK (scratch)))])
18107    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18108               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18109   "")
18110
18111 (define_peephole2
18112   [(match_scratch:DI 0 "r")
18113    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18114               (clobber (reg:CC 17))
18115               (clobber (mem:BLK (scratch)))])]
18116   "optimize_size"
18117   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18118               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18119               (clobber (mem:BLK (scratch)))])
18120    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18121               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18122   "")
18123
18124 ;; Convert esp additions to pop.
18125 (define_peephole2
18126   [(match_scratch:DI 0 "r")
18127    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18128               (clobber (reg:CC 17))])]
18129   ""
18130   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18131               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18132   "")
18133
18134 ;; Two pops case is tricky, since pop causes dependency on destination register.
18135 ;; We use two registers if available.
18136 (define_peephole2
18137   [(match_scratch:DI 0 "r")
18138    (match_scratch:DI 1 "r")
18139    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18140               (clobber (reg:CC 17))])]
18141   ""
18142   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18143               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18144    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18145               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18146   "")
18147
18148 (define_peephole2
18149   [(match_scratch:DI 0 "r")
18150    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18151               (clobber (reg:CC 17))])]
18152   "optimize_size"
18153   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18154               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18155    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18156               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18157   "")
18158 \f
18159 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18160 ;; imul $32bit_imm, reg, reg is direct decoded.
18161 (define_peephole2
18162   [(match_scratch:DI 3 "r")
18163    (parallel [(set (match_operand:DI 0 "register_operand" "")
18164                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18165                             (match_operand:DI 2 "immediate_operand" "")))
18166               (clobber (reg:CC 17))])]
18167   "TARGET_K8 && !optimize_size
18168    && (GET_CODE (operands[2]) != CONST_INT
18169        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18170   [(set (match_dup 3) (match_dup 1))
18171    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18172               (clobber (reg:CC 17))])]
18173 "")
18174
18175 (define_peephole2
18176   [(match_scratch:SI 3 "r")
18177    (parallel [(set (match_operand:SI 0 "register_operand" "")
18178                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18179                             (match_operand:SI 2 "immediate_operand" "")))
18180               (clobber (reg:CC 17))])]
18181   "TARGET_K8 && !optimize_size
18182    && (GET_CODE (operands[2]) != CONST_INT
18183        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18184   [(set (match_dup 3) (match_dup 1))
18185    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18186               (clobber (reg:CC 17))])]
18187 "")
18188
18189 (define_peephole2
18190   [(match_scratch:SI 3 "r")
18191    (parallel [(set (match_operand:DI 0 "register_operand" "")
18192                    (zero_extend:DI
18193                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18194                               (match_operand:SI 2 "immediate_operand" ""))))
18195               (clobber (reg:CC 17))])]
18196   "TARGET_K8 && !optimize_size
18197    && (GET_CODE (operands[2]) != CONST_INT
18198        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18199   [(set (match_dup 3) (match_dup 1))
18200    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18201               (clobber (reg:CC 17))])]
18202 "")
18203
18204 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18205 ;; Convert it into imul reg, reg
18206 ;; It would be better to force assembler to encode instruction using long
18207 ;; immediate, but there is apparently no way to do so.
18208 (define_peephole2
18209   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18210                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18211                             (match_operand:DI 2 "const_int_operand" "")))
18212               (clobber (reg:CC 17))])
18213    (match_scratch:DI 3 "r")]
18214   "TARGET_K8 && !optimize_size
18215    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18216   [(set (match_dup 3) (match_dup 2))
18217    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18218               (clobber (reg:CC 17))])]
18219 {
18220   if (!rtx_equal_p (operands[0], operands[1]))
18221     emit_move_insn (operands[0], operands[1]);
18222 })
18223
18224 (define_peephole2
18225   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18226                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18227                             (match_operand:SI 2 "const_int_operand" "")))
18228               (clobber (reg:CC 17))])
18229    (match_scratch:SI 3 "r")]
18230   "TARGET_K8 && !optimize_size
18231    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18232   [(set (match_dup 3) (match_dup 2))
18233    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18234               (clobber (reg:CC 17))])]
18235 {
18236   if (!rtx_equal_p (operands[0], operands[1]))
18237     emit_move_insn (operands[0], operands[1]);
18238 })
18239
18240 (define_peephole2
18241   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18242                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18243                             (match_operand:HI 2 "immediate_operand" "")))
18244               (clobber (reg:CC 17))])
18245    (match_scratch:HI 3 "r")]
18246   "TARGET_K8 && !optimize_size"
18247   [(set (match_dup 3) (match_dup 2))
18248    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18249               (clobber (reg:CC 17))])]
18250 {
18251   if (!rtx_equal_p (operands[0], operands[1]))
18252     emit_move_insn (operands[0], operands[1]);
18253 })
18254 \f
18255 ;; Call-value patterns last so that the wildcard operand does not
18256 ;; disrupt insn-recog's switch tables.
18257
18258 (define_insn "*call_value_pop_0"
18259   [(set (match_operand 0 "" "")
18260         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18261               (match_operand:SI 2 "" "")))
18262    (set (reg:SI 7) (plus:SI (reg:SI 7)
18263                             (match_operand:SI 3 "immediate_operand" "")))]
18264   "!TARGET_64BIT"
18265 {
18266   if (SIBLING_CALL_P (insn))
18267     return "jmp\t%P1";
18268   else
18269     return "call\t%P1";
18270 }
18271   [(set_attr "type" "callv")])
18272
18273 (define_insn "*call_value_pop_1"
18274   [(set (match_operand 0 "" "")
18275         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18276               (match_operand:SI 2 "" "")))
18277    (set (reg:SI 7) (plus:SI (reg:SI 7)
18278                             (match_operand:SI 3 "immediate_operand" "i")))]
18279   "!TARGET_64BIT"
18280 {
18281   if (constant_call_address_operand (operands[1], QImode))
18282     {
18283       if (SIBLING_CALL_P (insn))
18284         return "jmp\t%P1";
18285       else
18286         return "call\t%P1";
18287     }
18288   if (SIBLING_CALL_P (insn))
18289     return "jmp\t%A1";
18290   else
18291     return "call\t%A1";
18292 }
18293   [(set_attr "type" "callv")])
18294
18295 (define_insn "*call_value_0"
18296   [(set (match_operand 0 "" "")
18297         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18298               (match_operand:SI 2 "" "")))]
18299   "!TARGET_64BIT"
18300 {
18301   if (SIBLING_CALL_P (insn))
18302     return "jmp\t%P1";
18303   else
18304     return "call\t%P1";
18305 }
18306   [(set_attr "type" "callv")])
18307
18308 (define_insn "*call_value_0_rex64"
18309   [(set (match_operand 0 "" "")
18310         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18311               (match_operand:DI 2 "const_int_operand" "")))]
18312   "TARGET_64BIT"
18313 {
18314   if (SIBLING_CALL_P (insn))
18315     return "jmp\t%P1";
18316   else
18317     return "call\t%P1";
18318 }
18319   [(set_attr "type" "callv")])
18320
18321 (define_insn "*call_value_1"
18322   [(set (match_operand 0 "" "")
18323         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18324               (match_operand:SI 2 "" "")))]
18325   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18326 {
18327   if (constant_call_address_operand (operands[1], QImode))
18328     return "call\t%P1";
18329   return "call\t%*%1";
18330 }
18331   [(set_attr "type" "callv")])
18332
18333 (define_insn "*sibcall_value_1"
18334   [(set (match_operand 0 "" "")
18335         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18336               (match_operand:SI 2 "" "")))]
18337   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18338 {
18339   if (constant_call_address_operand (operands[1], QImode))
18340     return "jmp\t%P1";
18341   return "jmp\t%*%1";
18342 }
18343   [(set_attr "type" "callv")])
18344
18345 (define_insn "*call_value_1_rex64"
18346   [(set (match_operand 0 "" "")
18347         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18348               (match_operand:DI 2 "" "")))]
18349   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18350 {
18351   if (constant_call_address_operand (operands[1], QImode))
18352     return "call\t%P1";
18353   return "call\t%A1";
18354 }
18355   [(set_attr "type" "callv")])
18356
18357 (define_insn "*sibcall_value_1_rex64"
18358   [(set (match_operand 0 "" "")
18359         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18360               (match_operand:DI 2 "" "")))]
18361   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18362   "jmp\t%P1"
18363   [(set_attr "type" "callv")])
18364
18365 (define_insn "*sibcall_value_1_rex64_v"
18366   [(set (match_operand 0 "" "")
18367         (call (mem:QI (reg:DI 40))
18368               (match_operand:DI 1 "" "")))]
18369   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18370   "jmp\t*%%r11"
18371   [(set_attr "type" "callv")])
18372 \f
18373 (define_insn "trap"
18374   [(trap_if (const_int 1) (const_int 5))]
18375   ""
18376   "int\t$5")
18377
18378 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18379 ;;; for the sake of bounds checking.  By emitting bounds checks as
18380 ;;; conditional traps rather than as conditional jumps around
18381 ;;; unconditional traps we avoid introducing spurious basic-block
18382 ;;; boundaries and facilitate elimination of redundant checks.  In
18383 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18384 ;;; interrupt 5.
18385 ;;; 
18386 ;;; FIXME: Static branch prediction rules for ix86 are such that
18387 ;;; forward conditional branches predict as untaken.  As implemented
18388 ;;; below, pseudo conditional traps violate that rule.  We should use
18389 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18390 ;;; section loaded at the end of the text segment and branch forward
18391 ;;; there on bounds-failure, and then jump back immediately (in case
18392 ;;; the system chooses to ignore bounds violations, or to report
18393 ;;; violations and continue execution).
18394
18395 (define_expand "conditional_trap"
18396   [(trap_if (match_operator 0 "comparison_operator"
18397              [(match_dup 2) (const_int 0)])
18398             (match_operand 1 "const_int_operand" ""))]
18399   ""
18400 {
18401   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18402                               ix86_expand_compare (GET_CODE (operands[0]),
18403                                                    NULL, NULL),
18404                               operands[1]));
18405   DONE;
18406 })
18407
18408 (define_insn "*conditional_trap_1"
18409   [(trap_if (match_operator 0 "comparison_operator"
18410              [(reg 17) (const_int 0)])
18411             (match_operand 1 "const_int_operand" ""))]
18412   ""
18413 {
18414   operands[2] = gen_label_rtx ();
18415   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18416   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18417                              CODE_LABEL_NUMBER (operands[2]));
18418   RET;
18419 })
18420
18421         ;; Pentium III SIMD instructions.
18422
18423 ;; Moves for SSE/MMX regs.
18424
18425 (define_insn "movv4sf_internal"
18426   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18427         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18428   "TARGET_SSE"
18429   "@
18430     xorps\t%0, %0
18431     movaps\t{%1, %0|%0, %1}
18432     movaps\t{%1, %0|%0, %1}"
18433   [(set_attr "type" "ssemov")
18434    (set_attr "mode" "V4SF")])
18435
18436 (define_split
18437   [(set (match_operand:V4SF 0 "register_operand" "")
18438         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18439   "TARGET_SSE"
18440   [(set (match_dup 0)
18441         (vec_merge:V4SF
18442          (vec_duplicate:V4SF (match_dup 1))
18443          (match_dup 2)
18444          (const_int 1)))]
18445 {
18446   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18447   operands[2] = CONST0_RTX (V4SFmode);
18448 })
18449
18450 (define_insn "movv4si_internal"
18451   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18452         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18453   "TARGET_SSE"
18454 {
18455   switch (which_alternative)
18456     {
18457     case 0:
18458       if (get_attr_mode (insn) == MODE_V4SF)
18459         return "xorps\t%0, %0";
18460       else
18461         return "pxor\t%0, %0";
18462     case 1:
18463     case 2:
18464       if (get_attr_mode (insn) == MODE_V4SF)
18465         return "movaps\t{%1, %0|%0, %1}";
18466       else
18467         return "movdqa\t{%1, %0|%0, %1}";
18468     default:
18469       abort ();
18470     }
18471 }
18472   [(set_attr "type" "ssemov")
18473    (set (attr "mode")
18474         (cond [(eq_attr "alternative" "0,1")
18475                  (if_then_else
18476                    (ne (symbol_ref "optimize_size")
18477                        (const_int 0))
18478                    (const_string "V4SF")
18479                    (const_string "TI"))
18480                (eq_attr "alternative" "2")
18481                  (if_then_else
18482                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18483                             (const_int 0))
18484                         (ne (symbol_ref "optimize_size")
18485                             (const_int 0)))
18486                    (const_string "V4SF")
18487                    (const_string "TI"))]
18488                (const_string "TI")))])
18489
18490 (define_insn "movv2di_internal"
18491   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18492         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18493   "TARGET_SSE"
18494 {
18495   switch (which_alternative)
18496     {
18497     case 0:
18498       if (get_attr_mode (insn) == MODE_V4SF)
18499         return "xorps\t%0, %0";
18500       else
18501         return "pxor\t%0, %0";
18502     case 1:
18503     case 2:
18504       if (get_attr_mode (insn) == MODE_V4SF)
18505         return "movaps\t{%1, %0|%0, %1}";
18506       else
18507         return "movdqa\t{%1, %0|%0, %1}";
18508     default:
18509       abort ();
18510     }
18511 }
18512   [(set_attr "type" "ssemov")
18513    (set (attr "mode")
18514         (cond [(eq_attr "alternative" "0,1")
18515                  (if_then_else
18516                    (ne (symbol_ref "optimize_size")
18517                        (const_int 0))
18518                    (const_string "V4SF")
18519                    (const_string "TI"))
18520                (eq_attr "alternative" "2")
18521                  (if_then_else
18522                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18523                             (const_int 0))
18524                         (ne (symbol_ref "optimize_size")
18525                             (const_int 0)))
18526                    (const_string "V4SF")
18527                    (const_string "TI"))]
18528                (const_string "TI")))])
18529
18530 (define_split
18531   [(set (match_operand:V2DF 0 "register_operand" "")
18532         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18533   "TARGET_SSE2"
18534   [(set (match_dup 0)
18535         (vec_merge:V2DF
18536          (vec_duplicate:V2DF (match_dup 1))
18537          (match_dup 2)
18538          (const_int 1)))]
18539 {
18540   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18541   operands[2] = CONST0_RTX (V2DFmode);
18542 })
18543
18544 (define_insn "movv8qi_internal"
18545   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18546         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18547   "TARGET_MMX
18548    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18549   "@
18550     pxor\t%0, %0
18551     movq\t{%1, %0|%0, %1}
18552     movq\t{%1, %0|%0, %1}"
18553   [(set_attr "type" "mmxmov")
18554    (set_attr "mode" "DI")])
18555
18556 (define_insn "movv4hi_internal"
18557   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18558         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18559   "TARGET_MMX
18560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18561   "@
18562     pxor\t%0, %0
18563     movq\t{%1, %0|%0, %1}
18564     movq\t{%1, %0|%0, %1}"
18565   [(set_attr "type" "mmxmov")
18566    (set_attr "mode" "DI")])
18567
18568 (define_insn "movv2si_internal"
18569   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18570         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18571   "TARGET_MMX
18572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18573   "@
18574     pxor\t%0, %0
18575     movq\t{%1, %0|%0, %1}
18576     movq\t{%1, %0|%0, %1}"
18577   [(set_attr "type" "mmxcvt")
18578    (set_attr "mode" "DI")])
18579
18580 (define_insn "movv2sf_internal"
18581   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18582         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18583   "TARGET_3DNOW
18584    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18585   "@
18586     pxor\t%0, %0
18587     movq\t{%1, %0|%0, %1}
18588     movq\t{%1, %0|%0, %1}"
18589   [(set_attr "type" "mmxcvt")
18590    (set_attr "mode" "DI")])
18591
18592 (define_expand "movti"
18593   [(set (match_operand:TI 0 "nonimmediate_operand" "")
18594         (match_operand:TI 1 "nonimmediate_operand" ""))]
18595   "TARGET_SSE || TARGET_64BIT"
18596 {
18597   if (TARGET_64BIT)
18598     ix86_expand_move (TImode, operands);
18599   else
18600     ix86_expand_vector_move (TImode, operands);
18601   DONE;
18602 })
18603
18604 (define_expand "movtf"
18605   [(set (match_operand:TF 0 "nonimmediate_operand" "")
18606         (match_operand:TF 1 "nonimmediate_operand" ""))]
18607   "TARGET_64BIT"
18608 {
18609   if (TARGET_64BIT)
18610     ix86_expand_move (TFmode, operands);
18611   else
18612     ix86_expand_vector_move (TFmode, operands);
18613   DONE;
18614 })
18615
18616 (define_insn "movv2df_internal"
18617   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18618         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18619   "TARGET_SSE2
18620    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18621 {
18622   switch (which_alternative)
18623     {
18624     case 0:
18625       if (get_attr_mode (insn) == MODE_V4SF)
18626         return "xorps\t%0, %0";
18627       else
18628         return "xorpd\t%0, %0";
18629     case 1:
18630     case 2:
18631       if (get_attr_mode (insn) == MODE_V4SF)
18632         return "movaps\t{%1, %0|%0, %1}";
18633       else
18634         return "movapd\t{%1, %0|%0, %1}";
18635     default:
18636       abort ();
18637     }
18638 }
18639   [(set_attr "type" "ssemov")
18640    (set (attr "mode")
18641         (cond [(eq_attr "alternative" "0,1")
18642                  (if_then_else
18643                    (ne (symbol_ref "optimize_size")
18644                        (const_int 0))
18645                    (const_string "V4SF")
18646                    (const_string "V2DF"))
18647                (eq_attr "alternative" "2")
18648                  (if_then_else
18649                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18650                             (const_int 0))
18651                         (ne (symbol_ref "optimize_size")
18652                             (const_int 0)))
18653                    (const_string "V4SF")
18654                    (const_string "V2DF"))]
18655                (const_string "V2DF")))])
18656
18657 (define_insn "movv8hi_internal"
18658   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18659         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18660   "TARGET_SSE2
18661    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18662 {
18663   switch (which_alternative)
18664     {
18665     case 0:
18666       if (get_attr_mode (insn) == MODE_V4SF)
18667         return "xorps\t%0, %0";
18668       else
18669         return "pxor\t%0, %0";
18670     case 1:
18671     case 2:
18672       if (get_attr_mode (insn) == MODE_V4SF)
18673         return "movaps\t{%1, %0|%0, %1}";
18674       else
18675         return "movdqa\t{%1, %0|%0, %1}";
18676     default:
18677       abort ();
18678     }
18679 }
18680   [(set_attr "type" "ssemov")
18681    (set (attr "mode")
18682         (cond [(eq_attr "alternative" "0,1")
18683                  (if_then_else
18684                    (ne (symbol_ref "optimize_size")
18685                        (const_int 0))
18686                    (const_string "V4SF")
18687                    (const_string "TI"))
18688                (eq_attr "alternative" "2")
18689                  (if_then_else
18690                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18691                             (const_int 0))
18692                         (ne (symbol_ref "optimize_size")
18693                             (const_int 0)))
18694                    (const_string "V4SF")
18695                    (const_string "TI"))]
18696                (const_string "TI")))])
18697
18698 (define_insn "movv16qi_internal"
18699   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18700         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
18701   "TARGET_SSE2
18702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18703 {
18704   switch (which_alternative)
18705     {
18706     case 0:
18707       if (get_attr_mode (insn) == MODE_V4SF)
18708         return "xorps\t%0, %0";
18709       else
18710         return "pxor\t%0, %0";
18711     case 1:
18712     case 2:
18713       if (get_attr_mode (insn) == MODE_V4SF)
18714         return "movaps\t{%1, %0|%0, %1}";
18715       else
18716         return "movdqa\t{%1, %0|%0, %1}";
18717     default:
18718       abort ();
18719     }
18720 }
18721   [(set_attr "type" "ssemov")
18722    (set (attr "mode")
18723         (cond [(eq_attr "alternative" "0,1")
18724                  (if_then_else
18725                    (ne (symbol_ref "optimize_size")
18726                        (const_int 0))
18727                    (const_string "V4SF")
18728                    (const_string "TI"))
18729                (eq_attr "alternative" "2")
18730                  (if_then_else
18731                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18732                             (const_int 0))
18733                         (ne (symbol_ref "optimize_size")
18734                             (const_int 0)))
18735                    (const_string "V4SF")
18736                    (const_string "TI"))]
18737                (const_string "TI")))])
18738
18739 (define_expand "movv2df"
18740   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18741         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18742   "TARGET_SSE2"
18743 {
18744   ix86_expand_vector_move (V2DFmode, operands);
18745   DONE;
18746 })
18747
18748 (define_expand "movv8hi"
18749   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18750         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18751   "TARGET_SSE2"
18752 {
18753   ix86_expand_vector_move (V8HImode, operands);
18754   DONE;
18755 })
18756
18757 (define_expand "movv16qi"
18758   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18759         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18760   "TARGET_SSE2"
18761 {
18762   ix86_expand_vector_move (V16QImode, operands);
18763   DONE;
18764 })
18765
18766 (define_expand "movv4sf"
18767   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18768         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18769   "TARGET_SSE"
18770 {
18771   ix86_expand_vector_move (V4SFmode, operands);
18772   DONE;
18773 })
18774
18775 (define_expand "movv4si"
18776   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18777         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18778   "TARGET_SSE"
18779 {
18780   ix86_expand_vector_move (V4SImode, operands);
18781   DONE;
18782 })
18783
18784 (define_expand "movv2di"
18785   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18786         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18787   "TARGET_SSE"
18788 {
18789   ix86_expand_vector_move (V2DImode, operands);
18790   DONE;
18791 })
18792
18793 (define_expand "movv2si"
18794   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18795         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18796   "TARGET_MMX"
18797 {
18798   ix86_expand_vector_move (V2SImode, operands);
18799   DONE;
18800 })
18801
18802 (define_expand "movv4hi"
18803   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18804         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18805   "TARGET_MMX"
18806 {
18807   ix86_expand_vector_move (V4HImode, operands);
18808   DONE;
18809 })
18810
18811 (define_expand "movv8qi"
18812   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18813         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18814   "TARGET_MMX"
18815 {
18816   ix86_expand_vector_move (V8QImode, operands);
18817   DONE;
18818 })
18819
18820 (define_expand "movv2sf"
18821   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18822         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18823    "TARGET_3DNOW"
18824 {
18825   ix86_expand_vector_move (V2SFmode, operands);
18826   DONE;
18827 })
18828
18829 (define_insn "*pushti"
18830   [(set (match_operand:TI 0 "push_operand" "=<")
18831         (match_operand:TI 1 "register_operand" "x"))]
18832   "TARGET_SSE"
18833   "#")
18834
18835 (define_insn "*pushv2df"
18836   [(set (match_operand:V2DF 0 "push_operand" "=<")
18837         (match_operand:V2DF 1 "register_operand" "x"))]
18838   "TARGET_SSE"
18839   "#")
18840
18841 (define_insn "*pushv2di"
18842   [(set (match_operand:V2DI 0 "push_operand" "=<")
18843         (match_operand:V2DI 1 "register_operand" "x"))]
18844   "TARGET_SSE2"
18845   "#")
18846
18847 (define_insn "*pushv8hi"
18848   [(set (match_operand:V8HI 0 "push_operand" "=<")
18849         (match_operand:V8HI 1 "register_operand" "x"))]
18850   "TARGET_SSE2"
18851   "#")
18852
18853 (define_insn "*pushv16qi"
18854   [(set (match_operand:V16QI 0 "push_operand" "=<")
18855         (match_operand:V16QI 1 "register_operand" "x"))]
18856   "TARGET_SSE2"
18857   "#")
18858
18859 (define_insn "*pushv4sf"
18860   [(set (match_operand:V4SF 0 "push_operand" "=<")
18861         (match_operand:V4SF 1 "register_operand" "x"))]
18862   "TARGET_SSE"
18863   "#")
18864
18865 (define_insn "*pushv4si"
18866   [(set (match_operand:V4SI 0 "push_operand" "=<")
18867         (match_operand:V4SI 1 "register_operand" "x"))]
18868   "TARGET_SSE2"
18869   "#")
18870
18871 (define_insn "*pushv2si"
18872   [(set (match_operand:V2SI 0 "push_operand" "=<")
18873         (match_operand:V2SI 1 "register_operand" "y"))]
18874   "TARGET_MMX"
18875   "#")
18876
18877 (define_insn "*pushv4hi"
18878   [(set (match_operand:V4HI 0 "push_operand" "=<")
18879         (match_operand:V4HI 1 "register_operand" "y"))]
18880   "TARGET_MMX"
18881   "#")
18882
18883 (define_insn "*pushv8qi"
18884   [(set (match_operand:V8QI 0 "push_operand" "=<")
18885         (match_operand:V8QI 1 "register_operand" "y"))]
18886   "TARGET_MMX"
18887   "#")
18888
18889 (define_insn "*pushv2sf"
18890   [(set (match_operand:V2SF 0 "push_operand" "=<")
18891         (match_operand:V2SF 1 "register_operand" "y"))]
18892   "TARGET_3DNOW"
18893   "#")
18894
18895 (define_split
18896   [(set (match_operand 0 "push_operand" "")
18897         (match_operand 1 "register_operand" ""))]
18898   "!TARGET_64BIT && reload_completed
18899    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18900   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18901    (set (match_dup 2) (match_dup 1))]
18902   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18903                                  stack_pointer_rtx);
18904    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18905
18906 (define_split
18907   [(set (match_operand 0 "push_operand" "")
18908         (match_operand 1 "register_operand" ""))]
18909   "TARGET_64BIT && reload_completed
18910    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18911   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18912    (set (match_dup 2) (match_dup 1))]
18913   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18914                                  stack_pointer_rtx);
18915    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18916
18917
18918 (define_insn "movti_internal"
18919   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18920         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18921   "TARGET_SSE && !TARGET_64BIT
18922    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18923 {
18924   switch (which_alternative)
18925     {
18926     case 0:
18927       if (get_attr_mode (insn) == MODE_V4SF)
18928         return "xorps\t%0, %0";
18929       else
18930         return "pxor\t%0, %0";
18931     case 1:
18932     case 2:
18933       if (get_attr_mode (insn) == MODE_V4SF)
18934         return "movaps\t{%1, %0|%0, %1}";
18935       else
18936         return "movdqa\t{%1, %0|%0, %1}";
18937     default:
18938       abort ();
18939     }
18940 }
18941   [(set_attr "type" "ssemov,ssemov,ssemov")
18942    (set (attr "mode")
18943         (cond [(eq_attr "alternative" "0,1")
18944                  (if_then_else
18945                    (ne (symbol_ref "optimize_size")
18946                        (const_int 0))
18947                    (const_string "V4SF")
18948                    (const_string "TI"))
18949                (eq_attr "alternative" "2")
18950                  (if_then_else
18951                    (ne (symbol_ref "optimize_size")
18952                        (const_int 0))
18953                    (const_string "V4SF")
18954                    (const_string "TI"))]
18955                (const_string "TI")))])
18956
18957 (define_insn "*movti_rex64"
18958   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18959         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
18960   "TARGET_64BIT
18961    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18962 {
18963   switch (which_alternative)
18964     {
18965     case 0:
18966     case 1:
18967       return "#";
18968     case 2:
18969       if (get_attr_mode (insn) == MODE_V4SF)
18970         return "xorps\t%0, %0";
18971       else
18972         return "pxor\t%0, %0";
18973     case 3:
18974     case 4:
18975       if (get_attr_mode (insn) == MODE_V4SF)
18976         return "movaps\t{%1, %0|%0, %1}";
18977       else
18978         return "movdqa\t{%1, %0|%0, %1}";
18979     default:
18980       abort ();
18981     }
18982 }
18983   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18984    (set (attr "mode")
18985         (cond [(eq_attr "alternative" "2,3")
18986                  (if_then_else
18987                    (ne (symbol_ref "optimize_size")
18988                        (const_int 0))
18989                    (const_string "V4SF")
18990                    (const_string "TI"))
18991                (eq_attr "alternative" "4")
18992                  (if_then_else
18993                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18994                             (const_int 0))
18995                         (ne (symbol_ref "optimize_size")
18996                             (const_int 0)))
18997                    (const_string "V4SF")
18998                    (const_string "TI"))]
18999                (const_string "DI")))])
19000
19001 (define_insn "*movtf_rex64"
19002   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19003         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19004   "TARGET_64BIT
19005    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19006 {
19007   switch (which_alternative)
19008     {
19009     case 0:
19010     case 1:
19011       return "#";
19012     case 2:
19013       if (get_attr_mode (insn) == MODE_V4SF)
19014         return "xorps\t%0, %0";
19015       else
19016         return "pxor\t%0, %0";
19017     case 3:
19018     case 4:
19019       if (get_attr_mode (insn) == MODE_V4SF)
19020         return "movaps\t{%1, %0|%0, %1}";
19021       else
19022         return "movdqa\t{%1, %0|%0, %1}";
19023     default:
19024       abort ();
19025     }
19026 }
19027   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19028    (set (attr "mode")
19029         (cond [(eq_attr "alternative" "2,3")
19030                  (if_then_else
19031                    (ne (symbol_ref "optimize_size")
19032                        (const_int 0))
19033                    (const_string "V4SF")
19034                    (const_string "TI"))
19035                (eq_attr "alternative" "4")
19036                  (if_then_else
19037                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19038                             (const_int 0))
19039                         (ne (symbol_ref "optimize_size")
19040                             (const_int 0)))
19041                    (const_string "V4SF")
19042                    (const_string "TI"))]
19043                (const_string "DI")))])
19044
19045 (define_split
19046   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19047         (match_operand:TI 1 "general_operand" ""))]
19048   "reload_completed && !SSE_REG_P (operands[0])
19049    && !SSE_REG_P (operands[1])"
19050   [(const_int 0)]
19051   "ix86_split_long_move (operands); DONE;")
19052
19053 (define_split
19054   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19055         (match_operand:TF 1 "general_operand" ""))]
19056   "reload_completed && !SSE_REG_P (operands[0])
19057    && !SSE_REG_P (operands[1])"
19058   [(const_int 0)]
19059   "ix86_split_long_move (operands); DONE;")
19060
19061 ;; These two patterns are useful for specifying exactly whether to use
19062 ;; movaps or movups
19063 (define_expand "sse_movaps"
19064   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19065         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19066                      UNSPEC_MOVA))]
19067   "TARGET_SSE"
19068 {
19069   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19070     {
19071       rtx tmp = gen_reg_rtx (V4SFmode);
19072       emit_insn (gen_sse_movaps (tmp, operands[1]));
19073       emit_move_insn (operands[0], tmp);
19074       DONE;
19075     }
19076 })
19077
19078 (define_insn "*sse_movaps_1"
19079   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19080         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19081                      UNSPEC_MOVA))]
19082   "TARGET_SSE
19083    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19084   "movaps\t{%1, %0|%0, %1}"
19085   [(set_attr "type" "ssemov,ssemov")
19086    (set_attr "mode" "V4SF")])
19087
19088 (define_expand "sse_movups"
19089   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19090         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19091                      UNSPEC_MOVU))]
19092   "TARGET_SSE"
19093 {
19094   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19095     {
19096       rtx tmp = gen_reg_rtx (V4SFmode);
19097       emit_insn (gen_sse_movups (tmp, operands[1]));
19098       emit_move_insn (operands[0], tmp);
19099       DONE;
19100     }
19101 })
19102
19103 (define_insn "*sse_movups_1"
19104   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19105         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19106                      UNSPEC_MOVU))]
19107   "TARGET_SSE
19108    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19109   "movups\t{%1, %0|%0, %1}"
19110   [(set_attr "type" "ssecvt,ssecvt")
19111    (set_attr "mode" "V4SF")])
19112
19113 ;; SSE Strange Moves.
19114
19115 (define_insn "sse_movmskps"
19116   [(set (match_operand:SI 0 "register_operand" "=r")
19117         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19118                    UNSPEC_MOVMSK))]
19119   "TARGET_SSE"
19120   "movmskps\t{%1, %0|%0, %1}"
19121   [(set_attr "type" "ssecvt")
19122    (set_attr "mode" "V4SF")])
19123
19124 (define_insn "mmx_pmovmskb"
19125   [(set (match_operand:SI 0 "register_operand" "=r")
19126         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19127                    UNSPEC_MOVMSK))]
19128   "TARGET_SSE || TARGET_3DNOW_A"
19129   "pmovmskb\t{%1, %0|%0, %1}"
19130   [(set_attr "type" "ssecvt")
19131    (set_attr "mode" "V4SF")])
19132
19133
19134 (define_insn "mmx_maskmovq"
19135   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19136         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19137                       (match_operand:V8QI 2 "register_operand" "y")]
19138                      UNSPEC_MASKMOV))]
19139   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19140   ;; @@@ check ordering of operands in intel/nonintel syntax
19141   "maskmovq\t{%2, %1|%1, %2}"
19142   [(set_attr "type" "mmxcvt")
19143    (set_attr "mode" "DI")])
19144
19145 (define_insn "mmx_maskmovq_rex"
19146   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19147         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19148                       (match_operand:V8QI 2 "register_operand" "y")]
19149                      UNSPEC_MASKMOV))]
19150   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19151   ;; @@@ check ordering of operands in intel/nonintel syntax
19152   "maskmovq\t{%2, %1|%1, %2}"
19153   [(set_attr "type" "mmxcvt")
19154    (set_attr "mode" "DI")])
19155
19156 (define_insn "sse_movntv4sf"
19157   [(set (match_operand:V4SF 0 "memory_operand" "=m")
19158         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19159                      UNSPEC_MOVNT))]
19160   "TARGET_SSE"
19161   "movntps\t{%1, %0|%0, %1}"
19162   [(set_attr "type" "ssemov")
19163    (set_attr "mode" "V4SF")])
19164
19165 (define_insn "sse_movntdi"
19166   [(set (match_operand:DI 0 "memory_operand" "=m")
19167         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19168                    UNSPEC_MOVNT))]
19169   "TARGET_SSE || TARGET_3DNOW_A"
19170   "movntq\t{%1, %0|%0, %1}"
19171   [(set_attr "type" "mmxmov")
19172    (set_attr "mode" "DI")])
19173
19174 (define_insn "sse_movhlps"
19175   [(set (match_operand:V4SF 0 "register_operand" "=x")
19176         (vec_merge:V4SF
19177          (match_operand:V4SF 1 "register_operand" "0")
19178          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19179                           (parallel [(const_int 2)
19180                                      (const_int 3)
19181                                      (const_int 0)
19182                                      (const_int 1)]))
19183          (const_int 3)))]
19184   "TARGET_SSE"
19185   "movhlps\t{%2, %0|%0, %2}"
19186   [(set_attr "type" "ssecvt")
19187    (set_attr "mode" "V4SF")])
19188
19189 (define_insn "sse_movlhps"
19190   [(set (match_operand:V4SF 0 "register_operand" "=x")
19191         (vec_merge:V4SF
19192          (match_operand:V4SF 1 "register_operand" "0")
19193          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19194                           (parallel [(const_int 2)
19195                                      (const_int 3)
19196                                      (const_int 0)
19197                                      (const_int 1)]))
19198          (const_int 12)))]
19199   "TARGET_SSE"
19200   "movlhps\t{%2, %0|%0, %2}"
19201   [(set_attr "type" "ssecvt")
19202    (set_attr "mode" "V4SF")])
19203
19204 (define_insn "sse_movhps"
19205   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19206         (vec_merge:V4SF
19207          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19208          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19209          (const_int 12)))]
19210   "TARGET_SSE
19211    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19212   "movhps\t{%2, %0|%0, %2}"
19213   [(set_attr "type" "ssecvt")
19214    (set_attr "mode" "V4SF")])
19215
19216 (define_insn "sse_movlps"
19217   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19218         (vec_merge:V4SF
19219          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19220          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19221          (const_int 3)))]
19222   "TARGET_SSE
19223    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19224   "movlps\t{%2, %0|%0, %2}"
19225   [(set_attr "type" "ssecvt")
19226    (set_attr "mode" "V4SF")])
19227
19228 (define_expand "sse_loadss"
19229   [(match_operand:V4SF 0 "register_operand" "")
19230    (match_operand:SF 1 "memory_operand" "")]
19231   "TARGET_SSE"
19232 {
19233   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19234                                CONST0_RTX (V4SFmode)));
19235   DONE;
19236 })
19237
19238 (define_insn "sse_loadss_1"
19239   [(set (match_operand:V4SF 0 "register_operand" "=x")
19240         (vec_merge:V4SF
19241          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19242          (match_operand:V4SF 2 "const0_operand" "X")
19243          (const_int 1)))]
19244   "TARGET_SSE"
19245   "movss\t{%1, %0|%0, %1}"
19246   [(set_attr "type" "ssemov")
19247    (set_attr "mode" "SF")])
19248
19249 (define_insn "sse_movss"
19250   [(set (match_operand:V4SF 0 "register_operand" "=x")
19251         (vec_merge:V4SF
19252          (match_operand:V4SF 1 "register_operand" "0")
19253          (match_operand:V4SF 2 "register_operand" "x")
19254          (const_int 1)))]
19255   "TARGET_SSE"
19256   "movss\t{%2, %0|%0, %2}"
19257   [(set_attr "type" "ssemov")
19258    (set_attr "mode" "SF")])
19259
19260 (define_insn "sse_storess"
19261   [(set (match_operand:SF 0 "memory_operand" "=m")
19262         (vec_select:SF
19263          (match_operand:V4SF 1 "register_operand" "x")
19264          (parallel [(const_int 0)])))]
19265   "TARGET_SSE"
19266   "movss\t{%1, %0|%0, %1}"
19267   [(set_attr "type" "ssemov")
19268    (set_attr "mode" "SF")])
19269
19270 (define_insn "sse_shufps"
19271   [(set (match_operand:V4SF 0 "register_operand" "=x")
19272         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19273                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19274                       (match_operand:SI 3 "immediate_operand" "i")]
19275                      UNSPEC_SHUFFLE))]
19276   "TARGET_SSE"
19277   ;; @@@ check operand order for intel/nonintel syntax
19278   "shufps\t{%3, %2, %0|%0, %2, %3}"
19279   [(set_attr "type" "ssecvt")
19280    (set_attr "mode" "V4SF")])
19281
19282
19283 ;; SSE arithmetic
19284
19285 (define_insn "addv4sf3"
19286   [(set (match_operand:V4SF 0 "register_operand" "=x")
19287         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19288                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19289   "TARGET_SSE"
19290   "addps\t{%2, %0|%0, %2}"
19291   [(set_attr "type" "sseadd")
19292    (set_attr "mode" "V4SF")])
19293
19294 (define_insn "vmaddv4sf3"
19295   [(set (match_operand:V4SF 0 "register_operand" "=x")
19296         (vec_merge:V4SF
19297          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19298                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19299          (match_dup 1)
19300          (const_int 1)))]
19301   "TARGET_SSE"
19302   "addss\t{%2, %0|%0, %2}"
19303   [(set_attr "type" "sseadd")
19304    (set_attr "mode" "SF")])
19305
19306 (define_insn "subv4sf3"
19307   [(set (match_operand:V4SF 0 "register_operand" "=x")
19308         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19309                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19310   "TARGET_SSE"
19311   "subps\t{%2, %0|%0, %2}"
19312   [(set_attr "type" "sseadd")
19313    (set_attr "mode" "V4SF")])
19314
19315 (define_insn "vmsubv4sf3"
19316   [(set (match_operand:V4SF 0 "register_operand" "=x")
19317         (vec_merge:V4SF
19318          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19319                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19320          (match_dup 1)
19321          (const_int 1)))]
19322   "TARGET_SSE"
19323   "subss\t{%2, %0|%0, %2}"
19324   [(set_attr "type" "sseadd")
19325    (set_attr "mode" "SF")])
19326
19327 (define_insn "mulv4sf3"
19328   [(set (match_operand:V4SF 0 "register_operand" "=x")
19329         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19330                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19331   "TARGET_SSE"
19332   "mulps\t{%2, %0|%0, %2}"
19333   [(set_attr "type" "ssemul")
19334    (set_attr "mode" "V4SF")])
19335
19336 (define_insn "vmmulv4sf3"
19337   [(set (match_operand:V4SF 0 "register_operand" "=x")
19338         (vec_merge:V4SF
19339          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19340                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19341          (match_dup 1)
19342          (const_int 1)))]
19343   "TARGET_SSE"
19344   "mulss\t{%2, %0|%0, %2}"
19345   [(set_attr "type" "ssemul")
19346    (set_attr "mode" "SF")])
19347
19348 (define_insn "divv4sf3"
19349   [(set (match_operand:V4SF 0 "register_operand" "=x")
19350         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19351                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19352   "TARGET_SSE"
19353   "divps\t{%2, %0|%0, %2}"
19354   [(set_attr "type" "ssediv")
19355    (set_attr "mode" "V4SF")])
19356
19357 (define_insn "vmdivv4sf3"
19358   [(set (match_operand:V4SF 0 "register_operand" "=x")
19359         (vec_merge:V4SF
19360          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19361                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19362          (match_dup 1)
19363          (const_int 1)))]
19364   "TARGET_SSE"
19365   "divss\t{%2, %0|%0, %2}"
19366   [(set_attr "type" "ssediv")
19367    (set_attr "mode" "SF")])
19368
19369
19370 ;; SSE square root/reciprocal
19371
19372 (define_insn "rcpv4sf2"
19373   [(set (match_operand:V4SF 0 "register_operand" "=x")
19374         (unspec:V4SF
19375          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19376   "TARGET_SSE"
19377   "rcpps\t{%1, %0|%0, %1}"
19378   [(set_attr "type" "sse")
19379    (set_attr "mode" "V4SF")])
19380
19381 (define_insn "vmrcpv4sf2"
19382   [(set (match_operand:V4SF 0 "register_operand" "=x")
19383         (vec_merge:V4SF
19384          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19385                       UNSPEC_RCP)
19386          (match_operand:V4SF 2 "register_operand" "0")
19387          (const_int 1)))]
19388   "TARGET_SSE"
19389   "rcpss\t{%1, %0|%0, %1}"
19390   [(set_attr "type" "sse")
19391    (set_attr "mode" "SF")])
19392
19393 (define_insn "rsqrtv4sf2"
19394   [(set (match_operand:V4SF 0 "register_operand" "=x")
19395         (unspec:V4SF
19396          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19397   "TARGET_SSE"
19398   "rsqrtps\t{%1, %0|%0, %1}"
19399   [(set_attr "type" "sse")
19400    (set_attr "mode" "V4SF")])
19401
19402 (define_insn "vmrsqrtv4sf2"
19403   [(set (match_operand:V4SF 0 "register_operand" "=x")
19404         (vec_merge:V4SF
19405          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19406                       UNSPEC_RSQRT)
19407          (match_operand:V4SF 2 "register_operand" "0")
19408          (const_int 1)))]
19409   "TARGET_SSE"
19410   "rsqrtss\t{%1, %0|%0, %1}"
19411   [(set_attr "type" "sse")
19412    (set_attr "mode" "SF")])
19413
19414 (define_insn "sqrtv4sf2"
19415   [(set (match_operand:V4SF 0 "register_operand" "=x")
19416         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19417   "TARGET_SSE"
19418   "sqrtps\t{%1, %0|%0, %1}"
19419   [(set_attr "type" "sse")
19420    (set_attr "mode" "V4SF")])
19421
19422 (define_insn "vmsqrtv4sf2"
19423   [(set (match_operand:V4SF 0 "register_operand" "=x")
19424         (vec_merge:V4SF
19425          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19426          (match_operand:V4SF 2 "register_operand" "0")
19427          (const_int 1)))]
19428   "TARGET_SSE"
19429   "sqrtss\t{%1, %0|%0, %1}"
19430   [(set_attr "type" "sse")
19431    (set_attr "mode" "SF")])
19432
19433 ;; SSE logical operations.
19434
19435 ;; SSE defines logical operations on floating point values.  This brings
19436 ;; interesting challenge to RTL representation where logicals are only valid
19437 ;; on integral types.  We deal with this by representing the floating point
19438 ;; logical as logical on arguments casted to TImode as this is what hardware
19439 ;; really does.  Unfortunately hardware requires the type information to be
19440 ;; present and thus we must avoid subregs from being simplified and eliminated
19441 ;; in later compilation phases.
19442 ;;
19443 ;; We have following variants from each instruction:
19444 ;; sse_andsf3 - the operation taking V4SF vector operands
19445 ;;              and doing TImode cast on them
19446 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19447 ;;                      TImode, since backend insist on eliminating casts
19448 ;;                      on memory operands
19449 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19450 ;;                   We can not accept memory operand here as instruction reads
19451 ;;                   whole scalar.  This is generated only post reload by GCC
19452 ;;                   scalar float operations that expands to logicals (fabs)
19453 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19454 ;;                   memory operand.  Eventually combine can be able
19455 ;;                   to synthesize these using splitter.
19456 ;; sse2_anddf3, *sse2_anddf3_memory
19457 ;;              
19458 ;; 
19459 ;; These are not called andti3 etc. because we really really don't want
19460 ;; the compiler to widen DImode ands to TImode ands and then try to move
19461 ;; into DImode subregs of SSE registers, and them together, and move out
19462 ;; of DImode subregs again!
19463 ;; SSE1 single precision floating point logical operation
19464 (define_expand "sse_andv4sf3"
19465   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19466         (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19467                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19468   "TARGET_SSE"
19469   "")
19470
19471 (define_insn "*sse_andv4sf3"
19472   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19473         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19474                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19475   "TARGET_SSE
19476    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19477   "andps\t{%2, %0|%0, %2}"
19478   [(set_attr "type" "sselog")
19479    (set_attr "mode" "V4SF")])
19480
19481 (define_insn "*sse_andsf3"
19482   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19483         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19484                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19485   "TARGET_SSE
19486    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19487   "andps\t{%2, %0|%0, %2}"
19488   [(set_attr "type" "sselog")
19489    (set_attr "mode" "V4SF")])
19490
19491 (define_expand "sse_nandv4sf3"
19492   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19493         (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19494                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19495   "TARGET_SSE"
19496   "")
19497
19498 (define_insn "*sse_nandv4sf3"
19499   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19500         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19501                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19502   "TARGET_SSE"
19503   "andnps\t{%2, %0|%0, %2}"
19504   [(set_attr "type" "sselog")
19505    (set_attr "mode" "V4SF")])
19506
19507 (define_insn "*sse_nandsf3"
19508   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19509         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19510                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19511   "TARGET_SSE"
19512   "andnps\t{%2, %0|%0, %2}"
19513   [(set_attr "type" "sselog")
19514    (set_attr "mode" "V4SF")])
19515
19516 (define_expand "sse_iorv4sf3"
19517   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19518         (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19519                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19520   "TARGET_SSE"
19521   "")
19522
19523 (define_insn "*sse_iorv4sf3"
19524   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19525         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19526                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19527   "TARGET_SSE
19528    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19529   "orps\t{%2, %0|%0, %2}"
19530   [(set_attr "type" "sselog")
19531    (set_attr "mode" "V4SF")])
19532
19533 (define_insn "*sse_iorsf3"
19534   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19535         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19536                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19537   "TARGET_SSE
19538    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19539   "orps\t{%2, %0|%0, %2}"
19540   [(set_attr "type" "sselog")
19541    (set_attr "mode" "V4SF")])
19542
19543 (define_expand "sse_xorv4sf3"
19544   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19545         (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19546                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19547   "TARGET_SSE
19548    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19549   "")
19550
19551 (define_insn "*sse_xorv4sf3"
19552   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19553         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19554                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19555   "TARGET_SSE
19556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19557   "xorps\t{%2, %0|%0, %2}"
19558   [(set_attr "type" "sselog")
19559    (set_attr "mode" "V4SF")])
19560
19561 (define_insn "*sse_xorsf3"
19562   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19563         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19564                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19565   "TARGET_SSE
19566    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19567   "xorps\t{%2, %0|%0, %2}"
19568   [(set_attr "type" "sselog")
19569    (set_attr "mode" "V4SF")])
19570
19571 ;; SSE2 double precision floating point logical operation
19572
19573 (define_expand "sse2_andv2df3"
19574   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19575         (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19576                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19577   "TARGET_SSE2"
19578   "")
19579
19580 (define_insn "*sse2_andv2df3"
19581   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19582         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19583                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19584   "TARGET_SSE2
19585    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19586   "andpd\t{%2, %0|%0, %2}"
19587   [(set_attr "type" "sselog")
19588    (set_attr "mode" "V2DF")])
19589
19590 (define_insn "*sse2_andv2df3"
19591   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19592         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19593                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19594   "TARGET_SSE2
19595    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19596   "andpd\t{%2, %0|%0, %2}"
19597   [(set_attr "type" "sselog")
19598    (set_attr "mode" "V2DF")])
19599
19600 (define_expand "sse2_nandv2df3"
19601   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19602         (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19603                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19604   "TARGET_SSE2"
19605   "")
19606
19607 (define_insn "*sse2_nandv2df3"
19608   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19609         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19610                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19611   "TARGET_SSE2"
19612   "andnpd\t{%2, %0|%0, %2}"
19613   [(set_attr "type" "sselog")
19614    (set_attr "mode" "V2DF")])
19615
19616 (define_insn "*sse_nandti3_df"
19617   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19618         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19619                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19620   "TARGET_SSE2"
19621   "andnpd\t{%2, %0|%0, %2}"
19622   [(set_attr "type" "sselog")
19623    (set_attr "mode" "V2DF")])
19624
19625 (define_expand "sse2_iorv2df3"
19626   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19627         (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19628                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19629   "TARGET_SSE2"
19630   "")
19631
19632 (define_insn "*sse2_iorv2df3"
19633   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19634         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19635                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19636   "TARGET_SSE2
19637    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19638   "orpd\t{%2, %0|%0, %2}"
19639   [(set_attr "type" "sselog")
19640    (set_attr "mode" "V2DF")])
19641
19642 (define_insn "*sse2_iordf3"
19643   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19644         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19645                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19646   "TARGET_SSE2
19647    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19648   "orpd\t{%2, %0|%0, %2}"
19649   [(set_attr "type" "sselog")
19650    (set_attr "mode" "V2DF")])
19651
19652 (define_expand "sse2_xorv2df3"
19653   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19654         (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19655                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19656   "TARGET_SSE2"
19657   "")
19658
19659 (define_insn "*sse2_xorv2df3"
19660   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19661         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19662                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19663   "TARGET_SSE2
19664    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19665   "xorpd\t{%2, %0|%0, %2}"
19666   [(set_attr "type" "sselog")
19667    (set_attr "mode" "V2DF")])
19668
19669 (define_insn "*sse2_xordf3"
19670   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19671         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19672                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19673   "TARGET_SSE2
19674    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19675   "xorpd\t{%2, %0|%0, %2}"
19676   [(set_attr "type" "sselog")
19677    (set_attr "mode" "V2DF")])
19678
19679 ;; SSE2 integral logicals.  These patterns must always come after floating
19680 ;; point ones since we don't want compiler to use integer opcodes on floating
19681 ;; point SSE values to avoid matching of subregs in the match_operand.
19682 (define_insn "*sse2_andti3"
19683   [(set (match_operand:TI 0 "register_operand" "=x")
19684         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19685                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19686   "TARGET_SSE2
19687    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19688   "pand\t{%2, %0|%0, %2}"
19689   [(set_attr "type" "sselog")
19690    (set_attr "mode" "TI")])
19691
19692 (define_insn "sse2_andv2di3"
19693   [(set (match_operand:V2DI 0 "register_operand" "=x")
19694         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19695                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19696   "TARGET_SSE2
19697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19698   "pand\t{%2, %0|%0, %2}"
19699   [(set_attr "type" "sselog")
19700    (set_attr "mode" "TI")])
19701
19702 (define_insn "*sse2_nandti3"
19703   [(set (match_operand:TI 0 "register_operand" "=x")
19704         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19705                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19706   "TARGET_SSE2"
19707   "pandn\t{%2, %0|%0, %2}"
19708   [(set_attr "type" "sselog")
19709    (set_attr "mode" "TI")])
19710
19711 (define_insn "sse2_nandv2di3"
19712   [(set (match_operand:V2DI 0 "register_operand" "=x")
19713         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19714                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19715   "TARGET_SSE2
19716    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19717   "pandn\t{%2, %0|%0, %2}"
19718   [(set_attr "type" "sselog")
19719    (set_attr "mode" "TI")])
19720
19721 (define_insn "*sse2_iorti3"
19722   [(set (match_operand:TI 0 "register_operand" "=x")
19723         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19724                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19725   "TARGET_SSE2
19726    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19727   "por\t{%2, %0|%0, %2}"
19728   [(set_attr "type" "sselog")
19729    (set_attr "mode" "TI")])
19730
19731 (define_insn "sse2_iorv2di3"
19732   [(set (match_operand:V2DI 0 "register_operand" "=x")
19733         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19734                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19735   "TARGET_SSE2
19736    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19737   "por\t{%2, %0|%0, %2}"
19738   [(set_attr "type" "sselog")
19739    (set_attr "mode" "TI")])
19740
19741 (define_insn "*sse2_xorti3"
19742   [(set (match_operand:TI 0 "register_operand" "=x")
19743         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19744                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19745   "TARGET_SSE2
19746    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19747   "pxor\t{%2, %0|%0, %2}"
19748   [(set_attr "type" "sselog")
19749    (set_attr "mode" "TI")])
19750
19751 (define_insn "sse2_xorv2di3"
19752   [(set (match_operand:V2DI 0 "register_operand" "=x")
19753         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19754                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19755   "TARGET_SSE2
19756    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19757   "pxor\t{%2, %0|%0, %2}"
19758   [(set_attr "type" "sselog")
19759    (set_attr "mode" "TI")])
19760
19761 ;; Use xor, but don't show input operands so they aren't live before
19762 ;; this insn.
19763 (define_insn "sse_clrv4sf"
19764   [(set (match_operand:V4SF 0 "register_operand" "=x")
19765         (match_operand:V4SF 1 "const0_operand" "X"))]
19766   "TARGET_SSE"
19767 {
19768   if (get_attr_mode (insn) == MODE_TI)
19769     return "pxor\t{%0, %0|%0, %0}";
19770   else
19771     return "xorps\t{%0, %0|%0, %0}";
19772 }
19773   [(set_attr "type" "sselog")
19774    (set_attr "memory" "none")
19775    (set (attr "mode")
19776         (if_then_else
19777            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19778                          (const_int 0))
19779                      (ne (symbol_ref "TARGET_SSE2")
19780                          (const_int 0)))
19781                 (eq (symbol_ref "optimize_size")
19782                     (const_int 0)))
19783          (const_string "TI")
19784          (const_string "V4SF")))])
19785
19786 ;; Use xor, but don't show input operands so they aren't live before
19787 ;; this insn.
19788 (define_insn "sse_clrv2df"
19789   [(set (match_operand:V2DF 0 "register_operand" "=x")
19790         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19791   "TARGET_SSE2"
19792   "xorpd\t{%0, %0|%0, %0}"
19793   [(set_attr "type" "sselog")
19794    (set_attr "memory" "none")
19795    (set_attr "mode" "V4SF")])
19796
19797 ;; SSE mask-generating compares
19798
19799 (define_insn "maskcmpv4sf3"
19800   [(set (match_operand:V4SI 0 "register_operand" "=x")
19801         (match_operator:V4SI 3 "sse_comparison_operator"
19802                 [(match_operand:V4SF 1 "register_operand" "0")
19803                  (match_operand:V4SF 2 "register_operand" "x")]))]
19804   "TARGET_SSE"
19805   "cmp%D3ps\t{%2, %0|%0, %2}"
19806   [(set_attr "type" "ssecmp")
19807    (set_attr "mode" "V4SF")])
19808
19809 (define_insn "maskncmpv4sf3"
19810   [(set (match_operand:V4SI 0 "register_operand" "=x")
19811         (not:V4SI
19812          (match_operator:V4SI 3 "sse_comparison_operator"
19813                 [(match_operand:V4SF 1 "register_operand" "0")
19814                  (match_operand:V4SF 2 "register_operand" "x")])))]
19815   "TARGET_SSE"
19816 {
19817   if (GET_CODE (operands[3]) == UNORDERED)
19818     return "cmpordps\t{%2, %0|%0, %2}";
19819   else
19820     return "cmpn%D3ps\t{%2, %0|%0, %2}";
19821 }
19822   [(set_attr "type" "ssecmp")
19823    (set_attr "mode" "V4SF")])
19824
19825 (define_insn "vmmaskcmpv4sf3"
19826   [(set (match_operand:V4SI 0 "register_operand" "=x")
19827         (vec_merge:V4SI
19828          (match_operator:V4SI 3 "sse_comparison_operator"
19829                 [(match_operand:V4SF 1 "register_operand" "0")
19830                  (match_operand:V4SF 2 "register_operand" "x")])
19831          (subreg:V4SI (match_dup 1) 0)
19832          (const_int 1)))]
19833   "TARGET_SSE"
19834   "cmp%D3ss\t{%2, %0|%0, %2}"
19835   [(set_attr "type" "ssecmp")
19836    (set_attr "mode" "SF")])
19837
19838 (define_insn "vmmaskncmpv4sf3"
19839   [(set (match_operand:V4SI 0 "register_operand" "=x")
19840         (vec_merge:V4SI
19841          (not:V4SI
19842           (match_operator:V4SI 3 "sse_comparison_operator"
19843                 [(match_operand:V4SF 1 "register_operand" "0")
19844                  (match_operand:V4SF 2 "register_operand" "x")]))
19845          (subreg:V4SI (match_dup 1) 0)
19846          (const_int 1)))]
19847   "TARGET_SSE"
19848 {
19849   if (GET_CODE (operands[3]) == UNORDERED)
19850     return "cmpordss\t{%2, %0|%0, %2}";
19851   else
19852     return "cmpn%D3ss\t{%2, %0|%0, %2}";
19853 }
19854   [(set_attr "type" "ssecmp")
19855    (set_attr "mode" "SF")])
19856
19857 (define_insn "sse_comi"
19858   [(set (reg:CCFP 17)
19859         (compare:CCFP (vec_select:SF
19860                        (match_operand:V4SF 0 "register_operand" "x")
19861                        (parallel [(const_int 0)]))
19862                       (vec_select:SF
19863                        (match_operand:V4SF 1 "register_operand" "x")
19864                        (parallel [(const_int 0)]))))]
19865   "TARGET_SSE"
19866   "comiss\t{%1, %0|%0, %1}"
19867   [(set_attr "type" "ssecomi")
19868    (set_attr "mode" "SF")])
19869
19870 (define_insn "sse_ucomi"
19871   [(set (reg:CCFPU 17)
19872         (compare:CCFPU (vec_select:SF
19873                         (match_operand:V4SF 0 "register_operand" "x")
19874                         (parallel [(const_int 0)]))
19875                        (vec_select:SF
19876                         (match_operand:V4SF 1 "register_operand" "x")
19877                         (parallel [(const_int 0)]))))]
19878   "TARGET_SSE"
19879   "ucomiss\t{%1, %0|%0, %1}"
19880   [(set_attr "type" "ssecomi")
19881    (set_attr "mode" "SF")])
19882
19883
19884 ;; SSE unpack
19885
19886 (define_insn "sse_unpckhps"
19887   [(set (match_operand:V4SF 0 "register_operand" "=x")
19888         (vec_merge:V4SF
19889          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19890                           (parallel [(const_int 2)
19891                                      (const_int 0)
19892                                      (const_int 3)
19893                                      (const_int 1)]))
19894          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19895                           (parallel [(const_int 0)
19896                                      (const_int 2)
19897                                      (const_int 1)
19898                                      (const_int 3)]))
19899          (const_int 5)))]
19900   "TARGET_SSE"
19901   "unpckhps\t{%2, %0|%0, %2}"
19902   [(set_attr "type" "ssecvt")
19903    (set_attr "mode" "V4SF")])
19904
19905 (define_insn "sse_unpcklps"
19906   [(set (match_operand:V4SF 0 "register_operand" "=x")
19907         (vec_merge:V4SF
19908          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19909                           (parallel [(const_int 0)
19910                                      (const_int 2)
19911                                      (const_int 1)
19912                                      (const_int 3)]))
19913          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19914                           (parallel [(const_int 2)
19915                                      (const_int 0)
19916                                      (const_int 3)
19917                                      (const_int 1)]))
19918          (const_int 5)))]
19919   "TARGET_SSE"
19920   "unpcklps\t{%2, %0|%0, %2}"
19921   [(set_attr "type" "ssecvt")
19922    (set_attr "mode" "V4SF")])
19923
19924
19925 ;; SSE min/max
19926
19927 (define_insn "smaxv4sf3"
19928   [(set (match_operand:V4SF 0 "register_operand" "=x")
19929         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19930                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19931   "TARGET_SSE"
19932   "maxps\t{%2, %0|%0, %2}"
19933   [(set_attr "type" "sse")
19934    (set_attr "mode" "V4SF")])
19935
19936 (define_insn "vmsmaxv4sf3"
19937   [(set (match_operand:V4SF 0 "register_operand" "=x")
19938         (vec_merge:V4SF
19939          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19940                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19941          (match_dup 1)
19942          (const_int 1)))]
19943   "TARGET_SSE"
19944   "maxss\t{%2, %0|%0, %2}"
19945   [(set_attr "type" "sse")
19946    (set_attr "mode" "SF")])
19947
19948 (define_insn "sminv4sf3"
19949   [(set (match_operand:V4SF 0 "register_operand" "=x")
19950         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19951                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19952   "TARGET_SSE"
19953   "minps\t{%2, %0|%0, %2}"
19954   [(set_attr "type" "sse")
19955    (set_attr "mode" "V4SF")])
19956
19957 (define_insn "vmsminv4sf3"
19958   [(set (match_operand:V4SF 0 "register_operand" "=x")
19959         (vec_merge:V4SF
19960          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19961                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19962          (match_dup 1)
19963          (const_int 1)))]
19964   "TARGET_SSE"
19965   "minss\t{%2, %0|%0, %2}"
19966   [(set_attr "type" "sse")
19967    (set_attr "mode" "SF")])
19968
19969 ;; SSE <-> integer/MMX conversions
19970
19971 (define_insn "cvtpi2ps"
19972   [(set (match_operand:V4SF 0 "register_operand" "=x")
19973         (vec_merge:V4SF
19974          (match_operand:V4SF 1 "register_operand" "0")
19975          (vec_duplicate:V4SF
19976           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19977          (const_int 12)))]
19978   "TARGET_SSE"
19979   "cvtpi2ps\t{%2, %0|%0, %2}"
19980   [(set_attr "type" "ssecvt")
19981    (set_attr "mode" "V4SF")])
19982
19983 (define_insn "cvtps2pi"
19984   [(set (match_operand:V2SI 0 "register_operand" "=y")
19985         (vec_select:V2SI
19986          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19987          (parallel [(const_int 0) (const_int 1)])))]
19988   "TARGET_SSE"
19989   "cvtps2pi\t{%1, %0|%0, %1}"
19990   [(set_attr "type" "ssecvt")
19991    (set_attr "mode" "V4SF")])
19992
19993 (define_insn "cvttps2pi"
19994   [(set (match_operand:V2SI 0 "register_operand" "=y")
19995         (vec_select:V2SI
19996          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19997                       UNSPEC_FIX)
19998          (parallel [(const_int 0) (const_int 1)])))]
19999   "TARGET_SSE"
20000   "cvttps2pi\t{%1, %0|%0, %1}"
20001   [(set_attr "type" "ssecvt")
20002    (set_attr "mode" "SF")])
20003
20004 (define_insn "cvtsi2ss"
20005   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20006         (vec_merge:V4SF
20007          (match_operand:V4SF 1 "register_operand" "0,0")
20008          (vec_duplicate:V4SF
20009           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20010          (const_int 14)))]
20011   "TARGET_SSE"
20012   "cvtsi2ss\t{%2, %0|%0, %2}"
20013   [(set_attr "type" "sseicvt")
20014    (set_attr "athlon_decode" "vector,double")
20015    (set_attr "mode" "SF")])
20016
20017 (define_insn "cvtsi2ssq"
20018   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20019         (vec_merge:V4SF
20020          (match_operand:V4SF 1 "register_operand" "0,0")
20021          (vec_duplicate:V4SF
20022           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20023          (const_int 14)))]
20024   "TARGET_SSE && TARGET_64BIT"
20025   "cvtsi2ssq\t{%2, %0|%0, %2}"
20026   [(set_attr "type" "sseicvt")
20027    (set_attr "athlon_decode" "vector,double")
20028    (set_attr "mode" "SF")])
20029
20030 (define_insn "cvtss2si"
20031   [(set (match_operand:SI 0 "register_operand" "=r,r")
20032         (vec_select:SI
20033          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20034          (parallel [(const_int 0)])))]
20035   "TARGET_SSE"
20036   "cvtss2si\t{%1, %0|%0, %1}"
20037   [(set_attr "type" "sseicvt")
20038    (set_attr "athlon_decode" "double,vector")
20039    (set_attr "mode" "SI")])
20040
20041 (define_insn "cvtss2siq"
20042   [(set (match_operand:DI 0 "register_operand" "=r,r")
20043         (vec_select:DI
20044          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20045          (parallel [(const_int 0)])))]
20046   "TARGET_SSE"
20047   "cvtss2siq\t{%1, %0|%0, %1}"
20048   [(set_attr "type" "sseicvt")
20049    (set_attr "athlon_decode" "double,vector")
20050    (set_attr "mode" "DI")])
20051
20052 (define_insn "cvttss2si"
20053   [(set (match_operand:SI 0 "register_operand" "=r,r")
20054         (vec_select:SI
20055          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20056                       UNSPEC_FIX)
20057          (parallel [(const_int 0)])))]
20058   "TARGET_SSE"
20059   "cvttss2si\t{%1, %0|%0, %1}"
20060   [(set_attr "type" "sseicvt")
20061    (set_attr "mode" "SF")
20062    (set_attr "athlon_decode" "double,vector")])
20063
20064 (define_insn "cvttss2siq"
20065   [(set (match_operand:DI 0 "register_operand" "=r,r")
20066         (vec_select:DI
20067          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20068                       UNSPEC_FIX)
20069          (parallel [(const_int 0)])))]
20070   "TARGET_SSE && TARGET_64BIT"
20071   "cvttss2siq\t{%1, %0|%0, %1}"
20072   [(set_attr "type" "sseicvt")
20073    (set_attr "mode" "SF")
20074    (set_attr "athlon_decode" "double,vector")])
20075
20076
20077 ;; MMX insns
20078
20079 ;; MMX arithmetic
20080
20081 (define_insn "addv8qi3"
20082   [(set (match_operand:V8QI 0 "register_operand" "=y")
20083         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20084                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20085   "TARGET_MMX"
20086   "paddb\t{%2, %0|%0, %2}"
20087   [(set_attr "type" "mmxadd")
20088    (set_attr "mode" "DI")])
20089
20090 (define_insn "addv4hi3"
20091   [(set (match_operand:V4HI 0 "register_operand" "=y")
20092         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20093                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20094   "TARGET_MMX"
20095   "paddw\t{%2, %0|%0, %2}"
20096   [(set_attr "type" "mmxadd")
20097    (set_attr "mode" "DI")])
20098
20099 (define_insn "addv2si3"
20100   [(set (match_operand:V2SI 0 "register_operand" "=y")
20101         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20102                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20103   "TARGET_MMX"
20104   "paddd\t{%2, %0|%0, %2}"
20105   [(set_attr "type" "mmxadd")
20106    (set_attr "mode" "DI")])
20107
20108 (define_insn "mmx_adddi3"
20109   [(set (match_operand:DI 0 "register_operand" "=y")
20110         (unspec:DI
20111          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20112                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20113          UNSPEC_NOP))]
20114   "TARGET_MMX"
20115   "paddq\t{%2, %0|%0, %2}"
20116   [(set_attr "type" "mmxadd")
20117    (set_attr "mode" "DI")])
20118
20119 (define_insn "ssaddv8qi3"
20120   [(set (match_operand:V8QI 0 "register_operand" "=y")
20121         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20122                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20123   "TARGET_MMX"
20124   "paddsb\t{%2, %0|%0, %2}"
20125   [(set_attr "type" "mmxadd")
20126    (set_attr "mode" "DI")])
20127
20128 (define_insn "ssaddv4hi3"
20129   [(set (match_operand:V4HI 0 "register_operand" "=y")
20130         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20131                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20132   "TARGET_MMX"
20133   "paddsw\t{%2, %0|%0, %2}"
20134   [(set_attr "type" "mmxadd")
20135    (set_attr "mode" "DI")])
20136
20137 (define_insn "usaddv8qi3"
20138   [(set (match_operand:V8QI 0 "register_operand" "=y")
20139         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20140                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20141   "TARGET_MMX"
20142   "paddusb\t{%2, %0|%0, %2}"
20143   [(set_attr "type" "mmxadd")
20144    (set_attr "mode" "DI")])
20145
20146 (define_insn "usaddv4hi3"
20147   [(set (match_operand:V4HI 0 "register_operand" "=y")
20148         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20149                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20150   "TARGET_MMX"
20151   "paddusw\t{%2, %0|%0, %2}"
20152   [(set_attr "type" "mmxadd")
20153    (set_attr "mode" "DI")])
20154
20155 (define_insn "subv8qi3"
20156   [(set (match_operand:V8QI 0 "register_operand" "=y")
20157         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20158                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20159   "TARGET_MMX"
20160   "psubb\t{%2, %0|%0, %2}"
20161   [(set_attr "type" "mmxadd")
20162    (set_attr "mode" "DI")])
20163
20164 (define_insn "subv4hi3"
20165   [(set (match_operand:V4HI 0 "register_operand" "=y")
20166         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20167                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20168   "TARGET_MMX"
20169   "psubw\t{%2, %0|%0, %2}"
20170   [(set_attr "type" "mmxadd")
20171    (set_attr "mode" "DI")])
20172
20173 (define_insn "subv2si3"
20174   [(set (match_operand:V2SI 0 "register_operand" "=y")
20175         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20176                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20177   "TARGET_MMX"
20178   "psubd\t{%2, %0|%0, %2}"
20179   [(set_attr "type" "mmxadd")
20180    (set_attr "mode" "DI")])
20181
20182 (define_insn "mmx_subdi3"
20183   [(set (match_operand:DI 0 "register_operand" "=y")
20184         (unspec:DI
20185          [(minus:DI (match_operand:DI 1 "register_operand" "0")
20186                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20187          UNSPEC_NOP))]
20188   "TARGET_MMX"
20189   "psubq\t{%2, %0|%0, %2}"
20190   [(set_attr "type" "mmxadd")
20191    (set_attr "mode" "DI")])
20192
20193 (define_insn "sssubv8qi3"
20194   [(set (match_operand:V8QI 0 "register_operand" "=y")
20195         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20196                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20197   "TARGET_MMX"
20198   "psubsb\t{%2, %0|%0, %2}"
20199   [(set_attr "type" "mmxadd")
20200    (set_attr "mode" "DI")])
20201
20202 (define_insn "sssubv4hi3"
20203   [(set (match_operand:V4HI 0 "register_operand" "=y")
20204         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20205                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20206   "TARGET_MMX"
20207   "psubsw\t{%2, %0|%0, %2}"
20208   [(set_attr "type" "mmxadd")
20209    (set_attr "mode" "DI")])
20210
20211 (define_insn "ussubv8qi3"
20212   [(set (match_operand:V8QI 0 "register_operand" "=y")
20213         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20214                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20215   "TARGET_MMX"
20216   "psubusb\t{%2, %0|%0, %2}"
20217   [(set_attr "type" "mmxadd")
20218    (set_attr "mode" "DI")])
20219
20220 (define_insn "ussubv4hi3"
20221   [(set (match_operand:V4HI 0 "register_operand" "=y")
20222         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20223                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20224   "TARGET_MMX"
20225   "psubusw\t{%2, %0|%0, %2}"
20226   [(set_attr "type" "mmxadd")
20227    (set_attr "mode" "DI")])
20228
20229 (define_insn "mulv4hi3"
20230   [(set (match_operand:V4HI 0 "register_operand" "=y")
20231         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20232                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20233   "TARGET_MMX"
20234   "pmullw\t{%2, %0|%0, %2}"
20235   [(set_attr "type" "mmxmul")
20236    (set_attr "mode" "DI")])
20237
20238 (define_insn "smulv4hi3_highpart"
20239   [(set (match_operand:V4HI 0 "register_operand" "=y")
20240         (truncate:V4HI
20241          (lshiftrt:V4SI
20242           (mult:V4SI (sign_extend:V4SI
20243                       (match_operand:V4HI 1 "register_operand" "0"))
20244                      (sign_extend:V4SI
20245                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20246           (const_int 16))))]
20247   "TARGET_MMX"
20248   "pmulhw\t{%2, %0|%0, %2}"
20249   [(set_attr "type" "mmxmul")
20250    (set_attr "mode" "DI")])
20251
20252 (define_insn "umulv4hi3_highpart"
20253   [(set (match_operand:V4HI 0 "register_operand" "=y")
20254         (truncate:V4HI
20255          (lshiftrt:V4SI
20256           (mult:V4SI (zero_extend:V4SI
20257                       (match_operand:V4HI 1 "register_operand" "0"))
20258                      (zero_extend:V4SI
20259                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20260           (const_int 16))))]
20261   "TARGET_SSE || TARGET_3DNOW_A"
20262   "pmulhuw\t{%2, %0|%0, %2}"
20263   [(set_attr "type" "mmxmul")
20264    (set_attr "mode" "DI")])
20265
20266 (define_insn "mmx_pmaddwd"
20267   [(set (match_operand:V2SI 0 "register_operand" "=y")
20268         (plus:V2SI
20269          (mult:V2SI
20270           (sign_extend:V2SI
20271            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20272                             (parallel [(const_int 0) (const_int 2)])))
20273           (sign_extend:V2SI
20274            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20275                             (parallel [(const_int 0) (const_int 2)]))))
20276          (mult:V2SI
20277           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20278                                              (parallel [(const_int 1)
20279                                                         (const_int 3)])))
20280           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20281                                              (parallel [(const_int 1)
20282                                                         (const_int 3)]))))))]
20283   "TARGET_MMX"
20284   "pmaddwd\t{%2, %0|%0, %2}"
20285   [(set_attr "type" "mmxmul")
20286    (set_attr "mode" "DI")])
20287
20288
20289 ;; MMX logical operations
20290 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20291 ;; normal code that also wants to use the FPU from getting broken.
20292 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20293 (define_insn "mmx_iordi3"
20294   [(set (match_operand:DI 0 "register_operand" "=y")
20295         (unspec:DI
20296          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20297                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20298          UNSPEC_NOP))]
20299   "TARGET_MMX"
20300   "por\t{%2, %0|%0, %2}"
20301   [(set_attr "type" "mmxadd")
20302    (set_attr "mode" "DI")])
20303
20304 (define_insn "mmx_xordi3"
20305   [(set (match_operand:DI 0 "register_operand" "=y")
20306         (unspec:DI
20307          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20308                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20309          UNSPEC_NOP))]
20310   "TARGET_MMX"
20311   "pxor\t{%2, %0|%0, %2}"
20312   [(set_attr "type" "mmxadd")
20313    (set_attr "mode" "DI")
20314    (set_attr "memory" "none")])
20315
20316 ;; Same as pxor, but don't show input operands so that we don't think
20317 ;; they are live.
20318 (define_insn "mmx_clrdi"
20319   [(set (match_operand:DI 0 "register_operand" "=y")
20320         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20321   "TARGET_MMX"
20322   "pxor\t{%0, %0|%0, %0}"
20323   [(set_attr "type" "mmxadd")
20324    (set_attr "mode" "DI")
20325    (set_attr "memory" "none")])
20326
20327 (define_insn "mmx_anddi3"
20328   [(set (match_operand:DI 0 "register_operand" "=y")
20329         (unspec:DI
20330          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20331                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20332          UNSPEC_NOP))]
20333   "TARGET_MMX"
20334   "pand\t{%2, %0|%0, %2}"
20335   [(set_attr "type" "mmxadd")
20336    (set_attr "mode" "DI")])
20337
20338 (define_insn "mmx_nanddi3"
20339   [(set (match_operand:DI 0 "register_operand" "=y")
20340         (unspec:DI
20341          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20342                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20343          UNSPEC_NOP))]
20344   "TARGET_MMX"
20345   "pandn\t{%2, %0|%0, %2}"
20346   [(set_attr "type" "mmxadd")
20347    (set_attr "mode" "DI")])
20348
20349
20350 ;; MMX unsigned averages/sum of absolute differences
20351
20352 (define_insn "mmx_uavgv8qi3"
20353   [(set (match_operand:V8QI 0 "register_operand" "=y")
20354         (ashiftrt:V8QI
20355          (plus:V8QI (plus:V8QI
20356                      (match_operand:V8QI 1 "register_operand" "0")
20357                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20358                     (const_vector:V8QI [(const_int 1)
20359                                         (const_int 1)
20360                                         (const_int 1)
20361                                         (const_int 1)
20362                                         (const_int 1)
20363                                         (const_int 1)
20364                                         (const_int 1)
20365                                         (const_int 1)]))
20366          (const_int 1)))]
20367   "TARGET_SSE || TARGET_3DNOW_A"
20368   "pavgb\t{%2, %0|%0, %2}"
20369   [(set_attr "type" "mmxshft")
20370    (set_attr "mode" "DI")])
20371
20372 (define_insn "mmx_uavgv4hi3"
20373   [(set (match_operand:V4HI 0 "register_operand" "=y")
20374         (ashiftrt:V4HI
20375          (plus:V4HI (plus:V4HI
20376                      (match_operand:V4HI 1 "register_operand" "0")
20377                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20378                     (const_vector:V4HI [(const_int 1)
20379                                         (const_int 1)
20380                                         (const_int 1)
20381                                         (const_int 1)]))
20382          (const_int 1)))]
20383   "TARGET_SSE || TARGET_3DNOW_A"
20384   "pavgw\t{%2, %0|%0, %2}"
20385   [(set_attr "type" "mmxshft")
20386    (set_attr "mode" "DI")])
20387
20388 (define_insn "mmx_psadbw"
20389   [(set (match_operand:DI 0 "register_operand" "=y")
20390         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20391                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20392                    UNSPEC_PSADBW))]
20393   "TARGET_SSE || TARGET_3DNOW_A"
20394   "psadbw\t{%2, %0|%0, %2}"
20395   [(set_attr "type" "mmxshft")
20396    (set_attr "mode" "DI")])
20397
20398
20399 ;; MMX insert/extract/shuffle
20400
20401 (define_insn "mmx_pinsrw"
20402   [(set (match_operand:V4HI 0 "register_operand" "=y")
20403         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20404                         (vec_duplicate:V4HI
20405                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20406                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20407   "TARGET_SSE || TARGET_3DNOW_A"
20408   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20409   [(set_attr "type" "mmxcvt")
20410    (set_attr "mode" "DI")])
20411
20412 (define_insn "mmx_pextrw"
20413   [(set (match_operand:SI 0 "register_operand" "=r")
20414         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20415                                        (parallel
20416                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20417   "TARGET_SSE || TARGET_3DNOW_A"
20418   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20419   [(set_attr "type" "mmxcvt")
20420    (set_attr "mode" "DI")])
20421
20422 (define_insn "mmx_pshufw"
20423   [(set (match_operand:V4HI 0 "register_operand" "=y")
20424         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20425                       (match_operand:SI 2 "immediate_operand" "i")]
20426                      UNSPEC_SHUFFLE))]
20427   "TARGET_SSE || TARGET_3DNOW_A"
20428   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20429   [(set_attr "type" "mmxcvt")
20430    (set_attr "mode" "DI")])
20431
20432
20433 ;; MMX mask-generating comparisons
20434
20435 (define_insn "eqv8qi3"
20436   [(set (match_operand:V8QI 0 "register_operand" "=y")
20437         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20438                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20439   "TARGET_MMX"
20440   "pcmpeqb\t{%2, %0|%0, %2}"
20441   [(set_attr "type" "mmxcmp")
20442    (set_attr "mode" "DI")])
20443
20444 (define_insn "eqv4hi3"
20445   [(set (match_operand:V4HI 0 "register_operand" "=y")
20446         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20447                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20448   "TARGET_MMX"
20449   "pcmpeqw\t{%2, %0|%0, %2}"
20450   [(set_attr "type" "mmxcmp")
20451    (set_attr "mode" "DI")])
20452
20453 (define_insn "eqv2si3"
20454   [(set (match_operand:V2SI 0 "register_operand" "=y")
20455         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20456                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20457   "TARGET_MMX"
20458   "pcmpeqd\t{%2, %0|%0, %2}"
20459   [(set_attr "type" "mmxcmp")
20460    (set_attr "mode" "DI")])
20461
20462 (define_insn "gtv8qi3"
20463   [(set (match_operand:V8QI 0 "register_operand" "=y")
20464         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20465                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20466   "TARGET_MMX"
20467   "pcmpgtb\t{%2, %0|%0, %2}"
20468   [(set_attr "type" "mmxcmp")
20469    (set_attr "mode" "DI")])
20470
20471 (define_insn "gtv4hi3"
20472   [(set (match_operand:V4HI 0 "register_operand" "=y")
20473         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20474                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20475   "TARGET_MMX"
20476   "pcmpgtw\t{%2, %0|%0, %2}"
20477   [(set_attr "type" "mmxcmp")
20478    (set_attr "mode" "DI")])
20479
20480 (define_insn "gtv2si3"
20481   [(set (match_operand:V2SI 0 "register_operand" "=y")
20482         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20483                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20484   "TARGET_MMX"
20485   "pcmpgtd\t{%2, %0|%0, %2}"
20486   [(set_attr "type" "mmxcmp")
20487    (set_attr "mode" "DI")])
20488
20489
20490 ;; MMX max/min insns
20491
20492 (define_insn "umaxv8qi3"
20493   [(set (match_operand:V8QI 0 "register_operand" "=y")
20494         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20495                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20496   "TARGET_SSE || TARGET_3DNOW_A"
20497   "pmaxub\t{%2, %0|%0, %2}"
20498   [(set_attr "type" "mmxadd")
20499    (set_attr "mode" "DI")])
20500
20501 (define_insn "smaxv4hi3"
20502   [(set (match_operand:V4HI 0 "register_operand" "=y")
20503         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20504                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20505   "TARGET_SSE || TARGET_3DNOW_A"
20506   "pmaxsw\t{%2, %0|%0, %2}"
20507   [(set_attr "type" "mmxadd")
20508    (set_attr "mode" "DI")])
20509
20510 (define_insn "uminv8qi3"
20511   [(set (match_operand:V8QI 0 "register_operand" "=y")
20512         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20513                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20514   "TARGET_SSE || TARGET_3DNOW_A"
20515   "pminub\t{%2, %0|%0, %2}"
20516   [(set_attr "type" "mmxadd")
20517    (set_attr "mode" "DI")])
20518
20519 (define_insn "sminv4hi3"
20520   [(set (match_operand:V4HI 0 "register_operand" "=y")
20521         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20522                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20523   "TARGET_SSE || TARGET_3DNOW_A"
20524   "pminsw\t{%2, %0|%0, %2}"
20525   [(set_attr "type" "mmxadd")
20526    (set_attr "mode" "DI")])
20527
20528
20529 ;; MMX shifts
20530
20531 (define_insn "ashrv4hi3"
20532   [(set (match_operand:V4HI 0 "register_operand" "=y")
20533         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20534                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20535   "TARGET_MMX"
20536   "psraw\t{%2, %0|%0, %2}"
20537   [(set_attr "type" "mmxshft")
20538    (set_attr "mode" "DI")])
20539
20540 (define_insn "ashrv2si3"
20541   [(set (match_operand:V2SI 0 "register_operand" "=y")
20542         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20543                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20544   "TARGET_MMX"
20545   "psrad\t{%2, %0|%0, %2}"
20546   [(set_attr "type" "mmxshft")
20547    (set_attr "mode" "DI")])
20548
20549 (define_insn "lshrv4hi3"
20550   [(set (match_operand:V4HI 0 "register_operand" "=y")
20551         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20552                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20553   "TARGET_MMX"
20554   "psrlw\t{%2, %0|%0, %2}"
20555   [(set_attr "type" "mmxshft")
20556    (set_attr "mode" "DI")])
20557
20558 (define_insn "lshrv2si3"
20559   [(set (match_operand:V2SI 0 "register_operand" "=y")
20560         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20561                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20562   "TARGET_MMX"
20563   "psrld\t{%2, %0|%0, %2}"
20564   [(set_attr "type" "mmxshft")
20565    (set_attr "mode" "DI")])
20566
20567 ;; See logical MMX insns.
20568 (define_insn "mmx_lshrdi3"
20569   [(set (match_operand:DI 0 "register_operand" "=y")
20570         (unspec:DI
20571           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20572                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
20573           UNSPEC_NOP))]
20574   "TARGET_MMX"
20575   "psrlq\t{%2, %0|%0, %2}"
20576   [(set_attr "type" "mmxshft")
20577    (set_attr "mode" "DI")])
20578
20579 (define_insn "ashlv4hi3"
20580   [(set (match_operand:V4HI 0 "register_operand" "=y")
20581         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20582                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20583   "TARGET_MMX"
20584   "psllw\t{%2, %0|%0, %2}"
20585   [(set_attr "type" "mmxshft")
20586    (set_attr "mode" "DI")])
20587
20588 (define_insn "ashlv2si3"
20589   [(set (match_operand:V2SI 0 "register_operand" "=y")
20590         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20591                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20592   "TARGET_MMX"
20593   "pslld\t{%2, %0|%0, %2}"
20594   [(set_attr "type" "mmxshft")
20595    (set_attr "mode" "DI")])
20596
20597 ;; See logical MMX insns.
20598 (define_insn "mmx_ashldi3"
20599   [(set (match_operand:DI 0 "register_operand" "=y")
20600         (unspec:DI
20601          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20602                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
20603          UNSPEC_NOP))]
20604   "TARGET_MMX"
20605   "psllq\t{%2, %0|%0, %2}"
20606   [(set_attr "type" "mmxshft")
20607    (set_attr "mode" "DI")])
20608
20609
20610 ;; MMX pack/unpack insns.
20611
20612 (define_insn "mmx_packsswb"
20613   [(set (match_operand:V8QI 0 "register_operand" "=y")
20614         (vec_concat:V8QI
20615          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20616          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20617   "TARGET_MMX"
20618   "packsswb\t{%2, %0|%0, %2}"
20619   [(set_attr "type" "mmxshft")
20620    (set_attr "mode" "DI")])
20621
20622 (define_insn "mmx_packssdw"
20623   [(set (match_operand:V4HI 0 "register_operand" "=y")
20624         (vec_concat:V4HI
20625          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20626          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20627   "TARGET_MMX"
20628   "packssdw\t{%2, %0|%0, %2}"
20629   [(set_attr "type" "mmxshft")
20630    (set_attr "mode" "DI")])
20631
20632 (define_insn "mmx_packuswb"
20633   [(set (match_operand:V8QI 0 "register_operand" "=y")
20634         (vec_concat:V8QI
20635          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20636          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20637   "TARGET_MMX"
20638   "packuswb\t{%2, %0|%0, %2}"
20639   [(set_attr "type" "mmxshft")
20640    (set_attr "mode" "DI")])
20641
20642 (define_insn "mmx_punpckhbw"
20643   [(set (match_operand:V8QI 0 "register_operand" "=y")
20644         (vec_merge:V8QI
20645          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20646                           (parallel [(const_int 4)
20647                                      (const_int 0)
20648                                      (const_int 5)
20649                                      (const_int 1)
20650                                      (const_int 6)
20651                                      (const_int 2)
20652                                      (const_int 7)
20653                                      (const_int 3)]))
20654          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20655                           (parallel [(const_int 0)
20656                                      (const_int 4)
20657                                      (const_int 1)
20658                                      (const_int 5)
20659                                      (const_int 2)
20660                                      (const_int 6)
20661                                      (const_int 3)
20662                                      (const_int 7)]))
20663          (const_int 85)))]
20664   "TARGET_MMX"
20665   "punpckhbw\t{%2, %0|%0, %2}"
20666   [(set_attr "type" "mmxcvt")
20667    (set_attr "mode" "DI")])
20668
20669 (define_insn "mmx_punpckhwd"
20670   [(set (match_operand:V4HI 0 "register_operand" "=y")
20671         (vec_merge:V4HI
20672          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20673                           (parallel [(const_int 0)
20674                                      (const_int 2)
20675                                      (const_int 1)
20676                                      (const_int 3)]))
20677          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20678                           (parallel [(const_int 2)
20679                                      (const_int 0)
20680                                      (const_int 3)
20681                                      (const_int 1)]))
20682          (const_int 5)))]
20683   "TARGET_MMX"
20684   "punpckhwd\t{%2, %0|%0, %2}"
20685   [(set_attr "type" "mmxcvt")
20686    (set_attr "mode" "DI")])
20687
20688 (define_insn "mmx_punpckhdq"
20689   [(set (match_operand:V2SI 0 "register_operand" "=y")
20690         (vec_merge:V2SI
20691          (match_operand:V2SI 1 "register_operand" "0")
20692          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20693                           (parallel [(const_int 1)
20694                                      (const_int 0)]))
20695          (const_int 1)))]
20696   "TARGET_MMX"
20697   "punpckhdq\t{%2, %0|%0, %2}"
20698   [(set_attr "type" "mmxcvt")
20699    (set_attr "mode" "DI")])
20700
20701 (define_insn "mmx_punpcklbw"
20702   [(set (match_operand:V8QI 0 "register_operand" "=y")
20703         (vec_merge:V8QI
20704          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20705                           (parallel [(const_int 0)
20706                                      (const_int 4)
20707                                      (const_int 1)
20708                                      (const_int 5)
20709                                      (const_int 2)
20710                                      (const_int 6)
20711                                      (const_int 3)
20712                                      (const_int 7)]))
20713          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20714                           (parallel [(const_int 4)
20715                                      (const_int 0)
20716                                      (const_int 5)
20717                                      (const_int 1)
20718                                      (const_int 6)
20719                                      (const_int 2)
20720                                      (const_int 7)
20721                                      (const_int 3)]))
20722          (const_int 85)))]
20723   "TARGET_MMX"
20724   "punpcklbw\t{%2, %0|%0, %2}"
20725   [(set_attr "type" "mmxcvt")
20726    (set_attr "mode" "DI")])
20727
20728 (define_insn "mmx_punpcklwd"
20729   [(set (match_operand:V4HI 0 "register_operand" "=y")
20730         (vec_merge:V4HI
20731          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20732                           (parallel [(const_int 2)
20733                                      (const_int 0)
20734                                      (const_int 3)
20735                                      (const_int 1)]))
20736          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20737                           (parallel [(const_int 0)
20738                                      (const_int 2)
20739                                      (const_int 1)
20740                                      (const_int 3)]))
20741          (const_int 5)))]
20742   "TARGET_MMX"
20743   "punpcklwd\t{%2, %0|%0, %2}"
20744   [(set_attr "type" "mmxcvt")
20745    (set_attr "mode" "DI")])
20746
20747 (define_insn "mmx_punpckldq"
20748   [(set (match_operand:V2SI 0 "register_operand" "=y")
20749         (vec_merge:V2SI
20750          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20751                            (parallel [(const_int 1)
20752                                       (const_int 0)]))
20753          (match_operand:V2SI 2 "register_operand" "y")
20754          (const_int 1)))]
20755   "TARGET_MMX"
20756   "punpckldq\t{%2, %0|%0, %2}"
20757   [(set_attr "type" "mmxcvt")
20758    (set_attr "mode" "DI")])
20759
20760
20761 ;; Miscellaneous stuff
20762
20763 (define_insn "emms"
20764   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20765    (clobber (reg:XF 8))
20766    (clobber (reg:XF 9))
20767    (clobber (reg:XF 10))
20768    (clobber (reg:XF 11))
20769    (clobber (reg:XF 12))
20770    (clobber (reg:XF 13))
20771    (clobber (reg:XF 14))
20772    (clobber (reg:XF 15))
20773    (clobber (reg:DI 29))
20774    (clobber (reg:DI 30))
20775    (clobber (reg:DI 31))
20776    (clobber (reg:DI 32))
20777    (clobber (reg:DI 33))
20778    (clobber (reg:DI 34))
20779    (clobber (reg:DI 35))
20780    (clobber (reg:DI 36))]
20781   "TARGET_MMX"
20782   "emms"
20783   [(set_attr "type" "mmx")
20784    (set_attr "memory" "unknown")])
20785
20786 (define_insn "ldmxcsr"
20787   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20788                     UNSPECV_LDMXCSR)]
20789   "TARGET_SSE"
20790   "ldmxcsr\t%0"
20791   [(set_attr "type" "sse")
20792    (set_attr "memory" "load")])
20793
20794 (define_insn "stmxcsr"
20795   [(set (match_operand:SI 0 "memory_operand" "=m")
20796         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20797   "TARGET_SSE"
20798   "stmxcsr\t%0"
20799   [(set_attr "type" "sse")
20800    (set_attr "memory" "store")])
20801
20802 (define_expand "sfence"
20803   [(set (match_dup 0)
20804         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20805   "TARGET_SSE || TARGET_3DNOW_A"
20806 {
20807   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20808   MEM_VOLATILE_P (operands[0]) = 1;
20809 })
20810
20811 (define_insn "*sfence_insn"
20812   [(set (match_operand:BLK 0 "" "")
20813         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20814   "TARGET_SSE || TARGET_3DNOW_A"
20815   "sfence"
20816   [(set_attr "type" "sse")
20817    (set_attr "memory" "unknown")])
20818
20819 (define_expand "sse_prologue_save"
20820   [(parallel [(set (match_operand:BLK 0 "" "")
20821                    (unspec:BLK [(reg:DI 21)
20822                                 (reg:DI 22)
20823                                 (reg:DI 23)
20824                                 (reg:DI 24)
20825                                 (reg:DI 25)
20826                                 (reg:DI 26)
20827                                 (reg:DI 27)
20828                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20829               (use (match_operand:DI 1 "register_operand" ""))
20830               (use (match_operand:DI 2 "immediate_operand" ""))
20831               (use (label_ref:DI (match_operand 3 "" "")))])]
20832   "TARGET_64BIT"
20833   "")
20834
20835 (define_insn "*sse_prologue_save_insn"
20836   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20837                           (match_operand:DI 4 "const_int_operand" "n")))
20838         (unspec:BLK [(reg:DI 21)
20839                      (reg:DI 22)
20840                      (reg:DI 23)
20841                      (reg:DI 24)
20842                      (reg:DI 25)
20843                      (reg:DI 26)
20844                      (reg:DI 27)
20845                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20846    (use (match_operand:DI 1 "register_operand" "r"))
20847    (use (match_operand:DI 2 "const_int_operand" "i"))
20848    (use (label_ref:DI (match_operand 3 "" "X")))]
20849   "TARGET_64BIT
20850    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20851    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20852   "*
20853 {
20854   int i;
20855   operands[0] = gen_rtx_MEM (Pmode,
20856                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20857   output_asm_insn (\"jmp\\t%A1\", operands);
20858   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20859     {
20860       operands[4] = adjust_address (operands[0], DImode, i*16);
20861       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20862       PUT_MODE (operands[4], TImode);
20863       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20864         output_asm_insn (\"rex\", operands);
20865       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20866     }
20867   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20868                              CODE_LABEL_NUMBER (operands[3]));
20869   RET;
20870 }
20871   "
20872   [(set_attr "type" "other")
20873    (set_attr "length_immediate" "0")
20874    (set_attr "length_address" "0")
20875    (set_attr "length" "135")
20876    (set_attr "memory" "store")
20877    (set_attr "modrm" "0")
20878    (set_attr "mode" "DI")])
20879
20880 ;; 3Dnow! instructions
20881
20882 (define_insn "addv2sf3"
20883   [(set (match_operand:V2SF 0 "register_operand" "=y")
20884         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20885                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20886   "TARGET_3DNOW"
20887   "pfadd\\t{%2, %0|%0, %2}"
20888   [(set_attr "type" "mmxadd")
20889    (set_attr "mode" "V2SF")])
20890
20891 (define_insn "subv2sf3"
20892   [(set (match_operand:V2SF 0 "register_operand" "=y")
20893         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20894                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20895   "TARGET_3DNOW"
20896   "pfsub\\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "mmxadd")
20898    (set_attr "mode" "V2SF")])
20899
20900 (define_insn "subrv2sf3"
20901   [(set (match_operand:V2SF 0 "register_operand" "=y")
20902         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20903                     (match_operand:V2SF 1 "register_operand" "0")))]
20904   "TARGET_3DNOW"
20905   "pfsubr\\t{%2, %0|%0, %2}"
20906   [(set_attr "type" "mmxadd")
20907    (set_attr "mode" "V2SF")])
20908
20909 (define_insn "gtv2sf3"
20910   [(set (match_operand:V2SI 0 "register_operand" "=y")
20911         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20912                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20913  "TARGET_3DNOW"
20914   "pfcmpgt\\t{%2, %0|%0, %2}"
20915   [(set_attr "type" "mmxcmp")
20916    (set_attr "mode" "V2SF")])
20917
20918 (define_insn "gev2sf3"
20919   [(set (match_operand:V2SI 0 "register_operand" "=y")
20920         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20921                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20922   "TARGET_3DNOW"
20923   "pfcmpge\\t{%2, %0|%0, %2}"
20924   [(set_attr "type" "mmxcmp")
20925    (set_attr "mode" "V2SF")])
20926
20927 (define_insn "eqv2sf3"
20928   [(set (match_operand:V2SI 0 "register_operand" "=y")
20929         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20930                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20931   "TARGET_3DNOW"
20932   "pfcmpeq\\t{%2, %0|%0, %2}"
20933   [(set_attr "type" "mmxcmp")
20934    (set_attr "mode" "V2SF")])
20935
20936 (define_insn "pfmaxv2sf3"
20937   [(set (match_operand:V2SF 0 "register_operand" "=y")
20938         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20939                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20940   "TARGET_3DNOW"
20941   "pfmax\\t{%2, %0|%0, %2}"
20942   [(set_attr "type" "mmxadd")
20943    (set_attr "mode" "V2SF")])
20944
20945 (define_insn "pfminv2sf3"
20946   [(set (match_operand:V2SF 0 "register_operand" "=y")
20947         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20948                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20949   "TARGET_3DNOW"
20950   "pfmin\\t{%2, %0|%0, %2}"
20951   [(set_attr "type" "mmxadd")
20952    (set_attr "mode" "V2SF")])
20953
20954 (define_insn "mulv2sf3"
20955   [(set (match_operand:V2SF 0 "register_operand" "=y")
20956         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20957                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20958   "TARGET_3DNOW"
20959   "pfmul\\t{%2, %0|%0, %2}"
20960   [(set_attr "type" "mmxmul")
20961    (set_attr "mode" "V2SF")])
20962
20963 (define_insn "femms"
20964   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20965    (clobber (reg:XF 8))
20966    (clobber (reg:XF 9))
20967    (clobber (reg:XF 10))
20968    (clobber (reg:XF 11))
20969    (clobber (reg:XF 12))
20970    (clobber (reg:XF 13))
20971    (clobber (reg:XF 14))
20972    (clobber (reg:XF 15))
20973    (clobber (reg:DI 29))
20974    (clobber (reg:DI 30))
20975    (clobber (reg:DI 31))
20976    (clobber (reg:DI 32))
20977    (clobber (reg:DI 33))
20978    (clobber (reg:DI 34))
20979    (clobber (reg:DI 35))
20980    (clobber (reg:DI 36))]
20981   "TARGET_3DNOW"
20982   "femms"
20983   [(set_attr "type" "mmx")
20984    (set_attr "memory" "none")]) 
20985
20986 (define_insn "pf2id"
20987   [(set (match_operand:V2SI 0 "register_operand" "=y")
20988         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20989   "TARGET_3DNOW"
20990   "pf2id\\t{%1, %0|%0, %1}"
20991   [(set_attr "type" "mmxcvt")
20992    (set_attr "mode" "V2SF")])
20993
20994 (define_insn "pf2iw"
20995   [(set (match_operand:V2SI 0 "register_operand" "=y")
20996         (sign_extend:V2SI
20997            (ss_truncate:V2HI
20998               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20999   "TARGET_3DNOW_A"
21000   "pf2iw\\t{%1, %0|%0, %1}"
21001   [(set_attr "type" "mmxcvt")
21002    (set_attr "mode" "V2SF")])
21003
21004 (define_insn "pfacc"
21005   [(set (match_operand:V2SF 0 "register_operand" "=y")
21006         (vec_concat:V2SF
21007            (plus:SF
21008               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21009                              (parallel [(const_int  0)]))
21010               (vec_select:SF (match_dup 1)
21011                              (parallel [(const_int 1)])))
21012            (plus:SF
21013               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21014                              (parallel [(const_int  0)]))
21015               (vec_select:SF (match_dup 2)
21016                              (parallel [(const_int 1)])))))]
21017   "TARGET_3DNOW"
21018   "pfacc\\t{%2, %0|%0, %2}"
21019   [(set_attr "type" "mmxadd")
21020    (set_attr "mode" "V2SF")])
21021
21022 (define_insn "pfnacc"
21023   [(set (match_operand:V2SF 0 "register_operand" "=y")
21024         (vec_concat:V2SF
21025            (minus:SF
21026               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21027                              (parallel [(const_int 0)]))
21028               (vec_select:SF (match_dup 1)
21029                              (parallel [(const_int 1)])))
21030            (minus:SF
21031               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21032                              (parallel [(const_int  0)]))
21033               (vec_select:SF (match_dup 2)
21034                              (parallel [(const_int 1)])))))]
21035   "TARGET_3DNOW_A"
21036   "pfnacc\\t{%2, %0|%0, %2}"
21037   [(set_attr "type" "mmxadd")
21038    (set_attr "mode" "V2SF")])
21039
21040 (define_insn "pfpnacc"
21041   [(set (match_operand:V2SF 0 "register_operand" "=y")
21042         (vec_concat:V2SF
21043            (minus:SF
21044               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21045                              (parallel [(const_int 0)]))
21046               (vec_select:SF (match_dup 1)
21047                              (parallel [(const_int 1)])))
21048            (plus:SF
21049               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21050                              (parallel [(const_int 0)]))
21051               (vec_select:SF (match_dup 2)
21052                              (parallel [(const_int 1)])))))]
21053   "TARGET_3DNOW_A"
21054   "pfpnacc\\t{%2, %0|%0, %2}"
21055   [(set_attr "type" "mmxadd")
21056    (set_attr "mode" "V2SF")])
21057
21058 (define_insn "pi2fw"
21059   [(set (match_operand:V2SF 0 "register_operand" "=y")
21060         (float:V2SF
21061            (vec_concat:V2SI
21062               (sign_extend:SI
21063                  (truncate:HI
21064                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21065                                    (parallel [(const_int 0)]))))
21066               (sign_extend:SI
21067                  (truncate:HI
21068                     (vec_select:SI (match_dup 1)
21069                                    (parallel [(const_int  1)])))))))]
21070   "TARGET_3DNOW_A"
21071   "pi2fw\\t{%1, %0|%0, %1}"
21072   [(set_attr "type" "mmxcvt")
21073    (set_attr "mode" "V2SF")])
21074
21075 (define_insn "floatv2si2"
21076   [(set (match_operand:V2SF 0 "register_operand" "=y")
21077         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21078   "TARGET_3DNOW"
21079   "pi2fd\\t{%1, %0|%0, %1}"
21080   [(set_attr "type" "mmxcvt")
21081    (set_attr "mode" "V2SF")])
21082
21083 ;; This insn is identical to pavgb in operation, but the opcode is
21084 ;; different.  To avoid accidentally matching pavgb, use an unspec.
21085
21086 (define_insn "pavgusb"
21087  [(set (match_operand:V8QI 0 "register_operand" "=y")
21088        (unspec:V8QI
21089           [(match_operand:V8QI 1 "register_operand" "0")
21090            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21091           UNSPEC_PAVGUSB))]
21092   "TARGET_3DNOW"
21093   "pavgusb\\t{%2, %0|%0, %2}"
21094   [(set_attr "type" "mmxshft")
21095    (set_attr "mode" "TI")])
21096
21097 ;; 3DNow reciprocal and sqrt
21098  
21099 (define_insn "pfrcpv2sf2"
21100   [(set (match_operand:V2SF 0 "register_operand" "=y")
21101         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21102         UNSPEC_PFRCP))]
21103   "TARGET_3DNOW"
21104   "pfrcp\\t{%1, %0|%0, %1}"
21105   [(set_attr "type" "mmx")
21106    (set_attr "mode" "TI")])
21107
21108 (define_insn "pfrcpit1v2sf3"
21109   [(set (match_operand:V2SF 0 "register_operand" "=y")
21110         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21111                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21112                      UNSPEC_PFRCPIT1))]
21113   "TARGET_3DNOW"
21114   "pfrcpit1\\t{%2, %0|%0, %2}"
21115   [(set_attr "type" "mmx")
21116    (set_attr "mode" "TI")])
21117
21118 (define_insn "pfrcpit2v2sf3"
21119   [(set (match_operand:V2SF 0 "register_operand" "=y")
21120         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21121                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21122                      UNSPEC_PFRCPIT2))]
21123   "TARGET_3DNOW"
21124   "pfrcpit2\\t{%2, %0|%0, %2}"
21125   [(set_attr "type" "mmx")
21126    (set_attr "mode" "TI")])
21127
21128 (define_insn "pfrsqrtv2sf2"
21129   [(set (match_operand:V2SF 0 "register_operand" "=y")
21130         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21131                      UNSPEC_PFRSQRT))]
21132   "TARGET_3DNOW"
21133   "pfrsqrt\\t{%1, %0|%0, %1}"
21134   [(set_attr "type" "mmx")
21135    (set_attr "mode" "TI")])
21136                 
21137 (define_insn "pfrsqit1v2sf3"
21138   [(set (match_operand:V2SF 0 "register_operand" "=y")
21139         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21140                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21141                      UNSPEC_PFRSQIT1))]
21142   "TARGET_3DNOW"
21143   "pfrsqit1\\t{%2, %0|%0, %2}"
21144   [(set_attr "type" "mmx")
21145    (set_attr "mode" "TI")])
21146
21147 (define_insn "pmulhrwv4hi3"
21148   [(set (match_operand:V4HI 0 "register_operand" "=y")
21149         (truncate:V4HI
21150            (lshiftrt:V4SI
21151               (plus:V4SI
21152                  (mult:V4SI
21153                     (sign_extend:V4SI
21154                        (match_operand:V4HI 1 "register_operand" "0"))
21155                     (sign_extend:V4SI
21156                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21157                  (const_vector:V4SI [(const_int 32768)
21158                                      (const_int 32768)
21159                                      (const_int 32768)
21160                                      (const_int 32768)]))
21161               (const_int 16))))]
21162   "TARGET_3DNOW"
21163   "pmulhrw\\t{%2, %0|%0, %2}"
21164   [(set_attr "type" "mmxmul")
21165    (set_attr "mode" "TI")])
21166
21167 (define_insn "pswapdv2si2"
21168   [(set (match_operand:V2SI 0 "register_operand" "=y")
21169         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21170                          (parallel [(const_int 1) (const_int 0)])))]
21171   "TARGET_3DNOW_A"
21172   "pswapd\\t{%1, %0|%0, %1}"
21173   [(set_attr "type" "mmxcvt")
21174    (set_attr "mode" "TI")])
21175
21176 (define_insn "pswapdv2sf2"
21177   [(set (match_operand:V2SF 0 "register_operand" "=y")
21178         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21179                          (parallel [(const_int 1) (const_int 0)])))]
21180   "TARGET_3DNOW_A"
21181   "pswapd\\t{%1, %0|%0, %1}"
21182   [(set_attr "type" "mmxcvt")
21183    (set_attr "mode" "TI")])
21184
21185 (define_expand "prefetch"
21186   [(prefetch (match_operand 0 "address_operand" "")
21187              (match_operand:SI 1 "const_int_operand" "")
21188              (match_operand:SI 2 "const_int_operand" ""))]
21189   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21190 {
21191   int rw = INTVAL (operands[1]);
21192   int locality = INTVAL (operands[2]);
21193
21194   if (rw != 0 && rw != 1)
21195     abort ();
21196   if (locality < 0 || locality > 3)
21197     abort ();
21198   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21199     abort ();
21200
21201   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21202      suported by SSE counterpart or the SSE prefetch is not available
21203      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21204      of locality.  */
21205   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21206     operands[2] = GEN_INT (3);
21207   else
21208     operands[1] = const0_rtx;
21209 })
21210
21211 (define_insn "*prefetch_sse"
21212   [(prefetch (match_operand:SI 0 "address_operand" "p")
21213              (const_int 0)
21214              (match_operand:SI 1 "const_int_operand" ""))]
21215   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21216 {
21217   static const char * const patterns[4] = {
21218    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21219   };
21220
21221   int locality = INTVAL (operands[1]);
21222   if (locality < 0 || locality > 3)
21223     abort ();
21224
21225   return patterns[locality];  
21226 }
21227   [(set_attr "type" "sse")
21228    (set_attr "memory" "none")])
21229
21230 (define_insn "*prefetch_sse_rex"
21231   [(prefetch (match_operand:DI 0 "address_operand" "p")
21232              (const_int 0)
21233              (match_operand:SI 1 "const_int_operand" ""))]
21234   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21235 {
21236   static const char * const patterns[4] = {
21237    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21238   };
21239
21240   int locality = INTVAL (operands[1]);
21241   if (locality < 0 || locality > 3)
21242     abort ();
21243
21244   return patterns[locality];  
21245 }
21246   [(set_attr "type" "sse")
21247    (set_attr "memory" "none")])
21248
21249 (define_insn "*prefetch_3dnow"
21250   [(prefetch (match_operand:SI 0 "address_operand" "p")
21251              (match_operand:SI 1 "const_int_operand" "n")
21252              (const_int 3))]
21253   "TARGET_3DNOW && !TARGET_64BIT"
21254 {
21255   if (INTVAL (operands[1]) == 0)
21256     return "prefetch\t%a0";
21257   else
21258     return "prefetchw\t%a0";
21259 }
21260   [(set_attr "type" "mmx")
21261    (set_attr "memory" "none")])
21262
21263 (define_insn "*prefetch_3dnow_rex"
21264   [(prefetch (match_operand:DI 0 "address_operand" "p")
21265              (match_operand:SI 1 "const_int_operand" "n")
21266              (const_int 3))]
21267   "TARGET_3DNOW && TARGET_64BIT"
21268 {
21269   if (INTVAL (operands[1]) == 0)
21270     return "prefetch\t%a0";
21271   else
21272     return "prefetchw\t%a0";
21273 }
21274   [(set_attr "type" "mmx")
21275    (set_attr "memory" "none")])
21276
21277 ;; SSE2 support
21278
21279 (define_insn "addv2df3"
21280   [(set (match_operand:V2DF 0 "register_operand" "=x")
21281         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21282                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21283   "TARGET_SSE2"
21284   "addpd\t{%2, %0|%0, %2}"
21285   [(set_attr "type" "sseadd")
21286    (set_attr "mode" "V2DF")])
21287
21288 (define_insn "vmaddv2df3"
21289   [(set (match_operand:V2DF 0 "register_operand" "=x")
21290         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21291                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21292                         (match_dup 1)
21293                         (const_int 1)))]
21294   "TARGET_SSE2"
21295   "addsd\t{%2, %0|%0, %2}"
21296   [(set_attr "type" "sseadd")
21297    (set_attr "mode" "DF")])
21298
21299 (define_insn "subv2df3"
21300   [(set (match_operand:V2DF 0 "register_operand" "=x")
21301         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21302                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21303   "TARGET_SSE2"
21304   "subpd\t{%2, %0|%0, %2}"
21305   [(set_attr "type" "sseadd")
21306    (set_attr "mode" "V2DF")])
21307
21308 (define_insn "vmsubv2df3"
21309   [(set (match_operand:V2DF 0 "register_operand" "=x")
21310         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21311                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21312                         (match_dup 1)
21313                         (const_int 1)))]
21314   "TARGET_SSE2"
21315   "subsd\t{%2, %0|%0, %2}"
21316   [(set_attr "type" "sseadd")
21317    (set_attr "mode" "DF")])
21318
21319 (define_insn "mulv2df3"
21320   [(set (match_operand:V2DF 0 "register_operand" "=x")
21321         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21322                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21323   "TARGET_SSE2"
21324   "mulpd\t{%2, %0|%0, %2}"
21325   [(set_attr "type" "ssemul")
21326    (set_attr "mode" "V2DF")])
21327
21328 (define_insn "vmmulv2df3"
21329   [(set (match_operand:V2DF 0 "register_operand" "=x")
21330         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21331                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21332                         (match_dup 1)
21333                         (const_int 1)))]
21334   "TARGET_SSE2"
21335   "mulsd\t{%2, %0|%0, %2}"
21336   [(set_attr "type" "ssemul")
21337    (set_attr "mode" "DF")])
21338
21339 (define_insn "divv2df3"
21340   [(set (match_operand:V2DF 0 "register_operand" "=x")
21341         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21342                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21343   "TARGET_SSE2"
21344   "divpd\t{%2, %0|%0, %2}"
21345   [(set_attr "type" "ssediv")
21346    (set_attr "mode" "V2DF")])
21347
21348 (define_insn "vmdivv2df3"
21349   [(set (match_operand:V2DF 0 "register_operand" "=x")
21350         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21351                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21352                         (match_dup 1)
21353                         (const_int 1)))]
21354   "TARGET_SSE2"
21355   "divsd\t{%2, %0|%0, %2}"
21356   [(set_attr "type" "ssediv")
21357    (set_attr "mode" "DF")])
21358
21359 ;; SSE min/max
21360
21361 (define_insn "smaxv2df3"
21362   [(set (match_operand:V2DF 0 "register_operand" "=x")
21363         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21364                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21365   "TARGET_SSE2"
21366   "maxpd\t{%2, %0|%0, %2}"
21367   [(set_attr "type" "sseadd")
21368    (set_attr "mode" "V2DF")])
21369
21370 (define_insn "vmsmaxv2df3"
21371   [(set (match_operand:V2DF 0 "register_operand" "=x")
21372         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21373                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21374                         (match_dup 1)
21375                         (const_int 1)))]
21376   "TARGET_SSE2"
21377   "maxsd\t{%2, %0|%0, %2}"
21378   [(set_attr "type" "sseadd")
21379    (set_attr "mode" "DF")])
21380
21381 (define_insn "sminv2df3"
21382   [(set (match_operand:V2DF 0 "register_operand" "=x")
21383         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21384                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21385   "TARGET_SSE2"
21386   "minpd\t{%2, %0|%0, %2}"
21387   [(set_attr "type" "sseadd")
21388    (set_attr "mode" "V2DF")])
21389
21390 (define_insn "vmsminv2df3"
21391   [(set (match_operand:V2DF 0 "register_operand" "=x")
21392         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21393                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21394                         (match_dup 1)
21395                         (const_int 1)))]
21396   "TARGET_SSE2"
21397   "minsd\t{%2, %0|%0, %2}"
21398   [(set_attr "type" "sseadd")
21399    (set_attr "mode" "DF")])
21400 ;; SSE2 square root.  There doesn't appear to be an extension for the
21401 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21402
21403 (define_insn "sqrtv2df2"
21404   [(set (match_operand:V2DF 0 "register_operand" "=x")
21405         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21406   "TARGET_SSE2"
21407   "sqrtpd\t{%1, %0|%0, %1}"
21408   [(set_attr "type" "sse")
21409    (set_attr "mode" "V2DF")])
21410
21411 (define_insn "vmsqrtv2df2"
21412   [(set (match_operand:V2DF 0 "register_operand" "=x")
21413         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21414                         (match_operand:V2DF 2 "register_operand" "0")
21415                         (const_int 1)))]
21416   "TARGET_SSE2"
21417   "sqrtsd\t{%1, %0|%0, %1}"
21418   [(set_attr "type" "sse")
21419    (set_attr "mode" "SF")])
21420
21421 ;; SSE mask-generating compares
21422
21423 (define_insn "maskcmpv2df3"
21424   [(set (match_operand:V2DI 0 "register_operand" "=x")
21425         (match_operator:V2DI 3 "sse_comparison_operator"
21426                              [(match_operand:V2DF 1 "register_operand" "0")
21427                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21428   "TARGET_SSE2"
21429   "cmp%D3pd\t{%2, %0|%0, %2}"
21430   [(set_attr "type" "ssecmp")
21431    (set_attr "mode" "V2DF")])
21432
21433 (define_insn "maskncmpv2df3"
21434   [(set (match_operand:V2DI 0 "register_operand" "=x")
21435         (not:V2DI
21436          (match_operator:V2DI 3 "sse_comparison_operator"
21437                               [(match_operand:V2DF 1 "register_operand" "0")
21438                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21439   "TARGET_SSE2"
21440 {
21441   if (GET_CODE (operands[3]) == UNORDERED)
21442     return "cmpordps\t{%2, %0|%0, %2}";
21443   else
21444     return "cmpn%D3pd\t{%2, %0|%0, %2}";
21445 }
21446   [(set_attr "type" "ssecmp")
21447    (set_attr "mode" "V2DF")])
21448
21449 (define_insn "vmmaskcmpv2df3"
21450   [(set (match_operand:V2DI 0 "register_operand" "=x")
21451         (vec_merge:V2DI
21452          (match_operator:V2DI 3 "sse_comparison_operator"
21453                               [(match_operand:V2DF 1 "register_operand" "0")
21454                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21455          (subreg:V2DI (match_dup 1) 0)
21456          (const_int 1)))]
21457   "TARGET_SSE2"
21458   "cmp%D3sd\t{%2, %0|%0, %2}"
21459   [(set_attr "type" "ssecmp")
21460    (set_attr "mode" "DF")])
21461
21462 (define_insn "vmmaskncmpv2df3"
21463   [(set (match_operand:V2DI 0 "register_operand" "=x")
21464         (vec_merge:V2DI
21465          (not:V2DI
21466           (match_operator:V2DI 3 "sse_comparison_operator"
21467                                [(match_operand:V2DF 1 "register_operand" "0")
21468                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21469          (subreg:V2DI (match_dup 1) 0)
21470          (const_int 1)))]
21471   "TARGET_SSE2"
21472 {
21473   if (GET_CODE (operands[3]) == UNORDERED)
21474     return "cmpordsd\t{%2, %0|%0, %2}";
21475   else
21476     return "cmpn%D3sd\t{%2, %0|%0, %2}";
21477 }
21478   [(set_attr "type" "ssecmp")
21479    (set_attr "mode" "DF")])
21480
21481 (define_insn "sse2_comi"
21482   [(set (reg:CCFP 17)
21483         (compare:CCFP (vec_select:DF
21484                        (match_operand:V2DF 0 "register_operand" "x")
21485                        (parallel [(const_int 0)]))
21486                       (vec_select:DF
21487                        (match_operand:V2DF 1 "register_operand" "x")
21488                        (parallel [(const_int 0)]))))]
21489   "TARGET_SSE2"
21490   "comisd\t{%1, %0|%0, %1}"
21491   [(set_attr "type" "ssecomi")
21492    (set_attr "mode" "DF")])
21493
21494 (define_insn "sse2_ucomi"
21495   [(set (reg:CCFPU 17)
21496         (compare:CCFPU (vec_select:DF
21497                          (match_operand:V2DF 0 "register_operand" "x")
21498                          (parallel [(const_int 0)]))
21499                         (vec_select:DF
21500                          (match_operand:V2DF 1 "register_operand" "x")
21501                          (parallel [(const_int 0)]))))]
21502   "TARGET_SSE2"
21503   "ucomisd\t{%1, %0|%0, %1}"
21504   [(set_attr "type" "ssecomi")
21505    (set_attr "mode" "DF")])
21506
21507 ;; SSE Strange Moves.
21508
21509 (define_insn "sse2_movmskpd"
21510   [(set (match_operand:SI 0 "register_operand" "=r")
21511         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21512                    UNSPEC_MOVMSK))]
21513   "TARGET_SSE2"
21514   "movmskpd\t{%1, %0|%0, %1}"
21515   [(set_attr "type" "ssecvt")
21516    (set_attr "mode" "V2DF")])
21517
21518 (define_insn "sse2_pmovmskb"
21519   [(set (match_operand:SI 0 "register_operand" "=r")
21520         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21521                    UNSPEC_MOVMSK))]
21522   "TARGET_SSE2"
21523   "pmovmskb\t{%1, %0|%0, %1}"
21524   [(set_attr "type" "ssecvt")
21525    (set_attr "mode" "V2DF")])
21526
21527 (define_insn "sse2_maskmovdqu"
21528   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21529         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21530                        (match_operand:V16QI 2 "register_operand" "x")]
21531                       UNSPEC_MASKMOV))]
21532   "TARGET_SSE2"
21533   ;; @@@ check ordering of operands in intel/nonintel syntax
21534   "maskmovdqu\t{%2, %1|%1, %2}"
21535   [(set_attr "type" "ssecvt")
21536    (set_attr "mode" "TI")])
21537
21538 (define_insn "sse2_maskmovdqu_rex64"
21539   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21540         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21541                        (match_operand:V16QI 2 "register_operand" "x")]
21542                       UNSPEC_MASKMOV))]
21543   "TARGET_SSE2"
21544   ;; @@@ check ordering of operands in intel/nonintel syntax
21545   "maskmovdqu\t{%2, %1|%1, %2}"
21546   [(set_attr "type" "ssecvt")
21547    (set_attr "mode" "TI")])
21548
21549 (define_insn "sse2_movntv2df"
21550   [(set (match_operand:V2DF 0 "memory_operand" "=m")
21551         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21552                      UNSPEC_MOVNT))]
21553   "TARGET_SSE2"
21554   "movntpd\t{%1, %0|%0, %1}"
21555   [(set_attr "type" "ssecvt")
21556    (set_attr "mode" "V2DF")])
21557
21558 (define_insn "sse2_movntv2di"
21559   [(set (match_operand:V2DI 0 "memory_operand" "=m")
21560         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21561                      UNSPEC_MOVNT))]
21562   "TARGET_SSE2"
21563   "movntdq\t{%1, %0|%0, %1}"
21564   [(set_attr "type" "ssecvt")
21565    (set_attr "mode" "TI")])
21566
21567 (define_insn "sse2_movntsi"
21568   [(set (match_operand:SI 0 "memory_operand" "=m")
21569         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21570                    UNSPEC_MOVNT))]
21571   "TARGET_SSE2"
21572   "movnti\t{%1, %0|%0, %1}"
21573   [(set_attr "type" "ssecvt")
21574    (set_attr "mode" "V2DF")])
21575
21576 ;; SSE <-> integer/MMX conversions
21577
21578 ;; Conversions between SI and SF
21579
21580 (define_insn "cvtdq2ps"
21581   [(set (match_operand:V4SF 0 "register_operand" "=x")
21582         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21583   "TARGET_SSE2"
21584   "cvtdq2ps\t{%1, %0|%0, %1}"
21585   [(set_attr "type" "ssecvt")
21586    (set_attr "mode" "V2DF")])
21587
21588 (define_insn "cvtps2dq"
21589   [(set (match_operand:V4SI 0 "register_operand" "=x")
21590         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21591   "TARGET_SSE2"
21592   "cvtps2dq\t{%1, %0|%0, %1}"
21593   [(set_attr "type" "ssecvt")
21594    (set_attr "mode" "TI")])
21595
21596 (define_insn "cvttps2dq"
21597   [(set (match_operand:V4SI 0 "register_operand" "=x")
21598         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21599                      UNSPEC_FIX))]
21600   "TARGET_SSE2"
21601   "cvttps2dq\t{%1, %0|%0, %1}"
21602   [(set_attr "type" "ssecvt")
21603    (set_attr "mode" "TI")])
21604
21605 ;; Conversions between SI and DF
21606
21607 (define_insn "cvtdq2pd"
21608   [(set (match_operand:V2DF 0 "register_operand" "=x")
21609         (float:V2DF (vec_select:V2SI
21610                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21611                      (parallel
21612                       [(const_int 0)
21613                        (const_int 1)]))))]
21614   "TARGET_SSE2"
21615   "cvtdq2pd\t{%1, %0|%0, %1}"
21616   [(set_attr "type" "ssecvt")
21617    (set_attr "mode" "V2DF")])
21618
21619 (define_insn "cvtpd2dq"
21620   [(set (match_operand:V4SI 0 "register_operand" "=x")
21621         (vec_concat:V4SI
21622          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21623          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21624   "TARGET_SSE2"
21625   "cvtpd2dq\t{%1, %0|%0, %1}"
21626   [(set_attr "type" "ssecvt")
21627    (set_attr "mode" "TI")])
21628
21629 (define_insn "cvttpd2dq"
21630   [(set (match_operand:V4SI 0 "register_operand" "=x")
21631         (vec_concat:V4SI
21632          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21633                       UNSPEC_FIX)
21634          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21635   "TARGET_SSE2"
21636   "cvttpd2dq\t{%1, %0|%0, %1}"
21637   [(set_attr "type" "ssecvt")
21638    (set_attr "mode" "TI")])
21639
21640 (define_insn "cvtpd2pi"
21641   [(set (match_operand:V2SI 0 "register_operand" "=y")
21642         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21643   "TARGET_SSE2"
21644   "cvtpd2pi\t{%1, %0|%0, %1}"
21645   [(set_attr "type" "ssecvt")
21646    (set_attr "mode" "TI")])
21647
21648 (define_insn "cvttpd2pi"
21649   [(set (match_operand:V2SI 0 "register_operand" "=y")
21650         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21651                      UNSPEC_FIX))]
21652   "TARGET_SSE2"
21653   "cvttpd2pi\t{%1, %0|%0, %1}"
21654   [(set_attr "type" "ssecvt")
21655    (set_attr "mode" "TI")])
21656
21657 (define_insn "cvtpi2pd"
21658   [(set (match_operand:V2DF 0 "register_operand" "=x")
21659         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21660   "TARGET_SSE2"
21661   "cvtpi2pd\t{%1, %0|%0, %1}"
21662   [(set_attr "type" "ssecvt")
21663    (set_attr "mode" "TI")])
21664
21665 ;; Conversions between SI and DF
21666
21667 (define_insn "cvtsd2si"
21668   [(set (match_operand:SI 0 "register_operand" "=r,r")
21669         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21670                                (parallel [(const_int 0)]))))]
21671   "TARGET_SSE2"
21672   "cvtsd2si\t{%1, %0|%0, %1}"
21673   [(set_attr "type" "sseicvt")
21674    (set_attr "athlon_decode" "double,vector")
21675    (set_attr "mode" "SI")])
21676
21677 (define_insn "cvtsd2siq"
21678   [(set (match_operand:DI 0 "register_operand" "=r,r")
21679         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21680                                (parallel [(const_int 0)]))))]
21681   "TARGET_SSE2 && TARGET_64BIT"
21682   "cvtsd2siq\t{%1, %0|%0, %1}"
21683   [(set_attr "type" "sseicvt")
21684    (set_attr "athlon_decode" "double,vector")
21685    (set_attr "mode" "DI")])
21686
21687 (define_insn "cvttsd2si"
21688   [(set (match_operand:SI 0 "register_operand" "=r,r")
21689         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21690                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21691   "TARGET_SSE2"
21692   "cvttsd2si\t{%1, %0|%0, %1}"
21693   [(set_attr "type" "sseicvt")
21694    (set_attr "mode" "SI")
21695    (set_attr "athlon_decode" "double,vector")])
21696
21697 (define_insn "cvttsd2siq"
21698   [(set (match_operand:DI 0 "register_operand" "=r,r")
21699         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21700                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21701   "TARGET_SSE2 && TARGET_64BIT"
21702   "cvttsd2siq\t{%1, %0|%0, %1}"
21703   [(set_attr "type" "sseicvt")
21704    (set_attr "mode" "DI")
21705    (set_attr "athlon_decode" "double,vector")])
21706
21707 (define_insn "cvtsi2sd"
21708   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21709         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21710                         (vec_duplicate:V2DF
21711                           (float:DF
21712                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21713                         (const_int 2)))]
21714   "TARGET_SSE2"
21715   "cvtsi2sd\t{%2, %0|%0, %2}"
21716   [(set_attr "type" "sseicvt")
21717    (set_attr "mode" "DF")
21718    (set_attr "athlon_decode" "double,direct")])
21719
21720 (define_insn "cvtsi2sdq"
21721   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21722         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21723                         (vec_duplicate:V2DF
21724                           (float:DF
21725                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21726                         (const_int 2)))]
21727   "TARGET_SSE2 && TARGET_64BIT"
21728   "cvtsi2sdq\t{%2, %0|%0, %2}"
21729   [(set_attr "type" "sseicvt")
21730    (set_attr "mode" "DF")
21731    (set_attr "athlon_decode" "double,direct")])
21732
21733 ;; Conversions between SF and DF
21734
21735 (define_insn "cvtsd2ss"
21736   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21737         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21738                         (vec_duplicate:V4SF
21739                           (float_truncate:V2SF
21740                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21741                         (const_int 14)))]
21742   "TARGET_SSE2"
21743   "cvtsd2ss\t{%2, %0|%0, %2}"
21744   [(set_attr "type" "ssecvt")
21745    (set_attr "athlon_decode" "vector,double")
21746    (set_attr "mode" "SF")])
21747
21748 (define_insn "cvtss2sd"
21749   [(set (match_operand:V2DF 0 "register_operand" "=x")
21750         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21751                         (float_extend:V2DF
21752                           (vec_select:V2SF
21753                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21754                             (parallel [(const_int 0)
21755                                        (const_int 1)])))
21756                         (const_int 2)))]
21757   "TARGET_SSE2"
21758   "cvtss2sd\t{%2, %0|%0, %2}"
21759   [(set_attr "type" "ssecvt")
21760    (set_attr "mode" "DF")])
21761
21762 (define_insn "cvtpd2ps"
21763   [(set (match_operand:V4SF 0 "register_operand" "=x")
21764         (subreg:V4SF
21765           (vec_concat:V4SI
21766             (subreg:V2SI (float_truncate:V2SF
21767                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21768             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21769   "TARGET_SSE2"
21770   "cvtpd2ps\t{%1, %0|%0, %1}"
21771   [(set_attr "type" "ssecvt")
21772    (set_attr "mode" "V4SF")])
21773
21774 (define_insn "cvtps2pd"
21775   [(set (match_operand:V2DF 0 "register_operand" "=x")
21776         (float_extend:V2DF
21777           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21778                            (parallel [(const_int 0)
21779                                       (const_int 1)]))))]
21780   "TARGET_SSE2"
21781   "cvtps2pd\t{%1, %0|%0, %1}"
21782   [(set_attr "type" "ssecvt")
21783    (set_attr "mode" "V2DF")])
21784
21785 ;; SSE2 variants of MMX insns
21786
21787 ;; MMX arithmetic
21788
21789 (define_insn "addv16qi3"
21790   [(set (match_operand:V16QI 0 "register_operand" "=x")
21791         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21792                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21793   "TARGET_SSE2"
21794   "paddb\t{%2, %0|%0, %2}"
21795   [(set_attr "type" "sseiadd")
21796    (set_attr "mode" "TI")])
21797
21798 (define_insn "addv8hi3"
21799   [(set (match_operand:V8HI 0 "register_operand" "=x")
21800         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21801                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21802   "TARGET_SSE2"
21803   "paddw\t{%2, %0|%0, %2}"
21804   [(set_attr "type" "sseiadd")
21805    (set_attr "mode" "TI")])
21806
21807 (define_insn "addv4si3"
21808   [(set (match_operand:V4SI 0 "register_operand" "=x")
21809         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21810                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21811   "TARGET_SSE2"
21812   "paddd\t{%2, %0|%0, %2}"
21813   [(set_attr "type" "sseiadd")
21814    (set_attr "mode" "TI")])
21815
21816 (define_insn "addv2di3"
21817   [(set (match_operand:V2DI 0 "register_operand" "=x")
21818         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21819                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21820   "TARGET_SSE2"
21821   "paddq\t{%2, %0|%0, %2}"
21822   [(set_attr "type" "sseiadd")
21823    (set_attr "mode" "TI")])
21824
21825 (define_insn "ssaddv16qi3"
21826   [(set (match_operand:V16QI 0 "register_operand" "=x")
21827         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21828                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21829   "TARGET_SSE2"
21830   "paddsb\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "sseiadd")
21832    (set_attr "mode" "TI")])
21833
21834 (define_insn "ssaddv8hi3"
21835   [(set (match_operand:V8HI 0 "register_operand" "=x")
21836         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21837                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21838   "TARGET_SSE2"
21839   "paddsw\t{%2, %0|%0, %2}"
21840   [(set_attr "type" "sseiadd")
21841    (set_attr "mode" "TI")])
21842
21843 (define_insn "usaddv16qi3"
21844   [(set (match_operand:V16QI 0 "register_operand" "=x")
21845         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21846                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21847   "TARGET_SSE2"
21848   "paddusb\t{%2, %0|%0, %2}"
21849   [(set_attr "type" "sseiadd")
21850    (set_attr "mode" "TI")])
21851
21852 (define_insn "usaddv8hi3"
21853   [(set (match_operand:V8HI 0 "register_operand" "=x")
21854         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21855                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21856   "TARGET_SSE2"
21857   "paddusw\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "sseiadd")
21859    (set_attr "mode" "TI")])
21860
21861 (define_insn "subv16qi3"
21862   [(set (match_operand:V16QI 0 "register_operand" "=x")
21863         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21864                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21865   "TARGET_SSE2"
21866   "psubb\t{%2, %0|%0, %2}"
21867   [(set_attr "type" "sseiadd")
21868    (set_attr "mode" "TI")])
21869
21870 (define_insn "subv8hi3"
21871   [(set (match_operand:V8HI 0 "register_operand" "=x")
21872         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21873                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21874   "TARGET_SSE2"
21875   "psubw\t{%2, %0|%0, %2}"
21876   [(set_attr "type" "sseiadd")
21877    (set_attr "mode" "TI")])
21878
21879 (define_insn "subv4si3"
21880   [(set (match_operand:V4SI 0 "register_operand" "=x")
21881         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21882                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21883   "TARGET_SSE2"
21884   "psubd\t{%2, %0|%0, %2}"
21885   [(set_attr "type" "sseiadd")
21886    (set_attr "mode" "TI")])
21887
21888 (define_insn "subv2di3"
21889   [(set (match_operand:V2DI 0 "register_operand" "=x")
21890         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21891                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21892   "TARGET_SSE2"
21893   "psubq\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "sseiadd")
21895    (set_attr "mode" "TI")])
21896
21897 (define_insn "sssubv16qi3"
21898   [(set (match_operand:V16QI 0 "register_operand" "=x")
21899         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21900                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21901   "TARGET_SSE2"
21902   "psubsb\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "sseiadd")
21904    (set_attr "mode" "TI")])
21905
21906 (define_insn "sssubv8hi3"
21907   [(set (match_operand:V8HI 0 "register_operand" "=x")
21908         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21909                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21910   "TARGET_SSE2"
21911   "psubsw\t{%2, %0|%0, %2}"
21912   [(set_attr "type" "sseiadd")
21913    (set_attr "mode" "TI")])
21914
21915 (define_insn "ussubv16qi3"
21916   [(set (match_operand:V16QI 0 "register_operand" "=x")
21917         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21918                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21919   "TARGET_SSE2"
21920   "psubusb\t{%2, %0|%0, %2}"
21921   [(set_attr "type" "sseiadd")
21922    (set_attr "mode" "TI")])
21923
21924 (define_insn "ussubv8hi3"
21925   [(set (match_operand:V8HI 0 "register_operand" "=x")
21926         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21927                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21928   "TARGET_SSE2"
21929   "psubusw\t{%2, %0|%0, %2}"
21930   [(set_attr "type" "sseiadd")
21931    (set_attr "mode" "TI")])
21932
21933 (define_insn "mulv8hi3"
21934   [(set (match_operand:V8HI 0 "register_operand" "=x")
21935         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21936                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21937   "TARGET_SSE2"
21938   "pmullw\t{%2, %0|%0, %2}"
21939   [(set_attr "type" "sseimul")
21940    (set_attr "mode" "TI")])
21941
21942 (define_insn "smulv8hi3_highpart"
21943   [(set (match_operand:V8HI 0 "register_operand" "=x")
21944         (truncate:V8HI
21945          (lshiftrt:V8SI
21946           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21947                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21948           (const_int 16))))]
21949   "TARGET_SSE2"
21950   "pmulhw\t{%2, %0|%0, %2}"
21951   [(set_attr "type" "sseimul")
21952    (set_attr "mode" "TI")])
21953
21954 (define_insn "umulv8hi3_highpart"
21955   [(set (match_operand:V8HI 0 "register_operand" "=x")
21956         (truncate:V8HI
21957          (lshiftrt:V8SI
21958           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21959                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21960           (const_int 16))))]
21961   "TARGET_SSE2"
21962   "pmulhuw\t{%2, %0|%0, %2}"
21963   [(set_attr "type" "sseimul")
21964    (set_attr "mode" "TI")])
21965
21966 (define_insn "sse2_umulsidi3"
21967   [(set (match_operand:DI 0 "register_operand" "=y")
21968         (mult:DI (zero_extend:DI (vec_select:SI
21969                                   (match_operand:V2SI 1 "register_operand" "0")
21970                                   (parallel [(const_int 0)])))
21971                  (zero_extend:DI (vec_select:SI
21972                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21973                                   (parallel [(const_int 0)])))))]
21974   "TARGET_SSE2"
21975   "pmuludq\t{%2, %0|%0, %2}"
21976   [(set_attr "type" "sseimul")
21977    (set_attr "mode" "TI")])
21978
21979 (define_insn "sse2_umulv2siv2di3"
21980   [(set (match_operand:V2DI 0 "register_operand" "=x")
21981         (mult:V2DI (zero_extend:V2DI
21982                      (vec_select:V2SI
21983                        (match_operand:V4SI 1 "register_operand" "0")
21984                        (parallel [(const_int 0) (const_int 2)])))
21985                    (zero_extend:V2DI
21986                      (vec_select:V2SI
21987                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21988                        (parallel [(const_int 0) (const_int 2)])))))]
21989   "TARGET_SSE2"
21990   "pmuludq\t{%2, %0|%0, %2}"
21991   [(set_attr "type" "sseimul")
21992    (set_attr "mode" "TI")])
21993
21994 (define_insn "sse2_pmaddwd"
21995   [(set (match_operand:V4SI 0 "register_operand" "=x")
21996         (plus:V4SI
21997          (mult:V4SI
21998           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21999                                              (parallel [(const_int 0)
22000                                                         (const_int 2)
22001                                                         (const_int 4)
22002                                                         (const_int 6)])))
22003           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22004                                              (parallel [(const_int 0)
22005                                                         (const_int 2)
22006                                                         (const_int 4)
22007                                                         (const_int 6)]))))
22008          (mult:V4SI
22009           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22010                                              (parallel [(const_int 1)
22011                                                         (const_int 3)
22012                                                         (const_int 5)
22013                                                         (const_int 7)])))
22014           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22015                                              (parallel [(const_int 1)
22016                                                         (const_int 3)
22017                                                         (const_int 5)
22018                                                         (const_int 7)]))))))]
22019   "TARGET_SSE2"
22020   "pmaddwd\t{%2, %0|%0, %2}"
22021   [(set_attr "type" "sseiadd")
22022    (set_attr "mode" "TI")])
22023
22024 ;; Same as pxor, but don't show input operands so that we don't think
22025 ;; they are live.
22026 (define_insn "sse2_clrti"
22027   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22028   "TARGET_SSE2"
22029 {
22030   if (get_attr_mode (insn) == MODE_TI)
22031     return "pxor\t%0, %0";
22032   else
22033     return "xorps\t%0, %0";
22034 }
22035   [(set_attr "type" "ssemov")
22036    (set_attr "memory" "none")
22037    (set (attr "mode")
22038               (if_then_else
22039                 (ne (symbol_ref "optimize_size")
22040                     (const_int 0))
22041                 (const_string "V4SF")
22042                 (const_string "TI")))])
22043
22044 ;; MMX unsigned averages/sum of absolute differences
22045
22046 (define_insn "sse2_uavgv16qi3"
22047   [(set (match_operand:V16QI 0 "register_operand" "=x")
22048         (ashiftrt:V16QI
22049          (plus:V16QI (plus:V16QI
22050                      (match_operand:V16QI 1 "register_operand" "0")
22051                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22052                      (const_vector:V16QI [(const_int 1) (const_int 1)
22053                                           (const_int 1) (const_int 1)
22054                                           (const_int 1) (const_int 1)
22055                                           (const_int 1) (const_int 1)
22056                                           (const_int 1) (const_int 1)
22057                                           (const_int 1) (const_int 1)
22058                                           (const_int 1) (const_int 1)
22059                                           (const_int 1) (const_int 1)]))
22060          (const_int 1)))]
22061   "TARGET_SSE2"
22062   "pavgb\t{%2, %0|%0, %2}"
22063   [(set_attr "type" "sseiadd")
22064    (set_attr "mode" "TI")])
22065
22066 (define_insn "sse2_uavgv8hi3"
22067   [(set (match_operand:V8HI 0 "register_operand" "=x")
22068         (ashiftrt:V8HI
22069          (plus:V8HI (plus:V8HI
22070                      (match_operand:V8HI 1 "register_operand" "0")
22071                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22072                     (const_vector:V8HI [(const_int 1) (const_int 1)
22073                                         (const_int 1) (const_int 1)
22074                                         (const_int 1) (const_int 1)
22075                                         (const_int 1) (const_int 1)]))
22076          (const_int 1)))]
22077   "TARGET_SSE2"
22078   "pavgw\t{%2, %0|%0, %2}"
22079   [(set_attr "type" "sseiadd")
22080    (set_attr "mode" "TI")])
22081
22082 ;; @@@ this isn't the right representation.
22083 (define_insn "sse2_psadbw"
22084   [(set (match_operand:V2DI 0 "register_operand" "=x")
22085         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22086                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22087                      UNSPEC_PSADBW))]
22088   "TARGET_SSE2"
22089   "psadbw\t{%2, %0|%0, %2}"
22090   [(set_attr "type" "sseiadd")
22091    (set_attr "mode" "TI")])
22092
22093
22094 ;; MMX insert/extract/shuffle
22095
22096 (define_insn "sse2_pinsrw"
22097   [(set (match_operand:V8HI 0 "register_operand" "=x")
22098         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22099                         (vec_duplicate:V8HI
22100                          (truncate:HI
22101                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
22102                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22103   "TARGET_SSE2"
22104   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22105   [(set_attr "type" "ssecvt")
22106    (set_attr "mode" "TI")])
22107
22108 (define_insn "sse2_pextrw"
22109   [(set (match_operand:SI 0 "register_operand" "=r")
22110         (zero_extend:SI
22111           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22112                          (parallel
22113                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22114   "TARGET_SSE2"
22115   "pextrw\t{%2, %1, %0|%0, %1, %2}"
22116   [(set_attr "type" "ssecvt")
22117    (set_attr "mode" "TI")])
22118
22119 (define_insn "sse2_pshufd"
22120   [(set (match_operand:V4SI 0 "register_operand" "=x")
22121         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22122                       (match_operand:SI 2 "immediate_operand" "i")]
22123                      UNSPEC_SHUFFLE))]
22124   "TARGET_SSE2"
22125   "pshufd\t{%2, %1, %0|%0, %1, %2}"
22126   [(set_attr "type" "ssecvt")
22127    (set_attr "mode" "TI")])
22128
22129 (define_insn "sse2_pshuflw"
22130   [(set (match_operand:V8HI 0 "register_operand" "=x")
22131         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22132                       (match_operand:SI 2 "immediate_operand" "i")]
22133                      UNSPEC_PSHUFLW))]
22134   "TARGET_SSE2"
22135   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22136   [(set_attr "type" "ssecvt")
22137    (set_attr "mode" "TI")])
22138
22139 (define_insn "sse2_pshufhw"
22140   [(set (match_operand:V8HI 0 "register_operand" "=x")
22141         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22142                       (match_operand:SI 2 "immediate_operand" "i")]
22143                      UNSPEC_PSHUFHW))]
22144   "TARGET_SSE2"
22145   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22146   [(set_attr "type" "ssecvt")
22147    (set_attr "mode" "TI")])
22148
22149 ;; MMX mask-generating comparisons
22150
22151 (define_insn "eqv16qi3"
22152   [(set (match_operand:V16QI 0 "register_operand" "=x")
22153         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22154                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22155   "TARGET_SSE2"
22156   "pcmpeqb\t{%2, %0|%0, %2}"
22157   [(set_attr "type" "ssecmp")
22158    (set_attr "mode" "TI")])
22159
22160 (define_insn "eqv8hi3"
22161   [(set (match_operand:V8HI 0 "register_operand" "=x")
22162         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22163                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22164   "TARGET_SSE2"
22165   "pcmpeqw\t{%2, %0|%0, %2}"
22166   [(set_attr "type" "ssecmp")
22167    (set_attr "mode" "TI")])
22168
22169 (define_insn "eqv4si3"
22170   [(set (match_operand:V4SI 0 "register_operand" "=x")
22171         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22172                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22173   "TARGET_SSE2"
22174   "pcmpeqd\t{%2, %0|%0, %2}"
22175   [(set_attr "type" "ssecmp")
22176    (set_attr "mode" "TI")])
22177
22178 (define_insn "gtv16qi3"
22179   [(set (match_operand:V16QI 0 "register_operand" "=x")
22180         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22181                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22182   "TARGET_SSE2"
22183   "pcmpgtb\t{%2, %0|%0, %2}"
22184   [(set_attr "type" "ssecmp")
22185    (set_attr "mode" "TI")])
22186
22187 (define_insn "gtv8hi3"
22188   [(set (match_operand:V8HI 0 "register_operand" "=x")
22189         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22190                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22191   "TARGET_SSE2"
22192   "pcmpgtw\t{%2, %0|%0, %2}"
22193   [(set_attr "type" "ssecmp")
22194    (set_attr "mode" "TI")])
22195
22196 (define_insn "gtv4si3"
22197   [(set (match_operand:V4SI 0 "register_operand" "=x")
22198         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22199                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22200   "TARGET_SSE2"
22201   "pcmpgtd\t{%2, %0|%0, %2}"
22202   [(set_attr "type" "ssecmp")
22203    (set_attr "mode" "TI")])
22204
22205
22206 ;; MMX max/min insns
22207
22208 (define_insn "umaxv16qi3"
22209   [(set (match_operand:V16QI 0 "register_operand" "=x")
22210         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22211                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22212   "TARGET_SSE2"
22213   "pmaxub\t{%2, %0|%0, %2}"
22214   [(set_attr "type" "sseiadd")
22215    (set_attr "mode" "TI")])
22216
22217 (define_insn "smaxv8hi3"
22218   [(set (match_operand:V8HI 0 "register_operand" "=x")
22219         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22220                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22221   "TARGET_SSE2"
22222   "pmaxsw\t{%2, %0|%0, %2}"
22223   [(set_attr "type" "sseiadd")
22224    (set_attr "mode" "TI")])
22225
22226 (define_insn "uminv16qi3"
22227   [(set (match_operand:V16QI 0 "register_operand" "=x")
22228         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22229                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22230   "TARGET_SSE2"
22231   "pminub\t{%2, %0|%0, %2}"
22232   [(set_attr "type" "sseiadd")
22233    (set_attr "mode" "TI")])
22234
22235 (define_insn "sminv8hi3"
22236   [(set (match_operand:V8HI 0 "register_operand" "=x")
22237         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22238                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22239   "TARGET_SSE2"
22240   "pminsw\t{%2, %0|%0, %2}"
22241   [(set_attr "type" "sseiadd")
22242    (set_attr "mode" "TI")])
22243
22244
22245 ;; MMX shifts
22246
22247 (define_insn "ashrv8hi3"
22248   [(set (match_operand:V8HI 0 "register_operand" "=x")
22249         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22250                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22251   "TARGET_SSE2"
22252   "psraw\t{%2, %0|%0, %2}"
22253   [(set_attr "type" "sseishft")
22254    (set_attr "mode" "TI")])
22255
22256 (define_insn "ashrv4si3"
22257   [(set (match_operand:V4SI 0 "register_operand" "=x")
22258         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22259                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22260   "TARGET_SSE2"
22261   "psrad\t{%2, %0|%0, %2}"
22262   [(set_attr "type" "sseishft")
22263    (set_attr "mode" "TI")])
22264
22265 (define_insn "lshrv8hi3"
22266   [(set (match_operand:V8HI 0 "register_operand" "=x")
22267         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22268                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22269   "TARGET_SSE2"
22270   "psrlw\t{%2, %0|%0, %2}"
22271   [(set_attr "type" "sseishft")
22272    (set_attr "mode" "TI")])
22273
22274 (define_insn "lshrv4si3"
22275   [(set (match_operand:V4SI 0 "register_operand" "=x")
22276         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22277                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22278   "TARGET_SSE2"
22279   "psrld\t{%2, %0|%0, %2}"
22280   [(set_attr "type" "sseishft")
22281    (set_attr "mode" "TI")])
22282
22283 (define_insn "lshrv2di3"
22284   [(set (match_operand:V2DI 0 "register_operand" "=x")
22285         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22286                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22287   "TARGET_SSE2"
22288   "psrlq\t{%2, %0|%0, %2}"
22289   [(set_attr "type" "sseishft")
22290    (set_attr "mode" "TI")])
22291
22292 (define_insn "ashlv8hi3"
22293   [(set (match_operand:V8HI 0 "register_operand" "=x")
22294         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22295                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22296   "TARGET_SSE2"
22297   "psllw\t{%2, %0|%0, %2}"
22298   [(set_attr "type" "sseishft")
22299    (set_attr "mode" "TI")])
22300
22301 (define_insn "ashlv4si3"
22302   [(set (match_operand:V4SI 0 "register_operand" "=x")
22303         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22304                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22305   "TARGET_SSE2"
22306   "pslld\t{%2, %0|%0, %2}"
22307   [(set_attr "type" "sseishft")
22308    (set_attr "mode" "TI")])
22309
22310 (define_insn "ashlv2di3"
22311   [(set (match_operand:V2DI 0 "register_operand" "=x")
22312         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22313                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22314   "TARGET_SSE2"
22315   "psllq\t{%2, %0|%0, %2}"
22316   [(set_attr "type" "sseishft")
22317    (set_attr "mode" "TI")])
22318
22319 (define_insn "ashrv8hi3_ti"
22320   [(set (match_operand:V8HI 0 "register_operand" "=x")
22321         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22322                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22323   "TARGET_SSE2"
22324   "psraw\t{%2, %0|%0, %2}"
22325   [(set_attr "type" "sseishft")
22326    (set_attr "mode" "TI")])
22327
22328 (define_insn "ashrv4si3_ti"
22329   [(set (match_operand:V4SI 0 "register_operand" "=x")
22330         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22331                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22332   "TARGET_SSE2"
22333   "psrad\t{%2, %0|%0, %2}"
22334   [(set_attr "type" "sseishft")
22335    (set_attr "mode" "TI")])
22336
22337 (define_insn "lshrv8hi3_ti"
22338   [(set (match_operand:V8HI 0 "register_operand" "=x")
22339         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22340                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22341   "TARGET_SSE2"
22342   "psrlw\t{%2, %0|%0, %2}"
22343   [(set_attr "type" "sseishft")
22344    (set_attr "mode" "TI")])
22345
22346 (define_insn "lshrv4si3_ti"
22347   [(set (match_operand:V4SI 0 "register_operand" "=x")
22348         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22349                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22350   "TARGET_SSE2"
22351   "psrld\t{%2, %0|%0, %2}"
22352   [(set_attr "type" "sseishft")
22353    (set_attr "mode" "TI")])
22354
22355 (define_insn "lshrv2di3_ti"
22356   [(set (match_operand:V2DI 0 "register_operand" "=x")
22357         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22358                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22359   "TARGET_SSE2"
22360   "psrlq\t{%2, %0|%0, %2}"
22361   [(set_attr "type" "sseishft")
22362    (set_attr "mode" "TI")])
22363
22364 (define_insn "ashlv8hi3_ti"
22365   [(set (match_operand:V8HI 0 "register_operand" "=x")
22366         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22367                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22368   "TARGET_SSE2"
22369   "psllw\t{%2, %0|%0, %2}"
22370   [(set_attr "type" "sseishft")
22371    (set_attr "mode" "TI")])
22372
22373 (define_insn "ashlv4si3_ti"
22374   [(set (match_operand:V4SI 0 "register_operand" "=x")
22375         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22376                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22377   "TARGET_SSE2"
22378   "pslld\t{%2, %0|%0, %2}"
22379   [(set_attr "type" "sseishft")
22380    (set_attr "mode" "TI")])
22381
22382 (define_insn "ashlv2di3_ti"
22383   [(set (match_operand:V2DI 0 "register_operand" "=x")
22384         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22385                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22386   "TARGET_SSE2"
22387   "psllq\t{%2, %0|%0, %2}"
22388   [(set_attr "type" "sseishft")
22389    (set_attr "mode" "TI")])
22390
22391 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22392 ;; we wouldn't need here it since we never generate TImode arithmetic.
22393
22394 ;; There has to be some kind of prize for the weirdest new instruction...
22395 (define_insn "sse2_ashlti3"
22396   [(set (match_operand:TI 0 "register_operand" "=x")
22397         (unspec:TI
22398          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22399                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22400                                (const_int 8)))] UNSPEC_NOP))]
22401   "TARGET_SSE2"
22402   "pslldq\t{%2, %0|%0, %2}"
22403   [(set_attr "type" "sseishft")
22404    (set_attr "mode" "TI")])
22405
22406 (define_insn "sse2_lshrti3"
22407   [(set (match_operand:TI 0 "register_operand" "=x")
22408         (unspec:TI
22409          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22410                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22411                                 (const_int 8)))] UNSPEC_NOP))]
22412   "TARGET_SSE2"
22413   "psrldq\t{%2, %0|%0, %2}"
22414   [(set_attr "type" "sseishft")
22415    (set_attr "mode" "TI")])
22416
22417 ;; SSE unpack
22418
22419 (define_insn "sse2_unpckhpd"
22420   [(set (match_operand:V2DF 0 "register_operand" "=x")
22421         (vec_concat:V2DF
22422          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22423                         (parallel [(const_int 1)]))
22424          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22425                         (parallel [(const_int 1)]))))]
22426   "TARGET_SSE2"
22427   "unpckhpd\t{%2, %0|%0, %2}"
22428   [(set_attr "type" "ssecvt")
22429    (set_attr "mode" "V2DF")])
22430
22431 (define_insn "sse2_unpcklpd"
22432   [(set (match_operand:V2DF 0 "register_operand" "=x")
22433         (vec_concat:V2DF
22434          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22435                         (parallel [(const_int 0)]))
22436          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22437                         (parallel [(const_int 0)]))))]
22438   "TARGET_SSE2"
22439   "unpcklpd\t{%2, %0|%0, %2}"
22440   [(set_attr "type" "ssecvt")
22441    (set_attr "mode" "V2DF")])
22442
22443 ;; MMX pack/unpack insns.
22444
22445 (define_insn "sse2_packsswb"
22446   [(set (match_operand:V16QI 0 "register_operand" "=x")
22447         (vec_concat:V16QI
22448          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22449          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22450   "TARGET_SSE2"
22451   "packsswb\t{%2, %0|%0, %2}"
22452   [(set_attr "type" "ssecvt")
22453    (set_attr "mode" "TI")])
22454
22455 (define_insn "sse2_packssdw"
22456   [(set (match_operand:V8HI 0 "register_operand" "=x")
22457         (vec_concat:V8HI
22458          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22459          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22460   "TARGET_SSE2"
22461   "packssdw\t{%2, %0|%0, %2}"
22462   [(set_attr "type" "ssecvt")
22463    (set_attr "mode" "TI")])
22464
22465 (define_insn "sse2_packuswb"
22466   [(set (match_operand:V16QI 0 "register_operand" "=x")
22467         (vec_concat:V16QI
22468          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22469          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22470   "TARGET_SSE2"
22471   "packuswb\t{%2, %0|%0, %2}"
22472   [(set_attr "type" "ssecvt")
22473    (set_attr "mode" "TI")])
22474
22475 (define_insn "sse2_punpckhbw"
22476   [(set (match_operand:V16QI 0 "register_operand" "=x")
22477         (vec_merge:V16QI
22478          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22479                            (parallel [(const_int 8) (const_int 0)
22480                                       (const_int 9) (const_int 1)
22481                                       (const_int 10) (const_int 2)
22482                                       (const_int 11) (const_int 3)
22483                                       (const_int 12) (const_int 4)
22484                                       (const_int 13) (const_int 5)
22485                                       (const_int 14) (const_int 6)
22486                                       (const_int 15) (const_int 7)]))
22487          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22488                            (parallel [(const_int 0) (const_int 8)
22489                                       (const_int 1) (const_int 9)
22490                                       (const_int 2) (const_int 10)
22491                                       (const_int 3) (const_int 11)
22492                                       (const_int 4) (const_int 12)
22493                                       (const_int 5) (const_int 13)
22494                                       (const_int 6) (const_int 14)
22495                                       (const_int 7) (const_int 15)]))
22496          (const_int 21845)))]
22497   "TARGET_SSE2"
22498   "punpckhbw\t{%2, %0|%0, %2}"
22499   [(set_attr "type" "ssecvt")
22500    (set_attr "mode" "TI")])
22501
22502 (define_insn "sse2_punpckhwd"
22503   [(set (match_operand:V8HI 0 "register_operand" "=x")
22504         (vec_merge:V8HI
22505          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22506                           (parallel [(const_int 4) (const_int 0)
22507                                      (const_int 5) (const_int 1)
22508                                      (const_int 6) (const_int 2)
22509                                      (const_int 7) (const_int 3)]))
22510          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22511                           (parallel [(const_int 0) (const_int 4)
22512                                      (const_int 1) (const_int 5)
22513                                      (const_int 2) (const_int 6)
22514                                      (const_int 3) (const_int 7)]))
22515          (const_int 85)))]
22516   "TARGET_SSE2"
22517   "punpckhwd\t{%2, %0|%0, %2}"
22518   [(set_attr "type" "ssecvt")
22519    (set_attr "mode" "TI")])
22520
22521 (define_insn "sse2_punpckhdq"
22522   [(set (match_operand:V4SI 0 "register_operand" "=x")
22523         (vec_merge:V4SI
22524          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22525                           (parallel [(const_int 2) (const_int 0)
22526                                      (const_int 3) (const_int 1)]))
22527          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22528                           (parallel [(const_int 0) (const_int 2)
22529                                      (const_int 1) (const_int 3)]))
22530          (const_int 5)))]
22531   "TARGET_SSE2"
22532   "punpckhdq\t{%2, %0|%0, %2}"
22533   [(set_attr "type" "ssecvt")
22534    (set_attr "mode" "TI")])
22535
22536 (define_insn "sse2_punpcklbw"
22537   [(set (match_operand:V16QI 0 "register_operand" "=x")
22538         (vec_merge:V16QI
22539          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22540                            (parallel [(const_int 0) (const_int 8)
22541                                       (const_int 1) (const_int 9)
22542                                       (const_int 2) (const_int 10)
22543                                       (const_int 3) (const_int 11)
22544                                       (const_int 4) (const_int 12)
22545                                       (const_int 5) (const_int 13)
22546                                       (const_int 6) (const_int 14)
22547                                       (const_int 7) (const_int 15)]))
22548          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22549                            (parallel [(const_int 8) (const_int 0)
22550                                       (const_int 9) (const_int 1)
22551                                       (const_int 10) (const_int 2)
22552                                       (const_int 11) (const_int 3)
22553                                       (const_int 12) (const_int 4)
22554                                       (const_int 13) (const_int 5)
22555                                       (const_int 14) (const_int 6)
22556                                       (const_int 15) (const_int 7)]))
22557          (const_int 21845)))]
22558   "TARGET_SSE2"
22559   "punpcklbw\t{%2, %0|%0, %2}"
22560   [(set_attr "type" "ssecvt")
22561    (set_attr "mode" "TI")])
22562
22563 (define_insn "sse2_punpcklwd"
22564   [(set (match_operand:V8HI 0 "register_operand" "=x")
22565         (vec_merge:V8HI
22566          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22567                           (parallel [(const_int 0) (const_int 4)
22568                                      (const_int 1) (const_int 5)
22569                                      (const_int 2) (const_int 6)
22570                                      (const_int 3) (const_int 7)]))
22571          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22572                           (parallel [(const_int 4) (const_int 0)
22573                                      (const_int 5) (const_int 1)
22574                                      (const_int 6) (const_int 2)
22575                                      (const_int 7) (const_int 3)]))
22576          (const_int 85)))]
22577   "TARGET_SSE2"
22578   "punpcklwd\t{%2, %0|%0, %2}"
22579   [(set_attr "type" "ssecvt")
22580    (set_attr "mode" "TI")])
22581
22582 (define_insn "sse2_punpckldq"
22583   [(set (match_operand:V4SI 0 "register_operand" "=x")
22584         (vec_merge:V4SI
22585          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22586                           (parallel [(const_int 0) (const_int 2)
22587                                      (const_int 1) (const_int 3)]))
22588          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22589                           (parallel [(const_int 2) (const_int 0)
22590                                      (const_int 3) (const_int 1)]))
22591          (const_int 5)))]
22592   "TARGET_SSE2"
22593   "punpckldq\t{%2, %0|%0, %2}"
22594   [(set_attr "type" "ssecvt")
22595    (set_attr "mode" "TI")])
22596
22597 (define_insn "sse2_punpcklqdq"
22598   [(set (match_operand:V2DI 0 "register_operand" "=x")
22599         (vec_merge:V2DI
22600          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22601                           (parallel [(const_int 1)
22602                                      (const_int 0)]))
22603          (match_operand:V2DI 1 "register_operand" "0")
22604          (const_int 1)))]
22605   "TARGET_SSE2"
22606   "punpcklqdq\t{%2, %0|%0, %2}"
22607   [(set_attr "type" "ssecvt")
22608    (set_attr "mode" "TI")])
22609
22610 (define_insn "sse2_punpckhqdq"
22611   [(set (match_operand:V2DI 0 "register_operand" "=x")
22612         (vec_merge:V2DI
22613          (match_operand:V2DI 1 "register_operand" "0")
22614          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22615                           (parallel [(const_int 1)
22616                                      (const_int 0)]))
22617          (const_int 1)))]
22618   "TARGET_SSE2"
22619   "punpckhqdq\t{%2, %0|%0, %2}"
22620   [(set_attr "type" "ssecvt")
22621    (set_attr "mode" "TI")])
22622
22623 ;; SSE2 moves
22624
22625 (define_insn "sse2_movapd"
22626   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22627         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22628                      UNSPEC_MOVA))]
22629   "TARGET_SSE2
22630    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22631   "movapd\t{%1, %0|%0, %1}"
22632   [(set_attr "type" "ssemov")
22633    (set_attr "mode" "V2DF")])
22634
22635 (define_insn "sse2_movupd"
22636   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22637         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22638                      UNSPEC_MOVU))]
22639   "TARGET_SSE2
22640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22641   "movupd\t{%1, %0|%0, %1}"
22642   [(set_attr "type" "ssecvt")
22643    (set_attr "mode" "V2DF")])
22644
22645 (define_insn "sse2_movdqa"
22646   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22647         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22648                        UNSPEC_MOVA))]
22649   "TARGET_SSE2
22650    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22651   "movdqa\t{%1, %0|%0, %1}"
22652   [(set_attr "type" "ssemov")
22653    (set_attr "mode" "TI")])
22654
22655 (define_insn "sse2_movdqu"
22656   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22657         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22658                        UNSPEC_MOVU))]
22659   "TARGET_SSE2
22660    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22661   "movdqu\t{%1, %0|%0, %1}"
22662   [(set_attr "type" "ssecvt")
22663    (set_attr "mode" "TI")])
22664
22665 (define_insn "sse2_movdq2q"
22666   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22667         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22668                        (parallel [(const_int 0)])))]
22669   "TARGET_SSE2 && !TARGET_64BIT"
22670   "@
22671    movq\t{%1, %0|%0, %1}
22672    movdq2q\t{%1, %0|%0, %1}"
22673   [(set_attr "type" "ssecvt")
22674    (set_attr "mode" "TI")])
22675
22676 (define_insn "sse2_movdq2q_rex64"
22677   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22678         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22679                        (parallel [(const_int 0)])))]
22680   "TARGET_SSE2 && TARGET_64BIT"
22681   "@
22682    movq\t{%1, %0|%0, %1}
22683    movdq2q\t{%1, %0|%0, %1}
22684    movd\t{%1, %0|%0, %1}"
22685   [(set_attr "type" "ssecvt")
22686    (set_attr "mode" "TI")])
22687
22688 (define_insn "sse2_movq2dq"
22689   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22690         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22691                          (const_int 0)))]
22692   "TARGET_SSE2 && !TARGET_64BIT"
22693   "@
22694    movq\t{%1, %0|%0, %1}
22695    movq2dq\t{%1, %0|%0, %1}"
22696   [(set_attr "type" "ssecvt,ssemov")
22697    (set_attr "mode" "TI")])
22698
22699 (define_insn "sse2_movq2dq_rex64"
22700   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22701         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22702                          (const_int 0)))]
22703   "TARGET_SSE2 && TARGET_64BIT"
22704   "@
22705    movq\t{%1, %0|%0, %1}
22706    movq2dq\t{%1, %0|%0, %1}
22707    movd\t{%1, %0|%0, %1}"
22708   [(set_attr "type" "ssecvt,ssemov,ssecvt")
22709    (set_attr "mode" "TI")])
22710
22711 (define_insn "sse2_movq"
22712   [(set (match_operand:V2DI 0 "register_operand" "=x")
22713         (vec_concat:V2DI (vec_select:DI
22714                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22715                           (parallel [(const_int 0)]))
22716                          (const_int 0)))]
22717   "TARGET_SSE2"
22718   "movq\t{%1, %0|%0, %1}"
22719   [(set_attr "type" "ssemov")
22720    (set_attr "mode" "TI")])
22721
22722 (define_insn "sse2_loadd"
22723   [(set (match_operand:V4SI 0 "register_operand" "=x")
22724         (vec_merge:V4SI
22725          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22726          (const_vector:V4SI [(const_int 0)
22727                              (const_int 0)
22728                              (const_int 0)
22729                              (const_int 0)])
22730          (const_int 1)))]
22731   "TARGET_SSE2"
22732   "movd\t{%1, %0|%0, %1}"
22733   [(set_attr "type" "ssemov")
22734    (set_attr "mode" "TI")])
22735
22736 (define_insn "sse2_stored"
22737   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22738         (vec_select:SI
22739          (match_operand:V4SI 1 "register_operand" "x")
22740          (parallel [(const_int 0)])))]
22741   "TARGET_SSE2"
22742   "movd\t{%1, %0|%0, %1}"
22743   [(set_attr "type" "ssemov")
22744    (set_attr "mode" "TI")])
22745
22746 (define_insn "sse2_movhpd"
22747   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22748         (vec_merge:V2DF
22749          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22750          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22751          (const_int 2)))]
22752   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22753   "movhpd\t{%2, %0|%0, %2}"
22754   [(set_attr "type" "ssecvt")
22755    (set_attr "mode" "V2DF")])
22756
22757 (define_expand "sse2_loadsd"
22758   [(match_operand:V2DF 0 "register_operand" "")
22759    (match_operand:DF 1 "memory_operand" "")]
22760   "TARGET_SSE2"
22761 {
22762   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22763                                 CONST0_RTX (V2DFmode)));
22764   DONE;
22765 })
22766
22767 (define_insn "sse2_loadsd_1"
22768   [(set (match_operand:V2DF 0 "register_operand" "=x")
22769         (vec_merge:V2DF
22770          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22771          (match_operand:V2DF 2 "const0_operand" "X")
22772          (const_int 1)))]
22773   "TARGET_SSE2"
22774   "movsd\t{%1, %0|%0, %1}"
22775   [(set_attr "type" "ssecvt")
22776    (set_attr "mode" "DF")])
22777
22778 (define_insn "sse2_movsd"
22779   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22780         (vec_merge:V2DF
22781          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22782          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22783          (const_int 1)))]
22784   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22785   "@movsd\t{%2, %0|%0, %2}
22786     movlpd\t{%2, %0|%0, %2}
22787     movlpd\t{%2, %0|%0, %2}"
22788   [(set_attr "type" "ssecvt")
22789    (set_attr "mode" "DF,V2DF,V2DF")])
22790
22791 (define_insn "sse2_storesd"
22792   [(set (match_operand:DF 0 "memory_operand" "=m")
22793         (vec_select:DF
22794          (match_operand:V2DF 1 "register_operand" "x")
22795          (parallel [(const_int 0)])))]
22796   "TARGET_SSE2"
22797   "movsd\t{%1, %0|%0, %1}"
22798   [(set_attr "type" "ssecvt")
22799    (set_attr "mode" "DF")])
22800
22801 (define_insn "sse2_shufpd"
22802   [(set (match_operand:V2DF 0 "register_operand" "=x")
22803         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22804                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22805                       (match_operand:SI 3 "immediate_operand" "i")]
22806                      UNSPEC_SHUFFLE))]
22807   "TARGET_SSE2"
22808   ;; @@@ check operand order for intel/nonintel syntax
22809   "shufpd\t{%3, %2, %0|%0, %2, %3}"
22810   [(set_attr "type" "ssecvt")
22811    (set_attr "mode" "V2DF")])
22812
22813 (define_insn "sse2_clflush"
22814   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22815                     UNSPECV_CLFLUSH)]
22816   "TARGET_SSE2"
22817   "clflush %0"
22818   [(set_attr "type" "sse")
22819    (set_attr "memory" "unknown")])
22820
22821 (define_expand "sse2_mfence"
22822   [(set (match_dup 0)
22823         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22824   "TARGET_SSE2"
22825 {
22826   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22827   MEM_VOLATILE_P (operands[0]) = 1;
22828 })
22829
22830 (define_insn "*mfence_insn"
22831   [(set (match_operand:BLK 0 "" "")
22832         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22833   "TARGET_SSE2"
22834   "mfence"
22835   [(set_attr "type" "sse")
22836    (set_attr "memory" "unknown")])
22837
22838 (define_expand "sse2_lfence"
22839   [(set (match_dup 0)
22840         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22841   "TARGET_SSE2"
22842 {
22843   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22844   MEM_VOLATILE_P (operands[0]) = 1;
22845 })
22846
22847 (define_insn "*lfence_insn"
22848   [(set (match_operand:BLK 0 "" "")
22849         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22850   "TARGET_SSE2"
22851   "lfence"
22852   [(set_attr "type" "sse")
22853    (set_attr "memory" "unknown")])
22854
22855 ;; SSE3
22856
22857 (define_insn "mwait"
22858   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22859                      (match_operand:SI 1 "register_operand" "c")]
22860                     UNSPECV_MWAIT)]
22861   "TARGET_SSE3"
22862   "mwait\t%0, %1"
22863   [(set_attr "length" "3")])
22864
22865 (define_insn "monitor"
22866   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22867                      (match_operand:SI 1 "register_operand" "c")
22868                      (match_operand:SI 2 "register_operand" "d")]
22869                     UNSPECV_MONITOR)]
22870   "TARGET_SSE3"
22871   "monitor\t%0, %1, %2"
22872   [(set_attr "length" "3")])
22873
22874 ;; SSE3 arithmetic
22875
22876 (define_insn "addsubv4sf3"
22877   [(set (match_operand:V4SF 0 "register_operand" "=x")
22878         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22879                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22880                      UNSPEC_ADDSUB))]
22881   "TARGET_SSE3"
22882   "addsubps\t{%2, %0|%0, %2}"
22883   [(set_attr "type" "sseadd")
22884    (set_attr "mode" "V4SF")])
22885
22886 (define_insn "addsubv2df3"
22887   [(set (match_operand:V2DF 0 "register_operand" "=x")
22888         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22889                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22890                      UNSPEC_ADDSUB))]
22891   "TARGET_SSE3"
22892   "addsubpd\t{%2, %0|%0, %2}"
22893   [(set_attr "type" "sseadd")
22894    (set_attr "mode" "V2DF")])
22895
22896 (define_insn "haddv4sf3"
22897   [(set (match_operand:V4SF 0 "register_operand" "=x")
22898         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22899                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22900                      UNSPEC_HADD))]
22901   "TARGET_SSE3"
22902   "haddps\t{%2, %0|%0, %2}"
22903   [(set_attr "type" "sseadd")
22904    (set_attr "mode" "V4SF")])
22905
22906 (define_insn "haddv2df3"
22907   [(set (match_operand:V2DF 0 "register_operand" "=x")
22908         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22909                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22910                      UNSPEC_HADD))]
22911   "TARGET_SSE3"
22912   "haddpd\t{%2, %0|%0, %2}"
22913   [(set_attr "type" "sseadd")
22914    (set_attr "mode" "V2DF")])
22915
22916 (define_insn "hsubv4sf3"
22917   [(set (match_operand:V4SF 0 "register_operand" "=x")
22918         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22919                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22920                      UNSPEC_HSUB))]
22921   "TARGET_SSE3"
22922   "hsubps\t{%2, %0|%0, %2}"
22923   [(set_attr "type" "sseadd")
22924    (set_attr "mode" "V4SF")])
22925
22926 (define_insn "hsubv2df3"
22927   [(set (match_operand:V2DF 0 "register_operand" "=x")
22928         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22929                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22930                      UNSPEC_HSUB))]
22931   "TARGET_SSE3"
22932   "hsubpd\t{%2, %0|%0, %2}"
22933   [(set_attr "type" "sseadd")
22934    (set_attr "mode" "V2DF")])
22935
22936 (define_insn "movshdup"
22937   [(set (match_operand:V4SF 0 "register_operand" "=x")
22938         (unspec:V4SF
22939          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22940   "TARGET_SSE3"
22941   "movshdup\t{%1, %0|%0, %1}"
22942   [(set_attr "type" "sse")
22943    (set_attr "mode" "V4SF")])
22944
22945 (define_insn "movsldup"
22946   [(set (match_operand:V4SF 0 "register_operand" "=x")
22947         (unspec:V4SF
22948          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22949   "TARGET_SSE3"
22950   "movsldup\t{%1, %0|%0, %1}"
22951   [(set_attr "type" "sse")
22952    (set_attr "mode" "V4SF")])
22953
22954 (define_insn "lddqu"
22955   [(set (match_operand:V16QI 0 "register_operand" "=x")
22956         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22957                        UNSPEC_LDQQU))]
22958   "TARGET_SSE3"
22959   "lddqu\t{%1, %0|%0, %1}"
22960   [(set_attr "type" "ssecvt")
22961    (set_attr "mode" "TI")])
22962
22963 (define_insn "loadddup"
22964   [(set (match_operand:V2DF 0 "register_operand" "=x")
22965         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
22966   "TARGET_SSE3"
22967   "movddup\t{%1, %0|%0, %1}"
22968   [(set_attr "type" "ssecvt")
22969    (set_attr "mode" "DF")])
22970
22971 (define_insn "movddup"
22972   [(set (match_operand:V2DF 0 "register_operand" "=x")
22973         (vec_duplicate:V2DF
22974          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
22975                         (parallel [(const_int 0)]))))]
22976   "TARGET_SSE3"
22977   "movddup\t{%1, %0|%0, %1}"
22978   [(set_attr "type" "ssecvt")
22979    (set_attr "mode" "DF")])