Bring in a trimmed down gcc-3.4-20040618.
[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_PROBE          10)
67    (UNSPEC_STACK_ALLOC          11)
68    (UNSPEC_SET_GOT              12)
69    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70
71    ; TLS support
72    (UNSPEC_TP                   15)
73    (UNSPEC_TLS_GD               16)
74    (UNSPEC_TLS_LD_BASE          17)
75
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_SIN                  21)
79    (UNSPEC_COS                  22)
80    (UNSPEC_FNSTSW               24)
81    (UNSPEC_SAHF                 25)
82    (UNSPEC_FSTCW                26)
83    (UNSPEC_ADD_CARRY            27)
84    (UNSPEC_FLDCW                28)
85
86    ; For SSE/MMX support:
87    (UNSPEC_FIX                  30)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FSCALE               67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
123
124    ; REP instruction
125    (UNSPEC_REP                  75)
126   ])
127
128 (define_constants
129   [(UNSPECV_BLOCKAGE            0)
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 2 "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:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17223    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17224    (clobber (match_scratch:SI 1 "=0"))
17225    (clobber (reg:CC 17))]
17226   "!TARGET_64BIT && TARGET_STACK_PROBE"
17227   "call\t__alloca"
17228   [(set_attr "type" "multi")
17229    (set_attr "length" "5")])
17230
17231 (define_expand "allocate_stack_worker_postreload"
17232   [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17233                            UNSPEC_STACK_PROBE)
17234               (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17235               (clobber (match_dup 0))
17236               (clobber (reg:CC 17))])]
17237   ""
17238   "")
17239
17240 (define_insn "allocate_stack_worker_rex64"
17241   [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17242    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17243    (clobber (match_scratch:DI 1 "=0"))
17244    (clobber (reg:CC 17))]
17245   "TARGET_64BIT && TARGET_STACK_PROBE"
17246   "call\t__alloca"
17247   [(set_attr "type" "multi")
17248    (set_attr "length" "5")])
17249
17250 (define_expand "allocate_stack_worker_rex64_postreload"
17251   [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17252                            UNSPEC_STACK_PROBE)
17253               (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17254               (clobber (match_dup 0))
17255               (clobber (reg:CC 17))])]
17256   ""
17257   "")
17258
17259 (define_expand "allocate_stack"
17260   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17261                    (minus:SI (reg:SI 7)
17262                              (match_operand:SI 1 "general_operand" "")))
17263               (clobber (reg:CC 17))])
17264    (parallel [(set (reg:SI 7)
17265                    (minus:SI (reg:SI 7) (match_dup 1)))
17266               (clobber (reg:CC 17))])]
17267   "TARGET_STACK_PROBE"
17268 {
17269 #ifdef CHECK_STACK_LIMIT
17270   if (GET_CODE (operands[1]) == CONST_INT
17271       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17272     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17273                            operands[1]));
17274   else 
17275 #endif
17276     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17277                                                             operands[1])));
17278
17279   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17280   DONE;
17281 })
17282
17283 (define_expand "builtin_setjmp_receiver"
17284   [(label_ref (match_operand 0 "" ""))]
17285   "!TARGET_64BIT && flag_pic"
17286 {
17287   emit_insn (gen_set_got (pic_offset_table_rtx));
17288   DONE;
17289 })
17290 \f
17291 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17292
17293 (define_split
17294   [(set (match_operand 0 "register_operand" "")
17295         (match_operator 3 "promotable_binary_operator"
17296            [(match_operand 1 "register_operand" "")
17297             (match_operand 2 "aligned_operand" "")]))
17298    (clobber (reg:CC 17))]
17299   "! TARGET_PARTIAL_REG_STALL && reload_completed
17300    && ((GET_MODE (operands[0]) == HImode 
17301         && ((!optimize_size && !TARGET_FAST_PREFIX)
17302             || GET_CODE (operands[2]) != CONST_INT
17303             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17304        || (GET_MODE (operands[0]) == QImode 
17305            && (TARGET_PROMOTE_QImode || optimize_size)))"
17306   [(parallel [(set (match_dup 0)
17307                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17308               (clobber (reg:CC 17))])]
17309   "operands[0] = gen_lowpart (SImode, operands[0]);
17310    operands[1] = gen_lowpart (SImode, operands[1]);
17311    if (GET_CODE (operands[3]) != ASHIFT)
17312      operands[2] = gen_lowpart (SImode, operands[2]);
17313    PUT_MODE (operands[3], SImode);")
17314
17315 ; Promote the QImode tests, as i386 has encoding of the AND
17316 ; instruction with 32-bit sign-extended immediate and thus the
17317 ; instruction size is unchanged, except in the %eax case for
17318 ; which it is increased by one byte, hence the ! optimize_size.
17319 (define_split
17320   [(set (reg 17)
17321         (compare (and (match_operand 1 "aligned_operand" "")
17322                       (match_operand 2 "const_int_operand" ""))
17323                  (const_int 0)))
17324    (set (match_operand 0 "register_operand" "")
17325         (and (match_dup 1) (match_dup 2)))]
17326   "! TARGET_PARTIAL_REG_STALL && reload_completed
17327    /* Ensure that the operand will remain sign-extended immediate.  */
17328    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17329    && ! optimize_size
17330    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17331        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17332   [(parallel [(set (reg:CCNO 17)
17333                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17334                                  (const_int 0)))
17335               (set (match_dup 0)
17336                    (and:SI (match_dup 1) (match_dup 2)))])]
17337   "operands[2]
17338      = gen_int_mode (INTVAL (operands[2])
17339                      & GET_MODE_MASK (GET_MODE (operands[0])),
17340                      SImode);
17341    operands[0] = gen_lowpart (SImode, operands[0]);
17342    operands[1] = gen_lowpart (SImode, operands[1]);")
17343
17344 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17345 ; the TEST instruction with 32-bit sign-extended immediate and thus
17346 ; the instruction size would at least double, which is not what we
17347 ; want even with ! optimize_size.
17348 (define_split
17349   [(set (reg 17)
17350         (compare (and (match_operand:HI 0 "aligned_operand" "")
17351                       (match_operand:HI 1 "const_int_operand" ""))
17352                  (const_int 0)))]
17353   "! TARGET_PARTIAL_REG_STALL && reload_completed
17354    /* Ensure that the operand will remain sign-extended immediate.  */
17355    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17356    && ! TARGET_FAST_PREFIX
17357    && ! optimize_size"
17358   [(set (reg:CCNO 17)
17359         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17360                       (const_int 0)))]
17361   "operands[1]
17362      = gen_int_mode (INTVAL (operands[1])
17363                      & GET_MODE_MASK (GET_MODE (operands[0])),
17364                      SImode);
17365    operands[0] = gen_lowpart (SImode, operands[0]);")
17366
17367 (define_split
17368   [(set (match_operand 0 "register_operand" "")
17369         (neg (match_operand 1 "register_operand" "")))
17370    (clobber (reg:CC 17))]
17371   "! TARGET_PARTIAL_REG_STALL && reload_completed
17372    && (GET_MODE (operands[0]) == HImode
17373        || (GET_MODE (operands[0]) == QImode 
17374            && (TARGET_PROMOTE_QImode || optimize_size)))"
17375   [(parallel [(set (match_dup 0)
17376                    (neg:SI (match_dup 1)))
17377               (clobber (reg:CC 17))])]
17378   "operands[0] = gen_lowpart (SImode, operands[0]);
17379    operands[1] = gen_lowpart (SImode, operands[1]);")
17380
17381 (define_split
17382   [(set (match_operand 0 "register_operand" "")
17383         (not (match_operand 1 "register_operand" "")))]
17384   "! TARGET_PARTIAL_REG_STALL && reload_completed
17385    && (GET_MODE (operands[0]) == HImode
17386        || (GET_MODE (operands[0]) == QImode 
17387            && (TARGET_PROMOTE_QImode || optimize_size)))"
17388   [(set (match_dup 0)
17389         (not:SI (match_dup 1)))]
17390   "operands[0] = gen_lowpart (SImode, operands[0]);
17391    operands[1] = gen_lowpart (SImode, operands[1]);")
17392
17393 (define_split 
17394   [(set (match_operand 0 "register_operand" "")
17395         (if_then_else (match_operator 1 "comparison_operator" 
17396                                 [(reg 17) (const_int 0)])
17397                       (match_operand 2 "register_operand" "")
17398                       (match_operand 3 "register_operand" "")))]
17399   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17400    && (GET_MODE (operands[0]) == HImode
17401        || (GET_MODE (operands[0]) == QImode 
17402            && (TARGET_PROMOTE_QImode || optimize_size)))"
17403   [(set (match_dup 0)
17404         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17405   "operands[0] = gen_lowpart (SImode, operands[0]);
17406    operands[2] = gen_lowpart (SImode, operands[2]);
17407    operands[3] = gen_lowpart (SImode, operands[3]);")
17408                         
17409 \f
17410 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17411 ;; transform a complex memory operation into two memory to register operations.
17412
17413 ;; Don't push memory operands
17414 (define_peephole2
17415   [(set (match_operand:SI 0 "push_operand" "")
17416         (match_operand:SI 1 "memory_operand" ""))
17417    (match_scratch:SI 2 "r")]
17418   "! optimize_size && ! TARGET_PUSH_MEMORY"
17419   [(set (match_dup 2) (match_dup 1))
17420    (set (match_dup 0) (match_dup 2))]
17421   "")
17422
17423 (define_peephole2
17424   [(set (match_operand:DI 0 "push_operand" "")
17425         (match_operand:DI 1 "memory_operand" ""))
17426    (match_scratch:DI 2 "r")]
17427   "! optimize_size && ! TARGET_PUSH_MEMORY"
17428   [(set (match_dup 2) (match_dup 1))
17429    (set (match_dup 0) (match_dup 2))]
17430   "")
17431
17432 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17433 ;; SImode pushes.
17434 (define_peephole2
17435   [(set (match_operand:SF 0 "push_operand" "")
17436         (match_operand:SF 1 "memory_operand" ""))
17437    (match_scratch:SF 2 "r")]
17438   "! optimize_size && ! TARGET_PUSH_MEMORY"
17439   [(set (match_dup 2) (match_dup 1))
17440    (set (match_dup 0) (match_dup 2))]
17441   "")
17442
17443 (define_peephole2
17444   [(set (match_operand:HI 0 "push_operand" "")
17445         (match_operand:HI 1 "memory_operand" ""))
17446    (match_scratch:HI 2 "r")]
17447   "! optimize_size && ! TARGET_PUSH_MEMORY"
17448   [(set (match_dup 2) (match_dup 1))
17449    (set (match_dup 0) (match_dup 2))]
17450   "")
17451
17452 (define_peephole2
17453   [(set (match_operand:QI 0 "push_operand" "")
17454         (match_operand:QI 1 "memory_operand" ""))
17455    (match_scratch:QI 2 "q")]
17456   "! optimize_size && ! TARGET_PUSH_MEMORY"
17457   [(set (match_dup 2) (match_dup 1))
17458    (set (match_dup 0) (match_dup 2))]
17459   "")
17460
17461 ;; Don't move an immediate directly to memory when the instruction
17462 ;; gets too big.
17463 (define_peephole2
17464   [(match_scratch:SI 1 "r")
17465    (set (match_operand:SI 0 "memory_operand" "")
17466         (const_int 0))]
17467   "! optimize_size
17468    && ! TARGET_USE_MOV0
17469    && TARGET_SPLIT_LONG_MOVES
17470    && get_attr_length (insn) >= ix86_cost->large_insn
17471    && peep2_regno_dead_p (0, FLAGS_REG)"
17472   [(parallel [(set (match_dup 1) (const_int 0))
17473               (clobber (reg:CC 17))])
17474    (set (match_dup 0) (match_dup 1))]
17475   "")
17476
17477 (define_peephole2
17478   [(match_scratch:HI 1 "r")
17479    (set (match_operand:HI 0 "memory_operand" "")
17480         (const_int 0))]
17481   "! optimize_size
17482    && ! TARGET_USE_MOV0
17483    && TARGET_SPLIT_LONG_MOVES
17484    && get_attr_length (insn) >= ix86_cost->large_insn
17485    && peep2_regno_dead_p (0, FLAGS_REG)"
17486   [(parallel [(set (match_dup 2) (const_int 0))
17487               (clobber (reg:CC 17))])
17488    (set (match_dup 0) (match_dup 1))]
17489   "operands[2] = gen_lowpart (SImode, operands[1]);")
17490
17491 (define_peephole2
17492   [(match_scratch:QI 1 "q")
17493    (set (match_operand:QI 0 "memory_operand" "")
17494         (const_int 0))]
17495   "! optimize_size
17496    && ! TARGET_USE_MOV0
17497    && TARGET_SPLIT_LONG_MOVES
17498    && get_attr_length (insn) >= ix86_cost->large_insn
17499    && peep2_regno_dead_p (0, FLAGS_REG)"
17500   [(parallel [(set (match_dup 2) (const_int 0))
17501               (clobber (reg:CC 17))])
17502    (set (match_dup 0) (match_dup 1))]
17503   "operands[2] = gen_lowpart (SImode, operands[1]);")
17504
17505 (define_peephole2
17506   [(match_scratch:SI 2 "r")
17507    (set (match_operand:SI 0 "memory_operand" "")
17508         (match_operand:SI 1 "immediate_operand" ""))]
17509   "! optimize_size
17510    && get_attr_length (insn) >= ix86_cost->large_insn
17511    && TARGET_SPLIT_LONG_MOVES"
17512   [(set (match_dup 2) (match_dup 1))
17513    (set (match_dup 0) (match_dup 2))]
17514   "")
17515
17516 (define_peephole2
17517   [(match_scratch:HI 2 "r")
17518    (set (match_operand:HI 0 "memory_operand" "")
17519         (match_operand:HI 1 "immediate_operand" ""))]
17520   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17521   && TARGET_SPLIT_LONG_MOVES"
17522   [(set (match_dup 2) (match_dup 1))
17523    (set (match_dup 0) (match_dup 2))]
17524   "")
17525
17526 (define_peephole2
17527   [(match_scratch:QI 2 "q")
17528    (set (match_operand:QI 0 "memory_operand" "")
17529         (match_operand:QI 1 "immediate_operand" ""))]
17530   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17531   && TARGET_SPLIT_LONG_MOVES"
17532   [(set (match_dup 2) (match_dup 1))
17533    (set (match_dup 0) (match_dup 2))]
17534   "")
17535
17536 ;; Don't compare memory with zero, load and use a test instead.
17537 (define_peephole2
17538   [(set (reg 17)
17539         (compare (match_operand:SI 0 "memory_operand" "")
17540                  (const_int 0)))
17541    (match_scratch:SI 3 "r")]
17542   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17543   [(set (match_dup 3) (match_dup 0))
17544    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17545   "")
17546
17547 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17548 ;; Don't split NOTs with a displacement operand, because resulting XOR
17549 ;; will not be pairable anyway.
17550 ;;
17551 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17552 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17553 ;; so this split helps here as well.
17554 ;;
17555 ;; Note: Can't do this as a regular split because we can't get proper
17556 ;; lifetime information then.
17557
17558 (define_peephole2
17559   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17560         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17561   "!optimize_size
17562    && peep2_regno_dead_p (0, FLAGS_REG)
17563    && ((TARGET_PENTIUM 
17564         && (GET_CODE (operands[0]) != MEM
17565             || !memory_displacement_operand (operands[0], SImode)))
17566        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17567   [(parallel [(set (match_dup 0)
17568                    (xor:SI (match_dup 1) (const_int -1)))
17569               (clobber (reg:CC 17))])]
17570   "")
17571
17572 (define_peephole2
17573   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17574         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17575   "!optimize_size
17576    && peep2_regno_dead_p (0, FLAGS_REG)
17577    && ((TARGET_PENTIUM 
17578         && (GET_CODE (operands[0]) != MEM
17579             || !memory_displacement_operand (operands[0], HImode)))
17580        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17581   [(parallel [(set (match_dup 0)
17582                    (xor:HI (match_dup 1) (const_int -1)))
17583               (clobber (reg:CC 17))])]
17584   "")
17585
17586 (define_peephole2
17587   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17588         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17589   "!optimize_size
17590    && peep2_regno_dead_p (0, FLAGS_REG)
17591    && ((TARGET_PENTIUM 
17592         && (GET_CODE (operands[0]) != MEM
17593             || !memory_displacement_operand (operands[0], QImode)))
17594        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17595   [(parallel [(set (match_dup 0)
17596                    (xor:QI (match_dup 1) (const_int -1)))
17597               (clobber (reg:CC 17))])]
17598   "")
17599
17600 ;; Non pairable "test imm, reg" instructions can be translated to
17601 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17602 ;; byte opcode instead of two, have a short form for byte operands),
17603 ;; so do it for other CPUs as well.  Given that the value was dead,
17604 ;; this should not create any new dependencies.  Pass on the sub-word
17605 ;; versions if we're concerned about partial register stalls.
17606
17607 (define_peephole2
17608   [(set (reg 17)
17609         (compare (and:SI (match_operand:SI 0 "register_operand" "")
17610                          (match_operand:SI 1 "immediate_operand" ""))
17611                  (const_int 0)))]
17612   "ix86_match_ccmode (insn, CCNOmode)
17613    && (true_regnum (operands[0]) != 0
17614        || (GET_CODE (operands[1]) == CONST_INT
17615            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17616    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17617   [(parallel
17618      [(set (reg:CCNO 17)
17619            (compare:CCNO (and:SI (match_dup 0)
17620                                  (match_dup 1))
17621                          (const_int 0)))
17622       (set (match_dup 0)
17623            (and:SI (match_dup 0) (match_dup 1)))])]
17624   "")
17625
17626 ;; We don't need to handle HImode case, because it will be promoted to SImode
17627 ;; on ! TARGET_PARTIAL_REG_STALL
17628
17629 (define_peephole2
17630   [(set (reg 17)
17631         (compare (and:QI (match_operand:QI 0 "register_operand" "")
17632                          (match_operand:QI 1 "immediate_operand" ""))
17633                  (const_int 0)))]
17634   "! TARGET_PARTIAL_REG_STALL
17635    && ix86_match_ccmode (insn, CCNOmode)
17636    && true_regnum (operands[0]) != 0
17637    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17638   [(parallel
17639      [(set (reg:CCNO 17)
17640            (compare:CCNO (and:QI (match_dup 0)
17641                                  (match_dup 1))
17642                          (const_int 0)))
17643       (set (match_dup 0)
17644            (and:QI (match_dup 0) (match_dup 1)))])]
17645   "")
17646
17647 (define_peephole2
17648   [(set (reg 17)
17649         (compare
17650           (and:SI
17651             (zero_extract:SI
17652               (match_operand 0 "ext_register_operand" "")
17653               (const_int 8)
17654               (const_int 8))
17655             (match_operand 1 "const_int_operand" ""))
17656           (const_int 0)))]
17657   "! TARGET_PARTIAL_REG_STALL
17658    && ix86_match_ccmode (insn, CCNOmode)
17659    && true_regnum (operands[0]) != 0
17660    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17661   [(parallel [(set (reg:CCNO 17)
17662                    (compare:CCNO
17663                        (and:SI
17664                          (zero_extract:SI
17665                          (match_dup 0)
17666                          (const_int 8)
17667                          (const_int 8))
17668                         (match_dup 1))
17669                    (const_int 0)))
17670               (set (zero_extract:SI (match_dup 0)
17671                                     (const_int 8)
17672                                     (const_int 8))
17673                    (and:SI 
17674                      (zero_extract:SI
17675                        (match_dup 0)
17676                        (const_int 8)
17677                        (const_int 8))
17678                      (match_dup 1)))])]
17679   "")
17680
17681 ;; Don't do logical operations with memory inputs.
17682 (define_peephole2
17683   [(match_scratch:SI 2 "r")
17684    (parallel [(set (match_operand:SI 0 "register_operand" "")
17685                    (match_operator:SI 3 "arith_or_logical_operator"
17686                      [(match_dup 0)
17687                       (match_operand:SI 1 "memory_operand" "")]))
17688               (clobber (reg:CC 17))])]
17689   "! optimize_size && ! TARGET_READ_MODIFY"
17690   [(set (match_dup 2) (match_dup 1))
17691    (parallel [(set (match_dup 0)
17692                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17693               (clobber (reg:CC 17))])]
17694   "")
17695
17696 (define_peephole2
17697   [(match_scratch:SI 2 "r")
17698    (parallel [(set (match_operand:SI 0 "register_operand" "")
17699                    (match_operator:SI 3 "arith_or_logical_operator"
17700                      [(match_operand:SI 1 "memory_operand" "")
17701                       (match_dup 0)]))
17702               (clobber (reg:CC 17))])]
17703   "! optimize_size && ! TARGET_READ_MODIFY"
17704   [(set (match_dup 2) (match_dup 1))
17705    (parallel [(set (match_dup 0)
17706                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17707               (clobber (reg:CC 17))])]
17708   "")
17709
17710 ; Don't do logical operations with memory outputs
17711 ;
17712 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17713 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17714 ; the same decoder scheduling characteristics as the original.
17715
17716 (define_peephole2
17717   [(match_scratch:SI 2 "r")
17718    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17719                    (match_operator:SI 3 "arith_or_logical_operator"
17720                      [(match_dup 0)
17721                       (match_operand:SI 1 "nonmemory_operand" "")]))
17722               (clobber (reg:CC 17))])]
17723   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17724   [(set (match_dup 2) (match_dup 0))
17725    (parallel [(set (match_dup 2)
17726                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17727               (clobber (reg:CC 17))])
17728    (set (match_dup 0) (match_dup 2))]
17729   "")
17730
17731 (define_peephole2
17732   [(match_scratch:SI 2 "r")
17733    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17734                    (match_operator:SI 3 "arith_or_logical_operator"
17735                      [(match_operand:SI 1 "nonmemory_operand" "")
17736                       (match_dup 0)]))
17737               (clobber (reg:CC 17))])]
17738   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17739   [(set (match_dup 2) (match_dup 0))
17740    (parallel [(set (match_dup 2)
17741                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17742               (clobber (reg:CC 17))])
17743    (set (match_dup 0) (match_dup 2))]
17744   "")
17745
17746 ;; Attempt to always use XOR for zeroing registers.
17747 (define_peephole2
17748   [(set (match_operand 0 "register_operand" "")
17749         (const_int 0))]
17750   "(GET_MODE (operands[0]) == QImode
17751     || GET_MODE (operands[0]) == HImode
17752     || GET_MODE (operands[0]) == SImode
17753     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17754    && (! TARGET_USE_MOV0 || optimize_size)
17755    && peep2_regno_dead_p (0, FLAGS_REG)"
17756   [(parallel [(set (match_dup 0) (const_int 0))
17757               (clobber (reg:CC 17))])]
17758   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17759                               operands[0]);")
17760
17761 (define_peephole2
17762   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17763         (const_int 0))]
17764   "(GET_MODE (operands[0]) == QImode
17765     || GET_MODE (operands[0]) == HImode)
17766    && (! TARGET_USE_MOV0 || optimize_size)
17767    && peep2_regno_dead_p (0, FLAGS_REG)"
17768   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17769               (clobber (reg:CC 17))])])
17770
17771 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17772 (define_peephole2
17773   [(set (match_operand 0 "register_operand" "")
17774         (const_int -1))]
17775   "(GET_MODE (operands[0]) == HImode
17776     || GET_MODE (operands[0]) == SImode 
17777     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17778    && (optimize_size || TARGET_PENTIUM)
17779    && peep2_regno_dead_p (0, FLAGS_REG)"
17780   [(parallel [(set (match_dup 0) (const_int -1))
17781               (clobber (reg:CC 17))])]
17782   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17783                               operands[0]);")
17784
17785 ;; Attempt to convert simple leas to adds. These can be created by
17786 ;; move expanders.
17787 (define_peephole2
17788   [(set (match_operand:SI 0 "register_operand" "")
17789         (plus:SI (match_dup 0)
17790                  (match_operand:SI 1 "nonmemory_operand" "")))]
17791   "peep2_regno_dead_p (0, FLAGS_REG)"
17792   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17793               (clobber (reg:CC 17))])]
17794   "")
17795
17796 (define_peephole2
17797   [(set (match_operand:SI 0 "register_operand" "")
17798         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17799                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17800   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17801   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17802               (clobber (reg:CC 17))])]
17803   "operands[2] = gen_lowpart (SImode, operands[2]);")
17804
17805 (define_peephole2
17806   [(set (match_operand:DI 0 "register_operand" "")
17807         (plus:DI (match_dup 0)
17808                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17809   "peep2_regno_dead_p (0, FLAGS_REG)"
17810   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17811               (clobber (reg:CC 17))])]
17812   "")
17813
17814 (define_peephole2
17815   [(set (match_operand:SI 0 "register_operand" "")
17816         (mult:SI (match_dup 0)
17817                  (match_operand:SI 1 "const_int_operand" "")))]
17818   "exact_log2 (INTVAL (operands[1])) >= 0
17819    && peep2_regno_dead_p (0, FLAGS_REG)"
17820   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17821               (clobber (reg:CC 17))])]
17822   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17823
17824 (define_peephole2
17825   [(set (match_operand:DI 0 "register_operand" "")
17826         (mult:DI (match_dup 0)
17827                  (match_operand:DI 1 "const_int_operand" "")))]
17828   "exact_log2 (INTVAL (operands[1])) >= 0
17829    && peep2_regno_dead_p (0, FLAGS_REG)"
17830   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17831               (clobber (reg:CC 17))])]
17832   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17833
17834 (define_peephole2
17835   [(set (match_operand:SI 0 "register_operand" "")
17836         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17837                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17838   "exact_log2 (INTVAL (operands[2])) >= 0
17839    && REGNO (operands[0]) == REGNO (operands[1])
17840    && peep2_regno_dead_p (0, FLAGS_REG)"
17841   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17842               (clobber (reg:CC 17))])]
17843   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17844
17845 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17846 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17847 ;; many CPUs it is also faster, since special hardware to avoid esp
17848 ;; dependencies is present.
17849
17850 ;; While some of these conversions may be done using splitters, we use peepholes
17851 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17852
17853 ;; Convert prologue esp subtractions to push.
17854 ;; We need register to push.  In order to keep verify_flow_info happy we have
17855 ;; two choices
17856 ;; - use scratch and clobber it in order to avoid dependencies
17857 ;; - use already live register
17858 ;; We can't use the second way right now, since there is no reliable way how to
17859 ;; verify that given register is live.  First choice will also most likely in
17860 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17861 ;; call clobbered registers are dead.  We may want to use base pointer as an
17862 ;; alternative when no register is available later.
17863
17864 (define_peephole2
17865   [(match_scratch:SI 0 "r")
17866    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17867               (clobber (reg:CC 17))
17868               (clobber (mem:BLK (scratch)))])]
17869   "optimize_size || !TARGET_SUB_ESP_4"
17870   [(clobber (match_dup 0))
17871    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17872               (clobber (mem:BLK (scratch)))])])
17873
17874 (define_peephole2
17875   [(match_scratch:SI 0 "r")
17876    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17877               (clobber (reg:CC 17))
17878               (clobber (mem:BLK (scratch)))])]
17879   "optimize_size || !TARGET_SUB_ESP_8"
17880   [(clobber (match_dup 0))
17881    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17882    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17883               (clobber (mem:BLK (scratch)))])])
17884
17885 ;; Convert esp subtractions to push.
17886 (define_peephole2
17887   [(match_scratch:SI 0 "r")
17888    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17889               (clobber (reg:CC 17))])]
17890   "optimize_size || !TARGET_SUB_ESP_4"
17891   [(clobber (match_dup 0))
17892    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17893
17894 (define_peephole2
17895   [(match_scratch:SI 0 "r")
17896    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17897               (clobber (reg:CC 17))])]
17898   "optimize_size || !TARGET_SUB_ESP_8"
17899   [(clobber (match_dup 0))
17900    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17901    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17902
17903 ;; Convert epilogue deallocator to pop.
17904 (define_peephole2
17905   [(match_scratch:SI 0 "r")
17906    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17907               (clobber (reg:CC 17))
17908               (clobber (mem:BLK (scratch)))])]
17909   "optimize_size || !TARGET_ADD_ESP_4"
17910   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17911               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17912               (clobber (mem:BLK (scratch)))])]
17913   "")
17914
17915 ;; Two pops case is tricky, since pop causes dependency on destination register.
17916 ;; We use two registers if available.
17917 (define_peephole2
17918   [(match_scratch:SI 0 "r")
17919    (match_scratch:SI 1 "r")
17920    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17921               (clobber (reg:CC 17))
17922               (clobber (mem:BLK (scratch)))])]
17923   "optimize_size || !TARGET_ADD_ESP_8"
17924   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17925               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17926               (clobber (mem:BLK (scratch)))])
17927    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17928               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17929   "")
17930
17931 (define_peephole2
17932   [(match_scratch:SI 0 "r")
17933    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17934               (clobber (reg:CC 17))
17935               (clobber (mem:BLK (scratch)))])]
17936   "optimize_size"
17937   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17938               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17939               (clobber (mem:BLK (scratch)))])
17940    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17941               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17942   "")
17943
17944 ;; Convert esp additions to pop.
17945 (define_peephole2
17946   [(match_scratch:SI 0 "r")
17947    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17948               (clobber (reg:CC 17))])]
17949   ""
17950   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17951               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17952   "")
17953
17954 ;; Two pops case is tricky, since pop causes dependency on destination register.
17955 ;; We use two registers if available.
17956 (define_peephole2
17957   [(match_scratch:SI 0 "r")
17958    (match_scratch:SI 1 "r")
17959    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17960               (clobber (reg:CC 17))])]
17961   ""
17962   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17963               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17964    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17965               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17966   "")
17967
17968 (define_peephole2
17969   [(match_scratch:SI 0 "r")
17970    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17971               (clobber (reg:CC 17))])]
17972   "optimize_size"
17973   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17974               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
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   "")
17978 \f
17979 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17980 ;; required and register dies.
17981 (define_peephole2
17982   [(set (reg 17)
17983         (compare (match_operand:SI 0 "register_operand" "")
17984                  (match_operand:SI 1 "incdec_operand" "")))]
17985   "ix86_match_ccmode (insn, CCGCmode)
17986    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17987   [(parallel [(set (reg:CCGC 17)
17988                    (compare:CCGC (match_dup 0)
17989                                  (match_dup 1)))
17990               (clobber (match_dup 0))])]
17991   "")
17992
17993 (define_peephole2
17994   [(set (reg 17)
17995         (compare (match_operand:HI 0 "register_operand" "")
17996                  (match_operand:HI 1 "incdec_operand" "")))]
17997   "ix86_match_ccmode (insn, CCGCmode)
17998    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17999   [(parallel [(set (reg:CCGC 17)
18000                    (compare:CCGC (match_dup 0)
18001                                  (match_dup 1)))
18002               (clobber (match_dup 0))])]
18003   "")
18004
18005 (define_peephole2
18006   [(set (reg 17)
18007         (compare (match_operand:QI 0 "register_operand" "")
18008                  (match_operand:QI 1 "incdec_operand" "")))]
18009   "ix86_match_ccmode (insn, CCGCmode)
18010    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18011   [(parallel [(set (reg:CCGC 17)
18012                    (compare:CCGC (match_dup 0)
18013                                  (match_dup 1)))
18014               (clobber (match_dup 0))])]
18015   "")
18016
18017 ;; Convert compares with 128 to shorter add -128
18018 (define_peephole2
18019   [(set (reg 17)
18020         (compare (match_operand:SI 0 "register_operand" "")
18021                  (const_int 128)))]
18022   "ix86_match_ccmode (insn, CCGCmode)
18023    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18024   [(parallel [(set (reg:CCGC 17)
18025                    (compare:CCGC (match_dup 0)
18026                                  (const_int 128)))
18027               (clobber (match_dup 0))])]
18028   "")
18029
18030 (define_peephole2
18031   [(set (reg 17)
18032         (compare (match_operand:HI 0 "register_operand" "")
18033                  (const_int 128)))]
18034   "ix86_match_ccmode (insn, CCGCmode)
18035    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18036   [(parallel [(set (reg:CCGC 17)
18037                    (compare:CCGC (match_dup 0)
18038                                  (const_int 128)))
18039               (clobber (match_dup 0))])]
18040   "")
18041 \f
18042 (define_peephole2
18043   [(match_scratch:DI 0 "r")
18044    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18045               (clobber (reg:CC 17))
18046               (clobber (mem:BLK (scratch)))])]
18047   "optimize_size || !TARGET_SUB_ESP_4"
18048   [(clobber (match_dup 0))
18049    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18050               (clobber (mem:BLK (scratch)))])])
18051
18052 (define_peephole2
18053   [(match_scratch:DI 0 "r")
18054    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18055               (clobber (reg:CC 17))
18056               (clobber (mem:BLK (scratch)))])]
18057   "optimize_size || !TARGET_SUB_ESP_8"
18058   [(clobber (match_dup 0))
18059    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18060    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18061               (clobber (mem:BLK (scratch)))])])
18062
18063 ;; Convert esp subtractions to push.
18064 (define_peephole2
18065   [(match_scratch:DI 0 "r")
18066    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18067               (clobber (reg:CC 17))])]
18068   "optimize_size || !TARGET_SUB_ESP_4"
18069   [(clobber (match_dup 0))
18070    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18071
18072 (define_peephole2
18073   [(match_scratch:DI 0 "r")
18074    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18075               (clobber (reg:CC 17))])]
18076   "optimize_size || !TARGET_SUB_ESP_8"
18077   [(clobber (match_dup 0))
18078    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18079    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18080
18081 ;; Convert epilogue deallocator to pop.
18082 (define_peephole2
18083   [(match_scratch:DI 0 "r")
18084    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18085               (clobber (reg:CC 17))
18086               (clobber (mem:BLK (scratch)))])]
18087   "optimize_size || !TARGET_ADD_ESP_4"
18088   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18089               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18090               (clobber (mem:BLK (scratch)))])]
18091   "")
18092
18093 ;; Two pops case is tricky, since pop causes dependency on destination register.
18094 ;; We use two registers if available.
18095 (define_peephole2
18096   [(match_scratch:DI 0 "r")
18097    (match_scratch:DI 1 "r")
18098    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18099               (clobber (reg:CC 17))
18100               (clobber (mem:BLK (scratch)))])]
18101   "optimize_size || !TARGET_ADD_ESP_8"
18102   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18103               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18104               (clobber (mem:BLK (scratch)))])
18105    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18106               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18107   "")
18108
18109 (define_peephole2
18110   [(match_scratch:DI 0 "r")
18111    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18112               (clobber (reg:CC 17))
18113               (clobber (mem:BLK (scratch)))])]
18114   "optimize_size"
18115   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18116               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18117               (clobber (mem:BLK (scratch)))])
18118    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18119               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18120   "")
18121
18122 ;; Convert esp additions to pop.
18123 (define_peephole2
18124   [(match_scratch:DI 0 "r")
18125    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18126               (clobber (reg:CC 17))])]
18127   ""
18128   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18129               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18130   "")
18131
18132 ;; Two pops case is tricky, since pop causes dependency on destination register.
18133 ;; We use two registers if available.
18134 (define_peephole2
18135   [(match_scratch:DI 0 "r")
18136    (match_scratch:DI 1 "r")
18137    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18138               (clobber (reg:CC 17))])]
18139   ""
18140   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18141               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18142    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18143               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18144   "")
18145
18146 (define_peephole2
18147   [(match_scratch:DI 0 "r")
18148    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18149               (clobber (reg:CC 17))])]
18150   "optimize_size"
18151   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18152               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
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   "")
18156 \f
18157 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18158 ;; imul $32bit_imm, reg, reg is direct decoded.
18159 (define_peephole2
18160   [(match_scratch:DI 3 "r")
18161    (parallel [(set (match_operand:DI 0 "register_operand" "")
18162                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18163                             (match_operand:DI 2 "immediate_operand" "")))
18164               (clobber (reg:CC 17))])]
18165   "TARGET_K8 && !optimize_size
18166    && (GET_CODE (operands[2]) != CONST_INT
18167        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18168   [(set (match_dup 3) (match_dup 1))
18169    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18170               (clobber (reg:CC 17))])]
18171 "")
18172
18173 (define_peephole2
18174   [(match_scratch:SI 3 "r")
18175    (parallel [(set (match_operand:SI 0 "register_operand" "")
18176                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18177                             (match_operand:SI 2 "immediate_operand" "")))
18178               (clobber (reg:CC 17))])]
18179   "TARGET_K8 && !optimize_size
18180    && (GET_CODE (operands[2]) != CONST_INT
18181        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18182   [(set (match_dup 3) (match_dup 1))
18183    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18184               (clobber (reg:CC 17))])]
18185 "")
18186
18187 (define_peephole2
18188   [(match_scratch:SI 3 "r")
18189    (parallel [(set (match_operand:DI 0 "register_operand" "")
18190                    (zero_extend:DI
18191                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18192                               (match_operand:SI 2 "immediate_operand" ""))))
18193               (clobber (reg:CC 17))])]
18194   "TARGET_K8 && !optimize_size
18195    && (GET_CODE (operands[2]) != CONST_INT
18196        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18197   [(set (match_dup 3) (match_dup 1))
18198    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18199               (clobber (reg:CC 17))])]
18200 "")
18201
18202 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18203 ;; Convert it into imul reg, reg
18204 ;; It would be better to force assembler to encode instruction using long
18205 ;; immediate, but there is apparently no way to do so.
18206 (define_peephole2
18207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18208                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18209                             (match_operand:DI 2 "const_int_operand" "")))
18210               (clobber (reg:CC 17))])
18211    (match_scratch:DI 3 "r")]
18212   "TARGET_K8 && !optimize_size
18213    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18214   [(set (match_dup 3) (match_dup 2))
18215    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18216               (clobber (reg:CC 17))])]
18217 {
18218   if (!rtx_equal_p (operands[0], operands[1]))
18219     emit_move_insn (operands[0], operands[1]);
18220 })
18221
18222 (define_peephole2
18223   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18224                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18225                             (match_operand:SI 2 "const_int_operand" "")))
18226               (clobber (reg:CC 17))])
18227    (match_scratch:SI 3 "r")]
18228   "TARGET_K8 && !optimize_size
18229    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18230   [(set (match_dup 3) (match_dup 2))
18231    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18232               (clobber (reg:CC 17))])]
18233 {
18234   if (!rtx_equal_p (operands[0], operands[1]))
18235     emit_move_insn (operands[0], operands[1]);
18236 })
18237
18238 (define_peephole2
18239   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18240                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18241                             (match_operand:HI 2 "immediate_operand" "")))
18242               (clobber (reg:CC 17))])
18243    (match_scratch:HI 3 "r")]
18244   "TARGET_K8 && !optimize_size"
18245   [(set (match_dup 3) (match_dup 2))
18246    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18247               (clobber (reg:CC 17))])]
18248 {
18249   if (!rtx_equal_p (operands[0], operands[1]))
18250     emit_move_insn (operands[0], operands[1]);
18251 })
18252 \f
18253 ;; Call-value patterns last so that the wildcard operand does not
18254 ;; disrupt insn-recog's switch tables.
18255
18256 (define_insn "*call_value_pop_0"
18257   [(set (match_operand 0 "" "")
18258         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18259               (match_operand:SI 2 "" "")))
18260    (set (reg:SI 7) (plus:SI (reg:SI 7)
18261                             (match_operand:SI 3 "immediate_operand" "")))]
18262   "!TARGET_64BIT"
18263 {
18264   if (SIBLING_CALL_P (insn))
18265     return "jmp\t%P1";
18266   else
18267     return "call\t%P1";
18268 }
18269   [(set_attr "type" "callv")])
18270
18271 (define_insn "*call_value_pop_1"
18272   [(set (match_operand 0 "" "")
18273         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18274               (match_operand:SI 2 "" "")))
18275    (set (reg:SI 7) (plus:SI (reg:SI 7)
18276                             (match_operand:SI 3 "immediate_operand" "i")))]
18277   "!TARGET_64BIT"
18278 {
18279   if (constant_call_address_operand (operands[1], QImode))
18280     {
18281       if (SIBLING_CALL_P (insn))
18282         return "jmp\t%P1";
18283       else
18284         return "call\t%P1";
18285     }
18286   if (SIBLING_CALL_P (insn))
18287     return "jmp\t%A1";
18288   else
18289     return "call\t%A1";
18290 }
18291   [(set_attr "type" "callv")])
18292
18293 (define_insn "*call_value_0"
18294   [(set (match_operand 0 "" "")
18295         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18296               (match_operand:SI 2 "" "")))]
18297   "!TARGET_64BIT"
18298 {
18299   if (SIBLING_CALL_P (insn))
18300     return "jmp\t%P1";
18301   else
18302     return "call\t%P1";
18303 }
18304   [(set_attr "type" "callv")])
18305
18306 (define_insn "*call_value_0_rex64"
18307   [(set (match_operand 0 "" "")
18308         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18309               (match_operand:DI 2 "const_int_operand" "")))]
18310   "TARGET_64BIT"
18311 {
18312   if (SIBLING_CALL_P (insn))
18313     return "jmp\t%P1";
18314   else
18315     return "call\t%P1";
18316 }
18317   [(set_attr "type" "callv")])
18318
18319 (define_insn "*call_value_1"
18320   [(set (match_operand 0 "" "")
18321         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18322               (match_operand:SI 2 "" "")))]
18323   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18324 {
18325   if (constant_call_address_operand (operands[1], QImode))
18326     return "call\t%P1";
18327   return "call\t%*%1";
18328 }
18329   [(set_attr "type" "callv")])
18330
18331 (define_insn "*sibcall_value_1"
18332   [(set (match_operand 0 "" "")
18333         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18334               (match_operand:SI 2 "" "")))]
18335   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18336 {
18337   if (constant_call_address_operand (operands[1], QImode))
18338     return "jmp\t%P1";
18339   return "jmp\t%*%1";
18340 }
18341   [(set_attr "type" "callv")])
18342
18343 (define_insn "*call_value_1_rex64"
18344   [(set (match_operand 0 "" "")
18345         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18346               (match_operand:DI 2 "" "")))]
18347   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18348 {
18349   if (constant_call_address_operand (operands[1], QImode))
18350     return "call\t%P1";
18351   return "call\t%A1";
18352 }
18353   [(set_attr "type" "callv")])
18354
18355 (define_insn "*sibcall_value_1_rex64"
18356   [(set (match_operand 0 "" "")
18357         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18358               (match_operand:DI 2 "" "")))]
18359   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18360   "jmp\t%P1"
18361   [(set_attr "type" "callv")])
18362
18363 (define_insn "*sibcall_value_1_rex64_v"
18364   [(set (match_operand 0 "" "")
18365         (call (mem:QI (reg:DI 40))
18366               (match_operand:DI 1 "" "")))]
18367   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18368   "jmp\t*%%r11"
18369   [(set_attr "type" "callv")])
18370 \f
18371 (define_insn "trap"
18372   [(trap_if (const_int 1) (const_int 5))]
18373   ""
18374   "int\t$5")
18375
18376 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18377 ;;; for the sake of bounds checking.  By emitting bounds checks as
18378 ;;; conditional traps rather than as conditional jumps around
18379 ;;; unconditional traps we avoid introducing spurious basic-block
18380 ;;; boundaries and facilitate elimination of redundant checks.  In
18381 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18382 ;;; interrupt 5.
18383 ;;; 
18384 ;;; FIXME: Static branch prediction rules for ix86 are such that
18385 ;;; forward conditional branches predict as untaken.  As implemented
18386 ;;; below, pseudo conditional traps violate that rule.  We should use
18387 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18388 ;;; section loaded at the end of the text segment and branch forward
18389 ;;; there on bounds-failure, and then jump back immediately (in case
18390 ;;; the system chooses to ignore bounds violations, or to report
18391 ;;; violations and continue execution).
18392
18393 (define_expand "conditional_trap"
18394   [(trap_if (match_operator 0 "comparison_operator"
18395              [(match_dup 2) (const_int 0)])
18396             (match_operand 1 "const_int_operand" ""))]
18397   ""
18398 {
18399   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18400                               ix86_expand_compare (GET_CODE (operands[0]),
18401                                                    NULL, NULL),
18402                               operands[1]));
18403   DONE;
18404 })
18405
18406 (define_insn "*conditional_trap_1"
18407   [(trap_if (match_operator 0 "comparison_operator"
18408              [(reg 17) (const_int 0)])
18409             (match_operand 1 "const_int_operand" ""))]
18410   ""
18411 {
18412   operands[2] = gen_label_rtx ();
18413   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18414   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18415                              CODE_LABEL_NUMBER (operands[2]));
18416   RET;
18417 })
18418
18419         ;; Pentium III SIMD instructions.
18420
18421 ;; Moves for SSE/MMX regs.
18422
18423 (define_insn "movv4sf_internal"
18424   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18425         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18426   "TARGET_SSE"
18427   "@
18428     xorps\t%0, %0
18429     movaps\t{%1, %0|%0, %1}
18430     movaps\t{%1, %0|%0, %1}"
18431   [(set_attr "type" "ssemov")
18432    (set_attr "mode" "V4SF")])
18433
18434 (define_split
18435   [(set (match_operand:V4SF 0 "register_operand" "")
18436         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18437   "TARGET_SSE"
18438   [(set (match_dup 0)
18439         (vec_merge:V4SF
18440          (vec_duplicate:V4SF (match_dup 1))
18441          (match_dup 2)
18442          (const_int 1)))]
18443 {
18444   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18445   operands[2] = CONST0_RTX (V4SFmode);
18446 })
18447
18448 (define_insn "movv4si_internal"
18449   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18450         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18451   "TARGET_SSE"
18452 {
18453   switch (which_alternative)
18454     {
18455     case 0:
18456       if (get_attr_mode (insn) == MODE_V4SF)
18457         return "xorps\t%0, %0";
18458       else
18459         return "pxor\t%0, %0";
18460     case 1:
18461     case 2:
18462       if (get_attr_mode (insn) == MODE_V4SF)
18463         return "movaps\t{%1, %0|%0, %1}";
18464       else
18465         return "movdqa\t{%1, %0|%0, %1}";
18466     default:
18467       abort ();
18468     }
18469 }
18470   [(set_attr "type" "ssemov")
18471    (set (attr "mode")
18472         (cond [(eq_attr "alternative" "0,1")
18473                  (if_then_else
18474                    (ne (symbol_ref "optimize_size")
18475                        (const_int 0))
18476                    (const_string "V4SF")
18477                    (const_string "TI"))
18478                (eq_attr "alternative" "2")
18479                  (if_then_else
18480                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18481                             (const_int 0))
18482                         (ne (symbol_ref "optimize_size")
18483                             (const_int 0)))
18484                    (const_string "V4SF")
18485                    (const_string "TI"))]
18486                (const_string "TI")))])
18487
18488 (define_insn "movv2di_internal"
18489   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18490         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18491   "TARGET_SSE"
18492 {
18493   switch (which_alternative)
18494     {
18495     case 0:
18496       if (get_attr_mode (insn) == MODE_V4SF)
18497         return "xorps\t%0, %0";
18498       else
18499         return "pxor\t%0, %0";
18500     case 1:
18501     case 2:
18502       if (get_attr_mode (insn) == MODE_V4SF)
18503         return "movaps\t{%1, %0|%0, %1}";
18504       else
18505         return "movdqa\t{%1, %0|%0, %1}";
18506     default:
18507       abort ();
18508     }
18509 }
18510   [(set_attr "type" "ssemov")
18511    (set (attr "mode")
18512         (cond [(eq_attr "alternative" "0,1")
18513                  (if_then_else
18514                    (ne (symbol_ref "optimize_size")
18515                        (const_int 0))
18516                    (const_string "V4SF")
18517                    (const_string "TI"))
18518                (eq_attr "alternative" "2")
18519                  (if_then_else
18520                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18521                             (const_int 0))
18522                         (ne (symbol_ref "optimize_size")
18523                             (const_int 0)))
18524                    (const_string "V4SF")
18525                    (const_string "TI"))]
18526                (const_string "TI")))])
18527
18528 (define_split
18529   [(set (match_operand:V2DF 0 "register_operand" "")
18530         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18531   "TARGET_SSE2"
18532   [(set (match_dup 0)
18533         (vec_merge:V2DF
18534          (vec_duplicate:V2DF (match_dup 1))
18535          (match_dup 2)
18536          (const_int 1)))]
18537 {
18538   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18539   operands[2] = CONST0_RTX (V2DFmode);
18540 })
18541
18542 (define_insn "movv8qi_internal"
18543   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18544         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18545   "TARGET_MMX
18546    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18547   "@
18548     pxor\t%0, %0
18549     movq\t{%1, %0|%0, %1}
18550     movq\t{%1, %0|%0, %1}"
18551   [(set_attr "type" "mmxmov")
18552    (set_attr "mode" "DI")])
18553
18554 (define_insn "movv4hi_internal"
18555   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18556         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18557   "TARGET_MMX
18558    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18559   "@
18560     pxor\t%0, %0
18561     movq\t{%1, %0|%0, %1}
18562     movq\t{%1, %0|%0, %1}"
18563   [(set_attr "type" "mmxmov")
18564    (set_attr "mode" "DI")])
18565
18566 (define_insn "movv2si_internal"
18567   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18568         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18569   "TARGET_MMX
18570    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18571   "@
18572     pxor\t%0, %0
18573     movq\t{%1, %0|%0, %1}
18574     movq\t{%1, %0|%0, %1}"
18575   [(set_attr "type" "mmxcvt")
18576    (set_attr "mode" "DI")])
18577
18578 (define_insn "movv2sf_internal"
18579   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18580         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18581   "TARGET_3DNOW
18582    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18583   "@
18584     pxor\t%0, %0
18585     movq\t{%1, %0|%0, %1}
18586     movq\t{%1, %0|%0, %1}"
18587   [(set_attr "type" "mmxcvt")
18588    (set_attr "mode" "DI")])
18589
18590 (define_expand "movti"
18591   [(set (match_operand:TI 0 "nonimmediate_operand" "")
18592         (match_operand:TI 1 "nonimmediate_operand" ""))]
18593   "TARGET_SSE || TARGET_64BIT"
18594 {
18595   if (TARGET_64BIT)
18596     ix86_expand_move (TImode, operands);
18597   else
18598     ix86_expand_vector_move (TImode, operands);
18599   DONE;
18600 })
18601
18602 (define_expand "movtf"
18603   [(set (match_operand:TF 0 "nonimmediate_operand" "")
18604         (match_operand:TF 1 "nonimmediate_operand" ""))]
18605   "TARGET_64BIT"
18606 {
18607   if (TARGET_64BIT)
18608     ix86_expand_move (TFmode, operands);
18609   else
18610     ix86_expand_vector_move (TFmode, operands);
18611   DONE;
18612 })
18613
18614 (define_insn "movv2df_internal"
18615   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18616         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18617   "TARGET_SSE2
18618    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18619 {
18620   switch (which_alternative)
18621     {
18622     case 0:
18623       if (get_attr_mode (insn) == MODE_V4SF)
18624         return "xorps\t%0, %0";
18625       else
18626         return "xorpd\t%0, %0";
18627     case 1:
18628     case 2:
18629       if (get_attr_mode (insn) == MODE_V4SF)
18630         return "movaps\t{%1, %0|%0, %1}";
18631       else
18632         return "movapd\t{%1, %0|%0, %1}";
18633     default:
18634       abort ();
18635     }
18636 }
18637   [(set_attr "type" "ssemov")
18638    (set (attr "mode")
18639         (cond [(eq_attr "alternative" "0,1")
18640                  (if_then_else
18641                    (ne (symbol_ref "optimize_size")
18642                        (const_int 0))
18643                    (const_string "V4SF")
18644                    (const_string "V2DF"))
18645                (eq_attr "alternative" "2")
18646                  (if_then_else
18647                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18648                             (const_int 0))
18649                         (ne (symbol_ref "optimize_size")
18650                             (const_int 0)))
18651                    (const_string "V4SF")
18652                    (const_string "V2DF"))]
18653                (const_string "V2DF")))])
18654
18655 (define_insn "movv8hi_internal"
18656   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18657         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18658   "TARGET_SSE2
18659    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18660 {
18661   switch (which_alternative)
18662     {
18663     case 0:
18664       if (get_attr_mode (insn) == MODE_V4SF)
18665         return "xorps\t%0, %0";
18666       else
18667         return "pxor\t%0, %0";
18668     case 1:
18669     case 2:
18670       if (get_attr_mode (insn) == MODE_V4SF)
18671         return "movaps\t{%1, %0|%0, %1}";
18672       else
18673         return "movdqa\t{%1, %0|%0, %1}";
18674     default:
18675       abort ();
18676     }
18677 }
18678   [(set_attr "type" "ssemov")
18679    (set (attr "mode")
18680         (cond [(eq_attr "alternative" "0,1")
18681                  (if_then_else
18682                    (ne (symbol_ref "optimize_size")
18683                        (const_int 0))
18684                    (const_string "V4SF")
18685                    (const_string "TI"))
18686                (eq_attr "alternative" "2")
18687                  (if_then_else
18688                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18689                             (const_int 0))
18690                         (ne (symbol_ref "optimize_size")
18691                             (const_int 0)))
18692                    (const_string "V4SF")
18693                    (const_string "TI"))]
18694                (const_string "TI")))])
18695
18696 (define_insn "movv16qi_internal"
18697   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18698         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18699   "TARGET_SSE2
18700    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18701 {
18702   switch (which_alternative)
18703     {
18704     case 0:
18705       if (get_attr_mode (insn) == MODE_V4SF)
18706         return "xorps\t%0, %0";
18707       else
18708         return "pxor\t%0, %0";
18709     case 1:
18710     case 2:
18711       if (get_attr_mode (insn) == MODE_V4SF)
18712         return "movaps\t{%1, %0|%0, %1}";
18713       else
18714         return "movdqa\t{%1, %0|%0, %1}";
18715     default:
18716       abort ();
18717     }
18718 }
18719   [(set_attr "type" "ssemov")
18720    (set (attr "mode")
18721         (cond [(eq_attr "alternative" "0,1")
18722                  (if_then_else
18723                    (ne (symbol_ref "optimize_size")
18724                        (const_int 0))
18725                    (const_string "V4SF")
18726                    (const_string "TI"))
18727                (eq_attr "alternative" "2")
18728                  (if_then_else
18729                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18730                             (const_int 0))
18731                         (ne (symbol_ref "optimize_size")
18732                             (const_int 0)))
18733                    (const_string "V4SF")
18734                    (const_string "TI"))]
18735                (const_string "TI")))])
18736
18737 (define_expand "movv2df"
18738   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18739         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18740   "TARGET_SSE2"
18741 {
18742   ix86_expand_vector_move (V2DFmode, operands);
18743   DONE;
18744 })
18745
18746 (define_expand "movv8hi"
18747   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18748         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18749   "TARGET_SSE2"
18750 {
18751   ix86_expand_vector_move (V8HImode, operands);
18752   DONE;
18753 })
18754
18755 (define_expand "movv16qi"
18756   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18757         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18758   "TARGET_SSE2"
18759 {
18760   ix86_expand_vector_move (V16QImode, operands);
18761   DONE;
18762 })
18763
18764 (define_expand "movv4sf"
18765   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18766         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18767   "TARGET_SSE"
18768 {
18769   ix86_expand_vector_move (V4SFmode, operands);
18770   DONE;
18771 })
18772
18773 (define_expand "movv4si"
18774   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18775         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18776   "TARGET_SSE"
18777 {
18778   ix86_expand_vector_move (V4SImode, operands);
18779   DONE;
18780 })
18781
18782 (define_expand "movv2di"
18783   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18784         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18785   "TARGET_SSE"
18786 {
18787   ix86_expand_vector_move (V2DImode, operands);
18788   DONE;
18789 })
18790
18791 (define_expand "movv2si"
18792   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18793         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18794   "TARGET_MMX"
18795 {
18796   ix86_expand_vector_move (V2SImode, operands);
18797   DONE;
18798 })
18799
18800 (define_expand "movv4hi"
18801   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18802         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18803   "TARGET_MMX"
18804 {
18805   ix86_expand_vector_move (V4HImode, operands);
18806   DONE;
18807 })
18808
18809 (define_expand "movv8qi"
18810   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18811         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18812   "TARGET_MMX"
18813 {
18814   ix86_expand_vector_move (V8QImode, operands);
18815   DONE;
18816 })
18817
18818 (define_expand "movv2sf"
18819   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18820         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18821    "TARGET_3DNOW"
18822 {
18823   ix86_expand_vector_move (V2SFmode, operands);
18824   DONE;
18825 })
18826
18827 (define_insn "*pushti"
18828   [(set (match_operand:TI 0 "push_operand" "=<")
18829         (match_operand:TI 1 "register_operand" "x"))]
18830   "TARGET_SSE"
18831   "#")
18832
18833 (define_insn "*pushv2df"
18834   [(set (match_operand:V2DF 0 "push_operand" "=<")
18835         (match_operand:V2DF 1 "register_operand" "x"))]
18836   "TARGET_SSE"
18837   "#")
18838
18839 (define_insn "*pushv2di"
18840   [(set (match_operand:V2DI 0 "push_operand" "=<")
18841         (match_operand:V2DI 1 "register_operand" "x"))]
18842   "TARGET_SSE2"
18843   "#")
18844
18845 (define_insn "*pushv8hi"
18846   [(set (match_operand:V8HI 0 "push_operand" "=<")
18847         (match_operand:V8HI 1 "register_operand" "x"))]
18848   "TARGET_SSE2"
18849   "#")
18850
18851 (define_insn "*pushv16qi"
18852   [(set (match_operand:V16QI 0 "push_operand" "=<")
18853         (match_operand:V16QI 1 "register_operand" "x"))]
18854   "TARGET_SSE2"
18855   "#")
18856
18857 (define_insn "*pushv4sf"
18858   [(set (match_operand:V4SF 0 "push_operand" "=<")
18859         (match_operand:V4SF 1 "register_operand" "x"))]
18860   "TARGET_SSE"
18861   "#")
18862
18863 (define_insn "*pushv4si"
18864   [(set (match_operand:V4SI 0 "push_operand" "=<")
18865         (match_operand:V4SI 1 "register_operand" "x"))]
18866   "TARGET_SSE2"
18867   "#")
18868
18869 (define_insn "*pushv2si"
18870   [(set (match_operand:V2SI 0 "push_operand" "=<")
18871         (match_operand:V2SI 1 "register_operand" "y"))]
18872   "TARGET_MMX"
18873   "#")
18874
18875 (define_insn "*pushv4hi"
18876   [(set (match_operand:V4HI 0 "push_operand" "=<")
18877         (match_operand:V4HI 1 "register_operand" "y"))]
18878   "TARGET_MMX"
18879   "#")
18880
18881 (define_insn "*pushv8qi"
18882   [(set (match_operand:V8QI 0 "push_operand" "=<")
18883         (match_operand:V8QI 1 "register_operand" "y"))]
18884   "TARGET_MMX"
18885   "#")
18886
18887 (define_insn "*pushv2sf"
18888   [(set (match_operand:V2SF 0 "push_operand" "=<")
18889         (match_operand:V2SF 1 "register_operand" "y"))]
18890   "TARGET_3DNOW"
18891   "#")
18892
18893 (define_split
18894   [(set (match_operand 0 "push_operand" "")
18895         (match_operand 1 "register_operand" ""))]
18896   "!TARGET_64BIT && reload_completed
18897    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18898   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18899    (set (match_dup 2) (match_dup 1))]
18900   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18901                                  stack_pointer_rtx);
18902    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18903
18904 (define_split
18905   [(set (match_operand 0 "push_operand" "")
18906         (match_operand 1 "register_operand" ""))]
18907   "TARGET_64BIT && reload_completed
18908    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18909   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18910    (set (match_dup 2) (match_dup 1))]
18911   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18912                                  stack_pointer_rtx);
18913    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18914
18915
18916 (define_insn "movti_internal"
18917   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18918         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18919   "TARGET_SSE && !TARGET_64BIT
18920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18921 {
18922   switch (which_alternative)
18923     {
18924     case 0:
18925       if (get_attr_mode (insn) == MODE_V4SF)
18926         return "xorps\t%0, %0";
18927       else
18928         return "pxor\t%0, %0";
18929     case 1:
18930     case 2:
18931       if (get_attr_mode (insn) == MODE_V4SF)
18932         return "movaps\t{%1, %0|%0, %1}";
18933       else
18934         return "movdqa\t{%1, %0|%0, %1}";
18935     default:
18936       abort ();
18937     }
18938 }
18939   [(set_attr "type" "ssemov,ssemov,ssemov")
18940    (set (attr "mode")
18941         (cond [(eq_attr "alternative" "0,1")
18942                  (if_then_else
18943                    (ne (symbol_ref "optimize_size")
18944                        (const_int 0))
18945                    (const_string "V4SF")
18946                    (const_string "TI"))
18947                (eq_attr "alternative" "2")
18948                  (if_then_else
18949                    (ne (symbol_ref "optimize_size")
18950                        (const_int 0))
18951                    (const_string "V4SF")
18952                    (const_string "TI"))]
18953                (const_string "TI")))])
18954
18955 (define_insn "*movti_rex64"
18956   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18957         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
18958   "TARGET_64BIT
18959    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18960 {
18961   switch (which_alternative)
18962     {
18963     case 0:
18964     case 1:
18965       return "#";
18966     case 2:
18967       if (get_attr_mode (insn) == MODE_V4SF)
18968         return "xorps\t%0, %0";
18969       else
18970         return "pxor\t%0, %0";
18971     case 3:
18972     case 4:
18973       if (get_attr_mode (insn) == MODE_V4SF)
18974         return "movaps\t{%1, %0|%0, %1}";
18975       else
18976         return "movdqa\t{%1, %0|%0, %1}";
18977     default:
18978       abort ();
18979     }
18980 }
18981   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18982    (set (attr "mode")
18983         (cond [(eq_attr "alternative" "2,3")
18984                  (if_then_else
18985                    (ne (symbol_ref "optimize_size")
18986                        (const_int 0))
18987                    (const_string "V4SF")
18988                    (const_string "TI"))
18989                (eq_attr "alternative" "4")
18990                  (if_then_else
18991                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18992                             (const_int 0))
18993                         (ne (symbol_ref "optimize_size")
18994                             (const_int 0)))
18995                    (const_string "V4SF")
18996                    (const_string "TI"))]
18997                (const_string "DI")))])
18998
18999 (define_insn "*movtf_rex64"
19000   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19001         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19002   "TARGET_64BIT
19003    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19004 {
19005   switch (which_alternative)
19006     {
19007     case 0:
19008     case 1:
19009       return "#";
19010     case 2:
19011       if (get_attr_mode (insn) == MODE_V4SF)
19012         return "xorps\t%0, %0";
19013       else
19014         return "pxor\t%0, %0";
19015     case 3:
19016     case 4:
19017       if (get_attr_mode (insn) == MODE_V4SF)
19018         return "movaps\t{%1, %0|%0, %1}";
19019       else
19020         return "movdqa\t{%1, %0|%0, %1}";
19021     default:
19022       abort ();
19023     }
19024 }
19025   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19026    (set (attr "mode")
19027         (cond [(eq_attr "alternative" "2,3")
19028                  (if_then_else
19029                    (ne (symbol_ref "optimize_size")
19030                        (const_int 0))
19031                    (const_string "V4SF")
19032                    (const_string "TI"))
19033                (eq_attr "alternative" "4")
19034                  (if_then_else
19035                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19036                             (const_int 0))
19037                         (ne (symbol_ref "optimize_size")
19038                             (const_int 0)))
19039                    (const_string "V4SF")
19040                    (const_string "TI"))]
19041                (const_string "DI")))])
19042
19043 (define_split
19044   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19045         (match_operand:TI 1 "general_operand" ""))]
19046   "reload_completed && !SSE_REG_P (operands[0])
19047    && !SSE_REG_P (operands[1])"
19048   [(const_int 0)]
19049   "ix86_split_long_move (operands); DONE;")
19050
19051 (define_split
19052   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19053         (match_operand:TF 1 "general_operand" ""))]
19054   "reload_completed && !SSE_REG_P (operands[0])
19055    && !SSE_REG_P (operands[1])"
19056   [(const_int 0)]
19057   "ix86_split_long_move (operands); DONE;")
19058
19059 ;; These two patterns are useful for specifying exactly whether to use
19060 ;; movaps or movups
19061 (define_expand "sse_movaps"
19062   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19063         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19064                      UNSPEC_MOVA))]
19065   "TARGET_SSE"
19066 {
19067   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19068     {
19069       rtx tmp = gen_reg_rtx (V4SFmode);
19070       emit_insn (gen_sse_movaps (tmp, operands[1]));
19071       emit_move_insn (operands[0], tmp);
19072       DONE;
19073     }
19074 })
19075
19076 (define_insn "*sse_movaps_1"
19077   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19078         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19079                      UNSPEC_MOVA))]
19080   "TARGET_SSE
19081    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19082   "movaps\t{%1, %0|%0, %1}"
19083   [(set_attr "type" "ssemov,ssemov")
19084    (set_attr "mode" "V4SF")])
19085
19086 (define_expand "sse_movups"
19087   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19088         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19089                      UNSPEC_MOVU))]
19090   "TARGET_SSE"
19091 {
19092   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19093     {
19094       rtx tmp = gen_reg_rtx (V4SFmode);
19095       emit_insn (gen_sse_movups (tmp, operands[1]));
19096       emit_move_insn (operands[0], tmp);
19097       DONE;
19098     }
19099 })
19100
19101 (define_insn "*sse_movups_1"
19102   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19103         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19104                      UNSPEC_MOVU))]
19105   "TARGET_SSE
19106    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19107   "movups\t{%1, %0|%0, %1}"
19108   [(set_attr "type" "ssecvt,ssecvt")
19109    (set_attr "mode" "V4SF")])
19110
19111 ;; SSE Strange Moves.
19112
19113 (define_insn "sse_movmskps"
19114   [(set (match_operand:SI 0 "register_operand" "=r")
19115         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19116                    UNSPEC_MOVMSK))]
19117   "TARGET_SSE"
19118   "movmskps\t{%1, %0|%0, %1}"
19119   [(set_attr "type" "ssecvt")
19120    (set_attr "mode" "V4SF")])
19121
19122 (define_insn "mmx_pmovmskb"
19123   [(set (match_operand:SI 0 "register_operand" "=r")
19124         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19125                    UNSPEC_MOVMSK))]
19126   "TARGET_SSE || TARGET_3DNOW_A"
19127   "pmovmskb\t{%1, %0|%0, %1}"
19128   [(set_attr "type" "ssecvt")
19129    (set_attr "mode" "V4SF")])
19130
19131
19132 (define_insn "mmx_maskmovq"
19133   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19134         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19135                       (match_operand:V8QI 2 "register_operand" "y")]
19136                      UNSPEC_MASKMOV))]
19137   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19138   ;; @@@ check ordering of operands in intel/nonintel syntax
19139   "maskmovq\t{%2, %1|%1, %2}"
19140   [(set_attr "type" "mmxcvt")
19141    (set_attr "mode" "DI")])
19142
19143 (define_insn "mmx_maskmovq_rex"
19144   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19145         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19146                       (match_operand:V8QI 2 "register_operand" "y")]
19147                      UNSPEC_MASKMOV))]
19148   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19149   ;; @@@ check ordering of operands in intel/nonintel syntax
19150   "maskmovq\t{%2, %1|%1, %2}"
19151   [(set_attr "type" "mmxcvt")
19152    (set_attr "mode" "DI")])
19153
19154 (define_insn "sse_movntv4sf"
19155   [(set (match_operand:V4SF 0 "memory_operand" "=m")
19156         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19157                      UNSPEC_MOVNT))]
19158   "TARGET_SSE"
19159   "movntps\t{%1, %0|%0, %1}"
19160   [(set_attr "type" "ssemov")
19161    (set_attr "mode" "V4SF")])
19162
19163 (define_insn "sse_movntdi"
19164   [(set (match_operand:DI 0 "memory_operand" "=m")
19165         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19166                    UNSPEC_MOVNT))]
19167   "TARGET_SSE || TARGET_3DNOW_A"
19168   "movntq\t{%1, %0|%0, %1}"
19169   [(set_attr "type" "mmxmov")
19170    (set_attr "mode" "DI")])
19171
19172 (define_insn "sse_movhlps"
19173   [(set (match_operand:V4SF 0 "register_operand" "=x")
19174         (vec_merge:V4SF
19175          (match_operand:V4SF 1 "register_operand" "0")
19176          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19177                           (parallel [(const_int 2)
19178                                      (const_int 3)
19179                                      (const_int 0)
19180                                      (const_int 1)]))
19181          (const_int 3)))]
19182   "TARGET_SSE"
19183   "movhlps\t{%2, %0|%0, %2}"
19184   [(set_attr "type" "ssecvt")
19185    (set_attr "mode" "V4SF")])
19186
19187 (define_insn "sse_movlhps"
19188   [(set (match_operand:V4SF 0 "register_operand" "=x")
19189         (vec_merge:V4SF
19190          (match_operand:V4SF 1 "register_operand" "0")
19191          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19192                           (parallel [(const_int 2)
19193                                      (const_int 3)
19194                                      (const_int 0)
19195                                      (const_int 1)]))
19196          (const_int 12)))]
19197   "TARGET_SSE"
19198   "movlhps\t{%2, %0|%0, %2}"
19199   [(set_attr "type" "ssecvt")
19200    (set_attr "mode" "V4SF")])
19201
19202 (define_insn "sse_movhps"
19203   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19204         (vec_merge:V4SF
19205          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19206          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19207          (const_int 12)))]
19208   "TARGET_SSE
19209    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19210   "movhps\t{%2, %0|%0, %2}"
19211   [(set_attr "type" "ssecvt")
19212    (set_attr "mode" "V4SF")])
19213
19214 (define_insn "sse_movlps"
19215   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19216         (vec_merge:V4SF
19217          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19218          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19219          (const_int 3)))]
19220   "TARGET_SSE
19221    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19222   "movlps\t{%2, %0|%0, %2}"
19223   [(set_attr "type" "ssecvt")
19224    (set_attr "mode" "V4SF")])
19225
19226 (define_expand "sse_loadss"
19227   [(match_operand:V4SF 0 "register_operand" "")
19228    (match_operand:SF 1 "memory_operand" "")]
19229   "TARGET_SSE"
19230 {
19231   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19232                                CONST0_RTX (V4SFmode)));
19233   DONE;
19234 })
19235
19236 (define_insn "sse_loadss_1"
19237   [(set (match_operand:V4SF 0 "register_operand" "=x")
19238         (vec_merge:V4SF
19239          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19240          (match_operand:V4SF 2 "const0_operand" "X")
19241          (const_int 1)))]
19242   "TARGET_SSE"
19243   "movss\t{%1, %0|%0, %1}"
19244   [(set_attr "type" "ssemov")
19245    (set_attr "mode" "SF")])
19246
19247 (define_insn "sse_movss"
19248   [(set (match_operand:V4SF 0 "register_operand" "=x")
19249         (vec_merge:V4SF
19250          (match_operand:V4SF 1 "register_operand" "0")
19251          (match_operand:V4SF 2 "register_operand" "x")
19252          (const_int 1)))]
19253   "TARGET_SSE"
19254   "movss\t{%2, %0|%0, %2}"
19255   [(set_attr "type" "ssemov")
19256    (set_attr "mode" "SF")])
19257
19258 (define_insn "sse_storess"
19259   [(set (match_operand:SF 0 "memory_operand" "=m")
19260         (vec_select:SF
19261          (match_operand:V4SF 1 "register_operand" "x")
19262          (parallel [(const_int 0)])))]
19263   "TARGET_SSE"
19264   "movss\t{%1, %0|%0, %1}"
19265   [(set_attr "type" "ssemov")
19266    (set_attr "mode" "SF")])
19267
19268 (define_insn "sse_shufps"
19269   [(set (match_operand:V4SF 0 "register_operand" "=x")
19270         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19271                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19272                       (match_operand:SI 3 "immediate_operand" "i")]
19273                      UNSPEC_SHUFFLE))]
19274   "TARGET_SSE"
19275   ;; @@@ check operand order for intel/nonintel syntax
19276   "shufps\t{%3, %2, %0|%0, %2, %3}"
19277   [(set_attr "type" "ssecvt")
19278    (set_attr "mode" "V4SF")])
19279
19280
19281 ;; SSE arithmetic
19282
19283 (define_insn "addv4sf3"
19284   [(set (match_operand:V4SF 0 "register_operand" "=x")
19285         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19286                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19287   "TARGET_SSE"
19288   "addps\t{%2, %0|%0, %2}"
19289   [(set_attr "type" "sseadd")
19290    (set_attr "mode" "V4SF")])
19291
19292 (define_insn "vmaddv4sf3"
19293   [(set (match_operand:V4SF 0 "register_operand" "=x")
19294         (vec_merge:V4SF
19295          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19296                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19297          (match_dup 1)
19298          (const_int 1)))]
19299   "TARGET_SSE"
19300   "addss\t{%2, %0|%0, %2}"
19301   [(set_attr "type" "sseadd")
19302    (set_attr "mode" "SF")])
19303
19304 (define_insn "subv4sf3"
19305   [(set (match_operand:V4SF 0 "register_operand" "=x")
19306         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19307                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19308   "TARGET_SSE"
19309   "subps\t{%2, %0|%0, %2}"
19310   [(set_attr "type" "sseadd")
19311    (set_attr "mode" "V4SF")])
19312
19313 (define_insn "vmsubv4sf3"
19314   [(set (match_operand:V4SF 0 "register_operand" "=x")
19315         (vec_merge:V4SF
19316          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19317                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19318          (match_dup 1)
19319          (const_int 1)))]
19320   "TARGET_SSE"
19321   "subss\t{%2, %0|%0, %2}"
19322   [(set_attr "type" "sseadd")
19323    (set_attr "mode" "SF")])
19324
19325 (define_insn "mulv4sf3"
19326   [(set (match_operand:V4SF 0 "register_operand" "=x")
19327         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19328                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19329   "TARGET_SSE"
19330   "mulps\t{%2, %0|%0, %2}"
19331   [(set_attr "type" "ssemul")
19332    (set_attr "mode" "V4SF")])
19333
19334 (define_insn "vmmulv4sf3"
19335   [(set (match_operand:V4SF 0 "register_operand" "=x")
19336         (vec_merge:V4SF
19337          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19338                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19339          (match_dup 1)
19340          (const_int 1)))]
19341   "TARGET_SSE"
19342   "mulss\t{%2, %0|%0, %2}"
19343   [(set_attr "type" "ssemul")
19344    (set_attr "mode" "SF")])
19345
19346 (define_insn "divv4sf3"
19347   [(set (match_operand:V4SF 0 "register_operand" "=x")
19348         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19349                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19350   "TARGET_SSE"
19351   "divps\t{%2, %0|%0, %2}"
19352   [(set_attr "type" "ssediv")
19353    (set_attr "mode" "V4SF")])
19354
19355 (define_insn "vmdivv4sf3"
19356   [(set (match_operand:V4SF 0 "register_operand" "=x")
19357         (vec_merge:V4SF
19358          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19359                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19360          (match_dup 1)
19361          (const_int 1)))]
19362   "TARGET_SSE"
19363   "divss\t{%2, %0|%0, %2}"
19364   [(set_attr "type" "ssediv")
19365    (set_attr "mode" "SF")])
19366
19367
19368 ;; SSE square root/reciprocal
19369
19370 (define_insn "rcpv4sf2"
19371   [(set (match_operand:V4SF 0 "register_operand" "=x")
19372         (unspec:V4SF
19373          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19374   "TARGET_SSE"
19375   "rcpps\t{%1, %0|%0, %1}"
19376   [(set_attr "type" "sse")
19377    (set_attr "mode" "V4SF")])
19378
19379 (define_insn "vmrcpv4sf2"
19380   [(set (match_operand:V4SF 0 "register_operand" "=x")
19381         (vec_merge:V4SF
19382          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19383                       UNSPEC_RCP)
19384          (match_operand:V4SF 2 "register_operand" "0")
19385          (const_int 1)))]
19386   "TARGET_SSE"
19387   "rcpss\t{%1, %0|%0, %1}"
19388   [(set_attr "type" "sse")
19389    (set_attr "mode" "SF")])
19390
19391 (define_insn "rsqrtv4sf2"
19392   [(set (match_operand:V4SF 0 "register_operand" "=x")
19393         (unspec:V4SF
19394          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19395   "TARGET_SSE"
19396   "rsqrtps\t{%1, %0|%0, %1}"
19397   [(set_attr "type" "sse")
19398    (set_attr "mode" "V4SF")])
19399
19400 (define_insn "vmrsqrtv4sf2"
19401   [(set (match_operand:V4SF 0 "register_operand" "=x")
19402         (vec_merge:V4SF
19403          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19404                       UNSPEC_RSQRT)
19405          (match_operand:V4SF 2 "register_operand" "0")
19406          (const_int 1)))]
19407   "TARGET_SSE"
19408   "rsqrtss\t{%1, %0|%0, %1}"
19409   [(set_attr "type" "sse")
19410    (set_attr "mode" "SF")])
19411
19412 (define_insn "sqrtv4sf2"
19413   [(set (match_operand:V4SF 0 "register_operand" "=x")
19414         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19415   "TARGET_SSE"
19416   "sqrtps\t{%1, %0|%0, %1}"
19417   [(set_attr "type" "sse")
19418    (set_attr "mode" "V4SF")])
19419
19420 (define_insn "vmsqrtv4sf2"
19421   [(set (match_operand:V4SF 0 "register_operand" "=x")
19422         (vec_merge:V4SF
19423          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19424          (match_operand:V4SF 2 "register_operand" "0")
19425          (const_int 1)))]
19426   "TARGET_SSE"
19427   "sqrtss\t{%1, %0|%0, %1}"
19428   [(set_attr "type" "sse")
19429    (set_attr "mode" "SF")])
19430
19431 ;; SSE logical operations.
19432
19433 ;; SSE defines logical operations on floating point values.  This brings
19434 ;; interesting challenge to RTL representation where logicals are only valid
19435 ;; on integral types.  We deal with this by representing the floating point
19436 ;; logical as logical on arguments casted to TImode as this is what hardware
19437 ;; really does.  Unfortunately hardware requires the type information to be
19438 ;; present and thus we must avoid subregs from being simplified and eliminated
19439 ;; in later compilation phases.
19440 ;;
19441 ;; We have following variants from each instruction:
19442 ;; sse_andsf3 - the operation taking V4SF vector operands
19443 ;;              and doing TImode cast on them
19444 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19445 ;;                      TImode, since backend insist on eliminating casts
19446 ;;                      on memory operands
19447 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19448 ;;                   We can not accept memory operand here as instruction reads
19449 ;;                   whole scalar.  This is generated only post reload by GCC
19450 ;;                   scalar float operations that expands to logicals (fabs)
19451 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19452 ;;                   memory operand.  Eventually combine can be able
19453 ;;                   to synthesize these using splitter.
19454 ;; sse2_anddf3, *sse2_anddf3_memory
19455 ;;              
19456 ;; 
19457 ;; These are not called andti3 etc. because we really really don't want
19458 ;; the compiler to widen DImode ands to TImode ands and then try to move
19459 ;; into DImode subregs of SSE registers, and them together, and move out
19460 ;; of DImode subregs again!
19461 ;; SSE1 single precision floating point logical operation
19462 (define_expand "sse_andv4sf3"
19463   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19464         (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19465                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19466   "TARGET_SSE"
19467   "")
19468
19469 (define_insn "*sse_andv4sf3"
19470   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19471         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19472                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19473   "TARGET_SSE
19474    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19475   "andps\t{%2, %0|%0, %2}"
19476   [(set_attr "type" "sselog")
19477    (set_attr "mode" "V4SF")])
19478
19479 (define_insn "*sse_andsf3"
19480   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19481         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19482                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19483   "TARGET_SSE
19484    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19485   "andps\t{%2, %0|%0, %2}"
19486   [(set_attr "type" "sselog")
19487    (set_attr "mode" "V4SF")])
19488
19489 (define_expand "sse_nandv4sf3"
19490   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19491         (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19492                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19493   "TARGET_SSE"
19494   "")
19495
19496 (define_insn "*sse_nandv4sf3"
19497   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19498         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19499                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19500   "TARGET_SSE"
19501   "andnps\t{%2, %0|%0, %2}"
19502   [(set_attr "type" "sselog")
19503    (set_attr "mode" "V4SF")])
19504
19505 (define_insn "*sse_nandsf3"
19506   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19507         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19508                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19509   "TARGET_SSE"
19510   "andnps\t{%2, %0|%0, %2}"
19511   [(set_attr "type" "sselog")
19512    (set_attr "mode" "V4SF")])
19513
19514 (define_expand "sse_iorv4sf3"
19515   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19516         (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19517                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19518   "TARGET_SSE"
19519   "")
19520
19521 (define_insn "*sse_iorv4sf3"
19522   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19523         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19524                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19525   "TARGET_SSE
19526    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19527   "orps\t{%2, %0|%0, %2}"
19528   [(set_attr "type" "sselog")
19529    (set_attr "mode" "V4SF")])
19530
19531 (define_insn "*sse_iorsf3"
19532   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19533         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19534                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19535   "TARGET_SSE
19536    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19537   "orps\t{%2, %0|%0, %2}"
19538   [(set_attr "type" "sselog")
19539    (set_attr "mode" "V4SF")])
19540
19541 (define_expand "sse_xorv4sf3"
19542   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19543         (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19544                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19545   "TARGET_SSE
19546    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19547   "")
19548
19549 (define_insn "*sse_xorv4sf3"
19550   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19551         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19552                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19553   "TARGET_SSE
19554    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19555   "xorps\t{%2, %0|%0, %2}"
19556   [(set_attr "type" "sselog")
19557    (set_attr "mode" "V4SF")])
19558
19559 (define_insn "*sse_xorsf3"
19560   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19561         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19562                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19563   "TARGET_SSE
19564    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19565   "xorps\t{%2, %0|%0, %2}"
19566   [(set_attr "type" "sselog")
19567    (set_attr "mode" "V4SF")])
19568
19569 ;; SSE2 double precision floating point logical operation
19570
19571 (define_expand "sse2_andv2df3"
19572   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19573         (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19574                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19575   "TARGET_SSE2"
19576   "")
19577
19578 (define_insn "*sse2_andv2df3"
19579   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19580         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19581                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19582   "TARGET_SSE2
19583    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19584   "andpd\t{%2, %0|%0, %2}"
19585   [(set_attr "type" "sselog")
19586    (set_attr "mode" "V2DF")])
19587
19588 (define_insn "*sse2_andv2df3"
19589   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19590         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19591                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19592   "TARGET_SSE2
19593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19594   "andpd\t{%2, %0|%0, %2}"
19595   [(set_attr "type" "sselog")
19596    (set_attr "mode" "V2DF")])
19597
19598 (define_expand "sse2_nandv2df3"
19599   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19600         (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19601                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19602   "TARGET_SSE2"
19603   "")
19604
19605 (define_insn "*sse2_nandv2df3"
19606   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19607         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19608                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19609   "TARGET_SSE2"
19610   "andnpd\t{%2, %0|%0, %2}"
19611   [(set_attr "type" "sselog")
19612    (set_attr "mode" "V2DF")])
19613
19614 (define_insn "*sse_nandti3_df"
19615   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19616         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19617                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19618   "TARGET_SSE2"
19619   "andnpd\t{%2, %0|%0, %2}"
19620   [(set_attr "type" "sselog")
19621    (set_attr "mode" "V2DF")])
19622
19623 (define_expand "sse2_iorv2df3"
19624   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19625         (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19626                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19627   "TARGET_SSE2"
19628   "")
19629
19630 (define_insn "*sse2_iorv2df3"
19631   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19632         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19633                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19634   "TARGET_SSE2
19635    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19636   "orpd\t{%2, %0|%0, %2}"
19637   [(set_attr "type" "sselog")
19638    (set_attr "mode" "V2DF")])
19639
19640 (define_insn "*sse2_iordf3"
19641   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19642         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19643                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19644   "TARGET_SSE2
19645    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19646   "orpd\t{%2, %0|%0, %2}"
19647   [(set_attr "type" "sselog")
19648    (set_attr "mode" "V2DF")])
19649
19650 (define_expand "sse2_xorv2df3"
19651   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19652         (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19653                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19654   "TARGET_SSE2"
19655   "")
19656
19657 (define_insn "*sse2_xorv2df3"
19658   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19659         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19660                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19661   "TARGET_SSE2
19662    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19663   "xorpd\t{%2, %0|%0, %2}"
19664   [(set_attr "type" "sselog")
19665    (set_attr "mode" "V2DF")])
19666
19667 (define_insn "*sse2_xordf3"
19668   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19669         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19670                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19671   "TARGET_SSE2
19672    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19673   "xorpd\t{%2, %0|%0, %2}"
19674   [(set_attr "type" "sselog")
19675    (set_attr "mode" "V2DF")])
19676
19677 ;; SSE2 integral logicals.  These patterns must always come after floating
19678 ;; point ones since we don't want compiler to use integer opcodes on floating
19679 ;; point SSE values to avoid matching of subregs in the match_operand.
19680 (define_insn "*sse2_andti3"
19681   [(set (match_operand:TI 0 "register_operand" "=x")
19682         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19683                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19684   "TARGET_SSE2
19685    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19686   "pand\t{%2, %0|%0, %2}"
19687   [(set_attr "type" "sselog")
19688    (set_attr "mode" "TI")])
19689
19690 (define_insn "sse2_andv2di3"
19691   [(set (match_operand:V2DI 0 "register_operand" "=x")
19692         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19693                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19694   "TARGET_SSE2
19695    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19696   "pand\t{%2, %0|%0, %2}"
19697   [(set_attr "type" "sselog")
19698    (set_attr "mode" "TI")])
19699
19700 (define_insn "*sse2_nandti3"
19701   [(set (match_operand:TI 0 "register_operand" "=x")
19702         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19703                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19704   "TARGET_SSE2"
19705   "pandn\t{%2, %0|%0, %2}"
19706   [(set_attr "type" "sselog")
19707    (set_attr "mode" "TI")])
19708
19709 (define_insn "sse2_nandv2di3"
19710   [(set (match_operand:V2DI 0 "register_operand" "=x")
19711         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19712                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19713   "TARGET_SSE2
19714    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19715   "pandn\t{%2, %0|%0, %2}"
19716   [(set_attr "type" "sselog")
19717    (set_attr "mode" "TI")])
19718
19719 (define_insn "*sse2_iorti3"
19720   [(set (match_operand:TI 0 "register_operand" "=x")
19721         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19722                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19723   "TARGET_SSE2
19724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19725   "por\t{%2, %0|%0, %2}"
19726   [(set_attr "type" "sselog")
19727    (set_attr "mode" "TI")])
19728
19729 (define_insn "sse2_iorv2di3"
19730   [(set (match_operand:V2DI 0 "register_operand" "=x")
19731         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19732                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19733   "TARGET_SSE2
19734    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19735   "por\t{%2, %0|%0, %2}"
19736   [(set_attr "type" "sselog")
19737    (set_attr "mode" "TI")])
19738
19739 (define_insn "*sse2_xorti3"
19740   [(set (match_operand:TI 0 "register_operand" "=x")
19741         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19742                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19743   "TARGET_SSE2
19744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19745   "pxor\t{%2, %0|%0, %2}"
19746   [(set_attr "type" "sselog")
19747    (set_attr "mode" "TI")])
19748
19749 (define_insn "sse2_xorv2di3"
19750   [(set (match_operand:V2DI 0 "register_operand" "=x")
19751         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19752                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19753   "TARGET_SSE2
19754    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19755   "pxor\t{%2, %0|%0, %2}"
19756   [(set_attr "type" "sselog")
19757    (set_attr "mode" "TI")])
19758
19759 ;; Use xor, but don't show input operands so they aren't live before
19760 ;; this insn.
19761 (define_insn "sse_clrv4sf"
19762   [(set (match_operand:V4SF 0 "register_operand" "=x")
19763         (match_operand:V4SF 1 "const0_operand" "X"))]
19764   "TARGET_SSE"
19765 {
19766   if (get_attr_mode (insn) == MODE_TI)
19767     return "pxor\t{%0, %0|%0, %0}";
19768   else
19769     return "xorps\t{%0, %0|%0, %0}";
19770 }
19771   [(set_attr "type" "sselog")
19772    (set_attr "memory" "none")
19773    (set (attr "mode")
19774         (if_then_else
19775            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19776                          (const_int 0))
19777                      (ne (symbol_ref "TARGET_SSE2")
19778                          (const_int 0)))
19779                 (eq (symbol_ref "optimize_size")
19780                     (const_int 0)))
19781          (const_string "TI")
19782          (const_string "V4SF")))])
19783
19784 ;; Use xor, but don't show input operands so they aren't live before
19785 ;; this insn.
19786 (define_insn "sse_clrv2df"
19787   [(set (match_operand:V2DF 0 "register_operand" "=x")
19788         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19789   "TARGET_SSE2"
19790   "xorpd\t{%0, %0|%0, %0}"
19791   [(set_attr "type" "sselog")
19792    (set_attr "memory" "none")
19793    (set_attr "mode" "V4SF")])
19794
19795 ;; SSE mask-generating compares
19796
19797 (define_insn "maskcmpv4sf3"
19798   [(set (match_operand:V4SI 0 "register_operand" "=x")
19799         (match_operator:V4SI 3 "sse_comparison_operator"
19800                 [(match_operand:V4SF 1 "register_operand" "0")
19801                  (match_operand:V4SF 2 "register_operand" "x")]))]
19802   "TARGET_SSE"
19803   "cmp%D3ps\t{%2, %0|%0, %2}"
19804   [(set_attr "type" "ssecmp")
19805    (set_attr "mode" "V4SF")])
19806
19807 (define_insn "maskncmpv4sf3"
19808   [(set (match_operand:V4SI 0 "register_operand" "=x")
19809         (not:V4SI
19810          (match_operator:V4SI 3 "sse_comparison_operator"
19811                 [(match_operand:V4SF 1 "register_operand" "0")
19812                  (match_operand:V4SF 2 "register_operand" "x")])))]
19813   "TARGET_SSE"
19814 {
19815   if (GET_CODE (operands[3]) == UNORDERED)
19816     return "cmpordps\t{%2, %0|%0, %2}";
19817   else
19818     return "cmpn%D3ps\t{%2, %0|%0, %2}";
19819 }
19820   [(set_attr "type" "ssecmp")
19821    (set_attr "mode" "V4SF")])
19822
19823 (define_insn "vmmaskcmpv4sf3"
19824   [(set (match_operand:V4SI 0 "register_operand" "=x")
19825         (vec_merge:V4SI
19826          (match_operator:V4SI 3 "sse_comparison_operator"
19827                 [(match_operand:V4SF 1 "register_operand" "0")
19828                  (match_operand:V4SF 2 "register_operand" "x")])
19829          (subreg:V4SI (match_dup 1) 0)
19830          (const_int 1)))]
19831   "TARGET_SSE"
19832   "cmp%D3ss\t{%2, %0|%0, %2}"
19833   [(set_attr "type" "ssecmp")
19834    (set_attr "mode" "SF")])
19835
19836 (define_insn "vmmaskncmpv4sf3"
19837   [(set (match_operand:V4SI 0 "register_operand" "=x")
19838         (vec_merge:V4SI
19839          (not:V4SI
19840           (match_operator:V4SI 3 "sse_comparison_operator"
19841                 [(match_operand:V4SF 1 "register_operand" "0")
19842                  (match_operand:V4SF 2 "register_operand" "x")]))
19843          (subreg:V4SI (match_dup 1) 0)
19844          (const_int 1)))]
19845   "TARGET_SSE"
19846 {
19847   if (GET_CODE (operands[3]) == UNORDERED)
19848     return "cmpordss\t{%2, %0|%0, %2}";
19849   else
19850     return "cmpn%D3ss\t{%2, %0|%0, %2}";
19851 }
19852   [(set_attr "type" "ssecmp")
19853    (set_attr "mode" "SF")])
19854
19855 (define_insn "sse_comi"
19856   [(set (reg:CCFP 17)
19857         (compare:CCFP (vec_select:SF
19858                        (match_operand:V4SF 0 "register_operand" "x")
19859                        (parallel [(const_int 0)]))
19860                       (vec_select:SF
19861                        (match_operand:V4SF 1 "register_operand" "x")
19862                        (parallel [(const_int 0)]))))]
19863   "TARGET_SSE"
19864   "comiss\t{%1, %0|%0, %1}"
19865   [(set_attr "type" "ssecomi")
19866    (set_attr "mode" "SF")])
19867
19868 (define_insn "sse_ucomi"
19869   [(set (reg:CCFPU 17)
19870         (compare:CCFPU (vec_select:SF
19871                         (match_operand:V4SF 0 "register_operand" "x")
19872                         (parallel [(const_int 0)]))
19873                        (vec_select:SF
19874                         (match_operand:V4SF 1 "register_operand" "x")
19875                         (parallel [(const_int 0)]))))]
19876   "TARGET_SSE"
19877   "ucomiss\t{%1, %0|%0, %1}"
19878   [(set_attr "type" "ssecomi")
19879    (set_attr "mode" "SF")])
19880
19881
19882 ;; SSE unpack
19883
19884 (define_insn "sse_unpckhps"
19885   [(set (match_operand:V4SF 0 "register_operand" "=x")
19886         (vec_merge:V4SF
19887          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19888                           (parallel [(const_int 2)
19889                                      (const_int 0)
19890                                      (const_int 3)
19891                                      (const_int 1)]))
19892          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19893                           (parallel [(const_int 0)
19894                                      (const_int 2)
19895                                      (const_int 1)
19896                                      (const_int 3)]))
19897          (const_int 5)))]
19898   "TARGET_SSE"
19899   "unpckhps\t{%2, %0|%0, %2}"
19900   [(set_attr "type" "ssecvt")
19901    (set_attr "mode" "V4SF")])
19902
19903 (define_insn "sse_unpcklps"
19904   [(set (match_operand:V4SF 0 "register_operand" "=x")
19905         (vec_merge:V4SF
19906          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19907                           (parallel [(const_int 0)
19908                                      (const_int 2)
19909                                      (const_int 1)
19910                                      (const_int 3)]))
19911          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19912                           (parallel [(const_int 2)
19913                                      (const_int 0)
19914                                      (const_int 3)
19915                                      (const_int 1)]))
19916          (const_int 5)))]
19917   "TARGET_SSE"
19918   "unpcklps\t{%2, %0|%0, %2}"
19919   [(set_attr "type" "ssecvt")
19920    (set_attr "mode" "V4SF")])
19921
19922
19923 ;; SSE min/max
19924
19925 (define_insn "smaxv4sf3"
19926   [(set (match_operand:V4SF 0 "register_operand" "=x")
19927         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19928                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19929   "TARGET_SSE"
19930   "maxps\t{%2, %0|%0, %2}"
19931   [(set_attr "type" "sse")
19932    (set_attr "mode" "V4SF")])
19933
19934 (define_insn "vmsmaxv4sf3"
19935   [(set (match_operand:V4SF 0 "register_operand" "=x")
19936         (vec_merge:V4SF
19937          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19938                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19939          (match_dup 1)
19940          (const_int 1)))]
19941   "TARGET_SSE"
19942   "maxss\t{%2, %0|%0, %2}"
19943   [(set_attr "type" "sse")
19944    (set_attr "mode" "SF")])
19945
19946 (define_insn "sminv4sf3"
19947   [(set (match_operand:V4SF 0 "register_operand" "=x")
19948         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19949                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19950   "TARGET_SSE"
19951   "minps\t{%2, %0|%0, %2}"
19952   [(set_attr "type" "sse")
19953    (set_attr "mode" "V4SF")])
19954
19955 (define_insn "vmsminv4sf3"
19956   [(set (match_operand:V4SF 0 "register_operand" "=x")
19957         (vec_merge:V4SF
19958          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19959                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19960          (match_dup 1)
19961          (const_int 1)))]
19962   "TARGET_SSE"
19963   "minss\t{%2, %0|%0, %2}"
19964   [(set_attr "type" "sse")
19965    (set_attr "mode" "SF")])
19966
19967 ;; SSE <-> integer/MMX conversions
19968
19969 (define_insn "cvtpi2ps"
19970   [(set (match_operand:V4SF 0 "register_operand" "=x")
19971         (vec_merge:V4SF
19972          (match_operand:V4SF 1 "register_operand" "0")
19973          (vec_duplicate:V4SF
19974           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19975          (const_int 12)))]
19976   "TARGET_SSE"
19977   "cvtpi2ps\t{%2, %0|%0, %2}"
19978   [(set_attr "type" "ssecvt")
19979    (set_attr "mode" "V4SF")])
19980
19981 (define_insn "cvtps2pi"
19982   [(set (match_operand:V2SI 0 "register_operand" "=y")
19983         (vec_select:V2SI
19984          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19985          (parallel [(const_int 0) (const_int 1)])))]
19986   "TARGET_SSE"
19987   "cvtps2pi\t{%1, %0|%0, %1}"
19988   [(set_attr "type" "ssecvt")
19989    (set_attr "mode" "V4SF")])
19990
19991 (define_insn "cvttps2pi"
19992   [(set (match_operand:V2SI 0 "register_operand" "=y")
19993         (vec_select:V2SI
19994          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19995                       UNSPEC_FIX)
19996          (parallel [(const_int 0) (const_int 1)])))]
19997   "TARGET_SSE"
19998   "cvttps2pi\t{%1, %0|%0, %1}"
19999   [(set_attr "type" "ssecvt")
20000    (set_attr "mode" "SF")])
20001
20002 (define_insn "cvtsi2ss"
20003   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20004         (vec_merge:V4SF
20005          (match_operand:V4SF 1 "register_operand" "0,0")
20006          (vec_duplicate:V4SF
20007           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20008          (const_int 14)))]
20009   "TARGET_SSE"
20010   "cvtsi2ss\t{%2, %0|%0, %2}"
20011   [(set_attr "type" "sseicvt")
20012    (set_attr "athlon_decode" "vector,double")
20013    (set_attr "mode" "SF")])
20014
20015 (define_insn "cvtsi2ssq"
20016   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20017         (vec_merge:V4SF
20018          (match_operand:V4SF 1 "register_operand" "0,0")
20019          (vec_duplicate:V4SF
20020           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20021          (const_int 14)))]
20022   "TARGET_SSE && TARGET_64BIT"
20023   "cvtsi2ssq\t{%2, %0|%0, %2}"
20024   [(set_attr "type" "sseicvt")
20025    (set_attr "athlon_decode" "vector,double")
20026    (set_attr "mode" "SF")])
20027
20028 (define_insn "cvtss2si"
20029   [(set (match_operand:SI 0 "register_operand" "=r,r")
20030         (vec_select:SI
20031          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20032          (parallel [(const_int 0)])))]
20033   "TARGET_SSE"
20034   "cvtss2si\t{%1, %0|%0, %1}"
20035   [(set_attr "type" "sseicvt")
20036    (set_attr "athlon_decode" "double,vector")
20037    (set_attr "mode" "SI")])
20038
20039 (define_insn "cvtss2siq"
20040   [(set (match_operand:DI 0 "register_operand" "=r,r")
20041         (vec_select:DI
20042          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20043          (parallel [(const_int 0)])))]
20044   "TARGET_SSE"
20045   "cvtss2siq\t{%1, %0|%0, %1}"
20046   [(set_attr "type" "sseicvt")
20047    (set_attr "athlon_decode" "double,vector")
20048    (set_attr "mode" "DI")])
20049
20050 (define_insn "cvttss2si"
20051   [(set (match_operand:SI 0 "register_operand" "=r,r")
20052         (vec_select:SI
20053          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20054                       UNSPEC_FIX)
20055          (parallel [(const_int 0)])))]
20056   "TARGET_SSE"
20057   "cvttss2si\t{%1, %0|%0, %1}"
20058   [(set_attr "type" "sseicvt")
20059    (set_attr "mode" "SF")
20060    (set_attr "athlon_decode" "double,vector")])
20061
20062 (define_insn "cvttss2siq"
20063   [(set (match_operand:DI 0 "register_operand" "=r,r")
20064         (vec_select:DI
20065          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20066                       UNSPEC_FIX)
20067          (parallel [(const_int 0)])))]
20068   "TARGET_SSE && TARGET_64BIT"
20069   "cvttss2siq\t{%1, %0|%0, %1}"
20070   [(set_attr "type" "sseicvt")
20071    (set_attr "mode" "SF")
20072    (set_attr "athlon_decode" "double,vector")])
20073
20074
20075 ;; MMX insns
20076
20077 ;; MMX arithmetic
20078
20079 (define_insn "addv8qi3"
20080   [(set (match_operand:V8QI 0 "register_operand" "=y")
20081         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20082                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20083   "TARGET_MMX"
20084   "paddb\t{%2, %0|%0, %2}"
20085   [(set_attr "type" "mmxadd")
20086    (set_attr "mode" "DI")])
20087
20088 (define_insn "addv4hi3"
20089   [(set (match_operand:V4HI 0 "register_operand" "=y")
20090         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20091                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20092   "TARGET_MMX"
20093   "paddw\t{%2, %0|%0, %2}"
20094   [(set_attr "type" "mmxadd")
20095    (set_attr "mode" "DI")])
20096
20097 (define_insn "addv2si3"
20098   [(set (match_operand:V2SI 0 "register_operand" "=y")
20099         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20100                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20101   "TARGET_MMX"
20102   "paddd\t{%2, %0|%0, %2}"
20103   [(set_attr "type" "mmxadd")
20104    (set_attr "mode" "DI")])
20105
20106 (define_insn "mmx_adddi3"
20107   [(set (match_operand:DI 0 "register_operand" "=y")
20108         (unspec:DI
20109          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20110                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20111          UNSPEC_NOP))]
20112   "TARGET_MMX"
20113   "paddq\t{%2, %0|%0, %2}"
20114   [(set_attr "type" "mmxadd")
20115    (set_attr "mode" "DI")])
20116
20117 (define_insn "ssaddv8qi3"
20118   [(set (match_operand:V8QI 0 "register_operand" "=y")
20119         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20120                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20121   "TARGET_MMX"
20122   "paddsb\t{%2, %0|%0, %2}"
20123   [(set_attr "type" "mmxadd")
20124    (set_attr "mode" "DI")])
20125
20126 (define_insn "ssaddv4hi3"
20127   [(set (match_operand:V4HI 0 "register_operand" "=y")
20128         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20129                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20130   "TARGET_MMX"
20131   "paddsw\t{%2, %0|%0, %2}"
20132   [(set_attr "type" "mmxadd")
20133    (set_attr "mode" "DI")])
20134
20135 (define_insn "usaddv8qi3"
20136   [(set (match_operand:V8QI 0 "register_operand" "=y")
20137         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20138                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20139   "TARGET_MMX"
20140   "paddusb\t{%2, %0|%0, %2}"
20141   [(set_attr "type" "mmxadd")
20142    (set_attr "mode" "DI")])
20143
20144 (define_insn "usaddv4hi3"
20145   [(set (match_operand:V4HI 0 "register_operand" "=y")
20146         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20147                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20148   "TARGET_MMX"
20149   "paddusw\t{%2, %0|%0, %2}"
20150   [(set_attr "type" "mmxadd")
20151    (set_attr "mode" "DI")])
20152
20153 (define_insn "subv8qi3"
20154   [(set (match_operand:V8QI 0 "register_operand" "=y")
20155         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20156                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20157   "TARGET_MMX"
20158   "psubb\t{%2, %0|%0, %2}"
20159   [(set_attr "type" "mmxadd")
20160    (set_attr "mode" "DI")])
20161
20162 (define_insn "subv4hi3"
20163   [(set (match_operand:V4HI 0 "register_operand" "=y")
20164         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20165                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20166   "TARGET_MMX"
20167   "psubw\t{%2, %0|%0, %2}"
20168   [(set_attr "type" "mmxadd")
20169    (set_attr "mode" "DI")])
20170
20171 (define_insn "subv2si3"
20172   [(set (match_operand:V2SI 0 "register_operand" "=y")
20173         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20174                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20175   "TARGET_MMX"
20176   "psubd\t{%2, %0|%0, %2}"
20177   [(set_attr "type" "mmxadd")
20178    (set_attr "mode" "DI")])
20179
20180 (define_insn "mmx_subdi3"
20181   [(set (match_operand:DI 0 "register_operand" "=y")
20182         (unspec:DI
20183          [(minus:DI (match_operand:DI 1 "register_operand" "0")
20184                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20185          UNSPEC_NOP))]
20186   "TARGET_MMX"
20187   "psubq\t{%2, %0|%0, %2}"
20188   [(set_attr "type" "mmxadd")
20189    (set_attr "mode" "DI")])
20190
20191 (define_insn "sssubv8qi3"
20192   [(set (match_operand:V8QI 0 "register_operand" "=y")
20193         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20194                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20195   "TARGET_MMX"
20196   "psubsb\t{%2, %0|%0, %2}"
20197   [(set_attr "type" "mmxadd")
20198    (set_attr "mode" "DI")])
20199
20200 (define_insn "sssubv4hi3"
20201   [(set (match_operand:V4HI 0 "register_operand" "=y")
20202         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20203                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20204   "TARGET_MMX"
20205   "psubsw\t{%2, %0|%0, %2}"
20206   [(set_attr "type" "mmxadd")
20207    (set_attr "mode" "DI")])
20208
20209 (define_insn "ussubv8qi3"
20210   [(set (match_operand:V8QI 0 "register_operand" "=y")
20211         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20212                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20213   "TARGET_MMX"
20214   "psubusb\t{%2, %0|%0, %2}"
20215   [(set_attr "type" "mmxadd")
20216    (set_attr "mode" "DI")])
20217
20218 (define_insn "ussubv4hi3"
20219   [(set (match_operand:V4HI 0 "register_operand" "=y")
20220         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20221                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20222   "TARGET_MMX"
20223   "psubusw\t{%2, %0|%0, %2}"
20224   [(set_attr "type" "mmxadd")
20225    (set_attr "mode" "DI")])
20226
20227 (define_insn "mulv4hi3"
20228   [(set (match_operand:V4HI 0 "register_operand" "=y")
20229         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20230                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20231   "TARGET_MMX"
20232   "pmullw\t{%2, %0|%0, %2}"
20233   [(set_attr "type" "mmxmul")
20234    (set_attr "mode" "DI")])
20235
20236 (define_insn "smulv4hi3_highpart"
20237   [(set (match_operand:V4HI 0 "register_operand" "=y")
20238         (truncate:V4HI
20239          (lshiftrt:V4SI
20240           (mult:V4SI (sign_extend:V4SI
20241                       (match_operand:V4HI 1 "register_operand" "0"))
20242                      (sign_extend:V4SI
20243                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20244           (const_int 16))))]
20245   "TARGET_MMX"
20246   "pmulhw\t{%2, %0|%0, %2}"
20247   [(set_attr "type" "mmxmul")
20248    (set_attr "mode" "DI")])
20249
20250 (define_insn "umulv4hi3_highpart"
20251   [(set (match_operand:V4HI 0 "register_operand" "=y")
20252         (truncate:V4HI
20253          (lshiftrt:V4SI
20254           (mult:V4SI (zero_extend:V4SI
20255                       (match_operand:V4HI 1 "register_operand" "0"))
20256                      (zero_extend:V4SI
20257                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20258           (const_int 16))))]
20259   "TARGET_SSE || TARGET_3DNOW_A"
20260   "pmulhuw\t{%2, %0|%0, %2}"
20261   [(set_attr "type" "mmxmul")
20262    (set_attr "mode" "DI")])
20263
20264 (define_insn "mmx_pmaddwd"
20265   [(set (match_operand:V2SI 0 "register_operand" "=y")
20266         (plus:V2SI
20267          (mult:V2SI
20268           (sign_extend:V2SI
20269            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20270                             (parallel [(const_int 0) (const_int 2)])))
20271           (sign_extend:V2SI
20272            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20273                             (parallel [(const_int 0) (const_int 2)]))))
20274          (mult:V2SI
20275           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20276                                              (parallel [(const_int 1)
20277                                                         (const_int 3)])))
20278           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20279                                              (parallel [(const_int 1)
20280                                                         (const_int 3)]))))))]
20281   "TARGET_MMX"
20282   "pmaddwd\t{%2, %0|%0, %2}"
20283   [(set_attr "type" "mmxmul")
20284    (set_attr "mode" "DI")])
20285
20286
20287 ;; MMX logical operations
20288 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20289 ;; normal code that also wants to use the FPU from getting broken.
20290 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20291 (define_insn "mmx_iordi3"
20292   [(set (match_operand:DI 0 "register_operand" "=y")
20293         (unspec:DI
20294          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20295                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20296          UNSPEC_NOP))]
20297   "TARGET_MMX"
20298   "por\t{%2, %0|%0, %2}"
20299   [(set_attr "type" "mmxadd")
20300    (set_attr "mode" "DI")])
20301
20302 (define_insn "mmx_xordi3"
20303   [(set (match_operand:DI 0 "register_operand" "=y")
20304         (unspec:DI
20305          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20306                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20307          UNSPEC_NOP))]
20308   "TARGET_MMX"
20309   "pxor\t{%2, %0|%0, %2}"
20310   [(set_attr "type" "mmxadd")
20311    (set_attr "mode" "DI")
20312    (set_attr "memory" "none")])
20313
20314 ;; Same as pxor, but don't show input operands so that we don't think
20315 ;; they are live.
20316 (define_insn "mmx_clrdi"
20317   [(set (match_operand:DI 0 "register_operand" "=y")
20318         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20319   "TARGET_MMX"
20320   "pxor\t{%0, %0|%0, %0}"
20321   [(set_attr "type" "mmxadd")
20322    (set_attr "mode" "DI")
20323    (set_attr "memory" "none")])
20324
20325 (define_insn "mmx_anddi3"
20326   [(set (match_operand:DI 0 "register_operand" "=y")
20327         (unspec:DI
20328          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20329                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20330          UNSPEC_NOP))]
20331   "TARGET_MMX"
20332   "pand\t{%2, %0|%0, %2}"
20333   [(set_attr "type" "mmxadd")
20334    (set_attr "mode" "DI")])
20335
20336 (define_insn "mmx_nanddi3"
20337   [(set (match_operand:DI 0 "register_operand" "=y")
20338         (unspec:DI
20339          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20340                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20341          UNSPEC_NOP))]
20342   "TARGET_MMX"
20343   "pandn\t{%2, %0|%0, %2}"
20344   [(set_attr "type" "mmxadd")
20345    (set_attr "mode" "DI")])
20346
20347
20348 ;; MMX unsigned averages/sum of absolute differences
20349
20350 (define_insn "mmx_uavgv8qi3"
20351   [(set (match_operand:V8QI 0 "register_operand" "=y")
20352         (ashiftrt:V8QI
20353          (plus:V8QI (plus:V8QI
20354                      (match_operand:V8QI 1 "register_operand" "0")
20355                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20356                     (const_vector:V8QI [(const_int 1)
20357                                         (const_int 1)
20358                                         (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   "TARGET_SSE || TARGET_3DNOW_A"
20366   "pavgb\t{%2, %0|%0, %2}"
20367   [(set_attr "type" "mmxshft")
20368    (set_attr "mode" "DI")])
20369
20370 (define_insn "mmx_uavgv4hi3"
20371   [(set (match_operand:V4HI 0 "register_operand" "=y")
20372         (ashiftrt:V4HI
20373          (plus:V4HI (plus:V4HI
20374                      (match_operand:V4HI 1 "register_operand" "0")
20375                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20376                     (const_vector:V4HI [(const_int 1)
20377                                         (const_int 1)
20378                                         (const_int 1)
20379                                         (const_int 1)]))
20380          (const_int 1)))]
20381   "TARGET_SSE || TARGET_3DNOW_A"
20382   "pavgw\t{%2, %0|%0, %2}"
20383   [(set_attr "type" "mmxshft")
20384    (set_attr "mode" "DI")])
20385
20386 (define_insn "mmx_psadbw"
20387   [(set (match_operand:DI 0 "register_operand" "=y")
20388         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20389                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20390                    UNSPEC_PSADBW))]
20391   "TARGET_SSE || TARGET_3DNOW_A"
20392   "psadbw\t{%2, %0|%0, %2}"
20393   [(set_attr "type" "mmxshft")
20394    (set_attr "mode" "DI")])
20395
20396
20397 ;; MMX insert/extract/shuffle
20398
20399 (define_insn "mmx_pinsrw"
20400   [(set (match_operand:V4HI 0 "register_operand" "=y")
20401         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20402                         (vec_duplicate:V4HI
20403                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20404                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20405   "TARGET_SSE || TARGET_3DNOW_A"
20406   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20407   [(set_attr "type" "mmxcvt")
20408    (set_attr "mode" "DI")])
20409
20410 (define_insn "mmx_pextrw"
20411   [(set (match_operand:SI 0 "register_operand" "=r")
20412         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20413                                        (parallel
20414                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20415   "TARGET_SSE || TARGET_3DNOW_A"
20416   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20417   [(set_attr "type" "mmxcvt")
20418    (set_attr "mode" "DI")])
20419
20420 (define_insn "mmx_pshufw"
20421   [(set (match_operand:V4HI 0 "register_operand" "=y")
20422         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20423                       (match_operand:SI 2 "immediate_operand" "i")]
20424                      UNSPEC_SHUFFLE))]
20425   "TARGET_SSE || TARGET_3DNOW_A"
20426   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20427   [(set_attr "type" "mmxcvt")
20428    (set_attr "mode" "DI")])
20429
20430
20431 ;; MMX mask-generating comparisons
20432
20433 (define_insn "eqv8qi3"
20434   [(set (match_operand:V8QI 0 "register_operand" "=y")
20435         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20436                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20437   "TARGET_MMX"
20438   "pcmpeqb\t{%2, %0|%0, %2}"
20439   [(set_attr "type" "mmxcmp")
20440    (set_attr "mode" "DI")])
20441
20442 (define_insn "eqv4hi3"
20443   [(set (match_operand:V4HI 0 "register_operand" "=y")
20444         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20445                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20446   "TARGET_MMX"
20447   "pcmpeqw\t{%2, %0|%0, %2}"
20448   [(set_attr "type" "mmxcmp")
20449    (set_attr "mode" "DI")])
20450
20451 (define_insn "eqv2si3"
20452   [(set (match_operand:V2SI 0 "register_operand" "=y")
20453         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20454                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20455   "TARGET_MMX"
20456   "pcmpeqd\t{%2, %0|%0, %2}"
20457   [(set_attr "type" "mmxcmp")
20458    (set_attr "mode" "DI")])
20459
20460 (define_insn "gtv8qi3"
20461   [(set (match_operand:V8QI 0 "register_operand" "=y")
20462         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20463                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20464   "TARGET_MMX"
20465   "pcmpgtb\t{%2, %0|%0, %2}"
20466   [(set_attr "type" "mmxcmp")
20467    (set_attr "mode" "DI")])
20468
20469 (define_insn "gtv4hi3"
20470   [(set (match_operand:V4HI 0 "register_operand" "=y")
20471         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20472                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20473   "TARGET_MMX"
20474   "pcmpgtw\t{%2, %0|%0, %2}"
20475   [(set_attr "type" "mmxcmp")
20476    (set_attr "mode" "DI")])
20477
20478 (define_insn "gtv2si3"
20479   [(set (match_operand:V2SI 0 "register_operand" "=y")
20480         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20481                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20482   "TARGET_MMX"
20483   "pcmpgtd\t{%2, %0|%0, %2}"
20484   [(set_attr "type" "mmxcmp")
20485    (set_attr "mode" "DI")])
20486
20487
20488 ;; MMX max/min insns
20489
20490 (define_insn "umaxv8qi3"
20491   [(set (match_operand:V8QI 0 "register_operand" "=y")
20492         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20493                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20494   "TARGET_SSE || TARGET_3DNOW_A"
20495   "pmaxub\t{%2, %0|%0, %2}"
20496   [(set_attr "type" "mmxadd")
20497    (set_attr "mode" "DI")])
20498
20499 (define_insn "smaxv4hi3"
20500   [(set (match_operand:V4HI 0 "register_operand" "=y")
20501         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20502                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20503   "TARGET_SSE || TARGET_3DNOW_A"
20504   "pmaxsw\t{%2, %0|%0, %2}"
20505   [(set_attr "type" "mmxadd")
20506    (set_attr "mode" "DI")])
20507
20508 (define_insn "uminv8qi3"
20509   [(set (match_operand:V8QI 0 "register_operand" "=y")
20510         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20511                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20512   "TARGET_SSE || TARGET_3DNOW_A"
20513   "pminub\t{%2, %0|%0, %2}"
20514   [(set_attr "type" "mmxadd")
20515    (set_attr "mode" "DI")])
20516
20517 (define_insn "sminv4hi3"
20518   [(set (match_operand:V4HI 0 "register_operand" "=y")
20519         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20520                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20521   "TARGET_SSE || TARGET_3DNOW_A"
20522   "pminsw\t{%2, %0|%0, %2}"
20523   [(set_attr "type" "mmxadd")
20524    (set_attr "mode" "DI")])
20525
20526
20527 ;; MMX shifts
20528
20529 (define_insn "ashrv4hi3"
20530   [(set (match_operand:V4HI 0 "register_operand" "=y")
20531         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20532                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20533   "TARGET_MMX"
20534   "psraw\t{%2, %0|%0, %2}"
20535   [(set_attr "type" "mmxshft")
20536    (set_attr "mode" "DI")])
20537
20538 (define_insn "ashrv2si3"
20539   [(set (match_operand:V2SI 0 "register_operand" "=y")
20540         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20541                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20542   "TARGET_MMX"
20543   "psrad\t{%2, %0|%0, %2}"
20544   [(set_attr "type" "mmxshft")
20545    (set_attr "mode" "DI")])
20546
20547 (define_insn "lshrv4hi3"
20548   [(set (match_operand:V4HI 0 "register_operand" "=y")
20549         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20550                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20551   "TARGET_MMX"
20552   "psrlw\t{%2, %0|%0, %2}"
20553   [(set_attr "type" "mmxshft")
20554    (set_attr "mode" "DI")])
20555
20556 (define_insn "lshrv2si3"
20557   [(set (match_operand:V2SI 0 "register_operand" "=y")
20558         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20559                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20560   "TARGET_MMX"
20561   "psrld\t{%2, %0|%0, %2}"
20562   [(set_attr "type" "mmxshft")
20563    (set_attr "mode" "DI")])
20564
20565 ;; See logical MMX insns.
20566 (define_insn "mmx_lshrdi3"
20567   [(set (match_operand:DI 0 "register_operand" "=y")
20568         (unspec:DI
20569           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20570                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
20571           UNSPEC_NOP))]
20572   "TARGET_MMX"
20573   "psrlq\t{%2, %0|%0, %2}"
20574   [(set_attr "type" "mmxshft")
20575    (set_attr "mode" "DI")])
20576
20577 (define_insn "ashlv4hi3"
20578   [(set (match_operand:V4HI 0 "register_operand" "=y")
20579         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20580                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20581   "TARGET_MMX"
20582   "psllw\t{%2, %0|%0, %2}"
20583   [(set_attr "type" "mmxshft")
20584    (set_attr "mode" "DI")])
20585
20586 (define_insn "ashlv2si3"
20587   [(set (match_operand:V2SI 0 "register_operand" "=y")
20588         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20589                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20590   "TARGET_MMX"
20591   "pslld\t{%2, %0|%0, %2}"
20592   [(set_attr "type" "mmxshft")
20593    (set_attr "mode" "DI")])
20594
20595 ;; See logical MMX insns.
20596 (define_insn "mmx_ashldi3"
20597   [(set (match_operand:DI 0 "register_operand" "=y")
20598         (unspec:DI
20599          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20600                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
20601          UNSPEC_NOP))]
20602   "TARGET_MMX"
20603   "psllq\t{%2, %0|%0, %2}"
20604   [(set_attr "type" "mmxshft")
20605    (set_attr "mode" "DI")])
20606
20607
20608 ;; MMX pack/unpack insns.
20609
20610 (define_insn "mmx_packsswb"
20611   [(set (match_operand:V8QI 0 "register_operand" "=y")
20612         (vec_concat:V8QI
20613          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20614          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20615   "TARGET_MMX"
20616   "packsswb\t{%2, %0|%0, %2}"
20617   [(set_attr "type" "mmxshft")
20618    (set_attr "mode" "DI")])
20619
20620 (define_insn "mmx_packssdw"
20621   [(set (match_operand:V4HI 0 "register_operand" "=y")
20622         (vec_concat:V4HI
20623          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20624          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20625   "TARGET_MMX"
20626   "packssdw\t{%2, %0|%0, %2}"
20627   [(set_attr "type" "mmxshft")
20628    (set_attr "mode" "DI")])
20629
20630 (define_insn "mmx_packuswb"
20631   [(set (match_operand:V8QI 0 "register_operand" "=y")
20632         (vec_concat:V8QI
20633          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20634          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20635   "TARGET_MMX"
20636   "packuswb\t{%2, %0|%0, %2}"
20637   [(set_attr "type" "mmxshft")
20638    (set_attr "mode" "DI")])
20639
20640 (define_insn "mmx_punpckhbw"
20641   [(set (match_operand:V8QI 0 "register_operand" "=y")
20642         (vec_merge:V8QI
20643          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20644                           (parallel [(const_int 4)
20645                                      (const_int 0)
20646                                      (const_int 5)
20647                                      (const_int 1)
20648                                      (const_int 6)
20649                                      (const_int 2)
20650                                      (const_int 7)
20651                                      (const_int 3)]))
20652          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20653                           (parallel [(const_int 0)
20654                                      (const_int 4)
20655                                      (const_int 1)
20656                                      (const_int 5)
20657                                      (const_int 2)
20658                                      (const_int 6)
20659                                      (const_int 3)
20660                                      (const_int 7)]))
20661          (const_int 85)))]
20662   "TARGET_MMX"
20663   "punpckhbw\t{%2, %0|%0, %2}"
20664   [(set_attr "type" "mmxcvt")
20665    (set_attr "mode" "DI")])
20666
20667 (define_insn "mmx_punpckhwd"
20668   [(set (match_operand:V4HI 0 "register_operand" "=y")
20669         (vec_merge:V4HI
20670          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20671                           (parallel [(const_int 0)
20672                                      (const_int 2)
20673                                      (const_int 1)
20674                                      (const_int 3)]))
20675          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20676                           (parallel [(const_int 2)
20677                                      (const_int 0)
20678                                      (const_int 3)
20679                                      (const_int 1)]))
20680          (const_int 5)))]
20681   "TARGET_MMX"
20682   "punpckhwd\t{%2, %0|%0, %2}"
20683   [(set_attr "type" "mmxcvt")
20684    (set_attr "mode" "DI")])
20685
20686 (define_insn "mmx_punpckhdq"
20687   [(set (match_operand:V2SI 0 "register_operand" "=y")
20688         (vec_merge:V2SI
20689          (match_operand:V2SI 1 "register_operand" "0")
20690          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20691                           (parallel [(const_int 1)
20692                                      (const_int 0)]))
20693          (const_int 1)))]
20694   "TARGET_MMX"
20695   "punpckhdq\t{%2, %0|%0, %2}"
20696   [(set_attr "type" "mmxcvt")
20697    (set_attr "mode" "DI")])
20698
20699 (define_insn "mmx_punpcklbw"
20700   [(set (match_operand:V8QI 0 "register_operand" "=y")
20701         (vec_merge:V8QI
20702          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20703                           (parallel [(const_int 0)
20704                                      (const_int 4)
20705                                      (const_int 1)
20706                                      (const_int 5)
20707                                      (const_int 2)
20708                                      (const_int 6)
20709                                      (const_int 3)
20710                                      (const_int 7)]))
20711          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20712                           (parallel [(const_int 4)
20713                                      (const_int 0)
20714                                      (const_int 5)
20715                                      (const_int 1)
20716                                      (const_int 6)
20717                                      (const_int 2)
20718                                      (const_int 7)
20719                                      (const_int 3)]))
20720          (const_int 85)))]
20721   "TARGET_MMX"
20722   "punpcklbw\t{%2, %0|%0, %2}"
20723   [(set_attr "type" "mmxcvt")
20724    (set_attr "mode" "DI")])
20725
20726 (define_insn "mmx_punpcklwd"
20727   [(set (match_operand:V4HI 0 "register_operand" "=y")
20728         (vec_merge:V4HI
20729          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20730                           (parallel [(const_int 2)
20731                                      (const_int 0)
20732                                      (const_int 3)
20733                                      (const_int 1)]))
20734          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20735                           (parallel [(const_int 0)
20736                                      (const_int 2)
20737                                      (const_int 1)
20738                                      (const_int 3)]))
20739          (const_int 5)))]
20740   "TARGET_MMX"
20741   "punpcklwd\t{%2, %0|%0, %2}"
20742   [(set_attr "type" "mmxcvt")
20743    (set_attr "mode" "DI")])
20744
20745 (define_insn "mmx_punpckldq"
20746   [(set (match_operand:V2SI 0 "register_operand" "=y")
20747         (vec_merge:V2SI
20748          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20749                            (parallel [(const_int 1)
20750                                       (const_int 0)]))
20751          (match_operand:V2SI 2 "register_operand" "y")
20752          (const_int 1)))]
20753   "TARGET_MMX"
20754   "punpckldq\t{%2, %0|%0, %2}"
20755   [(set_attr "type" "mmxcvt")
20756    (set_attr "mode" "DI")])
20757
20758
20759 ;; Miscellaneous stuff
20760
20761 (define_insn "emms"
20762   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20763    (clobber (reg:XF 8))
20764    (clobber (reg:XF 9))
20765    (clobber (reg:XF 10))
20766    (clobber (reg:XF 11))
20767    (clobber (reg:XF 12))
20768    (clobber (reg:XF 13))
20769    (clobber (reg:XF 14))
20770    (clobber (reg:XF 15))
20771    (clobber (reg:DI 29))
20772    (clobber (reg:DI 30))
20773    (clobber (reg:DI 31))
20774    (clobber (reg:DI 32))
20775    (clobber (reg:DI 33))
20776    (clobber (reg:DI 34))
20777    (clobber (reg:DI 35))
20778    (clobber (reg:DI 36))]
20779   "TARGET_MMX"
20780   "emms"
20781   [(set_attr "type" "mmx")
20782    (set_attr "memory" "unknown")])
20783
20784 (define_insn "ldmxcsr"
20785   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20786                     UNSPECV_LDMXCSR)]
20787   "TARGET_SSE"
20788   "ldmxcsr\t%0"
20789   [(set_attr "type" "sse")
20790    (set_attr "memory" "load")])
20791
20792 (define_insn "stmxcsr"
20793   [(set (match_operand:SI 0 "memory_operand" "=m")
20794         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20795   "TARGET_SSE"
20796   "stmxcsr\t%0"
20797   [(set_attr "type" "sse")
20798    (set_attr "memory" "store")])
20799
20800 (define_expand "sfence"
20801   [(set (match_dup 0)
20802         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20803   "TARGET_SSE || TARGET_3DNOW_A"
20804 {
20805   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20806   MEM_VOLATILE_P (operands[0]) = 1;
20807 })
20808
20809 (define_insn "*sfence_insn"
20810   [(set (match_operand:BLK 0 "" "")
20811         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20812   "TARGET_SSE || TARGET_3DNOW_A"
20813   "sfence"
20814   [(set_attr "type" "sse")
20815    (set_attr "memory" "unknown")])
20816
20817 (define_expand "sse_prologue_save"
20818   [(parallel [(set (match_operand:BLK 0 "" "")
20819                    (unspec:BLK [(reg:DI 21)
20820                                 (reg:DI 22)
20821                                 (reg:DI 23)
20822                                 (reg:DI 24)
20823                                 (reg:DI 25)
20824                                 (reg:DI 26)
20825                                 (reg:DI 27)
20826                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20827               (use (match_operand:DI 1 "register_operand" ""))
20828               (use (match_operand:DI 2 "immediate_operand" ""))
20829               (use (label_ref:DI (match_operand 3 "" "")))])]
20830   "TARGET_64BIT"
20831   "")
20832
20833 (define_insn "*sse_prologue_save_insn"
20834   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20835                           (match_operand:DI 4 "const_int_operand" "n")))
20836         (unspec:BLK [(reg:DI 21)
20837                      (reg:DI 22)
20838                      (reg:DI 23)
20839                      (reg:DI 24)
20840                      (reg:DI 25)
20841                      (reg:DI 26)
20842                      (reg:DI 27)
20843                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20844    (use (match_operand:DI 1 "register_operand" "r"))
20845    (use (match_operand:DI 2 "const_int_operand" "i"))
20846    (use (label_ref:DI (match_operand 3 "" "X")))]
20847   "TARGET_64BIT
20848    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20849    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20850   "*
20851 {
20852   int i;
20853   operands[0] = gen_rtx_MEM (Pmode,
20854                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20855   output_asm_insn (\"jmp\\t%A1\", operands);
20856   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20857     {
20858       operands[4] = adjust_address (operands[0], DImode, i*16);
20859       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20860       PUT_MODE (operands[4], TImode);
20861       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20862         output_asm_insn (\"rex\", operands);
20863       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20864     }
20865   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20866                              CODE_LABEL_NUMBER (operands[3]));
20867   RET;
20868 }
20869   "
20870   [(set_attr "type" "other")
20871    (set_attr "length_immediate" "0")
20872    (set_attr "length_address" "0")
20873    (set_attr "length" "135")
20874    (set_attr "memory" "store")
20875    (set_attr "modrm" "0")
20876    (set_attr "mode" "DI")])
20877
20878 ;; 3Dnow! instructions
20879
20880 (define_insn "addv2sf3"
20881   [(set (match_operand:V2SF 0 "register_operand" "=y")
20882         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20883                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20884   "TARGET_3DNOW"
20885   "pfadd\\t{%2, %0|%0, %2}"
20886   [(set_attr "type" "mmxadd")
20887    (set_attr "mode" "V2SF")])
20888
20889 (define_insn "subv2sf3"
20890   [(set (match_operand:V2SF 0 "register_operand" "=y")
20891         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20892                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20893   "TARGET_3DNOW"
20894   "pfsub\\t{%2, %0|%0, %2}"
20895   [(set_attr "type" "mmxadd")
20896    (set_attr "mode" "V2SF")])
20897
20898 (define_insn "subrv2sf3"
20899   [(set (match_operand:V2SF 0 "register_operand" "=y")
20900         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20901                     (match_operand:V2SF 1 "register_operand" "0")))]
20902   "TARGET_3DNOW"
20903   "pfsubr\\t{%2, %0|%0, %2}"
20904   [(set_attr "type" "mmxadd")
20905    (set_attr "mode" "V2SF")])
20906
20907 (define_insn "gtv2sf3"
20908   [(set (match_operand:V2SI 0 "register_operand" "=y")
20909         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20910                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20911  "TARGET_3DNOW"
20912   "pfcmpgt\\t{%2, %0|%0, %2}"
20913   [(set_attr "type" "mmxcmp")
20914    (set_attr "mode" "V2SF")])
20915
20916 (define_insn "gev2sf3"
20917   [(set (match_operand:V2SI 0 "register_operand" "=y")
20918         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20919                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20920   "TARGET_3DNOW"
20921   "pfcmpge\\t{%2, %0|%0, %2}"
20922   [(set_attr "type" "mmxcmp")
20923    (set_attr "mode" "V2SF")])
20924
20925 (define_insn "eqv2sf3"
20926   [(set (match_operand:V2SI 0 "register_operand" "=y")
20927         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20928                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20929   "TARGET_3DNOW"
20930   "pfcmpeq\\t{%2, %0|%0, %2}"
20931   [(set_attr "type" "mmxcmp")
20932    (set_attr "mode" "V2SF")])
20933
20934 (define_insn "pfmaxv2sf3"
20935   [(set (match_operand:V2SF 0 "register_operand" "=y")
20936         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20937                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20938   "TARGET_3DNOW"
20939   "pfmax\\t{%2, %0|%0, %2}"
20940   [(set_attr "type" "mmxadd")
20941    (set_attr "mode" "V2SF")])
20942
20943 (define_insn "pfminv2sf3"
20944   [(set (match_operand:V2SF 0 "register_operand" "=y")
20945         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20946                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20947   "TARGET_3DNOW"
20948   "pfmin\\t{%2, %0|%0, %2}"
20949   [(set_attr "type" "mmxadd")
20950    (set_attr "mode" "V2SF")])
20951
20952 (define_insn "mulv2sf3"
20953   [(set (match_operand:V2SF 0 "register_operand" "=y")
20954         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20955                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20956   "TARGET_3DNOW"
20957   "pfmul\\t{%2, %0|%0, %2}"
20958   [(set_attr "type" "mmxmul")
20959    (set_attr "mode" "V2SF")])
20960
20961 (define_insn "femms"
20962   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20963    (clobber (reg:XF 8))
20964    (clobber (reg:XF 9))
20965    (clobber (reg:XF 10))
20966    (clobber (reg:XF 11))
20967    (clobber (reg:XF 12))
20968    (clobber (reg:XF 13))
20969    (clobber (reg:XF 14))
20970    (clobber (reg:XF 15))
20971    (clobber (reg:DI 29))
20972    (clobber (reg:DI 30))
20973    (clobber (reg:DI 31))
20974    (clobber (reg:DI 32))
20975    (clobber (reg:DI 33))
20976    (clobber (reg:DI 34))
20977    (clobber (reg:DI 35))
20978    (clobber (reg:DI 36))]
20979   "TARGET_3DNOW"
20980   "femms"
20981   [(set_attr "type" "mmx")
20982    (set_attr "memory" "none")]) 
20983
20984 (define_insn "pf2id"
20985   [(set (match_operand:V2SI 0 "register_operand" "=y")
20986         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20987   "TARGET_3DNOW"
20988   "pf2id\\t{%1, %0|%0, %1}"
20989   [(set_attr "type" "mmxcvt")
20990    (set_attr "mode" "V2SF")])
20991
20992 (define_insn "pf2iw"
20993   [(set (match_operand:V2SI 0 "register_operand" "=y")
20994         (sign_extend:V2SI
20995            (ss_truncate:V2HI
20996               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20997   "TARGET_3DNOW_A"
20998   "pf2iw\\t{%1, %0|%0, %1}"
20999   [(set_attr "type" "mmxcvt")
21000    (set_attr "mode" "V2SF")])
21001
21002 (define_insn "pfacc"
21003   [(set (match_operand:V2SF 0 "register_operand" "=y")
21004         (vec_concat:V2SF
21005            (plus:SF
21006               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21007                              (parallel [(const_int  0)]))
21008               (vec_select:SF (match_dup 1)
21009                              (parallel [(const_int 1)])))
21010            (plus:SF
21011               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21012                              (parallel [(const_int  0)]))
21013               (vec_select:SF (match_dup 2)
21014                              (parallel [(const_int 1)])))))]
21015   "TARGET_3DNOW"
21016   "pfacc\\t{%2, %0|%0, %2}"
21017   [(set_attr "type" "mmxadd")
21018    (set_attr "mode" "V2SF")])
21019
21020 (define_insn "pfnacc"
21021   [(set (match_operand:V2SF 0 "register_operand" "=y")
21022         (vec_concat:V2SF
21023            (minus:SF
21024               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21025                              (parallel [(const_int 0)]))
21026               (vec_select:SF (match_dup 1)
21027                              (parallel [(const_int 1)])))
21028            (minus:SF
21029               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21030                              (parallel [(const_int  0)]))
21031               (vec_select:SF (match_dup 2)
21032                              (parallel [(const_int 1)])))))]
21033   "TARGET_3DNOW_A"
21034   "pfnacc\\t{%2, %0|%0, %2}"
21035   [(set_attr "type" "mmxadd")
21036    (set_attr "mode" "V2SF")])
21037
21038 (define_insn "pfpnacc"
21039   [(set (match_operand:V2SF 0 "register_operand" "=y")
21040         (vec_concat:V2SF
21041            (minus:SF
21042               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21043                              (parallel [(const_int 0)]))
21044               (vec_select:SF (match_dup 1)
21045                              (parallel [(const_int 1)])))
21046            (plus:SF
21047               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21048                              (parallel [(const_int 0)]))
21049               (vec_select:SF (match_dup 2)
21050                              (parallel [(const_int 1)])))))]
21051   "TARGET_3DNOW_A"
21052   "pfpnacc\\t{%2, %0|%0, %2}"
21053   [(set_attr "type" "mmxadd")
21054    (set_attr "mode" "V2SF")])
21055
21056 (define_insn "pi2fw"
21057   [(set (match_operand:V2SF 0 "register_operand" "=y")
21058         (float:V2SF
21059            (vec_concat:V2SI
21060               (sign_extend:SI
21061                  (truncate:HI
21062                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21063                                    (parallel [(const_int 0)]))))
21064               (sign_extend:SI
21065                  (truncate:HI
21066                     (vec_select:SI (match_dup 1)
21067                                    (parallel [(const_int  1)])))))))]
21068   "TARGET_3DNOW_A"
21069   "pi2fw\\t{%1, %0|%0, %1}"
21070   [(set_attr "type" "mmxcvt")
21071    (set_attr "mode" "V2SF")])
21072
21073 (define_insn "floatv2si2"
21074   [(set (match_operand:V2SF 0 "register_operand" "=y")
21075         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21076   "TARGET_3DNOW"
21077   "pi2fd\\t{%1, %0|%0, %1}"
21078   [(set_attr "type" "mmxcvt")
21079    (set_attr "mode" "V2SF")])
21080
21081 ;; This insn is identical to pavgb in operation, but the opcode is
21082 ;; different.  To avoid accidentally matching pavgb, use an unspec.
21083
21084 (define_insn "pavgusb"
21085  [(set (match_operand:V8QI 0 "register_operand" "=y")
21086        (unspec:V8QI
21087           [(match_operand:V8QI 1 "register_operand" "0")
21088            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21089           UNSPEC_PAVGUSB))]
21090   "TARGET_3DNOW"
21091   "pavgusb\\t{%2, %0|%0, %2}"
21092   [(set_attr "type" "mmxshft")
21093    (set_attr "mode" "TI")])
21094
21095 ;; 3DNow reciprocal and sqrt
21096  
21097 (define_insn "pfrcpv2sf2"
21098   [(set (match_operand:V2SF 0 "register_operand" "=y")
21099         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21100         UNSPEC_PFRCP))]
21101   "TARGET_3DNOW"
21102   "pfrcp\\t{%1, %0|%0, %1}"
21103   [(set_attr "type" "mmx")
21104    (set_attr "mode" "TI")])
21105
21106 (define_insn "pfrcpit1v2sf3"
21107   [(set (match_operand:V2SF 0 "register_operand" "=y")
21108         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21109                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21110                      UNSPEC_PFRCPIT1))]
21111   "TARGET_3DNOW"
21112   "pfrcpit1\\t{%2, %0|%0, %2}"
21113   [(set_attr "type" "mmx")
21114    (set_attr "mode" "TI")])
21115
21116 (define_insn "pfrcpit2v2sf3"
21117   [(set (match_operand:V2SF 0 "register_operand" "=y")
21118         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21119                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21120                      UNSPEC_PFRCPIT2))]
21121   "TARGET_3DNOW"
21122   "pfrcpit2\\t{%2, %0|%0, %2}"
21123   [(set_attr "type" "mmx")
21124    (set_attr "mode" "TI")])
21125
21126 (define_insn "pfrsqrtv2sf2"
21127   [(set (match_operand:V2SF 0 "register_operand" "=y")
21128         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21129                      UNSPEC_PFRSQRT))]
21130   "TARGET_3DNOW"
21131   "pfrsqrt\\t{%1, %0|%0, %1}"
21132   [(set_attr "type" "mmx")
21133    (set_attr "mode" "TI")])
21134                 
21135 (define_insn "pfrsqit1v2sf3"
21136   [(set (match_operand:V2SF 0 "register_operand" "=y")
21137         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21138                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21139                      UNSPEC_PFRSQIT1))]
21140   "TARGET_3DNOW"
21141   "pfrsqit1\\t{%2, %0|%0, %2}"
21142   [(set_attr "type" "mmx")
21143    (set_attr "mode" "TI")])
21144
21145 (define_insn "pmulhrwv4hi3"
21146   [(set (match_operand:V4HI 0 "register_operand" "=y")
21147         (truncate:V4HI
21148            (lshiftrt:V4SI
21149               (plus:V4SI
21150                  (mult:V4SI
21151                     (sign_extend:V4SI
21152                        (match_operand:V4HI 1 "register_operand" "0"))
21153                     (sign_extend:V4SI
21154                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21155                  (const_vector:V4SI [(const_int 32768)
21156                                      (const_int 32768)
21157                                      (const_int 32768)
21158                                      (const_int 32768)]))
21159               (const_int 16))))]
21160   "TARGET_3DNOW"
21161   "pmulhrw\\t{%2, %0|%0, %2}"
21162   [(set_attr "type" "mmxmul")
21163    (set_attr "mode" "TI")])
21164
21165 (define_insn "pswapdv2si2"
21166   [(set (match_operand:V2SI 0 "register_operand" "=y")
21167         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21168                          (parallel [(const_int 1) (const_int 0)])))]
21169   "TARGET_3DNOW_A"
21170   "pswapd\\t{%1, %0|%0, %1}"
21171   [(set_attr "type" "mmxcvt")
21172    (set_attr "mode" "TI")])
21173
21174 (define_insn "pswapdv2sf2"
21175   [(set (match_operand:V2SF 0 "register_operand" "=y")
21176         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21177                          (parallel [(const_int 1) (const_int 0)])))]
21178   "TARGET_3DNOW_A"
21179   "pswapd\\t{%1, %0|%0, %1}"
21180   [(set_attr "type" "mmxcvt")
21181    (set_attr "mode" "TI")])
21182
21183 (define_expand "prefetch"
21184   [(prefetch (match_operand 0 "address_operand" "")
21185              (match_operand:SI 1 "const_int_operand" "")
21186              (match_operand:SI 2 "const_int_operand" ""))]
21187   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21188 {
21189   int rw = INTVAL (operands[1]);
21190   int locality = INTVAL (operands[2]);
21191
21192   if (rw != 0 && rw != 1)
21193     abort ();
21194   if (locality < 0 || locality > 3)
21195     abort ();
21196   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21197     abort ();
21198
21199   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21200      suported by SSE counterpart or the SSE prefetch is not available
21201      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21202      of locality.  */
21203   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21204     operands[2] = GEN_INT (3);
21205   else
21206     operands[1] = const0_rtx;
21207 })
21208
21209 (define_insn "*prefetch_sse"
21210   [(prefetch (match_operand:SI 0 "address_operand" "p")
21211              (const_int 0)
21212              (match_operand:SI 1 "const_int_operand" ""))]
21213   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21214 {
21215   static const char * const patterns[4] = {
21216    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21217   };
21218
21219   int locality = INTVAL (operands[1]);
21220   if (locality < 0 || locality > 3)
21221     abort ();
21222
21223   return patterns[locality];  
21224 }
21225   [(set_attr "type" "sse")
21226    (set_attr "memory" "none")])
21227
21228 (define_insn "*prefetch_sse_rex"
21229   [(prefetch (match_operand:DI 0 "address_operand" "p")
21230              (const_int 0)
21231              (match_operand:SI 1 "const_int_operand" ""))]
21232   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21233 {
21234   static const char * const patterns[4] = {
21235    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21236   };
21237
21238   int locality = INTVAL (operands[1]);
21239   if (locality < 0 || locality > 3)
21240     abort ();
21241
21242   return patterns[locality];  
21243 }
21244   [(set_attr "type" "sse")
21245    (set_attr "memory" "none")])
21246
21247 (define_insn "*prefetch_3dnow"
21248   [(prefetch (match_operand:SI 0 "address_operand" "p")
21249              (match_operand:SI 1 "const_int_operand" "n")
21250              (const_int 3))]
21251   "TARGET_3DNOW && !TARGET_64BIT"
21252 {
21253   if (INTVAL (operands[1]) == 0)
21254     return "prefetch\t%a0";
21255   else
21256     return "prefetchw\t%a0";
21257 }
21258   [(set_attr "type" "mmx")
21259    (set_attr "memory" "none")])
21260
21261 (define_insn "*prefetch_3dnow_rex"
21262   [(prefetch (match_operand:DI 0 "address_operand" "p")
21263              (match_operand:SI 1 "const_int_operand" "n")
21264              (const_int 3))]
21265   "TARGET_3DNOW && TARGET_64BIT"
21266 {
21267   if (INTVAL (operands[1]) == 0)
21268     return "prefetch\t%a0";
21269   else
21270     return "prefetchw\t%a0";
21271 }
21272   [(set_attr "type" "mmx")
21273    (set_attr "memory" "none")])
21274
21275 ;; SSE2 support
21276
21277 (define_insn "addv2df3"
21278   [(set (match_operand:V2DF 0 "register_operand" "=x")
21279         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21280                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21281   "TARGET_SSE2"
21282   "addpd\t{%2, %0|%0, %2}"
21283   [(set_attr "type" "sseadd")
21284    (set_attr "mode" "V2DF")])
21285
21286 (define_insn "vmaddv2df3"
21287   [(set (match_operand:V2DF 0 "register_operand" "=x")
21288         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21289                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21290                         (match_dup 1)
21291                         (const_int 1)))]
21292   "TARGET_SSE2"
21293   "addsd\t{%2, %0|%0, %2}"
21294   [(set_attr "type" "sseadd")
21295    (set_attr "mode" "DF")])
21296
21297 (define_insn "subv2df3"
21298   [(set (match_operand:V2DF 0 "register_operand" "=x")
21299         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21300                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21301   "TARGET_SSE2"
21302   "subpd\t{%2, %0|%0, %2}"
21303   [(set_attr "type" "sseadd")
21304    (set_attr "mode" "V2DF")])
21305
21306 (define_insn "vmsubv2df3"
21307   [(set (match_operand:V2DF 0 "register_operand" "=x")
21308         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21309                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21310                         (match_dup 1)
21311                         (const_int 1)))]
21312   "TARGET_SSE2"
21313   "subsd\t{%2, %0|%0, %2}"
21314   [(set_attr "type" "sseadd")
21315    (set_attr "mode" "DF")])
21316
21317 (define_insn "mulv2df3"
21318   [(set (match_operand:V2DF 0 "register_operand" "=x")
21319         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21320                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21321   "TARGET_SSE2"
21322   "mulpd\t{%2, %0|%0, %2}"
21323   [(set_attr "type" "ssemul")
21324    (set_attr "mode" "V2DF")])
21325
21326 (define_insn "vmmulv2df3"
21327   [(set (match_operand:V2DF 0 "register_operand" "=x")
21328         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21329                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21330                         (match_dup 1)
21331                         (const_int 1)))]
21332   "TARGET_SSE2"
21333   "mulsd\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "ssemul")
21335    (set_attr "mode" "DF")])
21336
21337 (define_insn "divv2df3"
21338   [(set (match_operand:V2DF 0 "register_operand" "=x")
21339         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21340                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21341   "TARGET_SSE2"
21342   "divpd\t{%2, %0|%0, %2}"
21343   [(set_attr "type" "ssediv")
21344    (set_attr "mode" "V2DF")])
21345
21346 (define_insn "vmdivv2df3"
21347   [(set (match_operand:V2DF 0 "register_operand" "=x")
21348         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21349                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21350                         (match_dup 1)
21351                         (const_int 1)))]
21352   "TARGET_SSE2"
21353   "divsd\t{%2, %0|%0, %2}"
21354   [(set_attr "type" "ssediv")
21355    (set_attr "mode" "DF")])
21356
21357 ;; SSE min/max
21358
21359 (define_insn "smaxv2df3"
21360   [(set (match_operand:V2DF 0 "register_operand" "=x")
21361         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21362                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21363   "TARGET_SSE2"
21364   "maxpd\t{%2, %0|%0, %2}"
21365   [(set_attr "type" "sseadd")
21366    (set_attr "mode" "V2DF")])
21367
21368 (define_insn "vmsmaxv2df3"
21369   [(set (match_operand:V2DF 0 "register_operand" "=x")
21370         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21371                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21372                         (match_dup 1)
21373                         (const_int 1)))]
21374   "TARGET_SSE2"
21375   "maxsd\t{%2, %0|%0, %2}"
21376   [(set_attr "type" "sseadd")
21377    (set_attr "mode" "DF")])
21378
21379 (define_insn "sminv2df3"
21380   [(set (match_operand:V2DF 0 "register_operand" "=x")
21381         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21382                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21383   "TARGET_SSE2"
21384   "minpd\t{%2, %0|%0, %2}"
21385   [(set_attr "type" "sseadd")
21386    (set_attr "mode" "V2DF")])
21387
21388 (define_insn "vmsminv2df3"
21389   [(set (match_operand:V2DF 0 "register_operand" "=x")
21390         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21391                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21392                         (match_dup 1)
21393                         (const_int 1)))]
21394   "TARGET_SSE2"
21395   "minsd\t{%2, %0|%0, %2}"
21396   [(set_attr "type" "sseadd")
21397    (set_attr "mode" "DF")])
21398 ;; SSE2 square root.  There doesn't appear to be an extension for the
21399 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21400
21401 (define_insn "sqrtv2df2"
21402   [(set (match_operand:V2DF 0 "register_operand" "=x")
21403         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21404   "TARGET_SSE2"
21405   "sqrtpd\t{%1, %0|%0, %1}"
21406   [(set_attr "type" "sse")
21407    (set_attr "mode" "V2DF")])
21408
21409 (define_insn "vmsqrtv2df2"
21410   [(set (match_operand:V2DF 0 "register_operand" "=x")
21411         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21412                         (match_operand:V2DF 2 "register_operand" "0")
21413                         (const_int 1)))]
21414   "TARGET_SSE2"
21415   "sqrtsd\t{%1, %0|%0, %1}"
21416   [(set_attr "type" "sse")
21417    (set_attr "mode" "SF")])
21418
21419 ;; SSE mask-generating compares
21420
21421 (define_insn "maskcmpv2df3"
21422   [(set (match_operand:V2DI 0 "register_operand" "=x")
21423         (match_operator:V2DI 3 "sse_comparison_operator"
21424                              [(match_operand:V2DF 1 "register_operand" "0")
21425                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21426   "TARGET_SSE2"
21427   "cmp%D3pd\t{%2, %0|%0, %2}"
21428   [(set_attr "type" "ssecmp")
21429    (set_attr "mode" "V2DF")])
21430
21431 (define_insn "maskncmpv2df3"
21432   [(set (match_operand:V2DI 0 "register_operand" "=x")
21433         (not:V2DI
21434          (match_operator:V2DI 3 "sse_comparison_operator"
21435                               [(match_operand:V2DF 1 "register_operand" "0")
21436                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21437   "TARGET_SSE2"
21438 {
21439   if (GET_CODE (operands[3]) == UNORDERED)
21440     return "cmpordps\t{%2, %0|%0, %2}";
21441   else
21442     return "cmpn%D3pd\t{%2, %0|%0, %2}";
21443 }
21444   [(set_attr "type" "ssecmp")
21445    (set_attr "mode" "V2DF")])
21446
21447 (define_insn "vmmaskcmpv2df3"
21448   [(set (match_operand:V2DI 0 "register_operand" "=x")
21449         (vec_merge:V2DI
21450          (match_operator:V2DI 3 "sse_comparison_operator"
21451                               [(match_operand:V2DF 1 "register_operand" "0")
21452                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21453          (subreg:V2DI (match_dup 1) 0)
21454          (const_int 1)))]
21455   "TARGET_SSE2"
21456   "cmp%D3sd\t{%2, %0|%0, %2}"
21457   [(set_attr "type" "ssecmp")
21458    (set_attr "mode" "DF")])
21459
21460 (define_insn "vmmaskncmpv2df3"
21461   [(set (match_operand:V2DI 0 "register_operand" "=x")
21462         (vec_merge:V2DI
21463          (not:V2DI
21464           (match_operator:V2DI 3 "sse_comparison_operator"
21465                                [(match_operand:V2DF 1 "register_operand" "0")
21466                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21467          (subreg:V2DI (match_dup 1) 0)
21468          (const_int 1)))]
21469   "TARGET_SSE2"
21470 {
21471   if (GET_CODE (operands[3]) == UNORDERED)
21472     return "cmpordsd\t{%2, %0|%0, %2}";
21473   else
21474     return "cmpn%D3sd\t{%2, %0|%0, %2}";
21475 }
21476   [(set_attr "type" "ssecmp")
21477    (set_attr "mode" "DF")])
21478
21479 (define_insn "sse2_comi"
21480   [(set (reg:CCFP 17)
21481         (compare:CCFP (vec_select:DF
21482                        (match_operand:V2DF 0 "register_operand" "x")
21483                        (parallel [(const_int 0)]))
21484                       (vec_select:DF
21485                        (match_operand:V2DF 1 "register_operand" "x")
21486                        (parallel [(const_int 0)]))))]
21487   "TARGET_SSE2"
21488   "comisd\t{%1, %0|%0, %1}"
21489   [(set_attr "type" "ssecomi")
21490    (set_attr "mode" "DF")])
21491
21492 (define_insn "sse2_ucomi"
21493   [(set (reg:CCFPU 17)
21494         (compare:CCFPU (vec_select:DF
21495                          (match_operand:V2DF 0 "register_operand" "x")
21496                          (parallel [(const_int 0)]))
21497                         (vec_select:DF
21498                          (match_operand:V2DF 1 "register_operand" "x")
21499                          (parallel [(const_int 0)]))))]
21500   "TARGET_SSE2"
21501   "ucomisd\t{%1, %0|%0, %1}"
21502   [(set_attr "type" "ssecomi")
21503    (set_attr "mode" "DF")])
21504
21505 ;; SSE Strange Moves.
21506
21507 (define_insn "sse2_movmskpd"
21508   [(set (match_operand:SI 0 "register_operand" "=r")
21509         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21510                    UNSPEC_MOVMSK))]
21511   "TARGET_SSE2"
21512   "movmskpd\t{%1, %0|%0, %1}"
21513   [(set_attr "type" "ssecvt")
21514    (set_attr "mode" "V2DF")])
21515
21516 (define_insn "sse2_pmovmskb"
21517   [(set (match_operand:SI 0 "register_operand" "=r")
21518         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21519                    UNSPEC_MOVMSK))]
21520   "TARGET_SSE2"
21521   "pmovmskb\t{%1, %0|%0, %1}"
21522   [(set_attr "type" "ssecvt")
21523    (set_attr "mode" "V2DF")])
21524
21525 (define_insn "sse2_maskmovdqu"
21526   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21527         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21528                        (match_operand:V16QI 2 "register_operand" "x")]
21529                       UNSPEC_MASKMOV))]
21530   "TARGET_SSE2"
21531   ;; @@@ check ordering of operands in intel/nonintel syntax
21532   "maskmovdqu\t{%2, %1|%1, %2}"
21533   [(set_attr "type" "ssecvt")
21534    (set_attr "mode" "TI")])
21535
21536 (define_insn "sse2_maskmovdqu_rex64"
21537   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21538         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21539                        (match_operand:V16QI 2 "register_operand" "x")]
21540                       UNSPEC_MASKMOV))]
21541   "TARGET_SSE2"
21542   ;; @@@ check ordering of operands in intel/nonintel syntax
21543   "maskmovdqu\t{%2, %1|%1, %2}"
21544   [(set_attr "type" "ssecvt")
21545    (set_attr "mode" "TI")])
21546
21547 (define_insn "sse2_movntv2df"
21548   [(set (match_operand:V2DF 0 "memory_operand" "=m")
21549         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21550                      UNSPEC_MOVNT))]
21551   "TARGET_SSE2"
21552   "movntpd\t{%1, %0|%0, %1}"
21553   [(set_attr "type" "ssecvt")
21554    (set_attr "mode" "V2DF")])
21555
21556 (define_insn "sse2_movntv2di"
21557   [(set (match_operand:V2DI 0 "memory_operand" "=m")
21558         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21559                      UNSPEC_MOVNT))]
21560   "TARGET_SSE2"
21561   "movntdq\t{%1, %0|%0, %1}"
21562   [(set_attr "type" "ssecvt")
21563    (set_attr "mode" "TI")])
21564
21565 (define_insn "sse2_movntsi"
21566   [(set (match_operand:SI 0 "memory_operand" "=m")
21567         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21568                    UNSPEC_MOVNT))]
21569   "TARGET_SSE2"
21570   "movnti\t{%1, %0|%0, %1}"
21571   [(set_attr "type" "ssecvt")
21572    (set_attr "mode" "V2DF")])
21573
21574 ;; SSE <-> integer/MMX conversions
21575
21576 ;; Conversions between SI and SF
21577
21578 (define_insn "cvtdq2ps"
21579   [(set (match_operand:V4SF 0 "register_operand" "=x")
21580         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21581   "TARGET_SSE2"
21582   "cvtdq2ps\t{%1, %0|%0, %1}"
21583   [(set_attr "type" "ssecvt")
21584    (set_attr "mode" "V2DF")])
21585
21586 (define_insn "cvtps2dq"
21587   [(set (match_operand:V4SI 0 "register_operand" "=x")
21588         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21589   "TARGET_SSE2"
21590   "cvtps2dq\t{%1, %0|%0, %1}"
21591   [(set_attr "type" "ssecvt")
21592    (set_attr "mode" "TI")])
21593
21594 (define_insn "cvttps2dq"
21595   [(set (match_operand:V4SI 0 "register_operand" "=x")
21596         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21597                      UNSPEC_FIX))]
21598   "TARGET_SSE2"
21599   "cvttps2dq\t{%1, %0|%0, %1}"
21600   [(set_attr "type" "ssecvt")
21601    (set_attr "mode" "TI")])
21602
21603 ;; Conversions between SI and DF
21604
21605 (define_insn "cvtdq2pd"
21606   [(set (match_operand:V2DF 0 "register_operand" "=x")
21607         (float:V2DF (vec_select:V2SI
21608                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21609                      (parallel
21610                       [(const_int 0)
21611                        (const_int 1)]))))]
21612   "TARGET_SSE2"
21613   "cvtdq2pd\t{%1, %0|%0, %1}"
21614   [(set_attr "type" "ssecvt")
21615    (set_attr "mode" "V2DF")])
21616
21617 (define_insn "cvtpd2dq"
21618   [(set (match_operand:V4SI 0 "register_operand" "=x")
21619         (vec_concat:V4SI
21620          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21621          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21622   "TARGET_SSE2"
21623   "cvtpd2dq\t{%1, %0|%0, %1}"
21624   [(set_attr "type" "ssecvt")
21625    (set_attr "mode" "TI")])
21626
21627 (define_insn "cvttpd2dq"
21628   [(set (match_operand:V4SI 0 "register_operand" "=x")
21629         (vec_concat:V4SI
21630          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21631                       UNSPEC_FIX)
21632          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21633   "TARGET_SSE2"
21634   "cvttpd2dq\t{%1, %0|%0, %1}"
21635   [(set_attr "type" "ssecvt")
21636    (set_attr "mode" "TI")])
21637
21638 (define_insn "cvtpd2pi"
21639   [(set (match_operand:V2SI 0 "register_operand" "=y")
21640         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21641   "TARGET_SSE2"
21642   "cvtpd2pi\t{%1, %0|%0, %1}"
21643   [(set_attr "type" "ssecvt")
21644    (set_attr "mode" "TI")])
21645
21646 (define_insn "cvttpd2pi"
21647   [(set (match_operand:V2SI 0 "register_operand" "=y")
21648         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21649                      UNSPEC_FIX))]
21650   "TARGET_SSE2"
21651   "cvttpd2pi\t{%1, %0|%0, %1}"
21652   [(set_attr "type" "ssecvt")
21653    (set_attr "mode" "TI")])
21654
21655 (define_insn "cvtpi2pd"
21656   [(set (match_operand:V2DF 0 "register_operand" "=x")
21657         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21658   "TARGET_SSE2"
21659   "cvtpi2pd\t{%1, %0|%0, %1}"
21660   [(set_attr "type" "ssecvt")
21661    (set_attr "mode" "TI")])
21662
21663 ;; Conversions between SI and DF
21664
21665 (define_insn "cvtsd2si"
21666   [(set (match_operand:SI 0 "register_operand" "=r,r")
21667         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21668                                (parallel [(const_int 0)]))))]
21669   "TARGET_SSE2"
21670   "cvtsd2si\t{%1, %0|%0, %1}"
21671   [(set_attr "type" "sseicvt")
21672    (set_attr "athlon_decode" "double,vector")
21673    (set_attr "mode" "SI")])
21674
21675 (define_insn "cvtsd2siq"
21676   [(set (match_operand:DI 0 "register_operand" "=r,r")
21677         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21678                                (parallel [(const_int 0)]))))]
21679   "TARGET_SSE2 && TARGET_64BIT"
21680   "cvtsd2siq\t{%1, %0|%0, %1}"
21681   [(set_attr "type" "sseicvt")
21682    (set_attr "athlon_decode" "double,vector")
21683    (set_attr "mode" "DI")])
21684
21685 (define_insn "cvttsd2si"
21686   [(set (match_operand:SI 0 "register_operand" "=r,r")
21687         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21688                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21689   "TARGET_SSE2"
21690   "cvttsd2si\t{%1, %0|%0, %1}"
21691   [(set_attr "type" "sseicvt")
21692    (set_attr "mode" "SI")
21693    (set_attr "athlon_decode" "double,vector")])
21694
21695 (define_insn "cvttsd2siq"
21696   [(set (match_operand:DI 0 "register_operand" "=r,r")
21697         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21698                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21699   "TARGET_SSE2 && TARGET_64BIT"
21700   "cvttsd2siq\t{%1, %0|%0, %1}"
21701   [(set_attr "type" "sseicvt")
21702    (set_attr "mode" "DI")
21703    (set_attr "athlon_decode" "double,vector")])
21704
21705 (define_insn "cvtsi2sd"
21706   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21707         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21708                         (vec_duplicate:V2DF
21709                           (float:DF
21710                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21711                         (const_int 2)))]
21712   "TARGET_SSE2"
21713   "cvtsi2sd\t{%2, %0|%0, %2}"
21714   [(set_attr "type" "sseicvt")
21715    (set_attr "mode" "DF")
21716    (set_attr "athlon_decode" "double,direct")])
21717
21718 (define_insn "cvtsi2sdq"
21719   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21720         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21721                         (vec_duplicate:V2DF
21722                           (float:DF
21723                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21724                         (const_int 2)))]
21725   "TARGET_SSE2 && TARGET_64BIT"
21726   "cvtsi2sdq\t{%2, %0|%0, %2}"
21727   [(set_attr "type" "sseicvt")
21728    (set_attr "mode" "DF")
21729    (set_attr "athlon_decode" "double,direct")])
21730
21731 ;; Conversions between SF and DF
21732
21733 (define_insn "cvtsd2ss"
21734   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21735         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21736                         (vec_duplicate:V4SF
21737                           (float_truncate:V2SF
21738                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21739                         (const_int 14)))]
21740   "TARGET_SSE2"
21741   "cvtsd2ss\t{%2, %0|%0, %2}"
21742   [(set_attr "type" "ssecvt")
21743    (set_attr "athlon_decode" "vector,double")
21744    (set_attr "mode" "SF")])
21745
21746 (define_insn "cvtss2sd"
21747   [(set (match_operand:V2DF 0 "register_operand" "=x")
21748         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21749                         (float_extend:V2DF
21750                           (vec_select:V2SF
21751                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21752                             (parallel [(const_int 0)
21753                                        (const_int 1)])))
21754                         (const_int 2)))]
21755   "TARGET_SSE2"
21756   "cvtss2sd\t{%2, %0|%0, %2}"
21757   [(set_attr "type" "ssecvt")
21758    (set_attr "mode" "DF")])
21759
21760 (define_insn "cvtpd2ps"
21761   [(set (match_operand:V4SF 0 "register_operand" "=x")
21762         (subreg:V4SF
21763           (vec_concat:V4SI
21764             (subreg:V2SI (float_truncate:V2SF
21765                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21766             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21767   "TARGET_SSE2"
21768   "cvtpd2ps\t{%1, %0|%0, %1}"
21769   [(set_attr "type" "ssecvt")
21770    (set_attr "mode" "V4SF")])
21771
21772 (define_insn "cvtps2pd"
21773   [(set (match_operand:V2DF 0 "register_operand" "=x")
21774         (float_extend:V2DF
21775           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21776                            (parallel [(const_int 0)
21777                                       (const_int 1)]))))]
21778   "TARGET_SSE2"
21779   "cvtps2pd\t{%1, %0|%0, %1}"
21780   [(set_attr "type" "ssecvt")
21781    (set_attr "mode" "V2DF")])
21782
21783 ;; SSE2 variants of MMX insns
21784
21785 ;; MMX arithmetic
21786
21787 (define_insn "addv16qi3"
21788   [(set (match_operand:V16QI 0 "register_operand" "=x")
21789         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21790                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21791   "TARGET_SSE2"
21792   "paddb\t{%2, %0|%0, %2}"
21793   [(set_attr "type" "sseiadd")
21794    (set_attr "mode" "TI")])
21795
21796 (define_insn "addv8hi3"
21797   [(set (match_operand:V8HI 0 "register_operand" "=x")
21798         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21799                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21800   "TARGET_SSE2"
21801   "paddw\t{%2, %0|%0, %2}"
21802   [(set_attr "type" "sseiadd")
21803    (set_attr "mode" "TI")])
21804
21805 (define_insn "addv4si3"
21806   [(set (match_operand:V4SI 0 "register_operand" "=x")
21807         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21808                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21809   "TARGET_SSE2"
21810   "paddd\t{%2, %0|%0, %2}"
21811   [(set_attr "type" "sseiadd")
21812    (set_attr "mode" "TI")])
21813
21814 (define_insn "addv2di3"
21815   [(set (match_operand:V2DI 0 "register_operand" "=x")
21816         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21817                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21818   "TARGET_SSE2"
21819   "paddq\t{%2, %0|%0, %2}"
21820   [(set_attr "type" "sseiadd")
21821    (set_attr "mode" "TI")])
21822
21823 (define_insn "ssaddv16qi3"
21824   [(set (match_operand:V16QI 0 "register_operand" "=x")
21825         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21826                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21827   "TARGET_SSE2"
21828   "paddsb\t{%2, %0|%0, %2}"
21829   [(set_attr "type" "sseiadd")
21830    (set_attr "mode" "TI")])
21831
21832 (define_insn "ssaddv8hi3"
21833   [(set (match_operand:V8HI 0 "register_operand" "=x")
21834         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21835                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21836   "TARGET_SSE2"
21837   "paddsw\t{%2, %0|%0, %2}"
21838   [(set_attr "type" "sseiadd")
21839    (set_attr "mode" "TI")])
21840
21841 (define_insn "usaddv16qi3"
21842   [(set (match_operand:V16QI 0 "register_operand" "=x")
21843         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21844                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21845   "TARGET_SSE2"
21846   "paddusb\t{%2, %0|%0, %2}"
21847   [(set_attr "type" "sseiadd")
21848    (set_attr "mode" "TI")])
21849
21850 (define_insn "usaddv8hi3"
21851   [(set (match_operand:V8HI 0 "register_operand" "=x")
21852         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21853                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21854   "TARGET_SSE2"
21855   "paddusw\t{%2, %0|%0, %2}"
21856   [(set_attr "type" "sseiadd")
21857    (set_attr "mode" "TI")])
21858
21859 (define_insn "subv16qi3"
21860   [(set (match_operand:V16QI 0 "register_operand" "=x")
21861         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21862                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21863   "TARGET_SSE2"
21864   "psubb\t{%2, %0|%0, %2}"
21865   [(set_attr "type" "sseiadd")
21866    (set_attr "mode" "TI")])
21867
21868 (define_insn "subv8hi3"
21869   [(set (match_operand:V8HI 0 "register_operand" "=x")
21870         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21871                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21872   "TARGET_SSE2"
21873   "psubw\t{%2, %0|%0, %2}"
21874   [(set_attr "type" "sseiadd")
21875    (set_attr "mode" "TI")])
21876
21877 (define_insn "subv4si3"
21878   [(set (match_operand:V4SI 0 "register_operand" "=x")
21879         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21880                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21881   "TARGET_SSE2"
21882   "psubd\t{%2, %0|%0, %2}"
21883   [(set_attr "type" "sseiadd")
21884    (set_attr "mode" "TI")])
21885
21886 (define_insn "subv2di3"
21887   [(set (match_operand:V2DI 0 "register_operand" "=x")
21888         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21889                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21890   "TARGET_SSE2"
21891   "psubq\t{%2, %0|%0, %2}"
21892   [(set_attr "type" "sseiadd")
21893    (set_attr "mode" "TI")])
21894
21895 (define_insn "sssubv16qi3"
21896   [(set (match_operand:V16QI 0 "register_operand" "=x")
21897         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21898                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21899   "TARGET_SSE2"
21900   "psubsb\t{%2, %0|%0, %2}"
21901   [(set_attr "type" "sseiadd")
21902    (set_attr "mode" "TI")])
21903
21904 (define_insn "sssubv8hi3"
21905   [(set (match_operand:V8HI 0 "register_operand" "=x")
21906         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21907                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21908   "TARGET_SSE2"
21909   "psubsw\t{%2, %0|%0, %2}"
21910   [(set_attr "type" "sseiadd")
21911    (set_attr "mode" "TI")])
21912
21913 (define_insn "ussubv16qi3"
21914   [(set (match_operand:V16QI 0 "register_operand" "=x")
21915         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21916                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21917   "TARGET_SSE2"
21918   "psubusb\t{%2, %0|%0, %2}"
21919   [(set_attr "type" "sseiadd")
21920    (set_attr "mode" "TI")])
21921
21922 (define_insn "ussubv8hi3"
21923   [(set (match_operand:V8HI 0 "register_operand" "=x")
21924         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21925                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21926   "TARGET_SSE2"
21927   "psubusw\t{%2, %0|%0, %2}"
21928   [(set_attr "type" "sseiadd")
21929    (set_attr "mode" "TI")])
21930
21931 (define_insn "mulv8hi3"
21932   [(set (match_operand:V8HI 0 "register_operand" "=x")
21933         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21934                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21935   "TARGET_SSE2"
21936   "pmullw\t{%2, %0|%0, %2}"
21937   [(set_attr "type" "sseimul")
21938    (set_attr "mode" "TI")])
21939
21940 (define_insn "smulv8hi3_highpart"
21941   [(set (match_operand:V8HI 0 "register_operand" "=x")
21942         (truncate:V8HI
21943          (lshiftrt:V8SI
21944           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21945                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21946           (const_int 16))))]
21947   "TARGET_SSE2"
21948   "pmulhw\t{%2, %0|%0, %2}"
21949   [(set_attr "type" "sseimul")
21950    (set_attr "mode" "TI")])
21951
21952 (define_insn "umulv8hi3_highpart"
21953   [(set (match_operand:V8HI 0 "register_operand" "=x")
21954         (truncate:V8HI
21955          (lshiftrt:V8SI
21956           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21957                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21958           (const_int 16))))]
21959   "TARGET_SSE2"
21960   "pmulhuw\t{%2, %0|%0, %2}"
21961   [(set_attr "type" "sseimul")
21962    (set_attr "mode" "TI")])
21963
21964 (define_insn "sse2_umulsidi3"
21965   [(set (match_operand:DI 0 "register_operand" "=y")
21966         (mult:DI (zero_extend:DI (vec_select:SI
21967                                   (match_operand:V2SI 1 "register_operand" "0")
21968                                   (parallel [(const_int 0)])))
21969                  (zero_extend:DI (vec_select:SI
21970                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21971                                   (parallel [(const_int 0)])))))]
21972   "TARGET_SSE2"
21973   "pmuludq\t{%2, %0|%0, %2}"
21974   [(set_attr "type" "sseimul")
21975    (set_attr "mode" "TI")])
21976
21977 (define_insn "sse2_umulv2siv2di3"
21978   [(set (match_operand:V2DI 0 "register_operand" "=x")
21979         (mult:V2DI (zero_extend:V2DI
21980                      (vec_select:V2SI
21981                        (match_operand:V4SI 1 "register_operand" "0")
21982                        (parallel [(const_int 0) (const_int 2)])))
21983                    (zero_extend:V2DI
21984                      (vec_select:V2SI
21985                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21986                        (parallel [(const_int 0) (const_int 2)])))))]
21987   "TARGET_SSE2"
21988   "pmuludq\t{%2, %0|%0, %2}"
21989   [(set_attr "type" "sseimul")
21990    (set_attr "mode" "TI")])
21991
21992 (define_insn "sse2_pmaddwd"
21993   [(set (match_operand:V4SI 0 "register_operand" "=x")
21994         (plus:V4SI
21995          (mult:V4SI
21996           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21997                                              (parallel [(const_int 0)
21998                                                         (const_int 2)
21999                                                         (const_int 4)
22000                                                         (const_int 6)])))
22001           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22002                                              (parallel [(const_int 0)
22003                                                         (const_int 2)
22004                                                         (const_int 4)
22005                                                         (const_int 6)]))))
22006          (mult:V4SI
22007           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22008                                              (parallel [(const_int 1)
22009                                                         (const_int 3)
22010                                                         (const_int 5)
22011                                                         (const_int 7)])))
22012           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22013                                              (parallel [(const_int 1)
22014                                                         (const_int 3)
22015                                                         (const_int 5)
22016                                                         (const_int 7)]))))))]
22017   "TARGET_SSE2"
22018   "pmaddwd\t{%2, %0|%0, %2}"
22019   [(set_attr "type" "sseiadd")
22020    (set_attr "mode" "TI")])
22021
22022 ;; Same as pxor, but don't show input operands so that we don't think
22023 ;; they are live.
22024 (define_insn "sse2_clrti"
22025   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22026   "TARGET_SSE2"
22027 {
22028   if (get_attr_mode (insn) == MODE_TI)
22029     return "pxor\t%0, %0";
22030   else
22031     return "xorps\t%0, %0";
22032 }
22033   [(set_attr "type" "ssemov")
22034    (set_attr "memory" "none")
22035    (set (attr "mode")
22036               (if_then_else
22037                 (ne (symbol_ref "optimize_size")
22038                     (const_int 0))
22039                 (const_string "V4SF")
22040                 (const_string "TI")))])
22041
22042 ;; MMX unsigned averages/sum of absolute differences
22043
22044 (define_insn "sse2_uavgv16qi3"
22045   [(set (match_operand:V16QI 0 "register_operand" "=x")
22046         (ashiftrt:V16QI
22047          (plus:V16QI (plus:V16QI
22048                      (match_operand:V16QI 1 "register_operand" "0")
22049                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22050                      (const_vector:V16QI [(const_int 1) (const_int 1)
22051                                           (const_int 1) (const_int 1)
22052                                           (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)))]
22059   "TARGET_SSE2"
22060   "pavgb\t{%2, %0|%0, %2}"
22061   [(set_attr "type" "sseiadd")
22062    (set_attr "mode" "TI")])
22063
22064 (define_insn "sse2_uavgv8hi3"
22065   [(set (match_operand:V8HI 0 "register_operand" "=x")
22066         (ashiftrt:V8HI
22067          (plus:V8HI (plus:V8HI
22068                      (match_operand:V8HI 1 "register_operand" "0")
22069                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22070                     (const_vector:V8HI [(const_int 1) (const_int 1)
22071                                         (const_int 1) (const_int 1)
22072                                         (const_int 1) (const_int 1)
22073                                         (const_int 1) (const_int 1)]))
22074          (const_int 1)))]
22075   "TARGET_SSE2"
22076   "pavgw\t{%2, %0|%0, %2}"
22077   [(set_attr "type" "sseiadd")
22078    (set_attr "mode" "TI")])
22079
22080 ;; @@@ this isn't the right representation.
22081 (define_insn "sse2_psadbw"
22082   [(set (match_operand:V2DI 0 "register_operand" "=x")
22083         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22084                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22085                      UNSPEC_PSADBW))]
22086   "TARGET_SSE2"
22087   "psadbw\t{%2, %0|%0, %2}"
22088   [(set_attr "type" "sseiadd")
22089    (set_attr "mode" "TI")])
22090
22091
22092 ;; MMX insert/extract/shuffle
22093
22094 (define_insn "sse2_pinsrw"
22095   [(set (match_operand:V8HI 0 "register_operand" "=x")
22096         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22097                         (vec_duplicate:V8HI
22098                          (truncate:HI
22099                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
22100                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22101   "TARGET_SSE2"
22102   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22103   [(set_attr "type" "ssecvt")
22104    (set_attr "mode" "TI")])
22105
22106 (define_insn "sse2_pextrw"
22107   [(set (match_operand:SI 0 "register_operand" "=r")
22108         (zero_extend:SI
22109           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22110                          (parallel
22111                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22112   "TARGET_SSE2"
22113   "pextrw\t{%2, %1, %0|%0, %1, %2}"
22114   [(set_attr "type" "ssecvt")
22115    (set_attr "mode" "TI")])
22116
22117 (define_insn "sse2_pshufd"
22118   [(set (match_operand:V4SI 0 "register_operand" "=x")
22119         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22120                       (match_operand:SI 2 "immediate_operand" "i")]
22121                      UNSPEC_SHUFFLE))]
22122   "TARGET_SSE2"
22123   "pshufd\t{%2, %1, %0|%0, %1, %2}"
22124   [(set_attr "type" "ssecvt")
22125    (set_attr "mode" "TI")])
22126
22127 (define_insn "sse2_pshuflw"
22128   [(set (match_operand:V8HI 0 "register_operand" "=x")
22129         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22130                       (match_operand:SI 2 "immediate_operand" "i")]
22131                      UNSPEC_PSHUFLW))]
22132   "TARGET_SSE2"
22133   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22134   [(set_attr "type" "ssecvt")
22135    (set_attr "mode" "TI")])
22136
22137 (define_insn "sse2_pshufhw"
22138   [(set (match_operand:V8HI 0 "register_operand" "=x")
22139         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22140                       (match_operand:SI 2 "immediate_operand" "i")]
22141                      UNSPEC_PSHUFHW))]
22142   "TARGET_SSE2"
22143   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22144   [(set_attr "type" "ssecvt")
22145    (set_attr "mode" "TI")])
22146
22147 ;; MMX mask-generating comparisons
22148
22149 (define_insn "eqv16qi3"
22150   [(set (match_operand:V16QI 0 "register_operand" "=x")
22151         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22152                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22153   "TARGET_SSE2"
22154   "pcmpeqb\t{%2, %0|%0, %2}"
22155   [(set_attr "type" "ssecmp")
22156    (set_attr "mode" "TI")])
22157
22158 (define_insn "eqv8hi3"
22159   [(set (match_operand:V8HI 0 "register_operand" "=x")
22160         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22161                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22162   "TARGET_SSE2"
22163   "pcmpeqw\t{%2, %0|%0, %2}"
22164   [(set_attr "type" "ssecmp")
22165    (set_attr "mode" "TI")])
22166
22167 (define_insn "eqv4si3"
22168   [(set (match_operand:V4SI 0 "register_operand" "=x")
22169         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22170                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22171   "TARGET_SSE2"
22172   "pcmpeqd\t{%2, %0|%0, %2}"
22173   [(set_attr "type" "ssecmp")
22174    (set_attr "mode" "TI")])
22175
22176 (define_insn "gtv16qi3"
22177   [(set (match_operand:V16QI 0 "register_operand" "=x")
22178         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22179                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22180   "TARGET_SSE2"
22181   "pcmpgtb\t{%2, %0|%0, %2}"
22182   [(set_attr "type" "ssecmp")
22183    (set_attr "mode" "TI")])
22184
22185 (define_insn "gtv8hi3"
22186   [(set (match_operand:V8HI 0 "register_operand" "=x")
22187         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22188                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22189   "TARGET_SSE2"
22190   "pcmpgtw\t{%2, %0|%0, %2}"
22191   [(set_attr "type" "ssecmp")
22192    (set_attr "mode" "TI")])
22193
22194 (define_insn "gtv4si3"
22195   [(set (match_operand:V4SI 0 "register_operand" "=x")
22196         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22197                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22198   "TARGET_SSE2"
22199   "pcmpgtd\t{%2, %0|%0, %2}"
22200   [(set_attr "type" "ssecmp")
22201    (set_attr "mode" "TI")])
22202
22203
22204 ;; MMX max/min insns
22205
22206 (define_insn "umaxv16qi3"
22207   [(set (match_operand:V16QI 0 "register_operand" "=x")
22208         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22209                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22210   "TARGET_SSE2"
22211   "pmaxub\t{%2, %0|%0, %2}"
22212   [(set_attr "type" "sseiadd")
22213    (set_attr "mode" "TI")])
22214
22215 (define_insn "smaxv8hi3"
22216   [(set (match_operand:V8HI 0 "register_operand" "=x")
22217         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22218                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22219   "TARGET_SSE2"
22220   "pmaxsw\t{%2, %0|%0, %2}"
22221   [(set_attr "type" "sseiadd")
22222    (set_attr "mode" "TI")])
22223
22224 (define_insn "uminv16qi3"
22225   [(set (match_operand:V16QI 0 "register_operand" "=x")
22226         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22227                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22228   "TARGET_SSE2"
22229   "pminub\t{%2, %0|%0, %2}"
22230   [(set_attr "type" "sseiadd")
22231    (set_attr "mode" "TI")])
22232
22233 (define_insn "sminv8hi3"
22234   [(set (match_operand:V8HI 0 "register_operand" "=x")
22235         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22236                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22237   "TARGET_SSE2"
22238   "pminsw\t{%2, %0|%0, %2}"
22239   [(set_attr "type" "sseiadd")
22240    (set_attr "mode" "TI")])
22241
22242
22243 ;; MMX shifts
22244
22245 (define_insn "ashrv8hi3"
22246   [(set (match_operand:V8HI 0 "register_operand" "=x")
22247         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22248                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22249   "TARGET_SSE2"
22250   "psraw\t{%2, %0|%0, %2}"
22251   [(set_attr "type" "sseishft")
22252    (set_attr "mode" "TI")])
22253
22254 (define_insn "ashrv4si3"
22255   [(set (match_operand:V4SI 0 "register_operand" "=x")
22256         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22257                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22258   "TARGET_SSE2"
22259   "psrad\t{%2, %0|%0, %2}"
22260   [(set_attr "type" "sseishft")
22261    (set_attr "mode" "TI")])
22262
22263 (define_insn "lshrv8hi3"
22264   [(set (match_operand:V8HI 0 "register_operand" "=x")
22265         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22266                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22267   "TARGET_SSE2"
22268   "psrlw\t{%2, %0|%0, %2}"
22269   [(set_attr "type" "sseishft")
22270    (set_attr "mode" "TI")])
22271
22272 (define_insn "lshrv4si3"
22273   [(set (match_operand:V4SI 0 "register_operand" "=x")
22274         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22275                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22276   "TARGET_SSE2"
22277   "psrld\t{%2, %0|%0, %2}"
22278   [(set_attr "type" "sseishft")
22279    (set_attr "mode" "TI")])
22280
22281 (define_insn "lshrv2di3"
22282   [(set (match_operand:V2DI 0 "register_operand" "=x")
22283         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22284                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22285   "TARGET_SSE2"
22286   "psrlq\t{%2, %0|%0, %2}"
22287   [(set_attr "type" "sseishft")
22288    (set_attr "mode" "TI")])
22289
22290 (define_insn "ashlv8hi3"
22291   [(set (match_operand:V8HI 0 "register_operand" "=x")
22292         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22293                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22294   "TARGET_SSE2"
22295   "psllw\t{%2, %0|%0, %2}"
22296   [(set_attr "type" "sseishft")
22297    (set_attr "mode" "TI")])
22298
22299 (define_insn "ashlv4si3"
22300   [(set (match_operand:V4SI 0 "register_operand" "=x")
22301         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22302                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22303   "TARGET_SSE2"
22304   "pslld\t{%2, %0|%0, %2}"
22305   [(set_attr "type" "sseishft")
22306    (set_attr "mode" "TI")])
22307
22308 (define_insn "ashlv2di3"
22309   [(set (match_operand:V2DI 0 "register_operand" "=x")
22310         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22311                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22312   "TARGET_SSE2"
22313   "psllq\t{%2, %0|%0, %2}"
22314   [(set_attr "type" "sseishft")
22315    (set_attr "mode" "TI")])
22316
22317 (define_insn "ashrv8hi3_ti"
22318   [(set (match_operand:V8HI 0 "register_operand" "=x")
22319         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22320                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22321   "TARGET_SSE2"
22322   "psraw\t{%2, %0|%0, %2}"
22323   [(set_attr "type" "sseishft")
22324    (set_attr "mode" "TI")])
22325
22326 (define_insn "ashrv4si3_ti"
22327   [(set (match_operand:V4SI 0 "register_operand" "=x")
22328         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22329                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22330   "TARGET_SSE2"
22331   "psrad\t{%2, %0|%0, %2}"
22332   [(set_attr "type" "sseishft")
22333    (set_attr "mode" "TI")])
22334
22335 (define_insn "lshrv8hi3_ti"
22336   [(set (match_operand:V8HI 0 "register_operand" "=x")
22337         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22338                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22339   "TARGET_SSE2"
22340   "psrlw\t{%2, %0|%0, %2}"
22341   [(set_attr "type" "sseishft")
22342    (set_attr "mode" "TI")])
22343
22344 (define_insn "lshrv4si3_ti"
22345   [(set (match_operand:V4SI 0 "register_operand" "=x")
22346         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22347                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22348   "TARGET_SSE2"
22349   "psrld\t{%2, %0|%0, %2}"
22350   [(set_attr "type" "sseishft")
22351    (set_attr "mode" "TI")])
22352
22353 (define_insn "lshrv2di3_ti"
22354   [(set (match_operand:V2DI 0 "register_operand" "=x")
22355         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22356                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22357   "TARGET_SSE2"
22358   "psrlq\t{%2, %0|%0, %2}"
22359   [(set_attr "type" "sseishft")
22360    (set_attr "mode" "TI")])
22361
22362 (define_insn "ashlv8hi3_ti"
22363   [(set (match_operand:V8HI 0 "register_operand" "=x")
22364         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22365                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22366   "TARGET_SSE2"
22367   "psllw\t{%2, %0|%0, %2}"
22368   [(set_attr "type" "sseishft")
22369    (set_attr "mode" "TI")])
22370
22371 (define_insn "ashlv4si3_ti"
22372   [(set (match_operand:V4SI 0 "register_operand" "=x")
22373         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22374                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22375   "TARGET_SSE2"
22376   "pslld\t{%2, %0|%0, %2}"
22377   [(set_attr "type" "sseishft")
22378    (set_attr "mode" "TI")])
22379
22380 (define_insn "ashlv2di3_ti"
22381   [(set (match_operand:V2DI 0 "register_operand" "=x")
22382         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22383                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22384   "TARGET_SSE2"
22385   "psllq\t{%2, %0|%0, %2}"
22386   [(set_attr "type" "sseishft")
22387    (set_attr "mode" "TI")])
22388
22389 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22390 ;; we wouldn't need here it since we never generate TImode arithmetic.
22391
22392 ;; There has to be some kind of prize for the weirdest new instruction...
22393 (define_insn "sse2_ashlti3"
22394   [(set (match_operand:TI 0 "register_operand" "=x")
22395         (unspec:TI
22396          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22397                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22398                                (const_int 8)))] UNSPEC_NOP))]
22399   "TARGET_SSE2"
22400   "pslldq\t{%2, %0|%0, %2}"
22401   [(set_attr "type" "sseishft")
22402    (set_attr "mode" "TI")])
22403
22404 (define_insn "sse2_lshrti3"
22405   [(set (match_operand:TI 0 "register_operand" "=x")
22406         (unspec:TI
22407          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22408                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22409                                 (const_int 8)))] UNSPEC_NOP))]
22410   "TARGET_SSE2"
22411   "psrldq\t{%2, %0|%0, %2}"
22412   [(set_attr "type" "sseishft")
22413    (set_attr "mode" "TI")])
22414
22415 ;; SSE unpack
22416
22417 (define_insn "sse2_unpckhpd"
22418   [(set (match_operand:V2DF 0 "register_operand" "=x")
22419         (vec_concat:V2DF
22420          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22421                         (parallel [(const_int 1)]))
22422          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22423                         (parallel [(const_int 1)]))))]
22424   "TARGET_SSE2"
22425   "unpckhpd\t{%2, %0|%0, %2}"
22426   [(set_attr "type" "ssecvt")
22427    (set_attr "mode" "V2DF")])
22428
22429 (define_insn "sse2_unpcklpd"
22430   [(set (match_operand:V2DF 0 "register_operand" "=x")
22431         (vec_concat:V2DF
22432          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22433                         (parallel [(const_int 0)]))
22434          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22435                         (parallel [(const_int 0)]))))]
22436   "TARGET_SSE2"
22437   "unpcklpd\t{%2, %0|%0, %2}"
22438   [(set_attr "type" "ssecvt")
22439    (set_attr "mode" "V2DF")])
22440
22441 ;; MMX pack/unpack insns.
22442
22443 (define_insn "sse2_packsswb"
22444   [(set (match_operand:V16QI 0 "register_operand" "=x")
22445         (vec_concat:V16QI
22446          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22447          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22448   "TARGET_SSE2"
22449   "packsswb\t{%2, %0|%0, %2}"
22450   [(set_attr "type" "ssecvt")
22451    (set_attr "mode" "TI")])
22452
22453 (define_insn "sse2_packssdw"
22454   [(set (match_operand:V8HI 0 "register_operand" "=x")
22455         (vec_concat:V8HI
22456          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22457          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22458   "TARGET_SSE2"
22459   "packssdw\t{%2, %0|%0, %2}"
22460   [(set_attr "type" "ssecvt")
22461    (set_attr "mode" "TI")])
22462
22463 (define_insn "sse2_packuswb"
22464   [(set (match_operand:V16QI 0 "register_operand" "=x")
22465         (vec_concat:V16QI
22466          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22467          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22468   "TARGET_SSE2"
22469   "packuswb\t{%2, %0|%0, %2}"
22470   [(set_attr "type" "ssecvt")
22471    (set_attr "mode" "TI")])
22472
22473 (define_insn "sse2_punpckhbw"
22474   [(set (match_operand:V16QI 0 "register_operand" "=x")
22475         (vec_merge:V16QI
22476          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22477                            (parallel [(const_int 8) (const_int 0)
22478                                       (const_int 9) (const_int 1)
22479                                       (const_int 10) (const_int 2)
22480                                       (const_int 11) (const_int 3)
22481                                       (const_int 12) (const_int 4)
22482                                       (const_int 13) (const_int 5)
22483                                       (const_int 14) (const_int 6)
22484                                       (const_int 15) (const_int 7)]))
22485          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22486                            (parallel [(const_int 0) (const_int 8)
22487                                       (const_int 1) (const_int 9)
22488                                       (const_int 2) (const_int 10)
22489                                       (const_int 3) (const_int 11)
22490                                       (const_int 4) (const_int 12)
22491                                       (const_int 5) (const_int 13)
22492                                       (const_int 6) (const_int 14)
22493                                       (const_int 7) (const_int 15)]))
22494          (const_int 21845)))]
22495   "TARGET_SSE2"
22496   "punpckhbw\t{%2, %0|%0, %2}"
22497   [(set_attr "type" "ssecvt")
22498    (set_attr "mode" "TI")])
22499
22500 (define_insn "sse2_punpckhwd"
22501   [(set (match_operand:V8HI 0 "register_operand" "=x")
22502         (vec_merge:V8HI
22503          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22504                           (parallel [(const_int 4) (const_int 0)
22505                                      (const_int 5) (const_int 1)
22506                                      (const_int 6) (const_int 2)
22507                                      (const_int 7) (const_int 3)]))
22508          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22509                           (parallel [(const_int 0) (const_int 4)
22510                                      (const_int 1) (const_int 5)
22511                                      (const_int 2) (const_int 6)
22512                                      (const_int 3) (const_int 7)]))
22513          (const_int 85)))]
22514   "TARGET_SSE2"
22515   "punpckhwd\t{%2, %0|%0, %2}"
22516   [(set_attr "type" "ssecvt")
22517    (set_attr "mode" "TI")])
22518
22519 (define_insn "sse2_punpckhdq"
22520   [(set (match_operand:V4SI 0 "register_operand" "=x")
22521         (vec_merge:V4SI
22522          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22523                           (parallel [(const_int 2) (const_int 0)
22524                                      (const_int 3) (const_int 1)]))
22525          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22526                           (parallel [(const_int 0) (const_int 2)
22527                                      (const_int 1) (const_int 3)]))
22528          (const_int 5)))]
22529   "TARGET_SSE2"
22530   "punpckhdq\t{%2, %0|%0, %2}"
22531   [(set_attr "type" "ssecvt")
22532    (set_attr "mode" "TI")])
22533
22534 (define_insn "sse2_punpcklbw"
22535   [(set (match_operand:V16QI 0 "register_operand" "=x")
22536         (vec_merge:V16QI
22537          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22538                            (parallel [(const_int 0) (const_int 8)
22539                                       (const_int 1) (const_int 9)
22540                                       (const_int 2) (const_int 10)
22541                                       (const_int 3) (const_int 11)
22542                                       (const_int 4) (const_int 12)
22543                                       (const_int 5) (const_int 13)
22544                                       (const_int 6) (const_int 14)
22545                                       (const_int 7) (const_int 15)]))
22546          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22547                            (parallel [(const_int 8) (const_int 0)
22548                                       (const_int 9) (const_int 1)
22549                                       (const_int 10) (const_int 2)
22550                                       (const_int 11) (const_int 3)
22551                                       (const_int 12) (const_int 4)
22552                                       (const_int 13) (const_int 5)
22553                                       (const_int 14) (const_int 6)
22554                                       (const_int 15) (const_int 7)]))
22555          (const_int 21845)))]
22556   "TARGET_SSE2"
22557   "punpcklbw\t{%2, %0|%0, %2}"
22558   [(set_attr "type" "ssecvt")
22559    (set_attr "mode" "TI")])
22560
22561 (define_insn "sse2_punpcklwd"
22562   [(set (match_operand:V8HI 0 "register_operand" "=x")
22563         (vec_merge:V8HI
22564          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22565                           (parallel [(const_int 0) (const_int 4)
22566                                      (const_int 1) (const_int 5)
22567                                      (const_int 2) (const_int 6)
22568                                      (const_int 3) (const_int 7)]))
22569          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22570                           (parallel [(const_int 4) (const_int 0)
22571                                      (const_int 5) (const_int 1)
22572                                      (const_int 6) (const_int 2)
22573                                      (const_int 7) (const_int 3)]))
22574          (const_int 85)))]
22575   "TARGET_SSE2"
22576   "punpcklwd\t{%2, %0|%0, %2}"
22577   [(set_attr "type" "ssecvt")
22578    (set_attr "mode" "TI")])
22579
22580 (define_insn "sse2_punpckldq"
22581   [(set (match_operand:V4SI 0 "register_operand" "=x")
22582         (vec_merge:V4SI
22583          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22584                           (parallel [(const_int 0) (const_int 2)
22585                                      (const_int 1) (const_int 3)]))
22586          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22587                           (parallel [(const_int 2) (const_int 0)
22588                                      (const_int 3) (const_int 1)]))
22589          (const_int 5)))]
22590   "TARGET_SSE2"
22591   "punpckldq\t{%2, %0|%0, %2}"
22592   [(set_attr "type" "ssecvt")
22593    (set_attr "mode" "TI")])
22594
22595 (define_insn "sse2_punpcklqdq"
22596   [(set (match_operand:V2DI 0 "register_operand" "=x")
22597         (vec_merge:V2DI
22598          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22599                           (parallel [(const_int 1)
22600                                      (const_int 0)]))
22601          (match_operand:V2DI 1 "register_operand" "0")
22602          (const_int 1)))]
22603   "TARGET_SSE2"
22604   "punpcklqdq\t{%2, %0|%0, %2}"
22605   [(set_attr "type" "ssecvt")
22606    (set_attr "mode" "TI")])
22607
22608 (define_insn "sse2_punpckhqdq"
22609   [(set (match_operand:V2DI 0 "register_operand" "=x")
22610         (vec_merge:V2DI
22611          (match_operand:V2DI 1 "register_operand" "0")
22612          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22613                           (parallel [(const_int 1)
22614                                      (const_int 0)]))
22615          (const_int 1)))]
22616   "TARGET_SSE2"
22617   "punpckhqdq\t{%2, %0|%0, %2}"
22618   [(set_attr "type" "ssecvt")
22619    (set_attr "mode" "TI")])
22620
22621 ;; SSE2 moves
22622
22623 (define_insn "sse2_movapd"
22624   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22625         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22626                      UNSPEC_MOVA))]
22627   "TARGET_SSE2
22628    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22629   "movapd\t{%1, %0|%0, %1}"
22630   [(set_attr "type" "ssemov")
22631    (set_attr "mode" "V2DF")])
22632
22633 (define_insn "sse2_movupd"
22634   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22635         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22636                      UNSPEC_MOVU))]
22637   "TARGET_SSE2
22638    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22639   "movupd\t{%1, %0|%0, %1}"
22640   [(set_attr "type" "ssecvt")
22641    (set_attr "mode" "V2DF")])
22642
22643 (define_insn "sse2_movdqa"
22644   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22645         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22646                        UNSPEC_MOVA))]
22647   "TARGET_SSE2
22648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22649   "movdqa\t{%1, %0|%0, %1}"
22650   [(set_attr "type" "ssemov")
22651    (set_attr "mode" "TI")])
22652
22653 (define_insn "sse2_movdqu"
22654   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22655         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22656                        UNSPEC_MOVU))]
22657   "TARGET_SSE2
22658    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22659   "movdqu\t{%1, %0|%0, %1}"
22660   [(set_attr "type" "ssecvt")
22661    (set_attr "mode" "TI")])
22662
22663 (define_insn "sse2_movdq2q"
22664   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22665         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22666                        (parallel [(const_int 0)])))]
22667   "TARGET_SSE2 && !TARGET_64BIT"
22668   "@
22669    movq\t{%1, %0|%0, %1}
22670    movdq2q\t{%1, %0|%0, %1}"
22671   [(set_attr "type" "ssecvt")
22672    (set_attr "mode" "TI")])
22673
22674 (define_insn "sse2_movdq2q_rex64"
22675   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22676         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22677                        (parallel [(const_int 0)])))]
22678   "TARGET_SSE2 && TARGET_64BIT"
22679   "@
22680    movq\t{%1, %0|%0, %1}
22681    movdq2q\t{%1, %0|%0, %1}
22682    movd\t{%1, %0|%0, %1}"
22683   [(set_attr "type" "ssecvt")
22684    (set_attr "mode" "TI")])
22685
22686 (define_insn "sse2_movq2dq"
22687   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22688         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22689                          (const_int 0)))]
22690   "TARGET_SSE2 && !TARGET_64BIT"
22691   "@
22692    movq\t{%1, %0|%0, %1}
22693    movq2dq\t{%1, %0|%0, %1}"
22694   [(set_attr "type" "ssecvt,ssemov")
22695    (set_attr "mode" "TI")])
22696
22697 (define_insn "sse2_movq2dq_rex64"
22698   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22699         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22700                          (const_int 0)))]
22701   "TARGET_SSE2 && TARGET_64BIT"
22702   "@
22703    movq\t{%1, %0|%0, %1}
22704    movq2dq\t{%1, %0|%0, %1}
22705    movd\t{%1, %0|%0, %1}"
22706   [(set_attr "type" "ssecvt,ssemov,ssecvt")
22707    (set_attr "mode" "TI")])
22708
22709 (define_insn "sse2_movq"
22710   [(set (match_operand:V2DI 0 "register_operand" "=x")
22711         (vec_concat:V2DI (vec_select:DI
22712                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22713                           (parallel [(const_int 0)]))
22714                          (const_int 0)))]
22715   "TARGET_SSE2"
22716   "movq\t{%1, %0|%0, %1}"
22717   [(set_attr "type" "ssemov")
22718    (set_attr "mode" "TI")])
22719
22720 (define_insn "sse2_loadd"
22721   [(set (match_operand:V4SI 0 "register_operand" "=x")
22722         (vec_merge:V4SI
22723          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22724          (const_vector:V4SI [(const_int 0)
22725                              (const_int 0)
22726                              (const_int 0)
22727                              (const_int 0)])
22728          (const_int 1)))]
22729   "TARGET_SSE2"
22730   "movd\t{%1, %0|%0, %1}"
22731   [(set_attr "type" "ssemov")
22732    (set_attr "mode" "TI")])
22733
22734 (define_insn "sse2_stored"
22735   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22736         (vec_select:SI
22737          (match_operand:V4SI 1 "register_operand" "x")
22738          (parallel [(const_int 0)])))]
22739   "TARGET_SSE2"
22740   "movd\t{%1, %0|%0, %1}"
22741   [(set_attr "type" "ssemov")
22742    (set_attr "mode" "TI")])
22743
22744 (define_insn "sse2_movhpd"
22745   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22746         (vec_merge:V2DF
22747          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22748          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22749          (const_int 2)))]
22750   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22751   "movhpd\t{%2, %0|%0, %2}"
22752   [(set_attr "type" "ssecvt")
22753    (set_attr "mode" "V2DF")])
22754
22755 (define_expand "sse2_loadsd"
22756   [(match_operand:V2DF 0 "register_operand" "")
22757    (match_operand:DF 1 "memory_operand" "")]
22758   "TARGET_SSE2"
22759 {
22760   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22761                                 CONST0_RTX (V2DFmode)));
22762   DONE;
22763 })
22764
22765 (define_insn "sse2_loadsd_1"
22766   [(set (match_operand:V2DF 0 "register_operand" "=x")
22767         (vec_merge:V2DF
22768          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22769          (match_operand:V2DF 2 "const0_operand" "X")
22770          (const_int 1)))]
22771   "TARGET_SSE2"
22772   "movsd\t{%1, %0|%0, %1}"
22773   [(set_attr "type" "ssecvt")
22774    (set_attr "mode" "DF")])
22775
22776 (define_insn "sse2_movsd"
22777   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22778         (vec_merge:V2DF
22779          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22780          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22781          (const_int 1)))]
22782   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22783   "@movsd\t{%2, %0|%0, %2}
22784     movlpd\t{%2, %0|%0, %2}
22785     movlpd\t{%2, %0|%0, %2}"
22786   [(set_attr "type" "ssecvt")
22787    (set_attr "mode" "DF,V2DF,V2DF")])
22788
22789 (define_insn "sse2_storesd"
22790   [(set (match_operand:DF 0 "memory_operand" "=m")
22791         (vec_select:DF
22792          (match_operand:V2DF 1 "register_operand" "x")
22793          (parallel [(const_int 0)])))]
22794   "TARGET_SSE2"
22795   "movsd\t{%1, %0|%0, %1}"
22796   [(set_attr "type" "ssecvt")
22797    (set_attr "mode" "DF")])
22798
22799 (define_insn "sse2_shufpd"
22800   [(set (match_operand:V2DF 0 "register_operand" "=x")
22801         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22802                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22803                       (match_operand:SI 3 "immediate_operand" "i")]
22804                      UNSPEC_SHUFFLE))]
22805   "TARGET_SSE2"
22806   ;; @@@ check operand order for intel/nonintel syntax
22807   "shufpd\t{%3, %2, %0|%0, %2, %3}"
22808   [(set_attr "type" "ssecvt")
22809    (set_attr "mode" "V2DF")])
22810
22811 (define_insn "sse2_clflush"
22812   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22813                     UNSPECV_CLFLUSH)]
22814   "TARGET_SSE2"
22815   "clflush %0"
22816   [(set_attr "type" "sse")
22817    (set_attr "memory" "unknown")])
22818
22819 (define_expand "sse2_mfence"
22820   [(set (match_dup 0)
22821         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22822   "TARGET_SSE2"
22823 {
22824   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22825   MEM_VOLATILE_P (operands[0]) = 1;
22826 })
22827
22828 (define_insn "*mfence_insn"
22829   [(set (match_operand:BLK 0 "" "")
22830         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22831   "TARGET_SSE2"
22832   "mfence"
22833   [(set_attr "type" "sse")
22834    (set_attr "memory" "unknown")])
22835
22836 (define_expand "sse2_lfence"
22837   [(set (match_dup 0)
22838         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22839   "TARGET_SSE2"
22840 {
22841   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22842   MEM_VOLATILE_P (operands[0]) = 1;
22843 })
22844
22845 (define_insn "*lfence_insn"
22846   [(set (match_operand:BLK 0 "" "")
22847         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22848   "TARGET_SSE2"
22849   "lfence"
22850   [(set_attr "type" "sse")
22851    (set_attr "memory" "unknown")])
22852
22853 ;; SSE3
22854
22855 (define_insn "mwait"
22856   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22857                      (match_operand:SI 1 "register_operand" "c")]
22858                     UNSPECV_MWAIT)]
22859   "TARGET_SSE3"
22860   "mwait\t%0, %1"
22861   [(set_attr "length" "3")])
22862
22863 (define_insn "monitor"
22864   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22865                      (match_operand:SI 1 "register_operand" "c")
22866                      (match_operand:SI 2 "register_operand" "d")]
22867                     UNSPECV_MONITOR)]
22868   "TARGET_SSE3"
22869   "monitor\t%0, %1, %2"
22870   [(set_attr "length" "3")])
22871
22872 ;; SSE3 arithmetic
22873
22874 (define_insn "addsubv4sf3"
22875   [(set (match_operand:V4SF 0 "register_operand" "=x")
22876         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22877                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22878                      UNSPEC_ADDSUB))]
22879   "TARGET_SSE3"
22880   "addsubps\t{%2, %0|%0, %2}"
22881   [(set_attr "type" "sseadd")
22882    (set_attr "mode" "V4SF")])
22883
22884 (define_insn "addsubv2df3"
22885   [(set (match_operand:V2DF 0 "register_operand" "=x")
22886         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22887                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22888                      UNSPEC_ADDSUB))]
22889   "TARGET_SSE3"
22890   "addsubpd\t{%2, %0|%0, %2}"
22891   [(set_attr "type" "sseadd")
22892    (set_attr "mode" "V2DF")])
22893
22894 (define_insn "haddv4sf3"
22895   [(set (match_operand:V4SF 0 "register_operand" "=x")
22896         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22897                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22898                      UNSPEC_HADD))]
22899   "TARGET_SSE3"
22900   "haddps\t{%2, %0|%0, %2}"
22901   [(set_attr "type" "sseadd")
22902    (set_attr "mode" "V4SF")])
22903
22904 (define_insn "haddv2df3"
22905   [(set (match_operand:V2DF 0 "register_operand" "=x")
22906         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22907                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22908                      UNSPEC_HADD))]
22909   "TARGET_SSE3"
22910   "haddpd\t{%2, %0|%0, %2}"
22911   [(set_attr "type" "sseadd")
22912    (set_attr "mode" "V2DF")])
22913
22914 (define_insn "hsubv4sf3"
22915   [(set (match_operand:V4SF 0 "register_operand" "=x")
22916         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22917                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22918                      UNSPEC_HSUB))]
22919   "TARGET_SSE3"
22920   "hsubps\t{%2, %0|%0, %2}"
22921   [(set_attr "type" "sseadd")
22922    (set_attr "mode" "V4SF")])
22923
22924 (define_insn "hsubv2df3"
22925   [(set (match_operand:V2DF 0 "register_operand" "=x")
22926         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22927                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22928                      UNSPEC_HSUB))]
22929   "TARGET_SSE3"
22930   "hsubpd\t{%2, %0|%0, %2}"
22931   [(set_attr "type" "sseadd")
22932    (set_attr "mode" "V2DF")])
22933
22934 (define_insn "movshdup"
22935   [(set (match_operand:V4SF 0 "register_operand" "=x")
22936         (unspec:V4SF
22937          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22938   "TARGET_SSE3"
22939   "movshdup\t{%1, %0|%0, %1}"
22940   [(set_attr "type" "sse")
22941    (set_attr "mode" "V4SF")])
22942
22943 (define_insn "movsldup"
22944   [(set (match_operand:V4SF 0 "register_operand" "=x")
22945         (unspec:V4SF
22946          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22947   "TARGET_SSE3"
22948   "movsldup\t{%1, %0|%0, %1}"
22949   [(set_attr "type" "sse")
22950    (set_attr "mode" "V4SF")])
22951
22952 (define_insn "lddqu"
22953   [(set (match_operand:V16QI 0 "register_operand" "=x")
22954         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22955                        UNSPEC_LDQQU))]
22956   "TARGET_SSE3"
22957   "lddqu\t{%1, %0|%0, %1}"
22958   [(set_attr "type" "ssecvt")
22959    (set_attr "mode" "TI")])
22960
22961 (define_insn "loadddup"
22962   [(set (match_operand:V2DF 0 "register_operand" "=x")
22963         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
22964   "TARGET_SSE3"
22965   "movddup\t{%1, %0|%0, %1}"
22966   [(set_attr "type" "ssecvt")
22967    (set_attr "mode" "DF")])
22968
22969 (define_insn "movddup"
22970   [(set (match_operand:V2DF 0 "register_operand" "=x")
22971         (vec_duplicate:V2DF
22972          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
22973                         (parallel [(const_int 0)]))))]
22974   "TARGET_SSE3"
22975   "movddup\t{%1, %0|%0, %1}"
22976   [(set_attr "type" "ssecvt")
22977    (set_attr "mode" "DF")])