OSDN Git Service

2004-02-11 Uros Bizjak <uros@kss-loka.si>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
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 [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "TARGET_PARTIAL_REG_STALL"
1383   "xchg{w}\t%1, %0"
1384   [(set_attr "type" "imov")
1385    (set_attr "pent_pair" "np")
1386    (set_attr "mode" "HI")
1387    (set_attr "modrm" "0")
1388    (set_attr "ppro_uops" "few")])
1389
1390 (define_insn "*swaphi_2"
1391   [(set (match_operand:HI 0 "register_operand" "+r")
1392         (match_operand:HI 1 "register_operand" "+r"))
1393    (set (match_dup 1)
1394         (match_dup 0))]
1395   "! TARGET_PARTIAL_REG_STALL"
1396   "xchg{l}\t%k1, %k0"
1397   [(set_attr "type" "imov")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "mode" "SI")
1400    (set_attr "modrm" "0")
1401    (set_attr "ppro_uops" "few")])
1402
1403 (define_expand "movstricthi"
1404   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1405         (match_operand:HI 1 "general_operand" ""))]
1406   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407 {
1408   /* Don't generate memory->memory moves, go through a register */
1409   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1410     operands[1] = force_reg (HImode, operands[1]);
1411 })
1412
1413 (define_insn "*movstricthi_1"
1414   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1415         (match_operand:HI 1 "general_operand" "rn,m"))]
1416   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1417    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1418   "mov{w}\t{%1, %0|%0, %1}"
1419   [(set_attr "type" "imov")
1420    (set_attr "mode" "HI")])
1421
1422 (define_insn "*movstricthi_xor"
1423   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1424         (match_operand:HI 1 "const0_operand" "i"))
1425    (clobber (reg:CC 17))]
1426   "reload_completed
1427    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1428   "xor{w}\t{%0, %0|%0, %0}"
1429   [(set_attr "type" "alu1")
1430    (set_attr "mode" "HI")
1431    (set_attr "length_immediate" "0")])
1432
1433 (define_expand "movqi"
1434   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1435         (match_operand:QI 1 "general_operand" ""))]
1436   ""
1437   "ix86_expand_move (QImode, operands); DONE;")
1438
1439 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1440 ;; "push a byte".  But actually we use pushw, which has the effect
1441 ;; of rounding the amount pushed up to a halfword.
1442
1443 (define_insn "*pushqi2"
1444   [(set (match_operand:QI 0 "push_operand" "=X,X")
1445         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1446   "!TARGET_64BIT"
1447   "@
1448    push{w}\t{|word ptr }%1
1449    push{w}\t%w1"
1450   [(set_attr "type" "push")
1451    (set_attr "mode" "HI")])
1452
1453 ;; For 64BIT abi we always round up to 8 bytes.
1454 (define_insn "*pushqi2_rex64"
1455   [(set (match_operand:QI 0 "push_operand" "=X")
1456         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1457   "TARGET_64BIT"
1458   "push{q}\t%q1"
1459   [(set_attr "type" "push")
1460    (set_attr "mode" "QI")])
1461
1462 ;; Situation is quite tricky about when to choose full sized (SImode) move
1463 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1464 ;; partial register dependency machines (such as AMD Athlon), where QImode
1465 ;; moves issue extra dependency and for partial register stalls machines
1466 ;; that don't use QImode patterns (and QImode move cause stall on the next
1467 ;; instruction).
1468 ;;
1469 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1470 ;; register stall machines with, where we use QImode instructions, since
1471 ;; partial register stall can be caused there.  Then we use movzx.
1472 (define_insn "*movqi_1"
1473   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1474         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1475   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1476 {
1477   switch (get_attr_type (insn))
1478     {
1479     case TYPE_IMOVX:
1480       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1481         abort ();
1482       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1483     default:
1484       if (get_attr_mode (insn) == MODE_SI)
1485         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1486       else
1487         return "mov{b}\t{%1, %0|%0, %1}";
1488     }
1489 }
1490   [(set (attr "type")
1491      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1492               (const_string "imov")
1493             (and (eq_attr "alternative" "3")
1494                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495                           (const_int 0))
1496                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1497                           (const_int 0))))
1498               (const_string "imov")
1499             (eq_attr "alternative" "3,5")
1500               (const_string "imovx")
1501             (and (ne (symbol_ref "TARGET_MOVX")
1502                      (const_int 0))
1503                  (eq_attr "alternative" "2"))
1504               (const_string "imovx")
1505            ]
1506            (const_string "imov")))
1507    (set (attr "mode")
1508       (cond [(eq_attr "alternative" "3,4,5")
1509                (const_string "SI")
1510              (eq_attr "alternative" "6")
1511                (const_string "QI")
1512              (eq_attr "type" "imovx")
1513                (const_string "SI")
1514              (and (eq_attr "type" "imov")
1515                   (and (eq_attr "alternative" "0,1,2")
1516                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517                            (const_int 0))))
1518                (const_string "SI")
1519              ;; Avoid partial register stalls when not using QImode arithmetic
1520              (and (eq_attr "type" "imov")
1521                   (and (eq_attr "alternative" "0,1,2")
1522                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1523                                 (const_int 0))
1524                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1525                                 (const_int 0)))))
1526                (const_string "SI")
1527            ]
1528            (const_string "QI")))])
1529
1530 (define_expand "reload_outqi"
1531   [(parallel [(match_operand:QI 0 "" "=m")
1532               (match_operand:QI 1 "register_operand" "r")
1533               (match_operand:QI 2 "register_operand" "=&q")])]
1534   ""
1535 {
1536   rtx op0, op1, op2;
1537   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1538
1539   if (reg_overlap_mentioned_p (op2, op0))
1540     abort ();
1541   if (! q_regs_operand (op1, QImode))
1542     {
1543       emit_insn (gen_movqi (op2, op1));
1544       op1 = op2;
1545     }
1546   emit_insn (gen_movqi (op0, op1));
1547   DONE;
1548 })
1549
1550 (define_insn "*swapqi"
1551   [(set (match_operand:QI 0 "register_operand" "+r")
1552         (match_operand:QI 1 "register_operand" "+r"))
1553    (set (match_dup 1)
1554         (match_dup 0))]
1555   ""
1556   "xchg{b}\t%1, %0"
1557   [(set_attr "type" "imov")
1558    (set_attr "pent_pair" "np")
1559    (set_attr "mode" "QI")
1560    (set_attr "modrm" "0")
1561    (set_attr "ppro_uops" "few")])
1562
1563 (define_expand "movstrictqi"
1564   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1565         (match_operand:QI 1 "general_operand" ""))]
1566   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1567 {
1568   /* Don't generate memory->memory moves, go through a register.  */
1569   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1570     operands[1] = force_reg (QImode, operands[1]);
1571 })
1572
1573 (define_insn "*movstrictqi_1"
1574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1575         (match_operand:QI 1 "general_operand" "*qn,m"))]
1576   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1577    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1578   "mov{b}\t{%1, %0|%0, %1}"
1579   [(set_attr "type" "imov")
1580    (set_attr "mode" "QI")])
1581
1582 (define_insn "*movstrictqi_xor"
1583   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1584         (match_operand:QI 1 "const0_operand" "i"))
1585    (clobber (reg:CC 17))]
1586   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1587   "xor{b}\t{%0, %0|%0, %0}"
1588   [(set_attr "type" "alu1")
1589    (set_attr "mode" "QI")
1590    (set_attr "length_immediate" "0")])
1591
1592 (define_insn "*movsi_extv_1"
1593   [(set (match_operand:SI 0 "register_operand" "=R")
1594         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1595                          (const_int 8)
1596                          (const_int 8)))]
1597   ""
1598   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1599   [(set_attr "type" "imovx")
1600    (set_attr "mode" "SI")])
1601
1602 (define_insn "*movhi_extv_1"
1603   [(set (match_operand:HI 0 "register_operand" "=R")
1604         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1605                          (const_int 8)
1606                          (const_int 8)))]
1607   ""
1608   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1609   [(set_attr "type" "imovx")
1610    (set_attr "mode" "SI")])
1611
1612 (define_insn "*movqi_extv_1"
1613   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "!TARGET_64BIT"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1626 }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1638
1639 (define_insn "*movqi_extv_1_rex64"
1640   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1641         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1642                          (const_int 8)
1643                          (const_int 8)))]
1644   "TARGET_64BIT"
1645 {
1646   switch (get_attr_type (insn))
1647     {
1648     case TYPE_IMOVX:
1649       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1650     default:
1651       return "mov{b}\t{%h1, %0|%0, %h1}";
1652     }
1653 }
1654   [(set (attr "type")
1655      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657                              (ne (symbol_ref "TARGET_MOVX")
1658                                  (const_int 0))))
1659         (const_string "imovx")
1660         (const_string "imov")))
1661    (set (attr "mode")
1662      (if_then_else (eq_attr "type" "imovx")
1663         (const_string "SI")
1664         (const_string "QI")))])
1665
1666 ;; Stores and loads of ax to arbitrary constant address.
1667 ;; We fake an second form of instruction to force reload to load address
1668 ;; into register when rax is not available
1669 (define_insn "*movabsqi_1_rex64"
1670   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1671         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1672   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1673   "@
1674    movabs{b}\t{%1, %P0|%P0, %1}
1675    mov{b}\t{%1, %a0|%a0, %1}"
1676   [(set_attr "type" "imov")
1677    (set_attr "modrm" "0,*")
1678    (set_attr "length_address" "8,0")
1679    (set_attr "length_immediate" "0,*")
1680    (set_attr "memory" "store")
1681    (set_attr "mode" "QI")])
1682
1683 (define_insn "*movabsqi_2_rex64"
1684   [(set (match_operand:QI 0 "register_operand" "=a,r")
1685         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1686   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1687   "@
1688    movabs{b}\t{%P1, %0|%0, %P1}
1689    mov{b}\t{%a1, %0|%0, %a1}"
1690   [(set_attr "type" "imov")
1691    (set_attr "modrm" "0,*")
1692    (set_attr "length_address" "8,0")
1693    (set_attr "length_immediate" "0")
1694    (set_attr "memory" "load")
1695    (set_attr "mode" "QI")])
1696
1697 (define_insn "*movsi_extzv_1"
1698   [(set (match_operand:SI 0 "register_operand" "=R")
1699         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1700                          (const_int 8)
1701                          (const_int 8)))]
1702   ""
1703   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1704   [(set_attr "type" "imovx")
1705    (set_attr "mode" "SI")])
1706
1707 (define_insn "*movqi_extzv_2"
1708   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "!TARGET_64BIT"
1713 {
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1721 }
1722   [(set (attr "type")
1723      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1724                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1725                              (ne (symbol_ref "TARGET_MOVX")
1726                                  (const_int 0))))
1727         (const_string "imovx")
1728         (const_string "imov")))
1729    (set (attr "mode")
1730      (if_then_else (eq_attr "type" "imovx")
1731         (const_string "SI")
1732         (const_string "QI")))])
1733
1734 (define_insn "*movqi_extzv_2_rex64"
1735   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1736         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737                                     (const_int 8)
1738                                     (const_int 8)) 0))]
1739   "TARGET_64BIT"
1740 {
1741   switch (get_attr_type (insn))
1742     {
1743     case TYPE_IMOVX:
1744       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1745     default:
1746       return "mov{b}\t{%h1, %0|%0, %h1}";
1747     }
1748 }
1749   [(set (attr "type")
1750      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1751                         (ne (symbol_ref "TARGET_MOVX")
1752                             (const_int 0)))
1753         (const_string "imovx")
1754         (const_string "imov")))
1755    (set (attr "mode")
1756      (if_then_else (eq_attr "type" "imovx")
1757         (const_string "SI")
1758         (const_string "QI")))])
1759
1760 (define_insn "movsi_insv_1"
1761   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1762                          (const_int 8)
1763                          (const_int 8))
1764         (match_operand:SI 1 "general_operand" "Qmn"))]
1765   "!TARGET_64BIT"
1766   "mov{b}\t{%b1, %h0|%h0, %b1}"
1767   [(set_attr "type" "imov")
1768    (set_attr "mode" "QI")])
1769
1770 (define_insn "*movsi_insv_1_rex64"
1771   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1772                          (const_int 8)
1773                          (const_int 8))
1774         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1775   "TARGET_64BIT"
1776   "mov{b}\t{%b1, %h0|%h0, %b1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "QI")])
1779
1780 (define_insn "*movqi_insv_2"
1781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1782                          (const_int 8)
1783                          (const_int 8))
1784         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1785                      (const_int 8)))]
1786   ""
1787   "mov{b}\t{%h1, %h0|%h0, %h1}"
1788   [(set_attr "type" "imov")
1789    (set_attr "mode" "QI")])
1790
1791 (define_expand "movdi"
1792   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1793         (match_operand:DI 1 "general_operand" ""))]
1794   ""
1795   "ix86_expand_move (DImode, operands); DONE;")
1796
1797 (define_insn "*pushdi"
1798   [(set (match_operand:DI 0 "push_operand" "=<")
1799         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1800   "!TARGET_64BIT"
1801   "#")
1802
1803 (define_insn "pushdi2_rex64"
1804   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1805         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1806   "TARGET_64BIT"
1807   "@
1808    push{q}\t%1
1809    #"
1810   [(set_attr "type" "push,multi")
1811    (set_attr "mode" "DI")])
1812
1813 ;; Convert impossible pushes of immediate to existing instructions.
1814 ;; First try to get scratch register and go through it.  In case this
1815 ;; fails, push sign extended lower part first and then overwrite
1816 ;; upper part by 32bit move.
1817 (define_peephole2
1818   [(match_scratch:DI 2 "r")
1819    (set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode)"
1823   [(set (match_dup 2) (match_dup 1))
1824    (set (match_dup 0) (match_dup 2))]
1825   "")
1826
1827 ;; We need to define this as both peepholer and splitter for case
1828 ;; peephole2 pass is not run.
1829 (define_peephole2
1830   [(set (match_operand:DI 0 "push_operand" "")
1831         (match_operand:DI 1 "immediate_operand" ""))]
1832   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1833    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1834   [(set (match_dup 0) (match_dup 1))
1835    (set (match_dup 2) (match_dup 3))]
1836   "split_di (operands + 1, 1, operands + 2, operands + 3);
1837    operands[1] = gen_lowpart (DImode, operands[2]);
1838    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1839                                                     GEN_INT (4)));
1840   ")
1841
1842 (define_split
1843   [(set (match_operand:DI 0 "push_operand" "")
1844         (match_operand:DI 1 "immediate_operand" ""))]
1845   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1846    && !symbolic_operand (operands[1], DImode)
1847    && !x86_64_immediate_operand (operands[1], DImode)"
1848   [(set (match_dup 0) (match_dup 1))
1849    (set (match_dup 2) (match_dup 3))]
1850   "split_di (operands + 1, 1, operands + 2, operands + 3);
1851    operands[1] = gen_lowpart (DImode, operands[2]);
1852    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1853                                                     GEN_INT (4)));
1854   ")
1855
1856 (define_insn "*pushdi2_prologue_rex64"
1857   [(set (match_operand:DI 0 "push_operand" "=<")
1858         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "push{q}\t%1"
1862   [(set_attr "type" "push")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "*popdi1_epilogue_rex64"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI 7)))
1868    (set (reg:DI 7)
1869         (plus:DI (reg:DI 7) (const_int 8)))
1870    (clobber (mem:BLK (scratch)))]
1871   "TARGET_64BIT"
1872   "pop{q}\t%0"
1873   [(set_attr "type" "pop")
1874    (set_attr "mode" "DI")])
1875
1876 (define_insn "popdi1"
1877   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1878         (mem:DI (reg:DI 7)))
1879    (set (reg:DI 7)
1880         (plus:DI (reg:DI 7) (const_int 8)))]
1881   "TARGET_64BIT"
1882   "pop{q}\t%0"
1883   [(set_attr "type" "pop")
1884    (set_attr "mode" "DI")])
1885
1886 (define_insn "*movdi_xor_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const0_operand" "i"))
1889    (clobber (reg:CC 17))]
1890   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1891    && reload_completed"
1892   "xor{l}\t{%k0, %k0|%k0, %k0}"
1893   [(set_attr "type" "alu1")
1894    (set_attr "mode" "SI")
1895    (set_attr "length_immediate" "0")])
1896
1897 (define_insn "*movdi_or_rex64"
1898   [(set (match_operand:DI 0 "register_operand" "=r")
1899         (match_operand:DI 1 "const_int_operand" "i"))
1900    (clobber (reg:CC 17))]
1901   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1902    && reload_completed
1903    && operands[1] == constm1_rtx"
1904 {
1905   operands[1] = constm1_rtx;
1906   return "or{q}\t{%1, %0|%0, %1}";
1907 }
1908   [(set_attr "type" "alu1")
1909    (set_attr "mode" "DI")
1910    (set_attr "length_immediate" "1")])
1911
1912 (define_insn "*movdi_2"
1913   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1914         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1915   "!TARGET_64BIT
1916    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1917   "@
1918    #
1919    #
1920    movq\t{%1, %0|%0, %1}
1921    movq\t{%1, %0|%0, %1}
1922    movq\t{%1, %0|%0, %1}
1923    movdqa\t{%1, %0|%0, %1}
1924    movq\t{%1, %0|%0, %1}"
1925   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1926    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1927
1928 (define_split
1929   [(set (match_operand:DI 0 "push_operand" "")
1930         (match_operand:DI 1 "general_operand" ""))]
1931   "!TARGET_64BIT && reload_completed
1932    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1933   [(const_int 0)]
1934   "ix86_split_long_move (operands); DONE;")
1935
1936 ;; %%% This multiword shite has got to go.
1937 (define_split
1938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1939         (match_operand:DI 1 "general_operand" ""))]
1940   "!TARGET_64BIT && reload_completed
1941    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1942    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1943   [(const_int 0)]
1944   "ix86_split_long_move (operands); DONE;")
1945
1946 (define_insn "*movdi_1_rex64"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1948         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1949   "TARGET_64BIT
1950    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1951    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1952 {
1953   switch (get_attr_type (insn))
1954     {
1955     case TYPE_SSEMOV:
1956       if (get_attr_mode (insn) == MODE_TI)
1957           return "movdqa\t{%1, %0|%0, %1}";
1958       /* FALLTHRU */
1959     case TYPE_MMXMOV:
1960       /* Moves from and into integer register is done using movd opcode with
1961          REX prefix.  */
1962       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1963           return "movd\t{%1, %0|%0, %1}";
1964       return "movq\t{%1, %0|%0, %1}";
1965     case TYPE_MULTI:
1966       return "#";
1967     case TYPE_LEA:
1968       return "lea{q}\t{%a1, %0|%0, %a1}";
1969     default:
1970       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1971         abort ();
1972       if (get_attr_mode (insn) == MODE_SI)
1973         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974       else if (which_alternative == 2)
1975         return "movabs{q}\t{%1, %0|%0, %1}";
1976       else
1977         return "mov{q}\t{%1, %0|%0, %1}";
1978     }
1979 }
1980   [(set (attr "type")
1981      (cond [(eq_attr "alternative" "5,6,7")
1982               (const_string "mmxmov")
1983             (eq_attr "alternative" "8,9,10")
1984               (const_string "ssemov")
1985             (eq_attr "alternative" "4")
1986               (const_string "multi")
1987             (and (ne (symbol_ref "flag_pic") (const_int 0))
1988                  (match_operand:DI 1 "symbolic_operand" ""))
1989               (const_string "lea")
1990            ]
1991            (const_string "imov")))
1992    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1993    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1994    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1995
1996 (define_insn "*movdi_1_rex64_nointerunit"
1997   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1998         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 (define_peephole2
2089   [(set (match_operand:DI 0 "memory_operand" "")
2090         (match_operand:DI 1 "immediate_operand" ""))]
2091   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2092    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2093   [(set (match_dup 2) (match_dup 3))
2094    (set (match_dup 4) (match_dup 5))]
2095   "split_di (operands, 2, operands + 2, operands + 4);")
2096
2097 (define_split
2098   [(set (match_operand:DI 0 "memory_operand" "")
2099         (match_operand:DI 1 "immediate_operand" ""))]
2100   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2101    && !symbolic_operand (operands[1], DImode)
2102    && !x86_64_immediate_operand (operands[1], DImode)"
2103   [(set (match_dup 2) (match_dup 3))
2104    (set (match_dup 4) (match_dup 5))]
2105   "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107 (define_insn "*swapdi_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "+r")
2109         (match_operand:DI 1 "register_operand" "+r"))
2110    (set (match_dup 1)
2111         (match_dup 0))]
2112   "TARGET_64BIT"
2113   "xchg{q}\t%1, %0"
2114   [(set_attr "type" "imov")
2115    (set_attr "pent_pair" "np")
2116    (set_attr "athlon_decode" "vector")
2117    (set_attr "mode" "DI")
2118    (set_attr "modrm" "0")
2119    (set_attr "ppro_uops" "few")])
2120
2121   
2122 (define_expand "movsf"
2123   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2124         (match_operand:SF 1 "general_operand" ""))]
2125   ""
2126   "ix86_expand_move (SFmode, operands); DONE;")
2127
2128 (define_insn "*pushsf"
2129   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2130         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2131   "!TARGET_64BIT"
2132 {
2133   switch (which_alternative)
2134     {
2135     case 1:
2136       return "push{l}\t%1";
2137
2138     default:
2139       /* This insn should be already split before reg-stack.  */
2140       abort ();
2141     }
2142 }
2143   [(set_attr "type" "multi,push,multi")
2144    (set_attr "mode" "SF,SI,SF")])
2145
2146 (define_insn "*pushsf_rex64"
2147   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2148         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2149   "TARGET_64BIT"
2150 {
2151   switch (which_alternative)
2152     {
2153     case 1:
2154       return "push{q}\t%q1";
2155
2156     default:
2157       /* This insn should be already split before reg-stack.  */
2158       abort ();
2159     }
2160 }
2161   [(set_attr "type" "multi,push,multi")
2162    (set_attr "mode" "SF,DI,SF")])
2163
2164 (define_split
2165   [(set (match_operand:SF 0 "push_operand" "")
2166         (match_operand:SF 1 "memory_operand" ""))]
2167   "reload_completed
2168    && GET_CODE (operands[1]) == MEM
2169    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2170    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2171   [(set (match_dup 0)
2172         (match_dup 1))]
2173   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2174
2175
2176 ;; %%% Kill this when call knows how to work this out.
2177 (define_split
2178   [(set (match_operand:SF 0 "push_operand" "")
2179         (match_operand:SF 1 "any_fp_register_operand" ""))]
2180   "!TARGET_64BIT"
2181   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2182    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2183
2184 (define_split
2185   [(set (match_operand:SF 0 "push_operand" "")
2186         (match_operand:SF 1 "any_fp_register_operand" ""))]
2187   "TARGET_64BIT"
2188   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2189    (set (mem:SF (reg:DI 7)) (match_dup 1))])
2190
2191 (define_insn "*movsf_1"
2192   [(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")
2193         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2200 {
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       if (REG_P (operands[1])
2205           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2206         return "fstp\t%y0";
2207       else if (STACK_TOP_P (operands[0]))
2208         return "fld%z1\t%y1";
2209       else
2210         return "fst\t%y0";
2211
2212     case 1:
2213       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2214         return "fstp%z0\t%y0";
2215       else
2216         return "fst%z0\t%y0";
2217
2218     case 2:
2219       return standard_80387_constant_opcode (operands[1]);
2220
2221     case 3:
2222     case 4:
2223       return "mov{l}\t{%1, %0|%0, %1}";
2224     case 5:
2225       if (get_attr_mode (insn) == MODE_TI)
2226         return "pxor\t%0, %0";
2227       else
2228         return "xorps\t%0, %0";
2229     case 6:
2230       if (get_attr_mode (insn) == MODE_V4SF)
2231         return "movaps\t{%1, %0|%0, %1}";
2232       else
2233         return "movss\t{%1, %0|%0, %1}";
2234     case 7:
2235     case 8:
2236       return "movss\t{%1, %0|%0, %1}";
2237
2238     case 9:
2239     case 10:
2240       return "movd\t{%1, %0|%0, %1}";
2241
2242     case 11:
2243       return "movq\t{%1, %0|%0, %1}";
2244
2245     default:
2246       abort();
2247     }
2248 }
2249   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2250    (set (attr "mode")
2251         (cond [(eq_attr "alternative" "3,4,9,10")
2252                  (const_string "SI")
2253                (eq_attr "alternative" "5")
2254                  (if_then_else
2255                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2256                                  (const_int 0))
2257                              (ne (symbol_ref "TARGET_SSE2")
2258                                  (const_int 0)))
2259                         (eq (symbol_ref "optimize_size")
2260                             (const_int 0)))
2261                    (const_string "TI")
2262                    (const_string "V4SF"))
2263                /* For architectures resolving dependencies on
2264                   whole SSE registers use APS move to break dependency
2265                   chains, otherwise use short move to avoid extra work. 
2266
2267                   Do the same for architectures resolving dependencies on
2268                   the parts.  While in DF mode it is better to always handle
2269                   just register parts, the SF mode is different due to lack
2270                   of instructions to load just part of the register.  It is
2271                   better to maintain the whole registers in single format
2272                   to avoid problems on using packed logical operations.  */
2273                (eq_attr "alternative" "6")
2274                  (if_then_else
2275                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2276                             (const_int 0))
2277                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2278                             (const_int 0)))
2279                    (const_string "V4SF")
2280                    (const_string "SF"))
2281                (eq_attr "alternative" "11")
2282                  (const_string "DI")]
2283                (const_string "SF")))])
2284
2285 (define_insn "*movsf_1_nointerunit"
2286   [(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")
2287         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2288   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2289    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2290    && (reload_in_progress || reload_completed
2291        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2292        || GET_CODE (operands[1]) != CONST_DOUBLE
2293        || memory_operand (operands[0], SFmode))" 
2294 {
2295   switch (which_alternative)
2296     {
2297     case 0:
2298       if (REG_P (operands[1])
2299           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2300         {
2301           if (REGNO (operands[0]) == FIRST_STACK_REG
2302               && TARGET_USE_FFREEP)
2303             return "ffreep\t%y0";
2304           return "fstp\t%y0";
2305         }
2306       else if (STACK_TOP_P (operands[0]))
2307         return "fld%z1\t%y1";
2308       else
2309         return "fst\t%y0";
2310
2311     case 1:
2312       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2313         return "fstp%z0\t%y0";
2314       else
2315         return "fst%z0\t%y0";
2316
2317     case 2:
2318       return standard_80387_constant_opcode (operands[1]);
2319
2320     case 3:
2321     case 4:
2322       return "mov{l}\t{%1, %0|%0, %1}";
2323     case 5:
2324       if (get_attr_mode (insn) == MODE_TI)
2325         return "pxor\t%0, %0";
2326       else
2327         return "xorps\t%0, %0";
2328     case 6:
2329       if (get_attr_mode (insn) == MODE_V4SF)
2330         return "movaps\t{%1, %0|%0, %1}";
2331       else
2332         return "movss\t{%1, %0|%0, %1}";
2333     case 7:
2334     case 8:
2335       return "movss\t{%1, %0|%0, %1}";
2336
2337     case 9:
2338     case 10:
2339       return "movd\t{%1, %0|%0, %1}";
2340
2341     case 11:
2342       return "movq\t{%1, %0|%0, %1}";
2343
2344     default:
2345       abort();
2346     }
2347 }
2348   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2349    (set (attr "mode")
2350         (cond [(eq_attr "alternative" "3,4,9,10")
2351                  (const_string "SI")
2352                (eq_attr "alternative" "5")
2353                  (if_then_else
2354                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2355                                  (const_int 0))
2356                              (ne (symbol_ref "TARGET_SSE2")
2357                                  (const_int 0)))
2358                         (eq (symbol_ref "optimize_size")
2359                             (const_int 0)))
2360                    (const_string "TI")
2361                    (const_string "V4SF"))
2362                /* For architectures resolving dependencies on
2363                   whole SSE registers use APS move to break dependency
2364                   chains, otherwise use short move to avoid extra work. 
2365
2366                   Do the same for architectures resolving dependencies on
2367                   the parts.  While in DF mode it is better to always handle
2368                   just register parts, the SF mode is different due to lack
2369                   of instructions to load just part of the register.  It is
2370                   better to maintain the whole registers in single format
2371                   to avoid problems on using packed logical operations.  */
2372                (eq_attr "alternative" "6")
2373                  (if_then_else
2374                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2375                             (const_int 0))
2376                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2377                             (const_int 0)))
2378                    (const_string "V4SF")
2379                    (const_string "SF"))
2380                (eq_attr "alternative" "11")
2381                  (const_string "DI")]
2382                (const_string "SF")))])
2383
2384 (define_insn "*swapsf"
2385   [(set (match_operand:SF 0 "register_operand" "+f")
2386         (match_operand:SF 1 "register_operand" "+f"))
2387    (set (match_dup 1)
2388         (match_dup 0))]
2389   "reload_completed || !TARGET_SSE"
2390 {
2391   if (STACK_TOP_P (operands[0]))
2392     return "fxch\t%1";
2393   else
2394     return "fxch\t%0";
2395 }
2396   [(set_attr "type" "fxch")
2397    (set_attr "mode" "SF")])
2398
2399 (define_expand "movdf"
2400   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2401         (match_operand:DF 1 "general_operand" ""))]
2402   ""
2403   "ix86_expand_move (DFmode, operands); DONE;")
2404
2405 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2406 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2407 ;; On the average, pushdf using integers can be still shorter.  Allow this
2408 ;; pattern for optimize_size too.
2409
2410 (define_insn "*pushdf_nointeger"
2411   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2412         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2413   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2414 {
2415   /* This insn should be already split before reg-stack.  */
2416   abort ();
2417 }
2418   [(set_attr "type" "multi")
2419    (set_attr "mode" "DF,SI,SI,DF")])
2420
2421 (define_insn "*pushdf_integer"
2422   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2423         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2424   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2425 {
2426   /* This insn should be already split before reg-stack.  */
2427   abort ();
2428 }
2429   [(set_attr "type" "multi")
2430    (set_attr "mode" "DF,SI,DF")])
2431
2432 ;; %%% Kill this when call knows how to work this out.
2433 (define_split
2434   [(set (match_operand:DF 0 "push_operand" "")
2435         (match_operand:DF 1 "any_fp_register_operand" ""))]
2436   "!TARGET_64BIT && reload_completed"
2437   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2438    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2439   "")
2440
2441 (define_split
2442   [(set (match_operand:DF 0 "push_operand" "")
2443         (match_operand:DF 1 "any_fp_register_operand" ""))]
2444   "TARGET_64BIT && reload_completed"
2445   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2446    (set (mem:DF (reg:DI 7)) (match_dup 1))]
2447   "")
2448
2449 (define_split
2450   [(set (match_operand:DF 0 "push_operand" "")
2451         (match_operand:DF 1 "general_operand" ""))]
2452   "reload_completed"
2453   [(const_int 0)]
2454   "ix86_split_long_move (operands); DONE;")
2455
2456 ;; Moving is usually shorter when only FP registers are used. This separate
2457 ;; movdf pattern avoids the use of integer registers for FP operations
2458 ;; when optimizing for size.
2459
2460 (define_insn "*movdf_nointeger"
2461   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2462         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2463   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2464    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2465    && (reload_in_progress || reload_completed
2466        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2467        || GET_CODE (operands[1]) != CONST_DOUBLE
2468        || memory_operand (operands[0], DFmode))" 
2469 {
2470   switch (which_alternative)
2471     {
2472     case 0:
2473       if (REG_P (operands[1])
2474           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2475         {
2476           if (REGNO (operands[0]) == FIRST_STACK_REG
2477               && TARGET_USE_FFREEP)
2478             return "ffreep\t%y0";
2479           return "fstp\t%y0";
2480         }
2481       else if (STACK_TOP_P (operands[0]))
2482         return "fld%z1\t%y1";
2483       else
2484         return "fst\t%y0";
2485
2486     case 1:
2487       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488         return "fstp%z0\t%y0";
2489       else
2490         return "fst%z0\t%y0";
2491
2492     case 2:
2493       return standard_80387_constant_opcode (operands[1]);
2494
2495     case 3:
2496     case 4:
2497       return "#";
2498     case 5:
2499       switch (get_attr_mode (insn))
2500         {
2501         case MODE_V4SF:
2502           return "xorps\t%0, %0";
2503         case MODE_V2DF:
2504           return "xorpd\t%0, %0";
2505         case MODE_TI:
2506           return "pxor\t%0, %0";
2507         default:
2508           abort ();
2509         }
2510     case 6:
2511       switch (get_attr_mode (insn))
2512         {
2513         case MODE_V4SF:
2514           return "movaps\t{%1, %0|%0, %1}";
2515         case MODE_V2DF:
2516           return "movapd\t{%1, %0|%0, %1}";
2517         case MODE_DF:
2518           return "movsd\t{%1, %0|%0, %1}";
2519         default:
2520           abort ();
2521         }
2522     case 7:
2523       if (get_attr_mode (insn) == MODE_V2DF)
2524         return "movlpd\t{%1, %0|%0, %1}";
2525       else
2526         return "movsd\t{%1, %0|%0, %1}";
2527     case 8:
2528       return "movsd\t{%1, %0|%0, %1}";
2529
2530     default:
2531       abort();
2532     }
2533 }
2534   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2535    (set (attr "mode")
2536         (cond [(eq_attr "alternative" "3,4")
2537                  (const_string "SI")
2538                /* xorps is one byte shorter.  */
2539                (eq_attr "alternative" "5")
2540                  (cond [(ne (symbol_ref "optimize_size")
2541                             (const_int 0))
2542                           (const_string "V4SF")
2543                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2544                             (const_int 0))
2545                           (const_string "TI")]
2546                        (const_string "V2DF"))
2547                /* For architectures resolving dependencies on
2548                   whole SSE registers use APD move to break dependency
2549                   chains, otherwise use short move to avoid extra work.
2550
2551                   movaps encodes one byte shorter.  */
2552                (eq_attr "alternative" "6")
2553                  (cond
2554                   [(ne (symbol_ref "optimize_size")
2555                        (const_int 0))
2556                      (const_string "V4SF")
2557                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2558                        (const_int 0))
2559                      (const_string "V2DF")]
2560                    (const_string "DF"))
2561                /* For architectures resolving dependencies on register
2562                   parts we may avoid extra work to zero out upper part
2563                   of register.  */
2564                (eq_attr "alternative" "7")
2565                  (if_then_else
2566                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2567                        (const_int 0))
2568                    (const_string "V2DF")
2569                    (const_string "DF"))]
2570                (const_string "DF")))])
2571
2572 (define_insn "*movdf_integer"
2573   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2574         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2575   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577    && (reload_in_progress || reload_completed
2578        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579        || GET_CODE (operands[1]) != CONST_DOUBLE
2580        || memory_operand (operands[0], DFmode))" 
2581 {
2582   switch (which_alternative)
2583     {
2584     case 0:
2585       if (REG_P (operands[1])
2586           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587         {
2588           if (REGNO (operands[0]) == FIRST_STACK_REG
2589               && TARGET_USE_FFREEP)
2590             return "ffreep\t%y0";
2591           return "fstp\t%y0";
2592         }
2593       else if (STACK_TOP_P (operands[0]))
2594         return "fld%z1\t%y1";
2595       else
2596         return "fst\t%y0";
2597
2598     case 1:
2599       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2600         return "fstp%z0\t%y0";
2601       else
2602         return "fst%z0\t%y0";
2603
2604     case 2:
2605       return standard_80387_constant_opcode (operands[1]);
2606
2607     case 3:
2608     case 4:
2609       return "#";
2610
2611     case 5:
2612       switch (get_attr_mode (insn))
2613         {
2614         case MODE_V4SF:
2615           return "xorps\t%0, %0";
2616         case MODE_V2DF:
2617           return "xorpd\t%0, %0";
2618         case MODE_TI:
2619           return "pxor\t%0, %0";
2620         default:
2621           abort ();
2622         }
2623     case 6:
2624       switch (get_attr_mode (insn))
2625         {
2626         case MODE_V4SF:
2627           return "movaps\t{%1, %0|%0, %1}";
2628         case MODE_V2DF:
2629           return "movapd\t{%1, %0|%0, %1}";
2630         case MODE_DF:
2631           return "movsd\t{%1, %0|%0, %1}";
2632         default:
2633           abort ();
2634         }
2635     case 7:
2636       if (get_attr_mode (insn) == MODE_V2DF)
2637         return "movlpd\t{%1, %0|%0, %1}";
2638       else
2639         return "movsd\t{%1, %0|%0, %1}";
2640     case 8:
2641       return "movsd\t{%1, %0|%0, %1}";
2642
2643     default:
2644       abort();
2645     }
2646 }
2647   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2648    (set (attr "mode")
2649         (cond [(eq_attr "alternative" "3,4")
2650                  (const_string "SI")
2651                /* xorps is one byte shorter.  */
2652                (eq_attr "alternative" "5")
2653                  (cond [(ne (symbol_ref "optimize_size")
2654                             (const_int 0))
2655                           (const_string "V4SF")
2656                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2657                             (const_int 0))
2658                           (const_string "TI")]
2659                        (const_string "V2DF"))
2660                /* For architectures resolving dependencies on
2661                   whole SSE registers use APD move to break dependency
2662                   chains, otherwise use short move to avoid extra work.  
2663
2664                   movaps encodes one byte shorter.  */
2665                (eq_attr "alternative" "6")
2666                  (cond
2667                   [(ne (symbol_ref "optimize_size")
2668                        (const_int 0))
2669                      (const_string "V4SF")
2670                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671                        (const_int 0))
2672                      (const_string "V2DF")]
2673                    (const_string "DF"))
2674                /* For architectures resolving dependencies on register
2675                   parts we may avoid extra work to zero out upper part
2676                   of register.  */
2677                (eq_attr "alternative" "7")
2678                  (if_then_else
2679                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2680                        (const_int 0))
2681                    (const_string "V2DF")
2682                    (const_string "DF"))]
2683                (const_string "DF")))])
2684
2685 (define_split
2686   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2687         (match_operand:DF 1 "general_operand" ""))]
2688   "reload_completed
2689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2690    && ! (ANY_FP_REG_P (operands[0]) || 
2691          (GET_CODE (operands[0]) == SUBREG
2692           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2693    && ! (ANY_FP_REG_P (operands[1]) || 
2694          (GET_CODE (operands[1]) == SUBREG
2695           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2696   [(const_int 0)]
2697   "ix86_split_long_move (operands); DONE;")
2698
2699 (define_insn "*swapdf"
2700   [(set (match_operand:DF 0 "register_operand" "+f")
2701         (match_operand:DF 1 "register_operand" "+f"))
2702    (set (match_dup 1)
2703         (match_dup 0))]
2704   "reload_completed || !TARGET_SSE2"
2705 {
2706   if (STACK_TOP_P (operands[0]))
2707     return "fxch\t%1";
2708   else
2709     return "fxch\t%0";
2710 }
2711   [(set_attr "type" "fxch")
2712    (set_attr "mode" "DF")])
2713
2714 (define_expand "movxf"
2715   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2716         (match_operand:XF 1 "general_operand" ""))]
2717   ""
2718   "ix86_expand_move (XFmode, operands); DONE;")
2719
2720 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2721 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2722 ;; Pushing using integer instructions is longer except for constants
2723 ;; and direct memory references.
2724 ;; (assuming that any given constant is pushed only once, but this ought to be
2725 ;;  handled elsewhere).
2726
2727 (define_insn "*pushxf_nointeger"
2728   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2729         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730   "optimize_size"
2731 {
2732   /* This insn should be already split before reg-stack.  */
2733   abort ();
2734 }
2735   [(set_attr "type" "multi")
2736    (set_attr "mode" "XF,SI,SI")])
2737
2738 (define_insn "*pushxf_integer"
2739   [(set (match_operand:XF 0 "push_operand" "=<,<")
2740         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2741   "!optimize_size"
2742 {
2743   /* This insn should be already split before reg-stack.  */
2744   abort ();
2745 }
2746   [(set_attr "type" "multi")
2747    (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2764    (set (mem:XF (reg:SI 7)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2772    (set (mem:XF (reg:DI 7)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2784 {
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       if (REG_P (operands[1])
2789           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790         {
2791           if (REGNO (operands[0]) == FIRST_STACK_REG
2792               && TARGET_USE_FFREEP)
2793             return "ffreep\t%y0";
2794           return "fstp\t%y0";
2795         }
2796       else if (STACK_TOP_P (operands[0]))
2797         return "fld%z1\t%y1";
2798       else
2799         return "fst\t%y0";
2800
2801     case 1:
2802       /* There is no non-popping store to memory for XFmode.  So if
2803          we need one, follow the store with a load.  */
2804       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2805         return "fstp%z0\t%y0\;fld%z0\t%y0";
2806       else
2807         return "fstp%z0\t%y0";
2808
2809     case 2:
2810       return standard_80387_constant_opcode (operands[1]);
2811
2812     case 3: case 4:
2813       return "#";
2814     }
2815   abort();
2816 }
2817   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2818    (set_attr "mode" "XF,XF,XF,SI,SI")])
2819
2820 (define_insn "*movxf_integer"
2821   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2822         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2823   "!optimize_size
2824    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2825    && (reload_in_progress || reload_completed
2826        || GET_CODE (operands[1]) != CONST_DOUBLE
2827        || memory_operand (operands[0], XFmode))" 
2828 {
2829   switch (which_alternative)
2830     {
2831     case 0:
2832       if (REG_P (operands[1])
2833           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834         {
2835           if (REGNO (operands[0]) == FIRST_STACK_REG
2836               && TARGET_USE_FFREEP)
2837             return "ffreep\t%y0";
2838           return "fstp\t%y0";
2839         }
2840       else if (STACK_TOP_P (operands[0]))
2841         return "fld%z1\t%y1";
2842       else
2843         return "fst\t%y0";
2844
2845     case 1:
2846       /* There is no non-popping store to memory for XFmode.  So if
2847          we need one, follow the store with a load.  */
2848       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2849         return "fstp%z0\t%y0\;fld%z0\t%y0";
2850       else
2851         return "fstp%z0\t%y0";
2852
2853     case 2:
2854       return standard_80387_constant_opcode (operands[1]);
2855
2856     case 3: case 4:
2857       return "#";
2858     }
2859   abort();
2860 }
2861   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2862    (set_attr "mode" "XF,XF,XF,SI,SI")])
2863
2864 (define_split
2865   [(set (match_operand 0 "nonimmediate_operand" "")
2866         (match_operand 1 "general_operand" ""))]
2867   "reload_completed
2868    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2869    && GET_MODE (operands[0]) == XFmode
2870    && ! (ANY_FP_REG_P (operands[0]) || 
2871          (GET_CODE (operands[0]) == SUBREG
2872           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2873    && ! (ANY_FP_REG_P (operands[1]) || 
2874          (GET_CODE (operands[1]) == SUBREG
2875           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2876   [(const_int 0)]
2877   "ix86_split_long_move (operands); DONE;")
2878
2879 (define_split
2880   [(set (match_operand 0 "register_operand" "")
2881         (match_operand 1 "memory_operand" ""))]
2882   "reload_completed
2883    && GET_CODE (operands[1]) == MEM
2884    && (GET_MODE (operands[0]) == XFmode
2885        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2886    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2887    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2888   [(set (match_dup 0) (match_dup 1))]
2889 {
2890   rtx c = get_pool_constant (XEXP (operands[1], 0));
2891   rtx r = operands[0];
2892
2893   if (GET_CODE (r) == SUBREG)
2894     r = SUBREG_REG (r);
2895
2896   if (SSE_REG_P (r))
2897     {
2898       if (!standard_sse_constant_p (c))
2899         FAIL;
2900     }
2901   else if (FP_REG_P (r))
2902     {
2903       if (!standard_80387_constant_p (c))
2904         FAIL;
2905     }
2906   else if (MMX_REG_P (r))
2907     FAIL;
2908
2909   operands[1] = c;
2910 })
2911
2912 (define_insn "swapxf"
2913   [(set (match_operand:XF 0 "register_operand" "+f")
2914         (match_operand:XF 1 "register_operand" "+f"))
2915    (set (match_dup 1)
2916         (match_dup 0))]
2917   ""
2918 {
2919   if (STACK_TOP_P (operands[0]))
2920     return "fxch\t%1";
2921   else
2922     return "fxch\t%0";
2923 }
2924   [(set_attr "type" "fxch")
2925    (set_attr "mode" "XF")])
2926 \f
2927 ;; Zero extension instructions
2928
2929 (define_expand "zero_extendhisi2"
2930   [(set (match_operand:SI 0 "register_operand" "")
2931      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2932   ""
2933 {
2934   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2935     {
2936       operands[1] = force_reg (HImode, operands[1]);
2937       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2938       DONE;
2939     }
2940 })
2941
2942 (define_insn "zero_extendhisi2_and"
2943   [(set (match_operand:SI 0 "register_operand" "=r")
2944      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2945    (clobber (reg:CC 17))]
2946   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2947   "#"
2948   [(set_attr "type" "alu1")
2949    (set_attr "mode" "SI")])
2950
2951 (define_split
2952   [(set (match_operand:SI 0 "register_operand" "")
2953         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2954    (clobber (reg:CC 17))]
2955   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2956   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2957               (clobber (reg:CC 17))])]
2958   "")
2959
2960 (define_insn "*zero_extendhisi2_movzwl"
2961   [(set (match_operand:SI 0 "register_operand" "=r")
2962      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2963   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2964   "movz{wl|x}\t{%1, %0|%0, %1}"
2965   [(set_attr "type" "imovx")
2966    (set_attr "mode" "SI")])
2967
2968 (define_expand "zero_extendqihi2"
2969   [(parallel
2970     [(set (match_operand:HI 0 "register_operand" "")
2971        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2972      (clobber (reg:CC 17))])]
2973   ""
2974   "")
2975
2976 (define_insn "*zero_extendqihi2_and"
2977   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2978      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2979    (clobber (reg:CC 17))]
2980   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2981   "#"
2982   [(set_attr "type" "alu1")
2983    (set_attr "mode" "HI")])
2984
2985 (define_insn "*zero_extendqihi2_movzbw_and"
2986   [(set (match_operand:HI 0 "register_operand" "=r,r")
2987      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2988    (clobber (reg:CC 17))]
2989   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2990   "#"
2991   [(set_attr "type" "imovx,alu1")
2992    (set_attr "mode" "HI")])
2993
2994 (define_insn "*zero_extendqihi2_movzbw"
2995   [(set (match_operand:HI 0 "register_operand" "=r")
2996      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2997   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2998   "movz{bw|x}\t{%1, %0|%0, %1}"
2999   [(set_attr "type" "imovx")
3000    (set_attr "mode" "HI")])
3001
3002 ;; For the movzbw case strip only the clobber
3003 (define_split
3004   [(set (match_operand:HI 0 "register_operand" "")
3005         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3006    (clobber (reg:CC 17))]
3007   "reload_completed 
3008    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3009    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3010   [(set (match_operand:HI 0 "register_operand" "")
3011         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3012
3013 ;; When source and destination does not overlap, clear destination
3014 ;; first and then do the movb
3015 (define_split
3016   [(set (match_operand:HI 0 "register_operand" "")
3017         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018    (clobber (reg:CC 17))]
3019   "reload_completed
3020    && ANY_QI_REG_P (operands[0])
3021    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3022    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3023   [(set (match_dup 0) (const_int 0))
3024    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3025   "operands[2] = gen_lowpart (QImode, operands[0]);")
3026
3027 ;; Rest is handled by single and.
3028 (define_split
3029   [(set (match_operand:HI 0 "register_operand" "")
3030         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3031    (clobber (reg:CC 17))]
3032   "reload_completed
3033    && true_regnum (operands[0]) == true_regnum (operands[1])"
3034   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3035               (clobber (reg:CC 17))])]
3036   "")
3037
3038 (define_expand "zero_extendqisi2"
3039   [(parallel
3040     [(set (match_operand:SI 0 "register_operand" "")
3041        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3042      (clobber (reg:CC 17))])]
3043   ""
3044   "")
3045
3046 (define_insn "*zero_extendqisi2_and"
3047   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3048      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3049    (clobber (reg:CC 17))]
3050   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3051   "#"
3052   [(set_attr "type" "alu1")
3053    (set_attr "mode" "SI")])
3054
3055 (define_insn "*zero_extendqisi2_movzbw_and"
3056   [(set (match_operand:SI 0 "register_operand" "=r,r")
3057      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3058    (clobber (reg:CC 17))]
3059   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3060   "#"
3061   [(set_attr "type" "imovx,alu1")
3062    (set_attr "mode" "SI")])
3063
3064 (define_insn "*zero_extendqisi2_movzbw"
3065   [(set (match_operand:SI 0 "register_operand" "=r")
3066      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3067   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3068   "movz{bl|x}\t{%1, %0|%0, %1}"
3069   [(set_attr "type" "imovx")
3070    (set_attr "mode" "SI")])
3071
3072 ;; For the movzbl case strip only the clobber
3073 (define_split
3074   [(set (match_operand:SI 0 "register_operand" "")
3075         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3076    (clobber (reg:CC 17))]
3077   "reload_completed 
3078    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3079    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3080   [(set (match_dup 0)
3081         (zero_extend:SI (match_dup 1)))])
3082
3083 ;; When source and destination does not overlap, clear destination
3084 ;; first and then do the movb
3085 (define_split
3086   [(set (match_operand:SI 0 "register_operand" "")
3087         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3088    (clobber (reg:CC 17))]
3089   "reload_completed
3090    && ANY_QI_REG_P (operands[0])
3091    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3092    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3093    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3094   [(set (match_dup 0) (const_int 0))
3095    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3096   "operands[2] = gen_lowpart (QImode, operands[0]);")
3097
3098 ;; Rest is handled by single and.
3099 (define_split
3100   [(set (match_operand:SI 0 "register_operand" "")
3101         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3102    (clobber (reg:CC 17))]
3103   "reload_completed
3104    && true_regnum (operands[0]) == true_regnum (operands[1])"
3105   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3106               (clobber (reg:CC 17))])]
3107   "")
3108
3109 ;; %%% Kill me once multi-word ops are sane.
3110 (define_expand "zero_extendsidi2"
3111   [(set (match_operand:DI 0 "register_operand" "=r")
3112      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3113   ""
3114   "if (!TARGET_64BIT)
3115      {
3116        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3117        DONE;
3118      }
3119   ")
3120
3121 (define_insn "zero_extendsidi2_32"
3122   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3123         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3124    (clobber (reg:CC 17))]
3125   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3126   "@
3127    #
3128    #
3129    #
3130    movd\t{%1, %0|%0, %1}
3131    movd\t{%1, %0|%0, %1}"
3132   [(set_attr "mode" "SI,SI,SI,DI,TI")
3133    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3134
3135 (define_insn "*zero_extendsidi2_32_1"
3136   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3137         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3138    (clobber (reg:CC 17))]
3139   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3140   "@
3141    #
3142    #
3143    #
3144    movd\t{%1, %0|%0, %1}
3145    movd\t{%1, %0|%0, %1}"
3146   [(set_attr "mode" "SI,SI,SI,DI,TI")
3147    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3148
3149 (define_insn "zero_extendsidi2_rex64"
3150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3151      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3152   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3153   "@
3154    mov\t{%k1, %k0|%k0, %k1}
3155    #
3156    movd\t{%1, %0|%0, %1}
3157    movd\t{%1, %0|%0, %1}"
3158   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3159    (set_attr "mode" "SI,DI,DI,TI")])
3160
3161 (define_insn "*zero_extendsidi2_rex64_1"
3162   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3163      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3164   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3165   "@
3166    mov\t{%k1, %k0|%k0, %k1}
3167    #
3168    movd\t{%1, %0|%0, %1}
3169    movd\t{%1, %0|%0, %1}"
3170   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3171    (set_attr "mode" "SI,DI,SI,SI")])
3172
3173 (define_split
3174   [(set (match_operand:DI 0 "memory_operand" "")
3175      (zero_extend:DI (match_dup 0)))]
3176   "TARGET_64BIT"
3177   [(set (match_dup 4) (const_int 0))]
3178   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3179
3180 (define_split 
3181   [(set (match_operand:DI 0 "register_operand" "")
3182         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3183    (clobber (reg:CC 17))]
3184   "!TARGET_64BIT && reload_completed
3185    && true_regnum (operands[0]) == true_regnum (operands[1])"
3186   [(set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_split 
3190   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3191         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3192    (clobber (reg:CC 17))]
3193   "!TARGET_64BIT && reload_completed
3194    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3195   [(set (match_dup 3) (match_dup 1))
3196    (set (match_dup 4) (const_int 0))]
3197   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3198
3199 (define_insn "zero_extendhidi2"
3200   [(set (match_operand:DI 0 "register_operand" "=r,r")
3201      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3202   "TARGET_64BIT"
3203   "@
3204    movz{wl|x}\t{%1, %k0|%k0, %1} 
3205    movz{wq|x}\t{%1, %0|%0, %1}"
3206   [(set_attr "type" "imovx")
3207    (set_attr "mode" "SI,DI")])
3208
3209 (define_insn "zero_extendqidi2"
3210   [(set (match_operand:DI 0 "register_operand" "=r,r")
3211      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3212   "TARGET_64BIT"
3213   "@
3214    movz{bl|x}\t{%1, %k0|%k0, %1} 
3215    movz{bq|x}\t{%1, %0|%0, %1}"
3216   [(set_attr "type" "imovx")
3217    (set_attr "mode" "SI,DI")])
3218 \f
3219 ;; Sign extension instructions
3220
3221 (define_expand "extendsidi2"
3222   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3223                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3224               (clobber (reg:CC 17))
3225               (clobber (match_scratch:SI 2 ""))])]
3226   ""
3227 {
3228   if (TARGET_64BIT)
3229     {
3230       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3231       DONE;
3232     }
3233 })
3234
3235 (define_insn "*extendsidi2_1"
3236   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3237         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3238    (clobber (reg:CC 17))
3239    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3240   "!TARGET_64BIT"
3241   "#")
3242
3243 (define_insn "extendsidi2_rex64"
3244   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3245         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3246   "TARGET_64BIT"
3247   "@
3248    {cltq|cdqe}
3249    movs{lq|x}\t{%1,%0|%0, %1}"
3250   [(set_attr "type" "imovx")
3251    (set_attr "mode" "DI")
3252    (set_attr "prefix_0f" "0")
3253    (set_attr "modrm" "0,1")])
3254
3255 (define_insn "extendhidi2"
3256   [(set (match_operand:DI 0 "register_operand" "=r")
3257         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3258   "TARGET_64BIT"
3259   "movs{wq|x}\t{%1,%0|%0, %1}"
3260   [(set_attr "type" "imovx")
3261    (set_attr "mode" "DI")])
3262
3263 (define_insn "extendqidi2"
3264   [(set (match_operand:DI 0 "register_operand" "=r")
3265         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3266   "TARGET_64BIT"
3267   "movs{bq|x}\t{%1,%0|%0, %1}"
3268    [(set_attr "type" "imovx")
3269     (set_attr "mode" "DI")])
3270
3271 ;; Extend to memory case when source register does die.
3272 (define_split 
3273   [(set (match_operand:DI 0 "memory_operand" "")
3274         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3275    (clobber (reg:CC 17))
3276    (clobber (match_operand:SI 2 "register_operand" ""))]
3277   "(reload_completed
3278     && dead_or_set_p (insn, operands[1])
3279     && !reg_mentioned_p (operands[1], operands[0]))"
3280   [(set (match_dup 3) (match_dup 1))
3281    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3282               (clobber (reg:CC 17))])
3283    (set (match_dup 4) (match_dup 1))]
3284   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3285
3286 ;; Extend to memory case when source register does not die.
3287 (define_split 
3288   [(set (match_operand:DI 0 "memory_operand" "")
3289         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3290    (clobber (reg:CC 17))
3291    (clobber (match_operand:SI 2 "register_operand" ""))]
3292   "reload_completed"
3293   [(const_int 0)]
3294 {
3295   split_di (&operands[0], 1, &operands[3], &operands[4]);
3296
3297   emit_move_insn (operands[3], operands[1]);
3298
3299   /* Generate a cltd if possible and doing so it profitable.  */
3300   if (true_regnum (operands[1]) == 0
3301       && true_regnum (operands[2]) == 1
3302       && (optimize_size || TARGET_USE_CLTD))
3303     {
3304       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3305     }
3306   else
3307     {
3308       emit_move_insn (operands[2], operands[1]);
3309       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3310     }
3311   emit_move_insn (operands[4], operands[2]);
3312   DONE;
3313 })
3314
3315 ;; Extend to register case.  Optimize case where source and destination
3316 ;; registers match and cases where we can use cltd.
3317 (define_split 
3318   [(set (match_operand:DI 0 "register_operand" "")
3319         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3320    (clobber (reg:CC 17))
3321    (clobber (match_scratch:SI 2 ""))]
3322   "reload_completed"
3323   [(const_int 0)]
3324 {
3325   split_di (&operands[0], 1, &operands[3], &operands[4]);
3326
3327   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3328     emit_move_insn (operands[3], operands[1]);
3329
3330   /* Generate a cltd if possible and doing so it profitable.  */
3331   if (true_regnum (operands[3]) == 0
3332       && (optimize_size || TARGET_USE_CLTD))
3333     {
3334       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3335       DONE;
3336     }
3337
3338   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3339     emit_move_insn (operands[4], operands[1]);
3340
3341   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3342   DONE;
3343 })
3344
3345 (define_insn "extendhisi2"
3346   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3347         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3348   ""
3349 {
3350   switch (get_attr_prefix_0f (insn))
3351     {
3352     case 0:
3353       return "{cwtl|cwde}";
3354     default:
3355       return "movs{wl|x}\t{%1,%0|%0, %1}";
3356     }
3357 }
3358   [(set_attr "type" "imovx")
3359    (set_attr "mode" "SI")
3360    (set (attr "prefix_0f")
3361      ;; movsx is short decodable while cwtl is vector decoded.
3362      (if_then_else (and (eq_attr "cpu" "!k6")
3363                         (eq_attr "alternative" "0"))
3364         (const_string "0")
3365         (const_string "1")))
3366    (set (attr "modrm")
3367      (if_then_else (eq_attr "prefix_0f" "0")
3368         (const_string "0")
3369         (const_string "1")))])
3370
3371 (define_insn "*extendhisi2_zext"
3372   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3373         (zero_extend:DI
3374           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3375   "TARGET_64BIT"
3376 {
3377   switch (get_attr_prefix_0f (insn))
3378     {
3379     case 0:
3380       return "{cwtl|cwde}";
3381     default:
3382       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3383     }
3384 }
3385   [(set_attr "type" "imovx")
3386    (set_attr "mode" "SI")
3387    (set (attr "prefix_0f")
3388      ;; movsx is short decodable while cwtl is vector decoded.
3389      (if_then_else (and (eq_attr "cpu" "!k6")
3390                         (eq_attr "alternative" "0"))
3391         (const_string "0")
3392         (const_string "1")))
3393    (set (attr "modrm")
3394      (if_then_else (eq_attr "prefix_0f" "0")
3395         (const_string "0")
3396         (const_string "1")))])
3397
3398 (define_insn "extendqihi2"
3399   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3400         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3401   ""
3402 {
3403   switch (get_attr_prefix_0f (insn))
3404     {
3405     case 0:
3406       return "{cbtw|cbw}";
3407     default:
3408       return "movs{bw|x}\t{%1,%0|%0, %1}";
3409     }
3410 }
3411   [(set_attr "type" "imovx")
3412    (set_attr "mode" "HI")
3413    (set (attr "prefix_0f")
3414      ;; movsx is short decodable while cwtl is vector decoded.
3415      (if_then_else (and (eq_attr "cpu" "!k6")
3416                         (eq_attr "alternative" "0"))
3417         (const_string "0")
3418         (const_string "1")))
3419    (set (attr "modrm")
3420      (if_then_else (eq_attr "prefix_0f" "0")
3421         (const_string "0")
3422         (const_string "1")))])
3423
3424 (define_insn "extendqisi2"
3425   [(set (match_operand:SI 0 "register_operand" "=r")
3426         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3427   ""
3428   "movs{bl|x}\t{%1,%0|%0, %1}"
3429    [(set_attr "type" "imovx")
3430     (set_attr "mode" "SI")])
3431
3432 (define_insn "*extendqisi2_zext"
3433   [(set (match_operand:DI 0 "register_operand" "=r")
3434         (zero_extend:DI
3435           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3436   "TARGET_64BIT"
3437   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3438    [(set_attr "type" "imovx")
3439     (set_attr "mode" "SI")])
3440 \f
3441 ;; Conversions between float and double.
3442
3443 ;; These are all no-ops in the model used for the 80387.  So just
3444 ;; emit moves.
3445
3446 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3447 (define_insn "*dummy_extendsfdf2"
3448   [(set (match_operand:DF 0 "push_operand" "=<")
3449         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3450   "0"
3451   "#")
3452
3453 (define_split
3454   [(set (match_operand:DF 0 "push_operand" "")
3455         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3456   "!TARGET_64BIT"
3457   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3458    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3459
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "TARGET_64BIT"
3464   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3465    (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_insn "*dummy_extendsfxf2"
3468   [(set (match_operand:XF 0 "push_operand" "=<")
3469         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3470   "0"
3471   "#")
3472
3473 (define_split
3474   [(set (match_operand:XF 0 "push_operand" "")
3475         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3476   ""
3477   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3478    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3479   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3480
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484   "TARGET_64BIT"
3485   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3486    (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3492   ""
3493   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3494    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496
3497 (define_split
3498   [(set (match_operand:XF 0 "push_operand" "")
3499         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500   "TARGET_64BIT"
3501   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3502    (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3503   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3504
3505 (define_expand "extendsfdf2"
3506   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3507         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3508   "TARGET_80387 || TARGET_SSE2"
3509 {
3510   /* ??? Needed for compress_float_constant since all fp constants
3511      are LEGITIMATE_CONSTANT_P.  */
3512   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3513     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3514   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3515     operands[1] = force_reg (SFmode, operands[1]);
3516 })
3517
3518 (define_insn "*extendsfdf2_1"
3519   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3520         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3521   "(TARGET_80387 || TARGET_SSE2)
3522    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3523 {
3524   switch (which_alternative)
3525     {
3526     case 0:
3527       if (REG_P (operands[1])
3528           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3529         return "fstp\t%y0";
3530       else if (STACK_TOP_P (operands[0]))
3531         return "fld%z1\t%y1";
3532       else
3533         return "fst\t%y0";
3534
3535     case 1:
3536       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3537         return "fstp%z0\t%y0";
3538
3539       else
3540         return "fst%z0\t%y0";
3541     case 2:
3542       return "cvtss2sd\t{%1, %0|%0, %1}";
3543
3544     default:
3545       abort ();
3546     }
3547 }
3548   [(set_attr "type" "fmov,fmov,ssecvt")
3549    (set_attr "mode" "SF,XF,DF")])
3550
3551 (define_insn "*extendsfdf2_1_sse_only"
3552   [(set (match_operand:DF 0 "register_operand" "=Y")
3553         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3554   "!TARGET_80387 && TARGET_SSE2
3555    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556   "cvtss2sd\t{%1, %0|%0, %1}"
3557   [(set_attr "type" "ssecvt")
3558    (set_attr "mode" "DF")])
3559
3560 (define_expand "extendsfxf2"
3561   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3562         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3563   "TARGET_80387"
3564 {
3565   /* ??? Needed for compress_float_constant since all fp constants
3566      are LEGITIMATE_CONSTANT_P.  */
3567   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3568     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3569   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3570     operands[1] = force_reg (SFmode, operands[1]);
3571 })
3572
3573 (define_insn "*extendsfxf2_1"
3574   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3575         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3576   "TARGET_80387
3577    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578 {
3579   switch (which_alternative)
3580     {
3581     case 0:
3582       if (REG_P (operands[1])
3583           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584         return "fstp\t%y0";
3585       else if (STACK_TOP_P (operands[0]))
3586         return "fld%z1\t%y1";
3587       else
3588         return "fst\t%y0";
3589
3590     case 1:
3591       /* There is no non-popping store to memory for XFmode.  So if
3592          we need one, follow the store with a load.  */
3593       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3594         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3595       else
3596         return "fstp%z0\t%y0";
3597
3598     default:
3599       abort ();
3600     }
3601 }
3602   [(set_attr "type" "fmov")
3603    (set_attr "mode" "SF,XF")])
3604
3605 (define_expand "extenddfxf2"
3606   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3607         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3608   "TARGET_80387"
3609 {
3610   /* ??? Needed for compress_float_constant since all fp constants
3611      are LEGITIMATE_CONSTANT_P.  */
3612   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3613     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3614   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3615     operands[1] = force_reg (DFmode, operands[1]);
3616 })
3617
3618 (define_insn "*extenddfxf2_1"
3619   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3620         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3621   "TARGET_80387
3622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3623 {
3624   switch (which_alternative)
3625     {
3626     case 0:
3627       if (REG_P (operands[1])
3628           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629         return "fstp\t%y0";
3630       else if (STACK_TOP_P (operands[0]))
3631         return "fld%z1\t%y1";
3632       else
3633         return "fst\t%y0";
3634
3635     case 1:
3636       /* There is no non-popping store to memory for XFmode.  So if
3637          we need one, follow the store with a load.  */
3638       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640       else
3641         return "fstp%z0\t%y0";
3642
3643     default:
3644       abort ();
3645     }
3646 }
3647   [(set_attr "type" "fmov")
3648    (set_attr "mode" "DF,XF")])
3649
3650 ;; %%% This seems bad bad news.
3651 ;; This cannot output into an f-reg because there is no way to be sure
3652 ;; of truncating in that case.  Otherwise this is just like a simple move
3653 ;; insn.  So we pretend we can output to a reg in order to get better
3654 ;; register preferencing, but we really use a stack slot.
3655
3656 (define_expand "truncdfsf2"
3657   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3658                    (float_truncate:SF
3659                     (match_operand:DF 1 "register_operand" "")))
3660               (clobber (match_dup 2))])]
3661   "TARGET_80387 || TARGET_SSE2"
3662   "
3663    if (TARGET_80387)
3664      operands[2] = assign_386_stack_local (SFmode, 0);
3665    else
3666      {
3667         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3668         DONE;
3669      }
3670 ")
3671
3672 (define_insn "*truncdfsf2_1"
3673   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3674         (float_truncate:SF
3675          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3676    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3677   "TARGET_80387 && !TARGET_SSE2"
3678 {
3679   switch (which_alternative)
3680     {
3681     case 0:
3682       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3683         return "fstp%z0\t%y0";
3684       else
3685         return "fst%z0\t%y0";
3686     default:
3687       abort ();
3688     }
3689 }
3690   [(set_attr "type" "fmov,multi,multi,multi")
3691    (set_attr "mode" "SF,SF,SF,SF")])
3692
3693 (define_insn "*truncdfsf2_1_sse"
3694   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3695         (float_truncate:SF
3696          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3697    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3698   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3699 {
3700   switch (which_alternative)
3701     {
3702     case 0:
3703       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3704         return "fstp%z0\t%y0";
3705       else
3706         return "fst%z0\t%y0";
3707     case 4:
3708       return "#";
3709     default:
3710       abort ();
3711     }
3712 }
3713   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3714    (set_attr "mode" "SF,SF,SF,SF,DF")])
3715
3716 (define_insn "*truncdfsf2_1_sse_nooverlap"
3717   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3718         (float_truncate:SF
3719          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3720    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3721   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3722 {
3723   switch (which_alternative)
3724     {
3725     case 0:
3726       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3727         return "fstp%z0\t%y0";
3728       else
3729         return "fst%z0\t%y0";
3730     case 4:
3731       return "#";
3732     default:
3733       abort ();
3734     }
3735 }
3736   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3737    (set_attr "mode" "SF,SF,SF,SF,DF")])
3738
3739 (define_insn "*truncdfsf2_2"
3740   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3741         (float_truncate:SF
3742          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3743   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3744    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3745 {
3746   switch (which_alternative)
3747     {
3748     case 0:
3749     case 1:
3750       return "cvtsd2ss\t{%1, %0|%0, %1}";
3751     case 2:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     default:
3757       abort ();
3758     }
3759 }
3760   [(set_attr "type" "ssecvt,ssecvt,fmov")
3761    (set_attr "athlon_decode" "vector,double,*")
3762    (set_attr "mode" "SF,SF,SF")])
3763
3764 (define_insn "*truncdfsf2_2_nooverlap"
3765   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3766         (float_truncate:SF
3767          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3768   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3769    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3770 {
3771   switch (which_alternative)
3772     {
3773     case 0:
3774       return "#";
3775     case 1:
3776       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777         return "fstp%z0\t%y0";
3778       else
3779         return "fst%z0\t%y0";
3780     default:
3781       abort ();
3782     }
3783 }
3784   [(set_attr "type" "ssecvt,fmov")
3785    (set_attr "mode" "DF,SF")])
3786
3787 (define_insn "*truncdfsf2_3"
3788   [(set (match_operand:SF 0 "memory_operand" "=m")
3789         (float_truncate:SF
3790          (match_operand:DF 1 "register_operand" "f")))]
3791   "TARGET_80387"
3792 {
3793   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3794     return "fstp%z0\t%y0";
3795   else
3796     return "fst%z0\t%y0";
3797 }
3798   [(set_attr "type" "fmov")
3799    (set_attr "mode" "SF")])
3800
3801 (define_insn "truncdfsf2_sse_only"
3802   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3803         (float_truncate:SF
3804          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3805   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3806   "cvtsd2ss\t{%1, %0|%0, %1}"
3807   [(set_attr "type" "ssecvt")
3808    (set_attr "athlon_decode" "vector,double")
3809    (set_attr "mode" "SF")])
3810
3811 (define_insn "*truncdfsf2_sse_only_nooverlap"
3812   [(set (match_operand:SF 0 "register_operand" "=&Y")
3813         (float_truncate:SF
3814          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3815   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3816   "#"
3817   [(set_attr "type" "ssecvt")
3818    (set_attr "mode" "DF")])
3819
3820 (define_split
3821   [(set (match_operand:SF 0 "memory_operand" "")
3822         (float_truncate:SF
3823          (match_operand:DF 1 "register_operand" "")))
3824    (clobber (match_operand:SF 2 "memory_operand" ""))]
3825   "TARGET_80387"
3826   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3827   "")
3828
3829 ; Avoid possible reformatting penalty on the destination by first
3830 ; zeroing it out
3831 (define_split
3832   [(set (match_operand:SF 0 "register_operand" "")
3833         (float_truncate:SF
3834          (match_operand:DF 1 "nonimmediate_operand" "")))
3835    (clobber (match_operand 2 "" ""))]
3836   "TARGET_80387 && reload_completed
3837    && SSE_REG_P (operands[0])
3838    && !STACK_REG_P (operands[1])"
3839   [(const_int 0)]
3840 {
3841   rtx src, dest;
3842   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3843     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3844   else
3845     {
3846       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3847       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3848       /* simplify_gen_subreg refuses to widen memory references.  */
3849       if (GET_CODE (src) == SUBREG)
3850         alter_subreg (&src);
3851       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3852         abort ();
3853       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3854       emit_insn (gen_cvtsd2ss (dest, dest, src));
3855     }
3856   DONE;
3857 })
3858
3859 (define_split
3860   [(set (match_operand:SF 0 "register_operand" "")
3861         (float_truncate:SF
3862          (match_operand:DF 1 "nonimmediate_operand" "")))]
3863   "TARGET_80387 && reload_completed
3864    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3865   [(const_int 0)]
3866 {
3867   rtx src, dest;
3868   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3869   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3870   /* simplify_gen_subreg refuses to widen memory references.  */
3871   if (GET_CODE (src) == SUBREG)
3872     alter_subreg (&src);
3873   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3874     abort ();
3875   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3876   emit_insn (gen_cvtsd2ss (dest, dest, src));
3877   DONE;
3878 })
3879
3880 (define_split
3881   [(set (match_operand:SF 0 "register_operand" "")
3882         (float_truncate:SF
3883          (match_operand:DF 1 "fp_register_operand" "")))
3884    (clobber (match_operand:SF 2 "memory_operand" ""))]
3885   "TARGET_80387 && reload_completed"
3886   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3887    (set (match_dup 0) (match_dup 2))]
3888   "")
3889
3890 (define_expand "truncxfsf2"
3891   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3892                    (float_truncate:SF
3893                     (match_operand:XF 1 "register_operand" "")))
3894               (clobber (match_dup 2))])]
3895   "TARGET_80387"
3896   "operands[2] = assign_386_stack_local (SFmode, 0);")
3897
3898 (define_insn "*truncxfsf2_1"
3899   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3900         (float_truncate:SF
3901          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3902    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3903   "TARGET_80387"
3904 {
3905   switch (which_alternative)
3906     {
3907     case 0:
3908       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3909         return "fstp%z0\t%y0";
3910       else
3911         return "fst%z0\t%y0";
3912     default:
3913       abort();
3914     }
3915 }
3916   [(set_attr "type" "fmov,multi,multi,multi")
3917    (set_attr "mode" "SF")])
3918
3919 (define_insn "*truncxfsf2_2"
3920   [(set (match_operand:SF 0 "memory_operand" "=m")
3921         (float_truncate:SF
3922          (match_operand:XF 1 "register_operand" "f")))]
3923   "TARGET_80387"
3924 {
3925   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926     return "fstp%z0\t%y0";
3927   else
3928     return "fst%z0\t%y0";
3929 }
3930   [(set_attr "type" "fmov")
3931    (set_attr "mode" "SF")])
3932
3933 (define_split
3934   [(set (match_operand:SF 0 "memory_operand" "")
3935         (float_truncate:SF
3936          (match_operand:XF 1 "register_operand" "")))
3937    (clobber (match_operand:SF 2 "memory_operand" ""))]
3938   "TARGET_80387"
3939   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3940   "")
3941
3942 (define_split
3943   [(set (match_operand:SF 0 "register_operand" "")
3944         (float_truncate:SF
3945          (match_operand:XF 1 "register_operand" "")))
3946    (clobber (match_operand:SF 2 "memory_operand" ""))]
3947   "TARGET_80387 && reload_completed"
3948   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3949    (set (match_dup 0) (match_dup 2))]
3950   "")
3951
3952 (define_expand "truncxfdf2"
3953   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3954                    (float_truncate:DF
3955                     (match_operand:XF 1 "register_operand" "")))
3956               (clobber (match_dup 2))])]
3957   "TARGET_80387"
3958   "operands[2] = assign_386_stack_local (DFmode, 0);")
3959
3960 (define_insn "*truncxfdf2_1"
3961   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3962         (float_truncate:DF
3963          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3964    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3965   "TARGET_80387"
3966 {
3967   switch (which_alternative)
3968     {
3969     case 0:
3970       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971         return "fstp%z0\t%y0";
3972       else
3973         return "fst%z0\t%y0";
3974     default:
3975       abort();
3976     }
3977   abort ();
3978 }
3979   [(set_attr "type" "fmov,multi,multi,multi")
3980    (set_attr "mode" "DF")])
3981
3982 (define_insn "*truncxfdf2_2"
3983   [(set (match_operand:DF 0 "memory_operand" "=m")
3984         (float_truncate:DF
3985           (match_operand:XF 1 "register_operand" "f")))]
3986   "TARGET_80387"
3987 {
3988   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3989     return "fstp%z0\t%y0";
3990   else
3991     return "fst%z0\t%y0";
3992 }
3993   [(set_attr "type" "fmov")
3994    (set_attr "mode" "DF")])
3995
3996 (define_split
3997   [(set (match_operand:DF 0 "memory_operand" "")
3998         (float_truncate:DF
3999          (match_operand:XF 1 "register_operand" "")))
4000    (clobber (match_operand:DF 2 "memory_operand" ""))]
4001   "TARGET_80387"
4002   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4003   "")
4004
4005 (define_split
4006   [(set (match_operand:DF 0 "register_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387 && reload_completed"
4011   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4012    (set (match_dup 0) (match_dup 2))]
4013   "")
4014
4015 \f
4016 ;; %%% Break up all these bad boys.
4017
4018 ;; Signed conversion to DImode.
4019
4020 (define_expand "fix_truncxfdi2"
4021   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4022                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4023               (clobber (reg:CC 17))])]
4024   "TARGET_80387"
4025   "")
4026
4027 (define_expand "fix_truncdfdi2"
4028   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4029                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4030               (clobber (reg:CC 17))])]
4031   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4032 {
4033   if (TARGET_64BIT && TARGET_SSE2)
4034    {
4035      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4036      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4037      if (out != operands[0])
4038         emit_move_insn (operands[0], out);
4039      DONE;
4040    }
4041 })
4042
4043 (define_expand "fix_truncsfdi2"
4044   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4045                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4046               (clobber (reg:CC 17))])] 
4047   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4048 {
4049   if (TARGET_SSE && TARGET_64BIT)
4050    {
4051      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4052      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4053      if (out != operands[0])
4054         emit_move_insn (operands[0], out);
4055      DONE;
4056    }
4057 })
4058
4059 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4060 ;; of the machinery.
4061 (define_insn_and_split "*fix_truncdi_1"
4062   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4063         (fix:DI (match_operand 1 "register_operand" "f,f")))
4064         (clobber (reg:CC 17))]
4065   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4066    && !reload_completed && !reload_in_progress
4067    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4068   "#"
4069   "&& 1"
4070   [(const_int 0)]
4071 {
4072   ix86_optimize_mode_switching = 1;
4073   operands[2] = assign_386_stack_local (HImode, 1);
4074   operands[3] = assign_386_stack_local (HImode, 2);
4075   if (memory_operand (operands[0], VOIDmode))
4076     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4077                                        operands[2], operands[3]));
4078   else
4079     {
4080       operands[4] = assign_386_stack_local (DImode, 0);
4081       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4082                                            operands[2], operands[3],
4083                                            operands[4]));
4084     }
4085   DONE;
4086 }
4087   [(set_attr "type" "fistp")
4088    (set_attr "mode" "DI")])
4089
4090 (define_insn "fix_truncdi_nomemory"
4091   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4092         (fix:DI (match_operand 1 "register_operand" "f,f")))
4093    (use (match_operand:HI 2 "memory_operand" "m,m"))
4094    (use (match_operand:HI 3 "memory_operand" "m,m"))
4095    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4096    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4097   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4098    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4099   "#"
4100   [(set_attr "type" "fistp")
4101    (set_attr "mode" "DI")])
4102
4103 (define_insn "fix_truncdi_memory"
4104   [(set (match_operand:DI 0 "memory_operand" "=m")
4105         (fix:DI (match_operand 1 "register_operand" "f")))
4106    (use (match_operand:HI 2 "memory_operand" "m"))
4107    (use (match_operand:HI 3 "memory_operand" "m"))
4108    (clobber (match_scratch:DF 4 "=&1f"))]
4109   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4110    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4111   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4112   [(set_attr "type" "fistp")
4113    (set_attr "mode" "DI")])
4114
4115 (define_split 
4116   [(set (match_operand:DI 0 "register_operand" "")
4117         (fix:DI (match_operand 1 "register_operand" "")))
4118    (use (match_operand:HI 2 "memory_operand" ""))
4119    (use (match_operand:HI 3 "memory_operand" ""))
4120    (clobber (match_operand:DI 4 "memory_operand" ""))
4121    (clobber (match_scratch 5 ""))]
4122   "reload_completed"
4123   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4124               (use (match_dup 2))
4125               (use (match_dup 3))
4126               (clobber (match_dup 5))])
4127    (set (match_dup 0) (match_dup 4))]
4128   "")
4129
4130 (define_split 
4131   [(set (match_operand:DI 0 "memory_operand" "")
4132         (fix:DI (match_operand 1 "register_operand" "")))
4133    (use (match_operand:HI 2 "memory_operand" ""))
4134    (use (match_operand:HI 3 "memory_operand" ""))
4135    (clobber (match_operand:DI 4 "memory_operand" ""))
4136    (clobber (match_scratch 5 ""))]
4137   "reload_completed"
4138   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4139               (use (match_dup 2))
4140               (use (match_dup 3))
4141               (clobber (match_dup 5))])]
4142   "")
4143
4144 ;; When SSE available, it is always faster to use it!
4145 (define_insn "fix_truncsfdi_sse"
4146   [(set (match_operand:DI 0 "register_operand" "=r,r")
4147         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4148   "TARGET_64BIT && TARGET_SSE"
4149   "cvttss2si{q}\t{%1, %0|%0, %1}"
4150   [(set_attr "type" "sseicvt")
4151    (set_attr "mode" "SF")
4152    (set_attr "athlon_decode" "double,vector")])
4153
4154 ;; Avoid vector decoded form of the instruction.
4155 (define_peephole2
4156   [(match_scratch:SF 2 "x")
4157    (set (match_operand:DI 0 "register_operand" "")
4158         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4159   "TARGET_K8 && !optimize_size"
4160   [(set (match_dup 2) (match_dup 1))
4161    (set (match_dup 0) (fix:DI (match_dup 2)))]
4162   "")
4163
4164 (define_insn "fix_truncdfdi_sse"
4165   [(set (match_operand:DI 0 "register_operand" "=r,r")
4166         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4167   "TARGET_64BIT && TARGET_SSE2"
4168   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4169   [(set_attr "type" "sseicvt,sseicvt")
4170    (set_attr "mode" "DF")
4171    (set_attr "athlon_decode" "double,vector")])
4172
4173 ;; Avoid vector decoded form of the instruction.
4174 (define_peephole2
4175   [(match_scratch:DF 2 "Y")
4176    (set (match_operand:DI 0 "register_operand" "")
4177         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4178   "TARGET_K8 && !optimize_size"
4179   [(set (match_dup 2) (match_dup 1))
4180    (set (match_dup 0) (fix:DI (match_dup 2)))]
4181   "")
4182
4183 ;; Signed conversion to SImode.
4184
4185 (define_expand "fix_truncxfsi2"
4186   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4187                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4188               (clobber (reg:CC 17))])]
4189   "TARGET_80387"
4190   "")
4191
4192 (define_expand "fix_truncdfsi2"
4193   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4194                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4195               (clobber (reg:CC 17))])]
4196   "TARGET_80387 || TARGET_SSE2"
4197 {
4198   if (TARGET_SSE2)
4199    {
4200      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4201      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4202      if (out != operands[0])
4203         emit_move_insn (operands[0], out);
4204      DONE;
4205    }
4206 })
4207
4208 (define_expand "fix_truncsfsi2"
4209   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4210                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4211               (clobber (reg:CC 17))])] 
4212   "TARGET_80387 || TARGET_SSE"
4213 {
4214   if (TARGET_SSE)
4215    {
4216      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4217      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4218      if (out != operands[0])
4219         emit_move_insn (operands[0], out);
4220      DONE;
4221    }
4222 })
4223
4224 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4225 ;; of the machinery.
4226 (define_insn_and_split "*fix_truncsi_1"
4227   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4228         (fix:SI (match_operand 1 "register_operand" "f,f")))
4229         (clobber (reg:CC 17))]
4230   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4231    && !reload_completed && !reload_in_progress
4232    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4233   "#"
4234   "&& 1"
4235   [(const_int 0)]
4236 {
4237   ix86_optimize_mode_switching = 1;
4238   operands[2] = assign_386_stack_local (HImode, 1);
4239   operands[3] = assign_386_stack_local (HImode, 2);
4240   if (memory_operand (operands[0], VOIDmode))
4241     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4242                                        operands[2], operands[3]));
4243   else
4244     {
4245       operands[4] = assign_386_stack_local (SImode, 0);
4246       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4247                                            operands[2], operands[3],
4248                                            operands[4]));
4249     }
4250   DONE;
4251 }
4252   [(set_attr "type" "fistp")
4253    (set_attr "mode" "SI")])
4254
4255 (define_insn "fix_truncsi_nomemory"
4256   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4257         (fix:SI (match_operand 1 "register_operand" "f,f")))
4258    (use (match_operand:HI 2 "memory_operand" "m,m"))
4259    (use (match_operand:HI 3 "memory_operand" "m,m"))
4260    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4261   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4262    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4263   "#"
4264   [(set_attr "type" "fistp")
4265    (set_attr "mode" "SI")])
4266
4267 (define_insn "fix_truncsi_memory"
4268   [(set (match_operand:SI 0 "memory_operand" "=m")
4269         (fix:SI (match_operand 1 "register_operand" "f")))
4270    (use (match_operand:HI 2 "memory_operand" "m"))
4271    (use (match_operand:HI 3 "memory_operand" "m"))]
4272   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4273    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4274   "* return output_fix_trunc (insn, operands);"
4275   [(set_attr "type" "fistp")
4276    (set_attr "mode" "SI")])
4277
4278 ;; When SSE available, it is always faster to use it!
4279 (define_insn "fix_truncsfsi_sse"
4280   [(set (match_operand:SI 0 "register_operand" "=r,r")
4281         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4282   "TARGET_SSE"
4283   "cvttss2si\t{%1, %0|%0, %1}"
4284   [(set_attr "type" "sseicvt")
4285    (set_attr "mode" "DF")
4286    (set_attr "athlon_decode" "double,vector")])
4287
4288 ;; Avoid vector decoded form of the instruction.
4289 (define_peephole2
4290   [(match_scratch:SF 2 "x")
4291    (set (match_operand:SI 0 "register_operand" "")
4292         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4293   "TARGET_K8 && !optimize_size"
4294   [(set (match_dup 2) (match_dup 1))
4295    (set (match_dup 0) (fix:SI (match_dup 2)))]
4296   "")
4297
4298 (define_insn "fix_truncdfsi_sse"
4299   [(set (match_operand:SI 0 "register_operand" "=r,r")
4300         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4301   "TARGET_SSE2"
4302   "cvttsd2si\t{%1, %0|%0, %1}"
4303   [(set_attr "type" "sseicvt")
4304    (set_attr "mode" "DF")
4305    (set_attr "athlon_decode" "double,vector")])
4306
4307 ;; Avoid vector decoded form of the instruction.
4308 (define_peephole2
4309   [(match_scratch:DF 2 "Y")
4310    (set (match_operand:SI 0 "register_operand" "")
4311         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4312   "TARGET_K8 && !optimize_size"
4313   [(set (match_dup 2) (match_dup 1))
4314    (set (match_dup 0) (fix:SI (match_dup 2)))]
4315   "")
4316
4317 (define_split 
4318   [(set (match_operand:SI 0 "register_operand" "")
4319         (fix:SI (match_operand 1 "register_operand" "")))
4320    (use (match_operand:HI 2 "memory_operand" ""))
4321    (use (match_operand:HI 3 "memory_operand" ""))
4322    (clobber (match_operand:SI 4 "memory_operand" ""))]
4323   "reload_completed"
4324   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4325               (use (match_dup 2))
4326               (use (match_dup 3))])
4327    (set (match_dup 0) (match_dup 4))]
4328   "")
4329
4330 (define_split 
4331   [(set (match_operand:SI 0 "memory_operand" "")
4332         (fix:SI (match_operand 1 "register_operand" "")))
4333    (use (match_operand:HI 2 "memory_operand" ""))
4334    (use (match_operand:HI 3 "memory_operand" ""))
4335    (clobber (match_operand:SI 4 "memory_operand" ""))]
4336   "reload_completed"
4337   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4338               (use (match_dup 2))
4339               (use (match_dup 3))])]
4340   "")
4341
4342 ;; Signed conversion to HImode.
4343
4344 (define_expand "fix_truncxfhi2"
4345   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4347               (clobber (reg:CC 17))])] 
4348   "TARGET_80387"
4349   "")
4350
4351 (define_expand "fix_truncdfhi2"
4352   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4353                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4354               (clobber (reg:CC 17))])]
4355   "TARGET_80387 && !TARGET_SSE2"
4356   "")
4357
4358 (define_expand "fix_truncsfhi2"
4359   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4360                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4361                (clobber (reg:CC 17))])]
4362   "TARGET_80387 && !TARGET_SSE"
4363   "")
4364
4365 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4366 ;; of the machinery.
4367 (define_insn_and_split "*fix_trunchi_1"
4368   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4369         (fix:HI (match_operand 1 "register_operand" "f,f")))
4370         (clobber (reg:CC 17))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !reload_completed && !reload_in_progress
4373    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374   "#"
4375   ""
4376   [(const_int 0)]
4377 {
4378   ix86_optimize_mode_switching = 1;
4379   operands[2] = assign_386_stack_local (HImode, 1);
4380   operands[3] = assign_386_stack_local (HImode, 2);
4381   if (memory_operand (operands[0], VOIDmode))
4382     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4383                                        operands[2], operands[3]));
4384   else
4385     {
4386       operands[4] = assign_386_stack_local (HImode, 0);
4387       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4388                                            operands[2], operands[3],
4389                                            operands[4]));
4390     }
4391   DONE;
4392 }
4393   [(set_attr "type" "fistp")
4394    (set_attr "mode" "HI")])
4395
4396 (define_insn "fix_trunchi_nomemory"
4397   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4398         (fix:HI (match_operand 1 "register_operand" "f,f")))
4399    (use (match_operand:HI 2 "memory_operand" "m,m"))
4400    (use (match_operand:HI 3 "memory_operand" "m,m"))
4401    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4402   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4403    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4404   "#"
4405   [(set_attr "type" "fistp")
4406    (set_attr "mode" "HI")])
4407
4408 (define_insn "fix_trunchi_memory"
4409   [(set (match_operand:HI 0 "memory_operand" "=m")
4410         (fix:HI (match_operand 1 "register_operand" "f")))
4411    (use (match_operand:HI 2 "memory_operand" "m"))
4412    (use (match_operand:HI 3 "memory_operand" "m"))]
4413   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4414    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4415   "* return output_fix_trunc (insn, operands);"
4416   [(set_attr "type" "fistp")
4417    (set_attr "mode" "HI")])
4418
4419 (define_split 
4420   [(set (match_operand:HI 0 "memory_operand" "")
4421         (fix:HI (match_operand 1 "register_operand" "")))
4422    (use (match_operand:HI 2 "memory_operand" ""))
4423    (use (match_operand:HI 3 "memory_operand" ""))
4424    (clobber (match_operand:HI 4 "memory_operand" ""))]
4425   "reload_completed"
4426   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4427               (use (match_dup 2))
4428               (use (match_dup 3))])]
4429   "")
4430
4431 (define_split 
4432   [(set (match_operand:HI 0 "register_operand" "")
4433         (fix:HI (match_operand 1 "register_operand" "")))
4434    (use (match_operand:HI 2 "memory_operand" ""))
4435    (use (match_operand:HI 3 "memory_operand" ""))
4436    (clobber (match_operand:HI 4 "memory_operand" ""))]
4437   "reload_completed"
4438   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4439               (use (match_dup 2))
4440               (use (match_dup 3))
4441               (clobber (match_dup 4))])
4442    (set (match_dup 0) (match_dup 4))]
4443   "")
4444
4445 ;; %% Not used yet.
4446 (define_insn "x86_fnstcw_1"
4447   [(set (match_operand:HI 0 "memory_operand" "=m")
4448         (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4449   "TARGET_80387"
4450   "fnstcw\t%0"
4451   [(set_attr "length" "2")
4452    (set_attr "mode" "HI")
4453    (set_attr "unit" "i387")
4454    (set_attr "ppro_uops" "few")])
4455
4456 (define_insn "x86_fldcw_1"
4457   [(set (reg:HI 18)
4458         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4459   "TARGET_80387"
4460   "fldcw\t%0"
4461   [(set_attr "length" "2")
4462    (set_attr "mode" "HI")
4463    (set_attr "unit" "i387")
4464    (set_attr "athlon_decode" "vector")
4465    (set_attr "ppro_uops" "few")])
4466 \f
4467 ;; Conversion between fixed point and floating point.
4468
4469 ;; Even though we only accept memory inputs, the backend _really_
4470 ;; wants to be able to do this between registers.
4471
4472 (define_expand "floathisf2"
4473   [(set (match_operand:SF 0 "register_operand" "")
4474         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4475   "TARGET_SSE || TARGET_80387"
4476 {
4477   if (TARGET_SSE && TARGET_SSE_MATH)
4478     {
4479       emit_insn (gen_floatsisf2 (operands[0],
4480                                  convert_to_mode (SImode, operands[1], 0)));
4481       DONE;
4482     }
4483 })
4484
4485 (define_insn "*floathisf2_1"
4486   [(set (match_operand:SF 0 "register_operand" "=f,f")
4487         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4488   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4489   "@
4490    fild%z1\t%1
4491    #"
4492   [(set_attr "type" "fmov,multi")
4493    (set_attr "mode" "SF")
4494    (set_attr "fp_int_src" "true")])
4495
4496 (define_expand "floatsisf2"
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "TARGET_SSE || TARGET_80387"
4500   "")
4501
4502 (define_insn "*floatsisf2_i387"
4503   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4504         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4505   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4506   "@
4507    fild%z1\t%1
4508    #
4509    cvtsi2ss\t{%1, %0|%0, %1}
4510    cvtsi2ss\t{%1, %0|%0, %1}"
4511   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4512    (set_attr "mode" "SF")
4513    (set_attr "athlon_decode" "*,*,vector,double")
4514    (set_attr "fp_int_src" "true")])
4515
4516 (define_insn "*floatsisf2_sse"
4517   [(set (match_operand:SF 0 "register_operand" "=x,x")
4518         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4519   "TARGET_SSE"
4520   "cvtsi2ss\t{%1, %0|%0, %1}"
4521   [(set_attr "type" "sseicvt")
4522    (set_attr "mode" "SF")
4523    (set_attr "athlon_decode" "vector,double")
4524    (set_attr "fp_int_src" "true")])
4525
4526 ; Avoid possible reformatting penalty on the destination by first
4527 ; zeroing it out
4528 (define_split
4529   [(set (match_operand:SF 0 "register_operand" "")
4530         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4531   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4532    && SSE_REG_P (operands[0])"
4533   [(const_int 0)]
4534 {
4535   rtx dest;
4536   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4537   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4538   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4539   DONE;
4540 })
4541
4542 (define_expand "floatdisf2"
4543   [(set (match_operand:SF 0 "register_operand" "")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4545   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4546   "")
4547
4548 (define_insn "*floatdisf2_i387_only"
4549   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4550         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4551   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4552   "@
4553    fild%z1\t%1
4554    #"
4555   [(set_attr "type" "fmov,multi")
4556    (set_attr "mode" "SF")
4557    (set_attr "fp_int_src" "true")])
4558
4559 (define_insn "*floatdisf2_i387"
4560   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4561         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4563   "@
4564    fild%z1\t%1
4565    #
4566    cvtsi2ss{q}\t{%1, %0|%0, %1}
4567    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569    (set_attr "mode" "SF")
4570    (set_attr "athlon_decode" "*,*,vector,double")
4571    (set_attr "fp_int_src" "true")])
4572
4573 (define_insn "*floatdisf2_sse"
4574   [(set (match_operand:SF 0 "register_operand" "=x,x")
4575         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4576   "TARGET_64BIT && TARGET_SSE"
4577   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4578   [(set_attr "type" "sseicvt")
4579    (set_attr "mode" "SF")
4580    (set_attr "athlon_decode" "vector,double")
4581    (set_attr "fp_int_src" "true")])
4582
4583 ; Avoid possible reformatting penalty on the destination by first
4584 ; zeroing it out
4585 (define_split
4586   [(set (match_operand:SF 0 "register_operand" "")
4587         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4588   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4589    && SSE_REG_P (operands[0])"
4590   [(const_int 0)]
4591 {
4592   rtx dest;
4593   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4594   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4595   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4596   DONE;
4597 })
4598
4599 (define_expand "floathidf2"
4600   [(set (match_operand:DF 0 "register_operand" "")
4601         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4602   "TARGET_SSE2 || TARGET_80387"
4603 {
4604   if (TARGET_SSE && TARGET_SSE_MATH)
4605     {
4606       emit_insn (gen_floatsidf2 (operands[0],
4607                                  convert_to_mode (SImode, operands[1], 0)));
4608       DONE;
4609     }
4610 })
4611
4612 (define_insn "*floathidf2_1"
4613   [(set (match_operand:DF 0 "register_operand" "=f,f")
4614         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4615   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4616   "@
4617    fild%z1\t%1
4618    #"
4619   [(set_attr "type" "fmov,multi")
4620    (set_attr "mode" "DF")
4621    (set_attr "fp_int_src" "true")])
4622
4623 (define_expand "floatsidf2"
4624   [(set (match_operand:DF 0 "register_operand" "")
4625         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4626   "TARGET_80387 || TARGET_SSE2"
4627   "")
4628
4629 (define_insn "*floatsidf2_i387"
4630   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4631         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4632   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4633   "@
4634    fild%z1\t%1
4635    #
4636    cvtsi2sd\t{%1, %0|%0, %1}
4637    cvtsi2sd\t{%1, %0|%0, %1}"
4638   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4639    (set_attr "mode" "DF")
4640    (set_attr "athlon_decode" "*,*,double,direct")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "*floatsidf2_sse"
4644   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4645         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4646   "TARGET_SSE2"
4647   "cvtsi2sd\t{%1, %0|%0, %1}"
4648   [(set_attr "type" "sseicvt")
4649    (set_attr "mode" "DF")
4650    (set_attr "athlon_decode" "double,direct")
4651    (set_attr "fp_int_src" "true")])
4652
4653 (define_expand "floatdidf2"
4654   [(set (match_operand:DF 0 "register_operand" "")
4655         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4656   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4657   "")
4658
4659 (define_insn "*floatdidf2_i387_only"
4660   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4662   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "DF")
4668    (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "*floatdidf2_i387"
4671   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4672         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4673   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4674   "@
4675    fild%z1\t%1
4676    #
4677    cvtsi2sd{q}\t{%1, %0|%0, %1}
4678    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4679   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4680    (set_attr "mode" "DF")
4681    (set_attr "athlon_decode" "*,*,double,direct")
4682    (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "*floatdidf2_sse"
4685   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4686         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4687   "TARGET_SSE2"
4688   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4689   [(set_attr "type" "sseicvt")
4690    (set_attr "mode" "DF")
4691    (set_attr "athlon_decode" "double,direct")
4692    (set_attr "fp_int_src" "true")])
4693
4694 (define_insn "floathixf2"
4695   [(set (match_operand:XF 0 "register_operand" "=f,f")
4696         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4697   "TARGET_80387"
4698   "@
4699    fild%z1\t%1
4700    #"
4701   [(set_attr "type" "fmov,multi")
4702    (set_attr "mode" "XF")
4703    (set_attr "fp_int_src" "true")])
4704
4705 (define_insn "floatsixf2"
4706   [(set (match_operand:XF 0 "register_operand" "=f,f")
4707         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4708   "TARGET_80387"
4709   "@
4710    fild%z1\t%1
4711    #"
4712   [(set_attr "type" "fmov,multi")
4713    (set_attr "mode" "XF")
4714    (set_attr "fp_int_src" "true")])
4715
4716 (define_insn "floatdixf2"
4717   [(set (match_operand:XF 0 "register_operand" "=f,f")
4718         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4719   "TARGET_80387"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "XF")
4725    (set_attr "fp_int_src" "true")])
4726
4727 ;; %%% Kill these when reload knows how to do it.
4728 (define_split
4729   [(set (match_operand 0 "fp_register_operand" "")
4730         (float (match_operand 1 "register_operand" "")))]
4731   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4732   [(const_int 0)]
4733 {
4734   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4735   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4736   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4737   ix86_free_from_memory (GET_MODE (operands[1]));
4738   DONE;
4739 })
4740
4741 (define_expand "floatunssisf2"
4742   [(use (match_operand:SF 0 "register_operand" ""))
4743    (use (match_operand:SI 1 "register_operand" ""))]
4744   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4745   "x86_emit_floatuns (operands); DONE;")
4746
4747 (define_expand "floatunsdisf2"
4748   [(use (match_operand:SF 0 "register_operand" ""))
4749    (use (match_operand:DI 1 "register_operand" ""))]
4750   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4751   "x86_emit_floatuns (operands); DONE;")
4752
4753 (define_expand "floatunsdidf2"
4754   [(use (match_operand:DF 0 "register_operand" ""))
4755    (use (match_operand:DI 1 "register_operand" ""))]
4756   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4757   "x86_emit_floatuns (operands); DONE;")
4758 \f
4759 ;; SSE extract/set expanders
4760
4761 (define_expand "vec_setv2df"
4762   [(match_operand:V2DF 0 "register_operand" "")
4763    (match_operand:DF 1 "register_operand" "")
4764    (match_operand 2 "const_int_operand" "")]
4765   "TARGET_SSE2"
4766 {
4767   switch (INTVAL (operands[2]))
4768     {
4769     case 0:
4770       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4771                                  simplify_gen_subreg (V2DFmode, operands[1],
4772                                                       DFmode, 0)));
4773       break;
4774     case 1:
4775       {
4776         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4777
4778         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4779       }
4780       break;
4781     default:
4782       abort ();
4783     }
4784   DONE;
4785 })
4786
4787 (define_expand "vec_extractv2df"
4788   [(match_operand:DF 0 "register_operand" "")
4789    (match_operand:V2DF 1 "register_operand" "")
4790    (match_operand 2 "const_int_operand" "")]
4791   "TARGET_SSE2"
4792 {
4793   switch (INTVAL (operands[2]))
4794     {
4795     case 0:
4796       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4797       break;
4798     case 1:
4799       {
4800         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4801
4802         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4803       }
4804       break;
4805     default:
4806       abort ();
4807     }
4808   DONE;
4809 })
4810
4811 (define_expand "vec_initv2df"
4812   [(match_operand:V2DF 0 "register_operand" "")
4813    (match_operand 1 "" "")]
4814   "TARGET_SSE2"
4815 {
4816   ix86_expand_vector_init (operands[0], operands[1]);
4817   DONE;
4818 })
4819
4820 (define_expand "vec_setv4sf"
4821   [(match_operand:V4SF 0 "register_operand" "")
4822    (match_operand:SF 1 "register_operand" "")
4823    (match_operand 2 "const_int_operand" "")]
4824   "TARGET_SSE"
4825 {
4826   switch (INTVAL (operands[2]))
4827     {
4828     case 0:
4829       emit_insn (gen_sse_movss (operands[0], operands[0],
4830                                 simplify_gen_subreg (V4SFmode, operands[1],
4831                                                      SFmode, 0)));
4832       break;
4833     case 1:
4834       {
4835         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4836         rtx tmp = gen_reg_rtx (V4SFmode);
4837  
4838         emit_move_insn (tmp, operands[0]);
4839         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4840         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4841         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4842                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4843       }
4844     case 2:
4845       {
4846         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4847         rtx tmp = gen_reg_rtx (V4SFmode);
4848
4849         emit_move_insn (tmp, operands[0]);
4850         emit_insn (gen_sse_movss (tmp, tmp, op1));
4851         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4852                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4853       }
4854       break;
4855     case 3:
4856       {
4857         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4858         rtx tmp = gen_reg_rtx (V4SFmode);
4859
4860         emit_move_insn (tmp, operands[0]);
4861         emit_insn (gen_sse_movss (tmp, tmp, op1));
4862         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4863                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4864       }
4865       break;
4866     default:
4867       abort ();
4868     }
4869   DONE;
4870 })
4871
4872 (define_expand "vec_extractv4sf"
4873   [(match_operand:SF 0 "register_operand" "")
4874    (match_operand:V4SF 1 "register_operand" "")
4875    (match_operand 2 "const_int_operand" "")]
4876   "TARGET_SSE"
4877 {
4878   switch (INTVAL (operands[2]))
4879     {
4880     case 0:
4881       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4882       break;
4883     case 1:
4884       {
4885         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4886         rtx tmp = gen_reg_rtx (V4SFmode);
4887  
4888         emit_move_insn (tmp, operands[1]);
4889         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4890                                    const1_rtx));
4891       }
4892     case 2:
4893       {
4894         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4895         rtx tmp = gen_reg_rtx (V4SFmode);
4896  
4897         emit_move_insn (tmp, operands[1]);
4898         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4899       }
4900     case 3:
4901       {
4902         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4903         rtx tmp = gen_reg_rtx (V4SFmode);
4904  
4905         emit_move_insn (tmp, operands[1]);
4906         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4907                                    GEN_INT (3)));
4908       }
4909     default:
4910       abort ();
4911     }
4912   DONE;
4913 })
4914
4915 (define_expand "vec_initv4sf"
4916   [(match_operand:V4SF 0 "register_operand" "")
4917    (match_operand 1 "" "")]
4918   "TARGET_SSE"
4919 {
4920   ix86_expand_vector_init (operands[0], operands[1]);
4921   DONE;
4922 })
4923 \f
4924 ;; Add instructions
4925
4926 ;; %%% splits for addsidi3
4927 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4928 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4929 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4930
4931 (define_expand "adddi3"
4932   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4934                  (match_operand:DI 2 "x86_64_general_operand" "")))
4935    (clobber (reg:CC 17))]
4936   ""
4937   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4938
4939 (define_insn "*adddi3_1"
4940   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4941         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4942                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4943    (clobber (reg:CC 17))]
4944   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4945   "#")
4946
4947 (define_split
4948   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4949         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4950                  (match_operand:DI 2 "general_operand" "")))
4951    (clobber (reg:CC 17))]
4952   "!TARGET_64BIT && reload_completed"
4953   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4954                                           UNSPEC_ADD_CARRY))
4955               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4956    (parallel [(set (match_dup 3)
4957                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4958                                      (match_dup 4))
4959                             (match_dup 5)))
4960               (clobber (reg:CC 17))])]
4961   "split_di (operands+0, 1, operands+0, operands+3);
4962    split_di (operands+1, 1, operands+1, operands+4);
4963    split_di (operands+2, 1, operands+2, operands+5);")
4964
4965 (define_insn "adddi3_carry_rex64"
4966   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4967           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4968                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4969                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4970    (clobber (reg:CC 17))]
4971   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4972   "adc{q}\t{%2, %0|%0, %2}"
4973   [(set_attr "type" "alu")
4974    (set_attr "pent_pair" "pu")
4975    (set_attr "mode" "DI")
4976    (set_attr "ppro_uops" "few")])
4977
4978 (define_insn "*adddi3_cc_rex64"
4979   [(set (reg:CC 17)
4980         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4981                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4982                    UNSPEC_ADD_CARRY))
4983    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4984         (plus:DI (match_dup 1) (match_dup 2)))]
4985   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4986   "add{q}\t{%2, %0|%0, %2}"
4987   [(set_attr "type" "alu")
4988    (set_attr "mode" "DI")])
4989
4990 (define_insn "addqi3_carry"
4991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4992           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4993                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4994                    (match_operand:QI 2 "general_operand" "qi,qm")))
4995    (clobber (reg:CC 17))]
4996   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4997   "adc{b}\t{%2, %0|%0, %2}"
4998   [(set_attr "type" "alu")
4999    (set_attr "pent_pair" "pu")
5000    (set_attr "mode" "QI")
5001    (set_attr "ppro_uops" "few")])
5002
5003 (define_insn "addhi3_carry"
5004   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5005           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5006                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5007                    (match_operand:HI 2 "general_operand" "ri,rm")))
5008    (clobber (reg:CC 17))]
5009   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5010   "adc{w}\t{%2, %0|%0, %2}"
5011   [(set_attr "type" "alu")
5012    (set_attr "pent_pair" "pu")
5013    (set_attr "mode" "HI")
5014    (set_attr "ppro_uops" "few")])
5015
5016 (define_insn "addsi3_carry"
5017   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5018           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5019                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5020                    (match_operand:SI 2 "general_operand" "ri,rm")))
5021    (clobber (reg:CC 17))]
5022   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5023   "adc{l}\t{%2, %0|%0, %2}"
5024   [(set_attr "type" "alu")
5025    (set_attr "pent_pair" "pu")
5026    (set_attr "mode" "SI")
5027    (set_attr "ppro_uops" "few")])
5028
5029 (define_insn "*addsi3_carry_zext"
5030   [(set (match_operand:DI 0 "register_operand" "=r")
5031           (zero_extend:DI 
5032             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5033                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5034                      (match_operand:SI 2 "general_operand" "rim"))))
5035    (clobber (reg:CC 17))]
5036   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5037   "adc{l}\t{%2, %k0|%k0, %2}"
5038   [(set_attr "type" "alu")
5039    (set_attr "pent_pair" "pu")
5040    (set_attr "mode" "SI")
5041    (set_attr "ppro_uops" "few")])
5042
5043 (define_insn "*addsi3_cc"
5044   [(set (reg:CC 17)
5045         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5046                     (match_operand:SI 2 "general_operand" "ri,rm")]
5047                    UNSPEC_ADD_CARRY))
5048    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5049         (plus:SI (match_dup 1) (match_dup 2)))]
5050   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5051   "add{l}\t{%2, %0|%0, %2}"
5052   [(set_attr "type" "alu")
5053    (set_attr "mode" "SI")])
5054
5055 (define_insn "addqi3_cc"
5056   [(set (reg:CC 17)
5057         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5058                     (match_operand:QI 2 "general_operand" "qi,qm")]
5059                    UNSPEC_ADD_CARRY))
5060    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5061         (plus:QI (match_dup 1) (match_dup 2)))]
5062   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5063   "add{b}\t{%2, %0|%0, %2}"
5064   [(set_attr "type" "alu")
5065    (set_attr "mode" "QI")])
5066
5067 (define_expand "addsi3"
5068   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5069                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5070                             (match_operand:SI 2 "general_operand" "")))
5071               (clobber (reg:CC 17))])]
5072   ""
5073   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5074
5075 (define_insn "*lea_1"
5076   [(set (match_operand:SI 0 "register_operand" "=r")
5077         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5078   "!TARGET_64BIT"
5079   "lea{l}\t{%a1, %0|%0, %a1}"
5080   [(set_attr "type" "lea")
5081    (set_attr "mode" "SI")])
5082
5083 (define_insn "*lea_1_rex64"
5084   [(set (match_operand:SI 0 "register_operand" "=r")
5085         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5086   "TARGET_64BIT"
5087   "lea{l}\t{%a1, %0|%0, %a1}"
5088   [(set_attr "type" "lea")
5089    (set_attr "mode" "SI")])
5090
5091 (define_insn "*lea_1_zext"
5092   [(set (match_operand:DI 0 "register_operand" "=r")
5093         (zero_extend:DI
5094          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5095   "TARGET_64BIT"
5096   "lea{l}\t{%a1, %k0|%k0, %a1}"
5097   [(set_attr "type" "lea")
5098    (set_attr "mode" "SI")])
5099
5100 (define_insn "*lea_2_rex64"
5101   [(set (match_operand:DI 0 "register_operand" "=r")
5102         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5103   "TARGET_64BIT"
5104   "lea{q}\t{%a1, %0|%0, %a1}"
5105   [(set_attr "type" "lea")
5106    (set_attr "mode" "DI")])
5107
5108 ;; The lea patterns for non-Pmodes needs to be matched by several
5109 ;; insns converted to real lea by splitters.
5110
5111 (define_insn_and_split "*lea_general_1"
5112   [(set (match_operand 0 "register_operand" "=r")
5113         (plus (plus (match_operand 1 "index_register_operand" "r")
5114                     (match_operand 2 "register_operand" "r"))
5115               (match_operand 3 "immediate_operand" "i")))]
5116   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5117     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5118    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5119    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5120    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5121    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5122        || GET_MODE (operands[3]) == VOIDmode)"
5123   "#"
5124   "&& reload_completed"
5125   [(const_int 0)]
5126 {
5127   rtx pat;
5128   operands[0] = gen_lowpart (SImode, operands[0]);
5129   operands[1] = gen_lowpart (Pmode, operands[1]);
5130   operands[2] = gen_lowpart (Pmode, operands[2]);
5131   operands[3] = gen_lowpart (Pmode, operands[3]);
5132   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5133                       operands[3]);
5134   if (Pmode != SImode)
5135     pat = gen_rtx_SUBREG (SImode, pat, 0);
5136   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5137   DONE;
5138 }
5139   [(set_attr "type" "lea")
5140    (set_attr "mode" "SI")])
5141
5142 (define_insn_and_split "*lea_general_1_zext"
5143   [(set (match_operand:DI 0 "register_operand" "=r")
5144         (zero_extend:DI
5145           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5146                             (match_operand:SI 2 "register_operand" "r"))
5147                    (match_operand:SI 3 "immediate_operand" "i"))))]
5148   "TARGET_64BIT"
5149   "#"
5150   "&& reload_completed"
5151   [(set (match_dup 0)
5152         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5153                                                      (match_dup 2))
5154                                             (match_dup 3)) 0)))]
5155 {
5156   operands[1] = gen_lowpart (Pmode, operands[1]);
5157   operands[2] = gen_lowpart (Pmode, operands[2]);
5158   operands[3] = gen_lowpart (Pmode, operands[3]);
5159 }
5160   [(set_attr "type" "lea")
5161    (set_attr "mode" "SI")])
5162
5163 (define_insn_and_split "*lea_general_2"
5164   [(set (match_operand 0 "register_operand" "=r")
5165         (plus (mult (match_operand 1 "index_register_operand" "r")
5166                     (match_operand 2 "const248_operand" "i"))
5167               (match_operand 3 "nonmemory_operand" "ri")))]
5168   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5169     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5170    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5171    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5172    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5173        || GET_MODE (operands[3]) == VOIDmode)"
5174   "#"
5175   "&& reload_completed"
5176   [(const_int 0)]
5177 {
5178   rtx pat;
5179   operands[0] = gen_lowpart (SImode, operands[0]);
5180   operands[1] = gen_lowpart (Pmode, operands[1]);
5181   operands[3] = gen_lowpart (Pmode, operands[3]);
5182   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5183                       operands[3]);
5184   if (Pmode != SImode)
5185     pat = gen_rtx_SUBREG (SImode, pat, 0);
5186   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5187   DONE;
5188 }
5189   [(set_attr "type" "lea")
5190    (set_attr "mode" "SI")])
5191
5192 (define_insn_and_split "*lea_general_2_zext"
5193   [(set (match_operand:DI 0 "register_operand" "=r")
5194         (zero_extend:DI
5195           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5196                             (match_operand:SI 2 "const248_operand" "n"))
5197                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5198   "TARGET_64BIT"
5199   "#"
5200   "&& reload_completed"
5201   [(set (match_dup 0)
5202         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5203                                                      (match_dup 2))
5204                                             (match_dup 3)) 0)))]
5205 {
5206   operands[1] = gen_lowpart (Pmode, operands[1]);
5207   operands[3] = gen_lowpart (Pmode, operands[3]);
5208 }
5209   [(set_attr "type" "lea")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn_and_split "*lea_general_3"
5213   [(set (match_operand 0 "register_operand" "=r")
5214         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5215                           (match_operand 2 "const248_operand" "i"))
5216                     (match_operand 3 "register_operand" "r"))
5217               (match_operand 4 "immediate_operand" "i")))]
5218   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5219     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5220    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5221    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5222    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5223   "#"
5224   "&& reload_completed"
5225   [(const_int 0)]
5226 {
5227   rtx pat;
5228   operands[0] = gen_lowpart (SImode, operands[0]);
5229   operands[1] = gen_lowpart (Pmode, operands[1]);
5230   operands[3] = gen_lowpart (Pmode, operands[3]);
5231   operands[4] = gen_lowpart (Pmode, operands[4]);
5232   pat = gen_rtx_PLUS (Pmode,
5233                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5234                                                          operands[2]),
5235                                     operands[3]),
5236                       operands[4]);
5237   if (Pmode != SImode)
5238     pat = gen_rtx_SUBREG (SImode, pat, 0);
5239   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5240   DONE;
5241 }
5242   [(set_attr "type" "lea")
5243    (set_attr "mode" "SI")])
5244
5245 (define_insn_and_split "*lea_general_3_zext"
5246   [(set (match_operand:DI 0 "register_operand" "=r")
5247         (zero_extend:DI
5248           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5249                                      (match_operand:SI 2 "const248_operand" "n"))
5250                             (match_operand:SI 3 "register_operand" "r"))
5251                    (match_operand:SI 4 "immediate_operand" "i"))))]
5252   "TARGET_64BIT"
5253   "#"
5254   "&& reload_completed"
5255   [(set (match_dup 0)
5256         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5257                                                               (match_dup 2))
5258                                                      (match_dup 3))
5259                                             (match_dup 4)) 0)))]
5260 {
5261   operands[1] = gen_lowpart (Pmode, operands[1]);
5262   operands[3] = gen_lowpart (Pmode, operands[3]);
5263   operands[4] = gen_lowpart (Pmode, operands[4]);
5264 }
5265   [(set_attr "type" "lea")
5266    (set_attr "mode" "SI")])
5267
5268 (define_insn "*adddi_1_rex64"
5269   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5270         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5271                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5272    (clobber (reg:CC 17))]
5273   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5274 {
5275   switch (get_attr_type (insn))
5276     {
5277     case TYPE_LEA:
5278       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5279       return "lea{q}\t{%a2, %0|%0, %a2}";
5280
5281     case TYPE_INCDEC:
5282       if (! rtx_equal_p (operands[0], operands[1]))
5283         abort ();
5284       if (operands[2] == const1_rtx)
5285         return "inc{q}\t%0";
5286       else if (operands[2] == constm1_rtx)
5287         return "dec{q}\t%0";
5288       else
5289         abort ();
5290
5291     default:
5292       if (! rtx_equal_p (operands[0], operands[1]))
5293         abort ();
5294
5295       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5296          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5297       if (GET_CODE (operands[2]) == CONST_INT
5298           /* Avoid overflows.  */
5299           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5300           && (INTVAL (operands[2]) == 128
5301               || (INTVAL (operands[2]) < 0
5302                   && INTVAL (operands[2]) != -128)))
5303         {
5304           operands[2] = GEN_INT (-INTVAL (operands[2]));
5305           return "sub{q}\t{%2, %0|%0, %2}";
5306         }
5307       return "add{q}\t{%2, %0|%0, %2}";
5308     }
5309 }
5310   [(set (attr "type")
5311      (cond [(eq_attr "alternative" "2")
5312               (const_string "lea")
5313             ; Current assemblers are broken and do not allow @GOTOFF in
5314             ; ought but a memory context.
5315             (match_operand:DI 2 "pic_symbolic_operand" "")
5316               (const_string "lea")
5317             (match_operand:DI 2 "incdec_operand" "")
5318               (const_string "incdec")
5319            ]
5320            (const_string "alu")))
5321    (set_attr "mode" "DI")])
5322
5323 ;; Convert lea to the lea pattern to avoid flags dependency.
5324 (define_split
5325   [(set (match_operand:DI 0 "register_operand" "")
5326         (plus:DI (match_operand:DI 1 "register_operand" "")
5327                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5328    (clobber (reg:CC 17))]
5329   "TARGET_64BIT && reload_completed
5330    && true_regnum (operands[0]) != true_regnum (operands[1])"
5331   [(set (match_dup 0)
5332         (plus:DI (match_dup 1)
5333                  (match_dup 2)))]
5334   "")
5335
5336 (define_insn "*adddi_2_rex64"
5337   [(set (reg 17)
5338         (compare
5339           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5340                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5341           (const_int 0)))                       
5342    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5343         (plus:DI (match_dup 1) (match_dup 2)))]
5344   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5345    && ix86_binary_operator_ok (PLUS, DImode, operands)
5346    /* Current assemblers are broken and do not allow @GOTOFF in
5347       ought but a memory context.  */
5348    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5349 {
5350   switch (get_attr_type (insn))
5351     {
5352     case TYPE_INCDEC:
5353       if (! rtx_equal_p (operands[0], operands[1]))
5354         abort ();
5355       if (operands[2] == const1_rtx)
5356         return "inc{q}\t%0";
5357       else if (operands[2] == constm1_rtx)
5358         return "dec{q}\t%0";
5359       else
5360         abort ();
5361
5362     default:
5363       if (! rtx_equal_p (operands[0], operands[1]))
5364         abort ();
5365       /* ???? We ought to handle there the 32bit case too
5366          - do we need new constraint?  */
5367       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5368          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5369       if (GET_CODE (operands[2]) == CONST_INT
5370           /* Avoid overflows.  */
5371           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5372           && (INTVAL (operands[2]) == 128
5373               || (INTVAL (operands[2]) < 0
5374                   && INTVAL (operands[2]) != -128)))
5375         {
5376           operands[2] = GEN_INT (-INTVAL (operands[2]));
5377           return "sub{q}\t{%2, %0|%0, %2}";
5378         }
5379       return "add{q}\t{%2, %0|%0, %2}";
5380     }
5381 }
5382   [(set (attr "type")
5383      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5384         (const_string "incdec")
5385         (const_string "alu")))
5386    (set_attr "mode" "DI")])
5387
5388 (define_insn "*adddi_3_rex64"
5389   [(set (reg 17)
5390         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5391                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5392    (clobber (match_scratch:DI 0 "=r"))]
5393   "TARGET_64BIT
5394    && ix86_match_ccmode (insn, CCZmode)
5395    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5396    /* Current assemblers are broken and do not allow @GOTOFF in
5397       ought but a memory context.  */
5398    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5399 {
5400   switch (get_attr_type (insn))
5401     {
5402     case TYPE_INCDEC:
5403       if (! rtx_equal_p (operands[0], operands[1]))
5404         abort ();
5405       if (operands[2] == const1_rtx)
5406         return "inc{q}\t%0";
5407       else if (operands[2] == constm1_rtx)
5408         return "dec{q}\t%0";
5409       else
5410         abort ();
5411
5412     default:
5413       if (! rtx_equal_p (operands[0], operands[1]))
5414         abort ();
5415       /* ???? We ought to handle there the 32bit case too
5416          - do we need new constraint?  */
5417       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5418          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5419       if (GET_CODE (operands[2]) == CONST_INT
5420           /* Avoid overflows.  */
5421           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5422           && (INTVAL (operands[2]) == 128
5423               || (INTVAL (operands[2]) < 0
5424                   && INTVAL (operands[2]) != -128)))
5425         {
5426           operands[2] = GEN_INT (-INTVAL (operands[2]));
5427           return "sub{q}\t{%2, %0|%0, %2}";
5428         }
5429       return "add{q}\t{%2, %0|%0, %2}";
5430     }
5431 }
5432   [(set (attr "type")
5433      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5434         (const_string "incdec")
5435         (const_string "alu")))
5436    (set_attr "mode" "DI")])
5437
5438 ; For comparisons against 1, -1 and 128, we may generate better code
5439 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5440 ; is matched then.  We can't accept general immediate, because for
5441 ; case of overflows,  the result is messed up.
5442 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5443 ; when negated.
5444 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5445 ; only for comparisons not depending on it.
5446 (define_insn "*adddi_4_rex64"
5447   [(set (reg 17)
5448         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5449                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5450    (clobber (match_scratch:DI 0 "=rm"))]
5451   "TARGET_64BIT
5452    &&  ix86_match_ccmode (insn, CCGCmode)"
5453 {
5454   switch (get_attr_type (insn))
5455     {
5456     case TYPE_INCDEC:
5457       if (operands[2] == constm1_rtx)
5458         return "inc{q}\t%0";
5459       else if (operands[2] == const1_rtx)
5460         return "dec{q}\t%0";
5461       else
5462         abort();
5463
5464     default:
5465       if (! rtx_equal_p (operands[0], operands[1]))
5466         abort ();
5467       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5468          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5469       if ((INTVAL (operands[2]) == -128
5470            || (INTVAL (operands[2]) > 0
5471                && INTVAL (operands[2]) != 128))
5472           /* Avoid overflows.  */
5473           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5474         return "sub{q}\t{%2, %0|%0, %2}";
5475       operands[2] = GEN_INT (-INTVAL (operands[2]));
5476       return "add{q}\t{%2, %0|%0, %2}";
5477     }
5478 }
5479   [(set (attr "type")
5480      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5481         (const_string "incdec")
5482         (const_string "alu")))
5483    (set_attr "mode" "DI")])
5484
5485 (define_insn "*adddi_5_rex64"
5486   [(set (reg 17)
5487         (compare
5488           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5489                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5490           (const_int 0)))                       
5491    (clobber (match_scratch:DI 0 "=r"))]
5492   "TARGET_64BIT
5493    && ix86_match_ccmode (insn, CCGOCmode)
5494    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5495    /* Current assemblers are broken and do not allow @GOTOFF in
5496       ought but a memory context.  */
5497    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5498 {
5499   switch (get_attr_type (insn))
5500     {
5501     case TYPE_INCDEC:
5502       if (! rtx_equal_p (operands[0], operands[1]))
5503         abort ();
5504       if (operands[2] == const1_rtx)
5505         return "inc{q}\t%0";
5506       else if (operands[2] == constm1_rtx)
5507         return "dec{q}\t%0";
5508       else
5509         abort();
5510
5511     default:
5512       if (! rtx_equal_p (operands[0], operands[1]))
5513         abort ();
5514       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5515          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5516       if (GET_CODE (operands[2]) == CONST_INT
5517           /* Avoid overflows.  */
5518           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5519           && (INTVAL (operands[2]) == 128
5520               || (INTVAL (operands[2]) < 0
5521                   && INTVAL (operands[2]) != -128)))
5522         {
5523           operands[2] = GEN_INT (-INTVAL (operands[2]));
5524           return "sub{q}\t{%2, %0|%0, %2}";
5525         }
5526       return "add{q}\t{%2, %0|%0, %2}";
5527     }
5528 }
5529   [(set (attr "type")
5530      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5531         (const_string "incdec")
5532         (const_string "alu")))
5533    (set_attr "mode" "DI")])
5534
5535
5536 (define_insn "*addsi_1"
5537   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5538         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5539                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5540    (clobber (reg:CC 17))]
5541   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5542 {
5543   switch (get_attr_type (insn))
5544     {
5545     case TYPE_LEA:
5546       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5547       return "lea{l}\t{%a2, %0|%0, %a2}";
5548
5549     case TYPE_INCDEC:
5550       if (! rtx_equal_p (operands[0], operands[1]))
5551         abort ();
5552       if (operands[2] == const1_rtx)
5553         return "inc{l}\t%0";
5554       else if (operands[2] == constm1_rtx)
5555         return "dec{l}\t%0";
5556       else
5557         abort();
5558
5559     default:
5560       if (! rtx_equal_p (operands[0], operands[1]))
5561         abort ();
5562
5563       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5564          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5565       if (GET_CODE (operands[2]) == CONST_INT
5566           && (INTVAL (operands[2]) == 128
5567               || (INTVAL (operands[2]) < 0
5568                   && INTVAL (operands[2]) != -128)))
5569         {
5570           operands[2] = GEN_INT (-INTVAL (operands[2]));
5571           return "sub{l}\t{%2, %0|%0, %2}";
5572         }
5573       return "add{l}\t{%2, %0|%0, %2}";
5574     }
5575 }
5576   [(set (attr "type")
5577      (cond [(eq_attr "alternative" "2")
5578               (const_string "lea")
5579             ; Current assemblers are broken and do not allow @GOTOFF in
5580             ; ought but a memory context.
5581             (match_operand:SI 2 "pic_symbolic_operand" "")
5582               (const_string "lea")
5583             (match_operand:SI 2 "incdec_operand" "")
5584               (const_string "incdec")
5585            ]
5586            (const_string "alu")))
5587    (set_attr "mode" "SI")])
5588
5589 ;; Convert lea to the lea pattern to avoid flags dependency.
5590 (define_split
5591   [(set (match_operand 0 "register_operand" "")
5592         (plus (match_operand 1 "register_operand" "")
5593               (match_operand 2 "nonmemory_operand" "")))
5594    (clobber (reg:CC 17))]
5595   "reload_completed
5596    && true_regnum (operands[0]) != true_regnum (operands[1])"
5597   [(const_int 0)]
5598 {
5599   rtx pat;
5600   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5601      may confuse gen_lowpart.  */
5602   if (GET_MODE (operands[0]) != Pmode)
5603     {
5604       operands[1] = gen_lowpart (Pmode, operands[1]);
5605       operands[2] = gen_lowpart (Pmode, operands[2]);
5606     }
5607   operands[0] = gen_lowpart (SImode, operands[0]);
5608   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5609   if (Pmode != SImode)
5610     pat = gen_rtx_SUBREG (SImode, pat, 0);
5611   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5612   DONE;
5613 })
5614
5615 ;; It may seem that nonimmediate operand is proper one for operand 1.
5616 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5617 ;; we take care in ix86_binary_operator_ok to not allow two memory
5618 ;; operands so proper swapping will be done in reload.  This allow
5619 ;; patterns constructed from addsi_1 to match.
5620 (define_insn "addsi_1_zext"
5621   [(set (match_operand:DI 0 "register_operand" "=r,r")
5622         (zero_extend:DI
5623           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5624                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5625    (clobber (reg:CC 17))]
5626   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627 {
5628   switch (get_attr_type (insn))
5629     {
5630     case TYPE_LEA:
5631       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5632       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5633
5634     case TYPE_INCDEC:
5635       if (operands[2] == const1_rtx)
5636         return "inc{l}\t%k0";
5637       else if (operands[2] == constm1_rtx)
5638         return "dec{l}\t%k0";
5639       else
5640         abort();
5641
5642     default:
5643       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5644          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5645       if (GET_CODE (operands[2]) == CONST_INT
5646           && (INTVAL (operands[2]) == 128
5647               || (INTVAL (operands[2]) < 0
5648                   && INTVAL (operands[2]) != -128)))
5649         {
5650           operands[2] = GEN_INT (-INTVAL (operands[2]));
5651           return "sub{l}\t{%2, %k0|%k0, %2}";
5652         }
5653       return "add{l}\t{%2, %k0|%k0, %2}";
5654     }
5655 }
5656   [(set (attr "type")
5657      (cond [(eq_attr "alternative" "1")
5658               (const_string "lea")
5659             ; Current assemblers are broken and do not allow @GOTOFF in
5660             ; ought but a memory context.
5661             (match_operand:SI 2 "pic_symbolic_operand" "")
5662               (const_string "lea")
5663             (match_operand:SI 2 "incdec_operand" "")
5664               (const_string "incdec")
5665            ]
5666            (const_string "alu")))
5667    (set_attr "mode" "SI")])
5668
5669 ;; Convert lea to the lea pattern to avoid flags dependency.
5670 (define_split
5671   [(set (match_operand:DI 0 "register_operand" "")
5672         (zero_extend:DI
5673           (plus:SI (match_operand:SI 1 "register_operand" "")
5674                    (match_operand:SI 2 "nonmemory_operand" ""))))
5675    (clobber (reg:CC 17))]
5676   "TARGET_64BIT && reload_completed
5677    && true_regnum (operands[0]) != true_regnum (operands[1])"
5678   [(set (match_dup 0)
5679         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5680 {
5681   operands[1] = gen_lowpart (Pmode, operands[1]);
5682   operands[2] = gen_lowpart (Pmode, operands[2]);
5683 })
5684
5685 (define_insn "*addsi_2"
5686   [(set (reg 17)
5687         (compare
5688           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5689                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5690           (const_int 0)))                       
5691    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5692         (plus:SI (match_dup 1) (match_dup 2)))]
5693   "ix86_match_ccmode (insn, CCGOCmode)
5694    && ix86_binary_operator_ok (PLUS, SImode, operands)
5695    /* Current assemblers are broken and do not allow @GOTOFF in
5696       ought but a memory context.  */
5697    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5698 {
5699   switch (get_attr_type (insn))
5700     {
5701     case TYPE_INCDEC:
5702       if (! rtx_equal_p (operands[0], operands[1]))
5703         abort ();
5704       if (operands[2] == const1_rtx)
5705         return "inc{l}\t%0";
5706       else if (operands[2] == constm1_rtx)
5707         return "dec{l}\t%0";
5708       else
5709         abort();
5710
5711     default:
5712       if (! rtx_equal_p (operands[0], operands[1]))
5713         abort ();
5714       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5715          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5716       if (GET_CODE (operands[2]) == CONST_INT
5717           && (INTVAL (operands[2]) == 128
5718               || (INTVAL (operands[2]) < 0
5719                   && INTVAL (operands[2]) != -128)))
5720         {
5721           operands[2] = GEN_INT (-INTVAL (operands[2]));
5722           return "sub{l}\t{%2, %0|%0, %2}";
5723         }
5724       return "add{l}\t{%2, %0|%0, %2}";
5725     }
5726 }
5727   [(set (attr "type")
5728      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5729         (const_string "incdec")
5730         (const_string "alu")))
5731    (set_attr "mode" "SI")])
5732
5733 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5734 (define_insn "*addsi_2_zext"
5735   [(set (reg 17)
5736         (compare
5737           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5738                    (match_operand:SI 2 "general_operand" "rmni"))
5739           (const_int 0)))                       
5740    (set (match_operand:DI 0 "register_operand" "=r")
5741         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5743    && ix86_binary_operator_ok (PLUS, SImode, operands)
5744    /* Current assemblers are broken and do not allow @GOTOFF in
5745       ought but a memory context.  */
5746    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5747 {
5748   switch (get_attr_type (insn))
5749     {
5750     case TYPE_INCDEC:
5751       if (operands[2] == const1_rtx)
5752         return "inc{l}\t%k0";
5753       else if (operands[2] == constm1_rtx)
5754         return "dec{l}\t%k0";
5755       else
5756         abort();
5757
5758     default:
5759       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5760          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5761       if (GET_CODE (operands[2]) == CONST_INT
5762           && (INTVAL (operands[2]) == 128
5763               || (INTVAL (operands[2]) < 0
5764                   && INTVAL (operands[2]) != -128)))
5765         {
5766           operands[2] = GEN_INT (-INTVAL (operands[2]));
5767           return "sub{l}\t{%2, %k0|%k0, %2}";
5768         }
5769       return "add{l}\t{%2, %k0|%k0, %2}";
5770     }
5771 }
5772   [(set (attr "type")
5773      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5774         (const_string "incdec")
5775         (const_string "alu")))
5776    (set_attr "mode" "SI")])
5777
5778 (define_insn "*addsi_3"
5779   [(set (reg 17)
5780         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5781                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5782    (clobber (match_scratch:SI 0 "=r"))]
5783   "ix86_match_ccmode (insn, CCZmode)
5784    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5785    /* Current assemblers are broken and do not allow @GOTOFF in
5786       ought but a memory context.  */
5787    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5788 {
5789   switch (get_attr_type (insn))
5790     {
5791     case TYPE_INCDEC:
5792       if (! rtx_equal_p (operands[0], operands[1]))
5793         abort ();
5794       if (operands[2] == const1_rtx)
5795         return "inc{l}\t%0";
5796       else if (operands[2] == constm1_rtx)
5797         return "dec{l}\t%0";
5798       else
5799         abort();
5800
5801     default:
5802       if (! rtx_equal_p (operands[0], operands[1]))
5803         abort ();
5804       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5806       if (GET_CODE (operands[2]) == CONST_INT
5807           && (INTVAL (operands[2]) == 128
5808               || (INTVAL (operands[2]) < 0
5809                   && INTVAL (operands[2]) != -128)))
5810         {
5811           operands[2] = GEN_INT (-INTVAL (operands[2]));
5812           return "sub{l}\t{%2, %0|%0, %2}";
5813         }
5814       return "add{l}\t{%2, %0|%0, %2}";
5815     }
5816 }
5817   [(set (attr "type")
5818      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5819         (const_string "incdec")
5820         (const_string "alu")))
5821    (set_attr "mode" "SI")])
5822
5823 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5824 (define_insn "*addsi_3_zext"
5825   [(set (reg 17)
5826         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5827                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5828    (set (match_operand:DI 0 "register_operand" "=r")
5829         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5830   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5831    && ix86_binary_operator_ok (PLUS, SImode, operands)
5832    /* Current assemblers are broken and do not allow @GOTOFF in
5833       ought but a memory context.  */
5834    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5835 {
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       if (operands[2] == const1_rtx)
5840         return "inc{l}\t%k0";
5841       else if (operands[2] == constm1_rtx)
5842         return "dec{l}\t%k0";
5843       else
5844         abort();
5845
5846     default:
5847       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5849       if (GET_CODE (operands[2]) == CONST_INT
5850           && (INTVAL (operands[2]) == 128
5851               || (INTVAL (operands[2]) < 0
5852                   && INTVAL (operands[2]) != -128)))
5853         {
5854           operands[2] = GEN_INT (-INTVAL (operands[2]));
5855           return "sub{l}\t{%2, %k0|%k0, %2}";
5856         }
5857       return "add{l}\t{%2, %k0|%k0, %2}";
5858     }
5859 }
5860   [(set (attr "type")
5861      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5862         (const_string "incdec")
5863         (const_string "alu")))
5864    (set_attr "mode" "SI")])
5865
5866 ; For comparisons against 1, -1 and 128, we may generate better code
5867 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5868 ; is matched then.  We can't accept general immediate, because for
5869 ; case of overflows,  the result is messed up.
5870 ; This pattern also don't hold of 0x80000000, since the value overflows
5871 ; when negated.
5872 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5873 ; only for comparisons not depending on it.
5874 (define_insn "*addsi_4"
5875   [(set (reg 17)
5876         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5877                  (match_operand:SI 2 "const_int_operand" "n")))
5878    (clobber (match_scratch:SI 0 "=rm"))]
5879   "ix86_match_ccmode (insn, CCGCmode)
5880    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5881 {
5882   switch (get_attr_type (insn))
5883     {
5884     case TYPE_INCDEC:
5885       if (operands[2] == constm1_rtx)
5886         return "inc{l}\t%0";
5887       else if (operands[2] == const1_rtx)
5888         return "dec{l}\t%0";
5889       else
5890         abort();
5891
5892     default:
5893       if (! rtx_equal_p (operands[0], operands[1]))
5894         abort ();
5895       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5896          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5897       if ((INTVAL (operands[2]) == -128
5898            || (INTVAL (operands[2]) > 0
5899                && INTVAL (operands[2]) != 128)))
5900         return "sub{l}\t{%2, %0|%0, %2}";
5901       operands[2] = GEN_INT (-INTVAL (operands[2]));
5902       return "add{l}\t{%2, %0|%0, %2}";
5903     }
5904 }
5905   [(set (attr "type")
5906      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5907         (const_string "incdec")
5908         (const_string "alu")))
5909    (set_attr "mode" "SI")])
5910
5911 (define_insn "*addsi_5"
5912   [(set (reg 17)
5913         (compare
5914           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5915                    (match_operand:SI 2 "general_operand" "rmni"))
5916           (const_int 0)))                       
5917    (clobber (match_scratch:SI 0 "=r"))]
5918   "ix86_match_ccmode (insn, CCGOCmode)
5919    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5920    /* Current assemblers are broken and do not allow @GOTOFF in
5921       ought but a memory context.  */
5922    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5923 {
5924   switch (get_attr_type (insn))
5925     {
5926     case TYPE_INCDEC:
5927       if (! rtx_equal_p (operands[0], operands[1]))
5928         abort ();
5929       if (operands[2] == const1_rtx)
5930         return "inc{l}\t%0";
5931       else if (operands[2] == constm1_rtx)
5932         return "dec{l}\t%0";
5933       else
5934         abort();
5935
5936     default:
5937       if (! rtx_equal_p (operands[0], operands[1]))
5938         abort ();
5939       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5940          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5941       if (GET_CODE (operands[2]) == CONST_INT
5942           && (INTVAL (operands[2]) == 128
5943               || (INTVAL (operands[2]) < 0
5944                   && INTVAL (operands[2]) != -128)))
5945         {
5946           operands[2] = GEN_INT (-INTVAL (operands[2]));
5947           return "sub{l}\t{%2, %0|%0, %2}";
5948         }
5949       return "add{l}\t{%2, %0|%0, %2}";
5950     }
5951 }
5952   [(set (attr "type")
5953      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5954         (const_string "incdec")
5955         (const_string "alu")))
5956    (set_attr "mode" "SI")])
5957
5958 (define_expand "addhi3"
5959   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5960                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5961                             (match_operand:HI 2 "general_operand" "")))
5962               (clobber (reg:CC 17))])]
5963   "TARGET_HIMODE_MATH"
5964   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5965
5966 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5967 ;; type optimizations enabled by define-splits.  This is not important
5968 ;; for PII, and in fact harmful because of partial register stalls.
5969
5970 (define_insn "*addhi_1_lea"
5971   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5972         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5973                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5974    (clobber (reg:CC 17))]
5975   "!TARGET_PARTIAL_REG_STALL
5976    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5977 {
5978   switch (get_attr_type (insn))
5979     {
5980     case TYPE_LEA:
5981       return "#";
5982     case TYPE_INCDEC:
5983       if (operands[2] == const1_rtx)
5984         return "inc{w}\t%0";
5985       else if (operands[2] == constm1_rtx)
5986         return "dec{w}\t%0";
5987       abort();
5988
5989     default:
5990       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5991          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5992       if (GET_CODE (operands[2]) == CONST_INT
5993           && (INTVAL (operands[2]) == 128
5994               || (INTVAL (operands[2]) < 0
5995                   && INTVAL (operands[2]) != -128)))
5996         {
5997           operands[2] = GEN_INT (-INTVAL (operands[2]));
5998           return "sub{w}\t{%2, %0|%0, %2}";
5999         }
6000       return "add{w}\t{%2, %0|%0, %2}";
6001     }
6002 }
6003   [(set (attr "type")
6004      (if_then_else (eq_attr "alternative" "2")
6005         (const_string "lea")
6006         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007            (const_string "incdec")
6008            (const_string "alu"))))
6009    (set_attr "mode" "HI,HI,SI")])
6010
6011 (define_insn "*addhi_1"
6012   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6013         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6014                  (match_operand:HI 2 "general_operand" "ri,rm")))
6015    (clobber (reg:CC 17))]
6016   "TARGET_PARTIAL_REG_STALL
6017    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6018 {
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == const1_rtx)
6023         return "inc{w}\t%0";
6024       else if (operands[2] == constm1_rtx)
6025         return "dec{w}\t%0";
6026       abort();
6027
6028     default:
6029       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6030          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6031       if (GET_CODE (operands[2]) == CONST_INT
6032           && (INTVAL (operands[2]) == 128
6033               || (INTVAL (operands[2]) < 0
6034                   && INTVAL (operands[2]) != -128)))
6035         {
6036           operands[2] = GEN_INT (-INTVAL (operands[2]));
6037           return "sub{w}\t{%2, %0|%0, %2}";
6038         }
6039       return "add{w}\t{%2, %0|%0, %2}";
6040     }
6041 }
6042   [(set (attr "type")
6043      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6044         (const_string "incdec")
6045         (const_string "alu")))
6046    (set_attr "mode" "HI")])
6047
6048 (define_insn "*addhi_2"
6049   [(set (reg 17)
6050         (compare
6051           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6052                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6053           (const_int 0)))                       
6054    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6055         (plus:HI (match_dup 1) (match_dup 2)))]
6056   "ix86_match_ccmode (insn, CCGOCmode)
6057    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6058 {
6059   switch (get_attr_type (insn))
6060     {
6061     case TYPE_INCDEC:
6062       if (operands[2] == const1_rtx)
6063         return "inc{w}\t%0";
6064       else if (operands[2] == constm1_rtx)
6065         return "dec{w}\t%0";
6066       abort();
6067
6068     default:
6069       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6070          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6071       if (GET_CODE (operands[2]) == CONST_INT
6072           && (INTVAL (operands[2]) == 128
6073               || (INTVAL (operands[2]) < 0
6074                   && INTVAL (operands[2]) != -128)))
6075         {
6076           operands[2] = GEN_INT (-INTVAL (operands[2]));
6077           return "sub{w}\t{%2, %0|%0, %2}";
6078         }
6079       return "add{w}\t{%2, %0|%0, %2}";
6080     }
6081 }
6082   [(set (attr "type")
6083      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6084         (const_string "incdec")
6085         (const_string "alu")))
6086    (set_attr "mode" "HI")])
6087
6088 (define_insn "*addhi_3"
6089   [(set (reg 17)
6090         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6091                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6092    (clobber (match_scratch:HI 0 "=r"))]
6093   "ix86_match_ccmode (insn, CCZmode)
6094    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6095 {
6096   switch (get_attr_type (insn))
6097     {
6098     case TYPE_INCDEC:
6099       if (operands[2] == const1_rtx)
6100         return "inc{w}\t%0";
6101       else if (operands[2] == constm1_rtx)
6102         return "dec{w}\t%0";
6103       abort();
6104
6105     default:
6106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6108       if (GET_CODE (operands[2]) == CONST_INT
6109           && (INTVAL (operands[2]) == 128
6110               || (INTVAL (operands[2]) < 0
6111                   && INTVAL (operands[2]) != -128)))
6112         {
6113           operands[2] = GEN_INT (-INTVAL (operands[2]));
6114           return "sub{w}\t{%2, %0|%0, %2}";
6115         }
6116       return "add{w}\t{%2, %0|%0, %2}";
6117     }
6118 }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "HI")])
6124
6125 ; See comments above addsi_3_imm for details.
6126 (define_insn "*addhi_4"
6127   [(set (reg 17)
6128         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6129                  (match_operand:HI 2 "const_int_operand" "n")))
6130    (clobber (match_scratch:HI 0 "=rm"))]
6131   "ix86_match_ccmode (insn, CCGCmode)
6132    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6133 {
6134   switch (get_attr_type (insn))
6135     {
6136     case TYPE_INCDEC:
6137       if (operands[2] == constm1_rtx)
6138         return "inc{w}\t%0";
6139       else if (operands[2] == const1_rtx)
6140         return "dec{w}\t%0";
6141       else
6142         abort();
6143
6144     default:
6145       if (! rtx_equal_p (operands[0], operands[1]))
6146         abort ();
6147       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6148          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6149       if ((INTVAL (operands[2]) == -128
6150            || (INTVAL (operands[2]) > 0
6151                && INTVAL (operands[2]) != 128)))
6152         return "sub{w}\t{%2, %0|%0, %2}";
6153       operands[2] = GEN_INT (-INTVAL (operands[2]));
6154       return "add{w}\t{%2, %0|%0, %2}";
6155     }
6156 }
6157   [(set (attr "type")
6158      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6159         (const_string "incdec")
6160         (const_string "alu")))
6161    (set_attr "mode" "SI")])
6162
6163
6164 (define_insn "*addhi_5"
6165   [(set (reg 17)
6166         (compare
6167           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6168                    (match_operand:HI 2 "general_operand" "rmni"))
6169           (const_int 0)))                       
6170    (clobber (match_scratch:HI 0 "=r"))]
6171   "ix86_match_ccmode (insn, CCGOCmode)
6172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{w}\t%0";
6179       else if (operands[2] == constm1_rtx)
6180         return "dec{w}\t%0";
6181       abort();
6182
6183     default:
6184       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6185          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6186       if (GET_CODE (operands[2]) == CONST_INT
6187           && (INTVAL (operands[2]) == 128
6188               || (INTVAL (operands[2]) < 0
6189                   && INTVAL (operands[2]) != -128)))
6190         {
6191           operands[2] = GEN_INT (-INTVAL (operands[2]));
6192           return "sub{w}\t{%2, %0|%0, %2}";
6193         }
6194       return "add{w}\t{%2, %0|%0, %2}";
6195     }
6196 }
6197   [(set (attr "type")
6198      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6199         (const_string "incdec")
6200         (const_string "alu")))
6201    (set_attr "mode" "HI")])
6202
6203 (define_expand "addqi3"
6204   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6205                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6206                             (match_operand:QI 2 "general_operand" "")))
6207               (clobber (reg:CC 17))])]
6208   "TARGET_QIMODE_MATH"
6209   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6210
6211 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6212 (define_insn "*addqi_1_lea"
6213   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6214         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6215                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6216    (clobber (reg:CC 17))]
6217   "!TARGET_PARTIAL_REG_STALL
6218    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6219 {
6220   int widen = (which_alternative == 2);
6221   switch (get_attr_type (insn))
6222     {
6223     case TYPE_LEA:
6224       return "#";
6225     case TYPE_INCDEC:
6226       if (operands[2] == const1_rtx)
6227         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6228       else if (operands[2] == constm1_rtx)
6229         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6230       abort();
6231
6232     default:
6233       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6234          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6235       if (GET_CODE (operands[2]) == CONST_INT
6236           && (INTVAL (operands[2]) == 128
6237               || (INTVAL (operands[2]) < 0
6238                   && INTVAL (operands[2]) != -128)))
6239         {
6240           operands[2] = GEN_INT (-INTVAL (operands[2]));
6241           if (widen)
6242             return "sub{l}\t{%2, %k0|%k0, %2}";
6243           else
6244             return "sub{b}\t{%2, %0|%0, %2}";
6245         }
6246       if (widen)
6247         return "add{l}\t{%k2, %k0|%k0, %k2}";
6248       else
6249         return "add{b}\t{%2, %0|%0, %2}";
6250     }
6251 }
6252   [(set (attr "type")
6253      (if_then_else (eq_attr "alternative" "3")
6254         (const_string "lea")
6255         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6256            (const_string "incdec")
6257            (const_string "alu"))))
6258    (set_attr "mode" "QI,QI,SI,SI")])
6259
6260 (define_insn "*addqi_1"
6261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6262         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6263                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6264    (clobber (reg:CC 17))]
6265   "TARGET_PARTIAL_REG_STALL
6266    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6267 {
6268   int widen = (which_alternative == 2);
6269   switch (get_attr_type (insn))
6270     {
6271     case TYPE_INCDEC:
6272       if (operands[2] == const1_rtx)
6273         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6274       else if (operands[2] == constm1_rtx)
6275         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6276       abort();
6277
6278     default:
6279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6280          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6281       if (GET_CODE (operands[2]) == CONST_INT
6282           && (INTVAL (operands[2]) == 128
6283               || (INTVAL (operands[2]) < 0
6284                   && INTVAL (operands[2]) != -128)))
6285         {
6286           operands[2] = GEN_INT (-INTVAL (operands[2]));
6287           if (widen)
6288             return "sub{l}\t{%2, %k0|%k0, %2}";
6289           else
6290             return "sub{b}\t{%2, %0|%0, %2}";
6291         }
6292       if (widen)
6293         return "add{l}\t{%k2, %k0|%k0, %k2}";
6294       else
6295         return "add{b}\t{%2, %0|%0, %2}";
6296     }
6297 }
6298   [(set (attr "type")
6299      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6300         (const_string "incdec")
6301         (const_string "alu")))
6302    (set_attr "mode" "QI,QI,SI")])
6303
6304 (define_insn "*addqi_1_slp"
6305   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6306         (plus:QI (match_dup 0)
6307                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6308    (clobber (reg:CC 17))]
6309   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6310    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6311 {
6312   switch (get_attr_type (insn))
6313     {
6314     case TYPE_INCDEC:
6315       if (operands[1] == const1_rtx)
6316         return "inc{b}\t%0";
6317       else if (operands[1] == constm1_rtx)
6318         return "dec{b}\t%0";
6319       abort();
6320
6321     default:
6322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6323       if (GET_CODE (operands[1]) == CONST_INT
6324           && INTVAL (operands[1]) < 0)
6325         {
6326           operands[1] = GEN_INT (-INTVAL (operands[1]));
6327           return "sub{b}\t{%1, %0|%0, %1}";
6328         }
6329       return "add{b}\t{%1, %0|%0, %1}";
6330     }
6331 }
6332   [(set (attr "type")
6333      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6334         (const_string "incdec")
6335         (const_string "alu1")))
6336    (set_attr "mode" "QI")])
6337
6338 (define_insn "*addqi_2"
6339   [(set (reg 17)
6340         (compare
6341           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6342                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6343           (const_int 0)))
6344    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6345         (plus:QI (match_dup 1) (match_dup 2)))]
6346   "ix86_match_ccmode (insn, CCGOCmode)
6347    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6348 {
6349   switch (get_attr_type (insn))
6350     {
6351     case TYPE_INCDEC:
6352       if (operands[2] == const1_rtx)
6353         return "inc{b}\t%0";
6354       else if (operands[2] == constm1_rtx
6355                || (GET_CODE (operands[2]) == CONST_INT
6356                    && INTVAL (operands[2]) == 255))
6357         return "dec{b}\t%0";
6358       abort();
6359
6360     default:
6361       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6362       if (GET_CODE (operands[2]) == CONST_INT
6363           && INTVAL (operands[2]) < 0)
6364         {
6365           operands[2] = GEN_INT (-INTVAL (operands[2]));
6366           return "sub{b}\t{%2, %0|%0, %2}";
6367         }
6368       return "add{b}\t{%2, %0|%0, %2}";
6369     }
6370 }
6371   [(set (attr "type")
6372      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6373         (const_string "incdec")
6374         (const_string "alu")))
6375    (set_attr "mode" "QI")])
6376
6377 (define_insn "*addqi_3"
6378   [(set (reg 17)
6379         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6380                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6381    (clobber (match_scratch:QI 0 "=q"))]
6382   "ix86_match_ccmode (insn, CCZmode)
6383    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6384 {
6385   switch (get_attr_type (insn))
6386     {
6387     case TYPE_INCDEC:
6388       if (operands[2] == const1_rtx)
6389         return "inc{b}\t%0";
6390       else if (operands[2] == constm1_rtx
6391                || (GET_CODE (operands[2]) == CONST_INT
6392                    && INTVAL (operands[2]) == 255))
6393         return "dec{b}\t%0";
6394       abort();
6395
6396     default:
6397       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6398       if (GET_CODE (operands[2]) == CONST_INT
6399           && INTVAL (operands[2]) < 0)
6400         {
6401           operands[2] = GEN_INT (-INTVAL (operands[2]));
6402           return "sub{b}\t{%2, %0|%0, %2}";
6403         }
6404       return "add{b}\t{%2, %0|%0, %2}";
6405     }
6406 }
6407   [(set (attr "type")
6408      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6409         (const_string "incdec")
6410         (const_string "alu")))
6411    (set_attr "mode" "QI")])
6412
6413 ; See comments above addsi_3_imm for details.
6414 (define_insn "*addqi_4"
6415   [(set (reg 17)
6416         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6417                  (match_operand:QI 2 "const_int_operand" "n")))
6418    (clobber (match_scratch:QI 0 "=qm"))]
6419   "ix86_match_ccmode (insn, CCGCmode)
6420    && (INTVAL (operands[2]) & 0xff) != 0x80"
6421 {
6422   switch (get_attr_type (insn))
6423     {
6424     case TYPE_INCDEC:
6425       if (operands[2] == constm1_rtx
6426           || (GET_CODE (operands[2]) == CONST_INT
6427               && INTVAL (operands[2]) == 255))
6428         return "inc{b}\t%0";
6429       else if (operands[2] == const1_rtx)
6430         return "dec{b}\t%0";
6431       else
6432         abort();
6433
6434     default:
6435       if (! rtx_equal_p (operands[0], operands[1]))
6436         abort ();
6437       if (INTVAL (operands[2]) < 0)
6438         {
6439           operands[2] = GEN_INT (-INTVAL (operands[2]));
6440           return "add{b}\t{%2, %0|%0, %2}";
6441         }
6442       return "sub{b}\t{%2, %0|%0, %2}";
6443     }
6444 }
6445   [(set (attr "type")
6446      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6447         (const_string "incdec")
6448         (const_string "alu")))
6449    (set_attr "mode" "QI")])
6450
6451
6452 (define_insn "*addqi_5"
6453   [(set (reg 17)
6454         (compare
6455           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6456                    (match_operand:QI 2 "general_operand" "qmni"))
6457           (const_int 0)))
6458    (clobber (match_scratch:QI 0 "=q"))]
6459   "ix86_match_ccmode (insn, CCGOCmode)
6460    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6461 {
6462   switch (get_attr_type (insn))
6463     {
6464     case TYPE_INCDEC:
6465       if (operands[2] == const1_rtx)
6466         return "inc{b}\t%0";
6467       else if (operands[2] == constm1_rtx
6468                || (GET_CODE (operands[2]) == CONST_INT
6469                    && INTVAL (operands[2]) == 255))
6470         return "dec{b}\t%0";
6471       abort();
6472
6473     default:
6474       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6475       if (GET_CODE (operands[2]) == CONST_INT
6476           && INTVAL (operands[2]) < 0)
6477         {
6478           operands[2] = GEN_INT (-INTVAL (operands[2]));
6479           return "sub{b}\t{%2, %0|%0, %2}";
6480         }
6481       return "add{b}\t{%2, %0|%0, %2}";
6482     }
6483 }
6484   [(set (attr "type")
6485      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6486         (const_string "incdec")
6487         (const_string "alu")))
6488    (set_attr "mode" "QI")])
6489
6490
6491 (define_insn "addqi_ext_1"
6492   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6493                          (const_int 8)
6494                          (const_int 8))
6495         (plus:SI
6496           (zero_extract:SI
6497             (match_operand 1 "ext_register_operand" "0")
6498             (const_int 8)
6499             (const_int 8))
6500           (match_operand:QI 2 "general_operand" "Qmn")))
6501    (clobber (reg:CC 17))]
6502   "!TARGET_64BIT"
6503 {
6504   switch (get_attr_type (insn))
6505     {
6506     case TYPE_INCDEC:
6507       if (operands[2] == const1_rtx)
6508         return "inc{b}\t%h0";
6509       else if (operands[2] == constm1_rtx
6510                || (GET_CODE (operands[2]) == CONST_INT
6511                    && INTVAL (operands[2]) == 255))
6512         return "dec{b}\t%h0";
6513       abort();
6514
6515     default:
6516       return "add{b}\t{%2, %h0|%h0, %2}";
6517     }
6518 }
6519   [(set (attr "type")
6520      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521         (const_string "incdec")
6522         (const_string "alu")))
6523    (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_ext_1_rex64"
6526   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6527                          (const_int 8)
6528                          (const_int 8))
6529         (plus:SI
6530           (zero_extract:SI
6531             (match_operand 1 "ext_register_operand" "0")
6532             (const_int 8)
6533             (const_int 8))
6534           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6535    (clobber (reg:CC 17))]
6536   "TARGET_64BIT"
6537 {
6538   switch (get_attr_type (insn))
6539     {
6540     case TYPE_INCDEC:
6541       if (operands[2] == const1_rtx)
6542         return "inc{b}\t%h0";
6543       else if (operands[2] == constm1_rtx
6544                || (GET_CODE (operands[2]) == CONST_INT
6545                    && INTVAL (operands[2]) == 255))
6546         return "dec{b}\t%h0";
6547       abort();
6548
6549     default:
6550       return "add{b}\t{%2, %h0|%h0, %2}";
6551     }
6552 }
6553   [(set (attr "type")
6554      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6555         (const_string "incdec")
6556         (const_string "alu")))
6557    (set_attr "mode" "QI")])
6558
6559 (define_insn "*addqi_ext_2"
6560   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6561                          (const_int 8)
6562                          (const_int 8))
6563         (plus:SI
6564           (zero_extract:SI
6565             (match_operand 1 "ext_register_operand" "%0")
6566             (const_int 8)
6567             (const_int 8))
6568           (zero_extract:SI
6569             (match_operand 2 "ext_register_operand" "Q")
6570             (const_int 8)
6571             (const_int 8))))
6572    (clobber (reg:CC 17))]
6573   ""
6574   "add{b}\t{%h2, %h0|%h0, %h2}"
6575   [(set_attr "type" "alu")
6576    (set_attr "mode" "QI")])
6577
6578 ;; The patterns that match these are at the end of this file.
6579
6580 (define_expand "addxf3"
6581   [(set (match_operand:XF 0 "register_operand" "")
6582         (plus:XF (match_operand:XF 1 "register_operand" "")
6583                  (match_operand:XF 2 "register_operand" "")))]
6584   "TARGET_80387"
6585   "")
6586
6587 (define_expand "adddf3"
6588   [(set (match_operand:DF 0 "register_operand" "")
6589         (plus:DF (match_operand:DF 1 "register_operand" "")
6590                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6591   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6592   "")
6593
6594 (define_expand "addsf3"
6595   [(set (match_operand:SF 0 "register_operand" "")
6596         (plus:SF (match_operand:SF 1 "register_operand" "")
6597                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6598   "TARGET_80387 || TARGET_SSE_MATH"
6599   "")
6600 \f
6601 ;; Subtract instructions
6602
6603 ;; %%% splits for subsidi3
6604
6605 (define_expand "subdi3"
6606   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6607                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6608                              (match_operand:DI 2 "x86_64_general_operand" "")))
6609               (clobber (reg:CC 17))])]
6610   ""
6611   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6612
6613 (define_insn "*subdi3_1"
6614   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6615         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6616                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6617    (clobber (reg:CC 17))]
6618   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6619   "#")
6620
6621 (define_split
6622   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6623         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6624                   (match_operand:DI 2 "general_operand" "")))
6625    (clobber (reg:CC 17))]
6626   "!TARGET_64BIT && reload_completed"
6627   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6628               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6629    (parallel [(set (match_dup 3)
6630                    (minus:SI (match_dup 4)
6631                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6632                                       (match_dup 5))))
6633               (clobber (reg:CC 17))])]
6634   "split_di (operands+0, 1, operands+0, operands+3);
6635    split_di (operands+1, 1, operands+1, operands+4);
6636    split_di (operands+2, 1, operands+2, operands+5);")
6637
6638 (define_insn "subdi3_carry_rex64"
6639   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6640           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6641             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6642                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6643    (clobber (reg:CC 17))]
6644   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6645   "sbb{q}\t{%2, %0|%0, %2}"
6646   [(set_attr "type" "alu")
6647    (set_attr "pent_pair" "pu")
6648    (set_attr "ppro_uops" "few")
6649    (set_attr "mode" "DI")])
6650
6651 (define_insn "*subdi_1_rex64"
6652   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6653         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6654                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6655    (clobber (reg:CC 17))]
6656   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6657   "sub{q}\t{%2, %0|%0, %2}"
6658   [(set_attr "type" "alu")
6659    (set_attr "mode" "DI")])
6660
6661 (define_insn "*subdi_2_rex64"
6662   [(set (reg 17)
6663         (compare
6664           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6665                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6666           (const_int 0)))
6667    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6668         (minus:DI (match_dup 1) (match_dup 2)))]
6669   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6670    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6671   "sub{q}\t{%2, %0|%0, %2}"
6672   [(set_attr "type" "alu")
6673    (set_attr "mode" "DI")])
6674
6675 (define_insn "*subdi_3_rex63"
6676   [(set (reg 17)
6677         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6678                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6679    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6680         (minus:DI (match_dup 1) (match_dup 2)))]
6681   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6682    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6683   "sub{q}\t{%2, %0|%0, %2}"
6684   [(set_attr "type" "alu")
6685    (set_attr "mode" "DI")])
6686
6687 (define_insn "subqi3_carry"
6688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6689           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6690             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6691                (match_operand:QI 2 "general_operand" "qi,qm"))))
6692    (clobber (reg:CC 17))]
6693   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6694   "sbb{b}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "pent_pair" "pu")
6697    (set_attr "ppro_uops" "few")
6698    (set_attr "mode" "QI")])
6699
6700 (define_insn "subhi3_carry"
6701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6704                (match_operand:HI 2 "general_operand" "ri,rm"))))
6705    (clobber (reg:CC 17))]
6706   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6707   "sbb{w}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "pent_pair" "pu")
6710    (set_attr "ppro_uops" "few")
6711    (set_attr "mode" "HI")])
6712
6713 (define_insn "subsi3_carry"
6714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6717                (match_operand:SI 2 "general_operand" "ri,rm"))))
6718    (clobber (reg:CC 17))]
6719   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sbb{l}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "pent_pair" "pu")
6723    (set_attr "ppro_uops" "few")
6724    (set_attr "mode" "SI")])
6725
6726 (define_insn "subsi3_carry_zext"
6727   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6728           (zero_extend:DI
6729             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6730               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6731                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6732    (clobber (reg:CC 17))]
6733   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734   "sbb{l}\t{%2, %k0|%k0, %2}"
6735   [(set_attr "type" "alu")
6736    (set_attr "pent_pair" "pu")
6737    (set_attr "ppro_uops" "few")
6738    (set_attr "mode" "SI")])
6739
6740 (define_expand "subsi3"
6741   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6742                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6743                              (match_operand:SI 2 "general_operand" "")))
6744               (clobber (reg:CC 17))])]
6745   ""
6746   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6747
6748 (define_insn "*subsi_1"
6749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6750         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6751                   (match_operand:SI 2 "general_operand" "ri,rm")))
6752    (clobber (reg:CC 17))]
6753   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6754   "sub{l}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_1_zext"
6759   [(set (match_operand:DI 0 "register_operand" "=r")
6760         (zero_extend:DI
6761           (minus:SI (match_operand:SI 1 "register_operand" "0")
6762                     (match_operand:SI 2 "general_operand" "rim"))))
6763    (clobber (reg:CC 17))]
6764   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6765   "sub{l}\t{%2, %k0|%k0, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "mode" "SI")])
6768
6769 (define_insn "*subsi_2"
6770   [(set (reg 17)
6771         (compare
6772           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6773                     (match_operand:SI 2 "general_operand" "ri,rm"))
6774           (const_int 0)))
6775    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6776         (minus:SI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCGOCmode)
6778    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779   "sub{l}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "SI")])
6782
6783 (define_insn "*subsi_2_zext"
6784   [(set (reg 17)
6785         (compare
6786           (minus:SI (match_operand:SI 1 "register_operand" "0")
6787                     (match_operand:SI 2 "general_operand" "rim"))
6788           (const_int 0)))
6789    (set (match_operand:DI 0 "register_operand" "=r")
6790         (zero_extend:DI
6791           (minus:SI (match_dup 1)
6792                     (match_dup 2))))]
6793   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6794    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6795   "sub{l}\t{%2, %k0|%k0, %2}"
6796   [(set_attr "type" "alu")
6797    (set_attr "mode" "SI")])
6798
6799 (define_insn "*subsi_3"
6800   [(set (reg 17)
6801         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802                  (match_operand:SI 2 "general_operand" "ri,rm")))
6803    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6804         (minus:SI (match_dup 1) (match_dup 2)))]
6805   "ix86_match_ccmode (insn, CCmode)
6806    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6807   "sub{l}\t{%2, %0|%0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "mode" "SI")])
6810
6811 (define_insn "*subsi_3_zext"
6812   [(set (reg 17)
6813         (compare (match_operand:SI 1 "register_operand" "0")
6814                  (match_operand:SI 2 "general_operand" "rim")))
6815    (set (match_operand:DI 0 "register_operand" "=r")
6816         (zero_extend:DI
6817           (minus:SI (match_dup 1)
6818                     (match_dup 2))))]
6819   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6820    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6821   "sub{q}\t{%2, %0|%0, %2}"
6822   [(set_attr "type" "alu")
6823    (set_attr "mode" "DI")])
6824
6825 (define_expand "subhi3"
6826   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6827                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6828                              (match_operand:HI 2 "general_operand" "")))
6829               (clobber (reg:CC 17))])]
6830   "TARGET_HIMODE_MATH"
6831   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6832
6833 (define_insn "*subhi_1"
6834   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6835         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836                   (match_operand:HI 2 "general_operand" "ri,rm")))
6837    (clobber (reg:CC 17))]
6838   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6839   "sub{w}\t{%2, %0|%0, %2}"
6840   [(set_attr "type" "alu")
6841    (set_attr "mode" "HI")])
6842
6843 (define_insn "*subhi_2"
6844   [(set (reg 17)
6845         (compare
6846           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6847                     (match_operand:HI 2 "general_operand" "ri,rm"))
6848           (const_int 0)))
6849    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6850         (minus:HI (match_dup 1) (match_dup 2)))]
6851   "ix86_match_ccmode (insn, CCGOCmode)
6852    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6853   "sub{w}\t{%2, %0|%0, %2}"
6854   [(set_attr "type" "alu")
6855    (set_attr "mode" "HI")])
6856
6857 (define_insn "*subhi_3"
6858   [(set (reg 17)
6859         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6860                  (match_operand:HI 2 "general_operand" "ri,rm")))
6861    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6862         (minus:HI (match_dup 1) (match_dup 2)))]
6863   "ix86_match_ccmode (insn, CCmode)
6864    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6865   "sub{w}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "alu")
6867    (set_attr "mode" "HI")])
6868
6869 (define_expand "subqi3"
6870   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6871                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6872                              (match_operand:QI 2 "general_operand" "")))
6873               (clobber (reg:CC 17))])]
6874   "TARGET_QIMODE_MATH"
6875   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6876
6877 (define_insn "*subqi_1"
6878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6881    (clobber (reg:CC 17))]
6882   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6883   "sub{b}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_1_slp"
6888   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6889         (minus:QI (match_dup 0)
6890                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6891    (clobber (reg:CC 17))]
6892   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6893    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6894   "sub{b}\t{%1, %0|%0, %1}"
6895   [(set_attr "type" "alu1")
6896    (set_attr "mode" "QI")])
6897
6898 (define_insn "*subqi_2"
6899   [(set (reg 17)
6900         (compare
6901           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6902                     (match_operand:QI 2 "general_operand" "qi,qm"))
6903           (const_int 0)))
6904    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6905         (minus:HI (match_dup 1) (match_dup 2)))]
6906   "ix86_match_ccmode (insn, CCGOCmode)
6907    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6908   "sub{b}\t{%2, %0|%0, %2}"
6909   [(set_attr "type" "alu")
6910    (set_attr "mode" "QI")])
6911
6912 (define_insn "*subqi_3"
6913   [(set (reg 17)
6914         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6915                  (match_operand:QI 2 "general_operand" "qi,qm")))
6916    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6917         (minus:HI (match_dup 1) (match_dup 2)))]
6918   "ix86_match_ccmode (insn, CCmode)
6919    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6920   "sub{b}\t{%2, %0|%0, %2}"
6921   [(set_attr "type" "alu")
6922    (set_attr "mode" "QI")])
6923
6924 ;; The patterns that match these are at the end of this file.
6925
6926 (define_expand "subxf3"
6927   [(set (match_operand:XF 0 "register_operand" "")
6928         (minus:XF (match_operand:XF 1 "register_operand" "")
6929                   (match_operand:XF 2 "register_operand" "")))]
6930   "TARGET_80387"
6931   "")
6932
6933 (define_expand "subdf3"
6934   [(set (match_operand:DF 0 "register_operand" "")
6935         (minus:DF (match_operand:DF 1 "register_operand" "")
6936                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6937   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6938   "")
6939
6940 (define_expand "subsf3"
6941   [(set (match_operand:SF 0 "register_operand" "")
6942         (minus:SF (match_operand:SF 1 "register_operand" "")
6943                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6944   "TARGET_80387 || TARGET_SSE_MATH"
6945   "")
6946 \f
6947 ;; Multiply instructions
6948
6949 (define_expand "muldi3"
6950   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6951                    (mult:DI (match_operand:DI 1 "register_operand" "")
6952                             (match_operand:DI 2 "x86_64_general_operand" "")))
6953               (clobber (reg:CC 17))])]
6954   "TARGET_64BIT"
6955   "")
6956
6957 (define_insn "*muldi3_1_rex64"
6958   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6959         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6960                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6961    (clobber (reg:CC 17))]
6962   "TARGET_64BIT
6963    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964   "@
6965    imul{q}\t{%2, %1, %0|%0, %1, %2}
6966    imul{q}\t{%2, %1, %0|%0, %1, %2}
6967    imul{q}\t{%2, %0|%0, %2}"
6968   [(set_attr "type" "imul")
6969    (set_attr "prefix_0f" "0,0,1")
6970    (set (attr "athlon_decode")
6971         (cond [(eq_attr "cpu" "athlon")
6972                   (const_string "vector")
6973                (eq_attr "alternative" "1")
6974                   (const_string "vector")
6975                (and (eq_attr "alternative" "2")
6976                     (match_operand 1 "memory_operand" ""))
6977                   (const_string "vector")]
6978               (const_string "direct")))
6979    (set_attr "mode" "DI")])
6980
6981 (define_expand "mulsi3"
6982   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6983                    (mult:SI (match_operand:SI 1 "register_operand" "")
6984                             (match_operand:SI 2 "general_operand" "")))
6985               (clobber (reg:CC 17))])]
6986   ""
6987   "")
6988
6989 (define_insn "*mulsi3_1"
6990   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6991         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6992                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6993    (clobber (reg:CC 17))]
6994   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6995   "@
6996    imul{l}\t{%2, %1, %0|%0, %1, %2}
6997    imul{l}\t{%2, %1, %0|%0, %1, %2}
6998    imul{l}\t{%2, %0|%0, %2}"
6999   [(set_attr "type" "imul")
7000    (set_attr "prefix_0f" "0,0,1")
7001    (set (attr "athlon_decode")
7002         (cond [(eq_attr "cpu" "athlon")
7003                   (const_string "vector")
7004                (eq_attr "alternative" "1")
7005                   (const_string "vector")
7006                (and (eq_attr "alternative" "2")
7007                     (match_operand 1 "memory_operand" ""))
7008                   (const_string "vector")]
7009               (const_string "direct")))
7010    (set_attr "mode" "SI")])
7011
7012 (define_insn "*mulsi3_1_zext"
7013   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7014         (zero_extend:DI
7015           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7016                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7017    (clobber (reg:CC 17))]
7018   "TARGET_64BIT
7019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7020   "@
7021    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7022    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7023    imul{l}\t{%2, %k0|%k0, %2}"
7024   [(set_attr "type" "imul")
7025    (set_attr "prefix_0f" "0,0,1")
7026    (set (attr "athlon_decode")
7027         (cond [(eq_attr "cpu" "athlon")
7028                   (const_string "vector")
7029                (eq_attr "alternative" "1")
7030                   (const_string "vector")
7031                (and (eq_attr "alternative" "2")
7032                     (match_operand 1 "memory_operand" ""))
7033                   (const_string "vector")]
7034               (const_string "direct")))
7035    (set_attr "mode" "SI")])
7036
7037 (define_expand "mulhi3"
7038   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7039                    (mult:HI (match_operand:HI 1 "register_operand" "")
7040                             (match_operand:HI 2 "general_operand" "")))
7041               (clobber (reg:CC 17))])]
7042   "TARGET_HIMODE_MATH"
7043   "")
7044
7045 (define_insn "*mulhi3_1"
7046   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7047         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7048                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7049    (clobber (reg:CC 17))]
7050   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7051   "@
7052    imul{w}\t{%2, %1, %0|%0, %1, %2}
7053    imul{w}\t{%2, %1, %0|%0, %1, %2}
7054    imul{w}\t{%2, %0|%0, %2}"
7055   [(set_attr "type" "imul")
7056    (set_attr "prefix_0f" "0,0,1")
7057    (set (attr "athlon_decode")
7058         (cond [(eq_attr "cpu" "athlon")
7059                   (const_string "vector")
7060                (eq_attr "alternative" "1,2")
7061                   (const_string "vector")]
7062               (const_string "direct")))
7063    (set_attr "mode" "HI")])
7064
7065 (define_expand "mulqi3"
7066   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7067                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7068                             (match_operand:QI 2 "register_operand" "")))
7069               (clobber (reg:CC 17))])]
7070   "TARGET_QIMODE_MATH"
7071   "")
7072
7073 (define_insn "*mulqi3_1"
7074   [(set (match_operand:QI 0 "register_operand" "=a")
7075         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7076                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7077    (clobber (reg:CC 17))]
7078   "TARGET_QIMODE_MATH
7079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080   "mul{b}\t%2"
7081   [(set_attr "type" "imul")
7082    (set_attr "length_immediate" "0")
7083    (set (attr "athlon_decode")
7084      (if_then_else (eq_attr "cpu" "athlon")
7085         (const_string "vector")
7086         (const_string "direct")))
7087    (set_attr "mode" "QI")])
7088
7089 (define_expand "umulqihi3"
7090   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7091                    (mult:HI (zero_extend:HI
7092                               (match_operand:QI 1 "nonimmediate_operand" ""))
7093                             (zero_extend:HI
7094                               (match_operand:QI 2 "register_operand" ""))))
7095               (clobber (reg:CC 17))])]
7096   "TARGET_QIMODE_MATH"
7097   "")
7098
7099 (define_insn "*umulqihi3_1"
7100   [(set (match_operand:HI 0 "register_operand" "=a")
7101         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7102                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7103    (clobber (reg:CC 17))]
7104   "TARGET_QIMODE_MATH
7105    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106   "mul{b}\t%2"
7107   [(set_attr "type" "imul")
7108    (set_attr "length_immediate" "0")
7109    (set (attr "athlon_decode")
7110      (if_then_else (eq_attr "cpu" "athlon")
7111         (const_string "vector")
7112         (const_string "direct")))
7113    (set_attr "mode" "QI")])
7114
7115 (define_expand "mulqihi3"
7116   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7117                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7118                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7119               (clobber (reg:CC 17))])]
7120   "TARGET_QIMODE_MATH"
7121   "")
7122
7123 (define_insn "*mulqihi3_insn"
7124   [(set (match_operand:HI 0 "register_operand" "=a")
7125         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7126                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7127    (clobber (reg:CC 17))]
7128   "TARGET_QIMODE_MATH
7129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7130   "imul{b}\t%2"
7131   [(set_attr "type" "imul")
7132    (set_attr "length_immediate" "0")
7133    (set (attr "athlon_decode")
7134      (if_then_else (eq_attr "cpu" "athlon")
7135         (const_string "vector")
7136         (const_string "direct")))
7137    (set_attr "mode" "QI")])
7138
7139 (define_expand "umulditi3"
7140   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7141                    (mult:TI (zero_extend:TI
7142                               (match_operand:DI 1 "nonimmediate_operand" ""))
7143                             (zero_extend:TI
7144                               (match_operand:DI 2 "register_operand" ""))))
7145               (clobber (reg:CC 17))])]
7146   "TARGET_64BIT"
7147   "")
7148
7149 (define_insn "*umulditi3_insn"
7150   [(set (match_operand:TI 0 "register_operand" "=A")
7151         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7152                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7153    (clobber (reg:CC 17))]
7154   "TARGET_64BIT
7155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7156   "mul{q}\t%2"
7157   [(set_attr "type" "imul")
7158    (set_attr "ppro_uops" "few")
7159    (set_attr "length_immediate" "0")
7160    (set (attr "athlon_decode")
7161      (if_then_else (eq_attr "cpu" "athlon")
7162         (const_string "vector")
7163         (const_string "double")))
7164    (set_attr "mode" "DI")])
7165
7166 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7167 (define_expand "umulsidi3"
7168   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7169                    (mult:DI (zero_extend:DI
7170                               (match_operand:SI 1 "nonimmediate_operand" ""))
7171                             (zero_extend:DI
7172                               (match_operand:SI 2 "register_operand" ""))))
7173               (clobber (reg:CC 17))])]
7174   "!TARGET_64BIT"
7175   "")
7176
7177 (define_insn "*umulsidi3_insn"
7178   [(set (match_operand:DI 0 "register_operand" "=A")
7179         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7180                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7181    (clobber (reg:CC 17))]
7182   "!TARGET_64BIT
7183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7184   "mul{l}\t%2"
7185   [(set_attr "type" "imul")
7186    (set_attr "ppro_uops" "few")
7187    (set_attr "length_immediate" "0")
7188    (set (attr "athlon_decode")
7189      (if_then_else (eq_attr "cpu" "athlon")
7190         (const_string "vector")
7191         (const_string "double")))
7192    (set_attr "mode" "SI")])
7193
7194 (define_expand "mulditi3"
7195   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7196                    (mult:TI (sign_extend:TI
7197                               (match_operand:DI 1 "nonimmediate_operand" ""))
7198                             (sign_extend:TI
7199                               (match_operand:DI 2 "register_operand" ""))))
7200               (clobber (reg:CC 17))])]
7201   "TARGET_64BIT"
7202   "")
7203
7204 (define_insn "*mulditi3_insn"
7205   [(set (match_operand:TI 0 "register_operand" "=A")
7206         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7207                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7208    (clobber (reg:CC 17))]
7209   "TARGET_64BIT
7210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7211   "imul{q}\t%2"
7212   [(set_attr "type" "imul")
7213    (set_attr "length_immediate" "0")
7214    (set (attr "athlon_decode")
7215      (if_then_else (eq_attr "cpu" "athlon")
7216         (const_string "vector")
7217         (const_string "double")))
7218    (set_attr "mode" "DI")])
7219
7220 (define_expand "mulsidi3"
7221   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7222                    (mult:DI (sign_extend:DI
7223                               (match_operand:SI 1 "nonimmediate_operand" ""))
7224                             (sign_extend:DI
7225                               (match_operand:SI 2 "register_operand" ""))))
7226               (clobber (reg:CC 17))])]
7227   "!TARGET_64BIT"
7228   "")
7229
7230 (define_insn "*mulsidi3_insn"
7231   [(set (match_operand:DI 0 "register_operand" "=A")
7232         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7233                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7234    (clobber (reg:CC 17))]
7235   "!TARGET_64BIT
7236    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7237   "imul{l}\t%2"
7238   [(set_attr "type" "imul")
7239    (set_attr "length_immediate" "0")
7240    (set (attr "athlon_decode")
7241      (if_then_else (eq_attr "cpu" "athlon")
7242         (const_string "vector")
7243         (const_string "double")))
7244    (set_attr "mode" "SI")])
7245
7246 (define_expand "umuldi3_highpart"
7247   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7248                    (truncate:DI
7249                      (lshiftrt:TI
7250                        (mult:TI (zero_extend:TI
7251                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7252                                 (zero_extend:TI
7253                                   (match_operand:DI 2 "register_operand" "")))
7254                        (const_int 64))))
7255               (clobber (match_scratch:DI 3 ""))
7256               (clobber (reg:CC 17))])]
7257   "TARGET_64BIT"
7258   "")
7259
7260 (define_insn "*umuldi3_highpart_rex64"
7261   [(set (match_operand:DI 0 "register_operand" "=d")
7262         (truncate:DI
7263           (lshiftrt:TI
7264             (mult:TI (zero_extend:TI
7265                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7266                      (zero_extend:TI
7267                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7268             (const_int 64))))
7269    (clobber (match_scratch:DI 3 "=1"))
7270    (clobber (reg:CC 17))]
7271   "TARGET_64BIT
7272    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7273   "mul{q}\t%2"
7274   [(set_attr "type" "imul")
7275    (set_attr "ppro_uops" "few")
7276    (set_attr "length_immediate" "0")
7277    (set (attr "athlon_decode")
7278      (if_then_else (eq_attr "cpu" "athlon")
7279         (const_string "vector")
7280         (const_string "double")))
7281    (set_attr "mode" "DI")])
7282
7283 (define_expand "umulsi3_highpart"
7284   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7285                    (truncate:SI
7286                      (lshiftrt:DI
7287                        (mult:DI (zero_extend:DI
7288                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7289                                 (zero_extend:DI
7290                                   (match_operand:SI 2 "register_operand" "")))
7291                        (const_int 32))))
7292               (clobber (match_scratch:SI 3 ""))
7293               (clobber (reg:CC 17))])]
7294   ""
7295   "")
7296
7297 (define_insn "*umulsi3_highpart_insn"
7298   [(set (match_operand:SI 0 "register_operand" "=d")
7299         (truncate:SI
7300           (lshiftrt:DI
7301             (mult:DI (zero_extend:DI
7302                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7303                      (zero_extend:DI
7304                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7305             (const_int 32))))
7306    (clobber (match_scratch:SI 3 "=1"))
7307    (clobber (reg:CC 17))]
7308   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7309   "mul{l}\t%2"
7310   [(set_attr "type" "imul")
7311    (set_attr "ppro_uops" "few")
7312    (set_attr "length_immediate" "0")
7313    (set (attr "athlon_decode")
7314      (if_then_else (eq_attr "cpu" "athlon")
7315         (const_string "vector")
7316         (const_string "double")))
7317    (set_attr "mode" "SI")])
7318
7319 (define_insn "*umulsi3_highpart_zext"
7320   [(set (match_operand:DI 0 "register_operand" "=d")
7321         (zero_extend:DI (truncate:SI
7322           (lshiftrt:DI
7323             (mult:DI (zero_extend:DI
7324                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7325                      (zero_extend:DI
7326                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7327             (const_int 32)))))
7328    (clobber (match_scratch:SI 3 "=1"))
7329    (clobber (reg:CC 17))]
7330   "TARGET_64BIT
7331    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7332   "mul{l}\t%2"
7333   [(set_attr "type" "imul")
7334    (set_attr "ppro_uops" "few")
7335    (set_attr "length_immediate" "0")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7341
7342 (define_expand "smuldi3_highpart"
7343   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7344                    (truncate:DI
7345                      (lshiftrt:TI
7346                        (mult:TI (sign_extend:TI
7347                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7348                                 (sign_extend:TI
7349                                   (match_operand:DI 2 "register_operand" "")))
7350                        (const_int 64))))
7351               (clobber (match_scratch:DI 3 ""))
7352               (clobber (reg:CC 17))])]
7353   "TARGET_64BIT"
7354   "")
7355
7356 (define_insn "*smuldi3_highpart_rex64"
7357   [(set (match_operand:DI 0 "register_operand" "=d")
7358         (truncate:DI
7359           (lshiftrt:TI
7360             (mult:TI (sign_extend:TI
7361                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7362                      (sign_extend:TI
7363                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7364             (const_int 64))))
7365    (clobber (match_scratch:DI 3 "=1"))
7366    (clobber (reg:CC 17))]
7367   "TARGET_64BIT
7368    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7369   "imul{q}\t%2"
7370   [(set_attr "type" "imul")
7371    (set_attr "ppro_uops" "few")
7372    (set (attr "athlon_decode")
7373      (if_then_else (eq_attr "cpu" "athlon")
7374         (const_string "vector")
7375         (const_string "double")))
7376    (set_attr "mode" "DI")])
7377
7378 (define_expand "smulsi3_highpart"
7379   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7380                    (truncate:SI
7381                      (lshiftrt:DI
7382                        (mult:DI (sign_extend:DI
7383                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7384                                 (sign_extend:DI
7385                                   (match_operand:SI 2 "register_operand" "")))
7386                        (const_int 32))))
7387               (clobber (match_scratch:SI 3 ""))
7388               (clobber (reg:CC 17))])]
7389   ""
7390   "")
7391
7392 (define_insn "*smulsi3_highpart_insn"
7393   [(set (match_operand:SI 0 "register_operand" "=d")
7394         (truncate:SI
7395           (lshiftrt:DI
7396             (mult:DI (sign_extend:DI
7397                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7398                      (sign_extend:DI
7399                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7400             (const_int 32))))
7401    (clobber (match_scratch:SI 3 "=1"))
7402    (clobber (reg:CC 17))]
7403   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7404   "imul{l}\t%2"
7405   [(set_attr "type" "imul")
7406    (set_attr "ppro_uops" "few")
7407    (set (attr "athlon_decode")
7408      (if_then_else (eq_attr "cpu" "athlon")
7409         (const_string "vector")
7410         (const_string "double")))
7411    (set_attr "mode" "SI")])
7412
7413 (define_insn "*smulsi3_highpart_zext"
7414   [(set (match_operand:DI 0 "register_operand" "=d")
7415         (zero_extend:DI (truncate:SI
7416           (lshiftrt:DI
7417             (mult:DI (sign_extend:DI
7418                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7419                      (sign_extend:DI
7420                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7421             (const_int 32)))))
7422    (clobber (match_scratch:SI 3 "=1"))
7423    (clobber (reg:CC 17))]
7424   "TARGET_64BIT
7425    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7426   "imul{l}\t%2"
7427   [(set_attr "type" "imul")
7428    (set_attr "ppro_uops" "few")
7429    (set (attr "athlon_decode")
7430      (if_then_else (eq_attr "cpu" "athlon")
7431         (const_string "vector")
7432         (const_string "double")))
7433    (set_attr "mode" "SI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "mulxf3"
7438   [(set (match_operand:XF 0 "register_operand" "")
7439         (mult:XF (match_operand:XF 1 "register_operand" "")
7440                  (match_operand:XF 2 "register_operand" "")))]
7441   "TARGET_80387"
7442   "")
7443
7444 (define_expand "muldf3"
7445   [(set (match_operand:DF 0 "register_operand" "")
7446         (mult:DF (match_operand:DF 1 "register_operand" "")
7447                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7448   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449   "")
7450
7451 (define_expand "mulsf3"
7452   [(set (match_operand:SF 0 "register_operand" "")
7453         (mult:SF (match_operand:SF 1 "register_operand" "")
7454                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7455   "TARGET_80387 || TARGET_SSE_MATH"
7456   "")
7457 \f
7458 ;; Divide instructions
7459
7460 (define_insn "divqi3"
7461   [(set (match_operand:QI 0 "register_operand" "=a")
7462         (div:QI (match_operand:HI 1 "register_operand" "0")
7463                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7464    (clobber (reg:CC 17))]
7465   "TARGET_QIMODE_MATH"
7466   "idiv{b}\t%2"
7467   [(set_attr "type" "idiv")
7468    (set_attr "mode" "QI")
7469    (set_attr "ppro_uops" "few")])
7470
7471 (define_insn "udivqi3"
7472   [(set (match_operand:QI 0 "register_operand" "=a")
7473         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7474                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7475    (clobber (reg:CC 17))]
7476   "TARGET_QIMODE_MATH"
7477   "div{b}\t%2"
7478   [(set_attr "type" "idiv")
7479    (set_attr "mode" "QI")
7480    (set_attr "ppro_uops" "few")])
7481
7482 ;; The patterns that match these are at the end of this file.
7483
7484 (define_expand "divxf3"
7485   [(set (match_operand:XF 0 "register_operand" "")
7486         (div:XF (match_operand:XF 1 "register_operand" "")
7487                 (match_operand:XF 2 "register_operand" "")))]
7488   "TARGET_80387"
7489   "")
7490
7491 (define_expand "divdf3"
7492   [(set (match_operand:DF 0 "register_operand" "")
7493         (div:DF (match_operand:DF 1 "register_operand" "")
7494                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7495    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7496    "")
7497  
7498 (define_expand "divsf3"
7499   [(set (match_operand:SF 0 "register_operand" "")
7500         (div:SF (match_operand:SF 1 "register_operand" "")
7501                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7502   "TARGET_80387 || TARGET_SSE_MATH"
7503   "")
7504 \f
7505 ;; Remainder instructions.
7506
7507 (define_expand "divmoddi4"
7508   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7509                    (div:DI (match_operand:DI 1 "register_operand" "")
7510                            (match_operand:DI 2 "nonimmediate_operand" "")))
7511               (set (match_operand:DI 3 "register_operand" "")
7512                    (mod:DI (match_dup 1) (match_dup 2)))
7513               (clobber (reg:CC 17))])]
7514   "TARGET_64BIT"
7515   "")
7516
7517 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7518 ;; Penalize eax case slightly because it results in worse scheduling
7519 ;; of code.
7520 (define_insn "*divmoddi4_nocltd_rex64"
7521   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7522         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7523                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7524    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7525         (mod:DI (match_dup 2) (match_dup 3)))
7526    (clobber (reg:CC 17))]
7527   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7528   "#"
7529   [(set_attr "type" "multi")])
7530
7531 (define_insn "*divmoddi4_cltd_rex64"
7532   [(set (match_operand:DI 0 "register_operand" "=a")
7533         (div:DI (match_operand:DI 2 "register_operand" "a")
7534                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7535    (set (match_operand:DI 1 "register_operand" "=&d")
7536         (mod:DI (match_dup 2) (match_dup 3)))
7537    (clobber (reg:CC 17))]
7538   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7539   "#"
7540   [(set_attr "type" "multi")])
7541
7542 (define_insn "*divmoddi_noext_rex64"
7543   [(set (match_operand:DI 0 "register_operand" "=a")
7544         (div:DI (match_operand:DI 1 "register_operand" "0")
7545                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546    (set (match_operand:DI 3 "register_operand" "=d")
7547         (mod:DI (match_dup 1) (match_dup 2)))
7548    (use (match_operand:DI 4 "register_operand" "3"))
7549    (clobber (reg:CC 17))]
7550   "TARGET_64BIT"
7551   "idiv{q}\t%2"
7552   [(set_attr "type" "idiv")
7553    (set_attr "mode" "DI")
7554    (set_attr "ppro_uops" "few")])
7555
7556 (define_split
7557   [(set (match_operand:DI 0 "register_operand" "")
7558         (div:DI (match_operand:DI 1 "register_operand" "")
7559                 (match_operand:DI 2 "nonimmediate_operand" "")))
7560    (set (match_operand:DI 3 "register_operand" "")
7561         (mod:DI (match_dup 1) (match_dup 2)))
7562    (clobber (reg:CC 17))]
7563   "TARGET_64BIT && reload_completed"
7564   [(parallel [(set (match_dup 3)
7565                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7566               (clobber (reg:CC 17))])
7567    (parallel [(set (match_dup 0)
7568                    (div:DI (reg:DI 0) (match_dup 2)))
7569               (set (match_dup 3)
7570                    (mod:DI (reg:DI 0) (match_dup 2)))
7571               (use (match_dup 3))
7572               (clobber (reg:CC 17))])]
7573 {
7574   /* Avoid use of cltd in favor of a mov+shift.  */
7575   if (!TARGET_USE_CLTD && !optimize_size)
7576     {
7577       if (true_regnum (operands[1]))
7578         emit_move_insn (operands[0], operands[1]);
7579       else
7580         emit_move_insn (operands[3], operands[1]);
7581       operands[4] = operands[3];
7582     }
7583   else
7584     {
7585       if (true_regnum (operands[1]))
7586         abort();
7587       operands[4] = operands[1];
7588     }
7589 })
7590
7591
7592 (define_expand "divmodsi4"
7593   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7594                    (div:SI (match_operand:SI 1 "register_operand" "")
7595                            (match_operand:SI 2 "nonimmediate_operand" "")))
7596               (set (match_operand:SI 3 "register_operand" "")
7597                    (mod:SI (match_dup 1) (match_dup 2)))
7598               (clobber (reg:CC 17))])]
7599   ""
7600   "")
7601
7602 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7603 ;; Penalize eax case slightly because it results in worse scheduling
7604 ;; of code.
7605 (define_insn "*divmodsi4_nocltd"
7606   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7607         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7608                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7609    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7610         (mod:SI (match_dup 2) (match_dup 3)))
7611    (clobber (reg:CC 17))]
7612   "!optimize_size && !TARGET_USE_CLTD"
7613   "#"
7614   [(set_attr "type" "multi")])
7615
7616 (define_insn "*divmodsi4_cltd"
7617   [(set (match_operand:SI 0 "register_operand" "=a")
7618         (div:SI (match_operand:SI 2 "register_operand" "a")
7619                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7620    (set (match_operand:SI 1 "register_operand" "=&d")
7621         (mod:SI (match_dup 2) (match_dup 3)))
7622    (clobber (reg:CC 17))]
7623   "optimize_size || TARGET_USE_CLTD"
7624   "#"
7625   [(set_attr "type" "multi")])
7626
7627 (define_insn "*divmodsi_noext"
7628   [(set (match_operand:SI 0 "register_operand" "=a")
7629         (div:SI (match_operand:SI 1 "register_operand" "0")
7630                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7631    (set (match_operand:SI 3 "register_operand" "=d")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (use (match_operand:SI 4 "register_operand" "3"))
7634    (clobber (reg:CC 17))]
7635   ""
7636   "idiv{l}\t%2"
7637   [(set_attr "type" "idiv")
7638    (set_attr "mode" "SI")
7639    (set_attr "ppro_uops" "few")])
7640
7641 (define_split
7642   [(set (match_operand:SI 0 "register_operand" "")
7643         (div:SI (match_operand:SI 1 "register_operand" "")
7644                 (match_operand:SI 2 "nonimmediate_operand" "")))
7645    (set (match_operand:SI 3 "register_operand" "")
7646         (mod:SI (match_dup 1) (match_dup 2)))
7647    (clobber (reg:CC 17))]
7648   "reload_completed"
7649   [(parallel [(set (match_dup 3)
7650                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7651               (clobber (reg:CC 17))])
7652    (parallel [(set (match_dup 0)
7653                    (div:SI (reg:SI 0) (match_dup 2)))
7654               (set (match_dup 3)
7655                    (mod:SI (reg:SI 0) (match_dup 2)))
7656               (use (match_dup 3))
7657               (clobber (reg:CC 17))])]
7658 {
7659   /* Avoid use of cltd in favor of a mov+shift.  */
7660   if (!TARGET_USE_CLTD && !optimize_size)
7661     {
7662       if (true_regnum (operands[1]))
7663         emit_move_insn (operands[0], operands[1]);
7664       else
7665         emit_move_insn (operands[3], operands[1]);
7666       operands[4] = operands[3];
7667     }
7668   else
7669     {
7670       if (true_regnum (operands[1]))
7671         abort();
7672       operands[4] = operands[1];
7673     }
7674 })
7675 ;; %%% Split me.
7676 (define_insn "divmodhi4"
7677   [(set (match_operand:HI 0 "register_operand" "=a")
7678         (div:HI (match_operand:HI 1 "register_operand" "0")
7679                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7680    (set (match_operand:HI 3 "register_operand" "=&d")
7681         (mod:HI (match_dup 1) (match_dup 2)))
7682    (clobber (reg:CC 17))]
7683   "TARGET_HIMODE_MATH"
7684   "cwtd\;idiv{w}\t%2"
7685   [(set_attr "type" "multi")
7686    (set_attr "length_immediate" "0")
7687    (set_attr "mode" "SI")])
7688
7689 (define_insn "udivmoddi4"
7690   [(set (match_operand:DI 0 "register_operand" "=a")
7691         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7692                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7693    (set (match_operand:DI 3 "register_operand" "=&d")
7694         (umod:DI (match_dup 1) (match_dup 2)))
7695    (clobber (reg:CC 17))]
7696   "TARGET_64BIT"
7697   "xor{q}\t%3, %3\;div{q}\t%2"
7698   [(set_attr "type" "multi")
7699    (set_attr "length_immediate" "0")
7700    (set_attr "mode" "DI")])
7701
7702 (define_insn "*udivmoddi4_noext"
7703   [(set (match_operand:DI 0 "register_operand" "=a")
7704         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7705                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7706    (set (match_operand:DI 3 "register_operand" "=d")
7707         (umod:DI (match_dup 1) (match_dup 2)))
7708    (use (match_dup 3))
7709    (clobber (reg:CC 17))]
7710   "TARGET_64BIT"
7711   "div{q}\t%2"
7712   [(set_attr "type" "idiv")
7713    (set_attr "ppro_uops" "few")
7714    (set_attr "mode" "DI")])
7715
7716 (define_split
7717   [(set (match_operand:DI 0 "register_operand" "")
7718         (udiv:DI (match_operand:DI 1 "register_operand" "")
7719                  (match_operand:DI 2 "nonimmediate_operand" "")))
7720    (set (match_operand:DI 3 "register_operand" "")
7721         (umod:DI (match_dup 1) (match_dup 2)))
7722    (clobber (reg:CC 17))]
7723   "TARGET_64BIT && reload_completed"
7724   [(set (match_dup 3) (const_int 0))
7725    (parallel [(set (match_dup 0)
7726                    (udiv:DI (match_dup 1) (match_dup 2)))
7727               (set (match_dup 3)
7728                    (umod:DI (match_dup 1) (match_dup 2)))
7729               (use (match_dup 3))
7730               (clobber (reg:CC 17))])]
7731   "")
7732
7733 (define_insn "udivmodsi4"
7734   [(set (match_operand:SI 0 "register_operand" "=a")
7735         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7736                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7737    (set (match_operand:SI 3 "register_operand" "=&d")
7738         (umod:SI (match_dup 1) (match_dup 2)))
7739    (clobber (reg:CC 17))]
7740   ""
7741   "xor{l}\t%3, %3\;div{l}\t%2"
7742   [(set_attr "type" "multi")
7743    (set_attr "length_immediate" "0")
7744    (set_attr "mode" "SI")])
7745
7746 (define_insn "*udivmodsi4_noext"
7747   [(set (match_operand:SI 0 "register_operand" "=a")
7748         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7749                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7750    (set (match_operand:SI 3 "register_operand" "=d")
7751         (umod:SI (match_dup 1) (match_dup 2)))
7752    (use (match_dup 3))
7753    (clobber (reg:CC 17))]
7754   ""
7755   "div{l}\t%2"
7756   [(set_attr "type" "idiv")
7757    (set_attr "ppro_uops" "few")
7758    (set_attr "mode" "SI")])
7759
7760 (define_split
7761   [(set (match_operand:SI 0 "register_operand" "")
7762         (udiv:SI (match_operand:SI 1 "register_operand" "")
7763                  (match_operand:SI 2 "nonimmediate_operand" "")))
7764    (set (match_operand:SI 3 "register_operand" "")
7765         (umod:SI (match_dup 1) (match_dup 2)))
7766    (clobber (reg:CC 17))]
7767   "reload_completed"
7768   [(set (match_dup 3) (const_int 0))
7769    (parallel [(set (match_dup 0)
7770                    (udiv:SI (match_dup 1) (match_dup 2)))
7771               (set (match_dup 3)
7772                    (umod:SI (match_dup 1) (match_dup 2)))
7773               (use (match_dup 3))
7774               (clobber (reg:CC 17))])]
7775   "")
7776
7777 (define_expand "udivmodhi4"
7778   [(set (match_dup 4) (const_int 0))
7779    (parallel [(set (match_operand:HI 0 "register_operand" "")
7780                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7781                             (match_operand:HI 2 "nonimmediate_operand" "")))
7782               (set (match_operand:HI 3 "register_operand" "")
7783                    (umod:HI (match_dup 1) (match_dup 2)))
7784               (use (match_dup 4))
7785               (clobber (reg:CC 17))])]
7786   "TARGET_HIMODE_MATH"
7787   "operands[4] = gen_reg_rtx (HImode);")
7788
7789 (define_insn "*udivmodhi_noext"
7790   [(set (match_operand:HI 0 "register_operand" "=a")
7791         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7792                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7793    (set (match_operand:HI 3 "register_operand" "=d")
7794         (umod:HI (match_dup 1) (match_dup 2)))
7795    (use (match_operand:HI 4 "register_operand" "3"))
7796    (clobber (reg:CC 17))]
7797   ""
7798   "div{w}\t%2"
7799   [(set_attr "type" "idiv")
7800    (set_attr "mode" "HI")
7801    (set_attr "ppro_uops" "few")])
7802
7803 ;; We can not use div/idiv for double division, because it causes
7804 ;; "division by zero" on the overflow and that's not what we expect
7805 ;; from truncate.  Because true (non truncating) double division is
7806 ;; never generated, we can't create this insn anyway.
7807 ;
7808 ;(define_insn ""
7809 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7810 ;       (truncate:SI
7811 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7812 ;                  (zero_extend:DI
7813 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7814 ;   (set (match_operand:SI 3 "register_operand" "=d")
7815 ;       (truncate:SI
7816 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7817 ;   (clobber (reg:CC 17))]
7818 ;  ""
7819 ;  "div{l}\t{%2, %0|%0, %2}"
7820 ;  [(set_attr "type" "idiv")
7821 ;   (set_attr "ppro_uops" "few")])
7822 \f
7823 ;;- Logical AND instructions
7824
7825 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7826 ;; Note that this excludes ah.
7827
7828 (define_insn "*testdi_1_rex64"
7829   [(set (reg 17)
7830         (compare
7831           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7832                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7833           (const_int 0)))]
7834   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836   "@
7837    test{l}\t{%k1, %k0|%k0, %k1} 
7838    test{l}\t{%k1, %k0|%k0, %k1} 
7839    test{q}\t{%1, %0|%0, %1} 
7840    test{q}\t{%1, %0|%0, %1} 
7841    test{q}\t{%1, %0|%0, %1}"
7842   [(set_attr "type" "test")
7843    (set_attr "modrm" "0,1,0,1,1")
7844    (set_attr "mode" "SI,SI,DI,DI,DI")
7845    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7846
7847 (define_insn "testsi_1"
7848   [(set (reg 17)
7849         (compare
7850           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7851                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7852           (const_int 0)))]
7853   "ix86_match_ccmode (insn, CCNOmode)
7854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7855   "test{l}\t{%1, %0|%0, %1}"
7856   [(set_attr "type" "test")
7857    (set_attr "modrm" "0,1,1")
7858    (set_attr "mode" "SI")
7859    (set_attr "pent_pair" "uv,np,uv")])
7860
7861 (define_expand "testsi_ccno_1"
7862   [(set (reg:CCNO 17)
7863         (compare:CCNO
7864           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7865                   (match_operand:SI 1 "nonmemory_operand" ""))
7866           (const_int 0)))]
7867   ""
7868   "")
7869
7870 (define_insn "*testhi_1"
7871   [(set (reg 17)
7872         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7873                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7874                  (const_int 0)))]
7875   "ix86_match_ccmode (insn, CCNOmode)
7876    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7877   "test{w}\t{%1, %0|%0, %1}"
7878   [(set_attr "type" "test")
7879    (set_attr "modrm" "0,1,1")
7880    (set_attr "mode" "HI")
7881    (set_attr "pent_pair" "uv,np,uv")])
7882
7883 (define_expand "testqi_ccz_1"
7884   [(set (reg:CCZ 17)
7885         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7886                              (match_operand:QI 1 "nonmemory_operand" ""))
7887                  (const_int 0)))]
7888   ""
7889   "")
7890
7891 (define_insn "*testqi_1"
7892   [(set (reg 17)
7893         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895                  (const_int 0)))]
7896   "ix86_match_ccmode (insn, CCNOmode)
7897    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7898 {
7899   if (which_alternative == 3)
7900     {
7901       if (GET_CODE (operands[1]) == CONST_INT
7902           && (INTVAL (operands[1]) & 0xffffff00))
7903         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7904       return "test{l}\t{%1, %k0|%k0, %1}";
7905     }
7906   return "test{b}\t{%1, %0|%0, %1}";
7907 }
7908   [(set_attr "type" "test")
7909    (set_attr "modrm" "0,1,1,1")
7910    (set_attr "mode" "QI,QI,QI,SI")
7911    (set_attr "pent_pair" "uv,np,uv,np")])
7912
7913 (define_expand "testqi_ext_ccno_0"
7914   [(set (reg:CCNO 17)
7915         (compare:CCNO
7916           (and:SI
7917             (zero_extract:SI
7918               (match_operand 0 "ext_register_operand" "")
7919               (const_int 8)
7920               (const_int 8))
7921             (match_operand 1 "const_int_operand" ""))
7922           (const_int 0)))]
7923   ""
7924   "")
7925
7926 (define_insn "*testqi_ext_0"
7927   [(set (reg 17)
7928         (compare
7929           (and:SI
7930             (zero_extract:SI
7931               (match_operand 0 "ext_register_operand" "Q")
7932               (const_int 8)
7933               (const_int 8))
7934             (match_operand 1 "const_int_operand" "n"))
7935           (const_int 0)))]
7936   "ix86_match_ccmode (insn, CCNOmode)"
7937   "test{b}\t{%1, %h0|%h0, %1}"
7938   [(set_attr "type" "test")
7939    (set_attr "mode" "QI")
7940    (set_attr "length_immediate" "1")
7941    (set_attr "pent_pair" "np")])
7942
7943 (define_insn "*testqi_ext_1"
7944   [(set (reg 17)
7945         (compare
7946           (and:SI
7947             (zero_extract:SI
7948               (match_operand 0 "ext_register_operand" "Q")
7949               (const_int 8)
7950               (const_int 8))
7951             (zero_extend:SI
7952               (match_operand:QI 1 "general_operand" "Qm")))
7953           (const_int 0)))]
7954   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7955    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7956   "test{b}\t{%1, %h0|%h0, %1}"
7957   [(set_attr "type" "test")
7958    (set_attr "mode" "QI")])
7959
7960 (define_insn "*testqi_ext_1_rex64"
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_extend:SI
7969               (match_operand:QI 1 "register_operand" "Q")))
7970           (const_int 0)))]
7971   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%1, %h0|%h0, %1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")])
7975
7976 (define_insn "*testqi_ext_2"
7977   [(set (reg 17)
7978         (compare
7979           (and:SI
7980             (zero_extract:SI
7981               (match_operand 0 "ext_register_operand" "Q")
7982               (const_int 8)
7983               (const_int 8))
7984             (zero_extract:SI
7985               (match_operand 1 "ext_register_operand" "Q")
7986               (const_int 8)
7987               (const_int 8)))
7988           (const_int 0)))]
7989   "ix86_match_ccmode (insn, CCNOmode)"
7990   "test{b}\t{%h1, %h0|%h0, %h1}"
7991   [(set_attr "type" "test")
7992    (set_attr "mode" "QI")])
7993
7994 ;; Combine likes to form bit extractions for some tests.  Humor it.
7995 (define_insn "*testqi_ext_3"
7996   [(set (reg 17)
7997         (compare (zero_extract:SI
7998                    (match_operand 0 "nonimmediate_operand" "rm")
7999                    (match_operand:SI 1 "const_int_operand" "")
8000                    (match_operand:SI 2 "const_int_operand" ""))
8001                  (const_int 0)))]
8002   "ix86_match_ccmode (insn, CCNOmode)
8003    && (GET_MODE (operands[0]) == SImode
8004        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8005        || GET_MODE (operands[0]) == HImode
8006        || GET_MODE (operands[0]) == QImode)"
8007   "#")
8008
8009 (define_insn "*testqi_ext_3_rex64"
8010   [(set (reg 17)
8011         (compare (zero_extract:DI
8012                    (match_operand 0 "nonimmediate_operand" "rm")
8013                    (match_operand:DI 1 "const_int_operand" "")
8014                    (match_operand:DI 2 "const_int_operand" ""))
8015                  (const_int 0)))]
8016   "TARGET_64BIT
8017    && ix86_match_ccmode (insn, CCNOmode)
8018    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8019    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8020    /* Ensure that resulting mask is zero or sign extended operand.  */
8021    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8022        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8023            && INTVAL (operands[1]) > 32))
8024    && (GET_MODE (operands[0]) == SImode
8025        || GET_MODE (operands[0]) == DImode
8026        || GET_MODE (operands[0]) == HImode
8027        || GET_MODE (operands[0]) == QImode)"
8028   "#")
8029
8030 (define_split
8031   [(set (reg 17)
8032         (compare (zero_extract
8033                    (match_operand 0 "nonimmediate_operand" "")
8034                    (match_operand 1 "const_int_operand" "")
8035                    (match_operand 2 "const_int_operand" ""))
8036                  (const_int 0)))]
8037   "ix86_match_ccmode (insn, CCNOmode)"
8038   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8039 {
8040   HOST_WIDE_INT len = INTVAL (operands[1]);
8041   HOST_WIDE_INT pos = INTVAL (operands[2]);
8042   HOST_WIDE_INT mask;
8043   enum machine_mode mode, submode;
8044
8045   mode = GET_MODE (operands[0]);
8046   if (GET_CODE (operands[0]) == MEM)
8047     {
8048       /* ??? Combine likes to put non-volatile mem extractions in QImode
8049          no matter the size of the test.  So find a mode that works.  */
8050       if (! MEM_VOLATILE_P (operands[0]))
8051         {
8052           mode = smallest_mode_for_size (pos + len, MODE_INT);
8053           operands[0] = adjust_address (operands[0], mode, 0);
8054         }
8055     }
8056   else if (GET_CODE (operands[0]) == SUBREG
8057            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8058                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8059            && pos + len <= GET_MODE_BITSIZE (submode))
8060     {
8061       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8062       mode = submode;
8063       operands[0] = SUBREG_REG (operands[0]);
8064     }
8065   else if (mode == HImode && pos + len <= 8)
8066     {
8067       /* Small HImode tests can be converted to QImode.  */
8068       mode = QImode;
8069       operands[0] = gen_lowpart (QImode, operands[0]);
8070     }
8071
8072   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8073   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8074
8075   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8076 })
8077
8078 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8079 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8080 ;; this is relatively important trick.
8081 ;; Do the conversion only post-reload to avoid limiting of the register class
8082 ;; to QI regs.
8083 (define_split
8084   [(set (reg 17)
8085         (compare
8086           (and (match_operand 0 "register_operand" "")
8087                (match_operand 1 "const_int_operand" ""))
8088           (const_int 0)))]
8089    "reload_completed
8090     && QI_REG_P (operands[0])
8091     && ((ix86_match_ccmode (insn, CCZmode)
8092          && !(INTVAL (operands[1]) & ~(255 << 8)))
8093         || (ix86_match_ccmode (insn, CCNOmode)
8094             && !(INTVAL (operands[1]) & ~(127 << 8))))
8095     && GET_MODE (operands[0]) != QImode"
8096   [(set (reg:CCNO 17)
8097         (compare:CCNO
8098           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8099                   (match_dup 1))
8100           (const_int 0)))]
8101   "operands[0] = gen_lowpart (SImode, operands[0]);
8102    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8103
8104 (define_split
8105   [(set (reg 17)
8106         (compare
8107           (and (match_operand 0 "nonimmediate_operand" "")
8108                (match_operand 1 "const_int_operand" ""))
8109           (const_int 0)))]
8110    "reload_completed
8111     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8112     && ((ix86_match_ccmode (insn, CCZmode)
8113          && !(INTVAL (operands[1]) & ~255))
8114         || (ix86_match_ccmode (insn, CCNOmode)
8115             && !(INTVAL (operands[1]) & ~127)))
8116     && GET_MODE (operands[0]) != QImode"
8117   [(set (reg:CCNO 17)
8118         (compare:CCNO
8119           (and:QI (match_dup 0)
8120                   (match_dup 1))
8121           (const_int 0)))]
8122   "operands[0] = gen_lowpart (QImode, operands[0]);
8123    operands[1] = gen_lowpart (QImode, operands[1]);")
8124
8125
8126 ;; %%% This used to optimize known byte-wide and operations to memory,
8127 ;; and sometimes to QImode registers.  If this is considered useful,
8128 ;; it should be done with splitters.
8129
8130 (define_expand "anddi3"
8131   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8132         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8133                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8134    (clobber (reg:CC 17))]
8135   "TARGET_64BIT"
8136   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8137
8138 (define_insn "*anddi_1_rex64"
8139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8140         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8141                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8142    (clobber (reg:CC 17))]
8143   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8144 {
8145   switch (get_attr_type (insn))
8146     {
8147     case TYPE_IMOVX:
8148       {
8149         enum machine_mode mode;
8150
8151         if (GET_CODE (operands[2]) != CONST_INT)
8152           abort ();
8153         if (INTVAL (operands[2]) == 0xff)
8154           mode = QImode;
8155         else if (INTVAL (operands[2]) == 0xffff)
8156           mode = HImode;
8157         else
8158           abort ();
8159         
8160         operands[1] = gen_lowpart (mode, operands[1]);
8161         if (mode == QImode)
8162           return "movz{bq|x}\t{%1,%0|%0, %1}";
8163         else
8164           return "movz{wq|x}\t{%1,%0|%0, %1}";
8165       }
8166
8167     default:
8168       if (! rtx_equal_p (operands[0], operands[1]))
8169         abort ();
8170       if (get_attr_mode (insn) == MODE_SI)
8171         return "and{l}\t{%k2, %k0|%k0, %k2}";
8172       else
8173         return "and{q}\t{%2, %0|%0, %2}";
8174     }
8175 }
8176   [(set_attr "type" "alu,alu,alu,imovx")
8177    (set_attr "length_immediate" "*,*,*,0")
8178    (set_attr "mode" "SI,DI,DI,DI")])
8179
8180 (define_insn "*anddi_2"
8181   [(set (reg 17)
8182         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8183                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8184                  (const_int 0)))
8185    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8186         (and:DI (match_dup 1) (match_dup 2)))]
8187   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8188    && ix86_binary_operator_ok (AND, DImode, operands)"
8189   "@
8190    and{l}\t{%k2, %k0|%k0, %k2} 
8191    and{q}\t{%2, %0|%0, %2} 
8192    and{q}\t{%2, %0|%0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "mode" "SI,DI,DI")])
8195
8196 (define_expand "andsi3"
8197   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8198         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8199                 (match_operand:SI 2 "general_operand" "")))
8200    (clobber (reg:CC 17))]
8201   ""
8202   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8203
8204 (define_insn "*andsi_1"
8205   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8206         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8207                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8208    (clobber (reg:CC 17))]
8209   "ix86_binary_operator_ok (AND, SImode, operands)"
8210 {
8211   switch (get_attr_type (insn))
8212     {
8213     case TYPE_IMOVX:
8214       {
8215         enum machine_mode mode;
8216
8217         if (GET_CODE (operands[2]) != CONST_INT)
8218           abort ();
8219         if (INTVAL (operands[2]) == 0xff)
8220           mode = QImode;
8221         else if (INTVAL (operands[2]) == 0xffff)
8222           mode = HImode;
8223         else
8224           abort ();
8225         
8226         operands[1] = gen_lowpart (mode, operands[1]);
8227         if (mode == QImode)
8228           return "movz{bl|x}\t{%1,%0|%0, %1}";
8229         else
8230           return "movz{wl|x}\t{%1,%0|%0, %1}";
8231       }
8232
8233     default:
8234       if (! rtx_equal_p (operands[0], operands[1]))
8235         abort ();
8236       return "and{l}\t{%2, %0|%0, %2}";
8237     }
8238 }
8239   [(set_attr "type" "alu,alu,imovx")
8240    (set_attr "length_immediate" "*,*,0")
8241    (set_attr "mode" "SI")])
8242
8243 (define_split
8244   [(set (match_operand 0 "register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -65536)))
8247    (clobber (reg:CC 17))]
8248   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8249   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250   "operands[1] = gen_lowpart (HImode, operands[0]);")
8251
8252 (define_split
8253   [(set (match_operand 0 "ext_register_operand" "")
8254         (and (match_dup 0)
8255              (const_int -256)))
8256    (clobber (reg:CC 17))]
8257   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8259   "operands[1] = gen_lowpart (QImode, operands[0]);")
8260
8261 (define_split
8262   [(set (match_operand 0 "ext_register_operand" "")
8263         (and (match_dup 0)
8264              (const_int -65281)))
8265    (clobber (reg:CC 17))]
8266   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8267   [(parallel [(set (zero_extract:SI (match_dup 0)
8268                                     (const_int 8)
8269                                     (const_int 8))
8270                    (xor:SI 
8271                      (zero_extract:SI (match_dup 0)
8272                                       (const_int 8)
8273                                       (const_int 8))
8274                      (zero_extract:SI (match_dup 0)
8275                                       (const_int 8)
8276                                       (const_int 8))))
8277               (clobber (reg:CC 17))])]
8278   "operands[0] = gen_lowpart (SImode, operands[0]);")
8279
8280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8281 (define_insn "*andsi_1_zext"
8282   [(set (match_operand:DI 0 "register_operand" "=r")
8283         (zero_extend:DI
8284           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8285                   (match_operand:SI 2 "general_operand" "rim"))))
8286    (clobber (reg:CC 17))]
8287   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8288   "and{l}\t{%2, %k0|%k0, %2}"
8289   [(set_attr "type" "alu")
8290    (set_attr "mode" "SI")])
8291
8292 (define_insn "*andsi_2"
8293   [(set (reg 17)
8294         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8295                          (match_operand:SI 2 "general_operand" "rim,ri"))
8296                  (const_int 0)))
8297    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8298         (and:SI (match_dup 1) (match_dup 2)))]
8299   "ix86_match_ccmode (insn, CCNOmode)
8300    && ix86_binary_operator_ok (AND, SImode, operands)"
8301   "and{l}\t{%2, %0|%0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "SI")])
8304
8305 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8306 (define_insn "*andsi_2_zext"
8307   [(set (reg 17)
8308         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8309                          (match_operand:SI 2 "general_operand" "rim"))
8310                  (const_int 0)))
8311    (set (match_operand:DI 0 "register_operand" "=r")
8312         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8313   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8314    && ix86_binary_operator_ok (AND, SImode, operands)"
8315   "and{l}\t{%2, %k0|%k0, %2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "mode" "SI")])
8318
8319 (define_expand "andhi3"
8320   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8321         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8322                 (match_operand:HI 2 "general_operand" "")))
8323    (clobber (reg:CC 17))]
8324   "TARGET_HIMODE_MATH"
8325   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8326
8327 (define_insn "*andhi_1"
8328   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8329         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8330                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8331    (clobber (reg:CC 17))]
8332   "ix86_binary_operator_ok (AND, HImode, operands)"
8333 {
8334   switch (get_attr_type (insn))
8335     {
8336     case TYPE_IMOVX:
8337       if (GET_CODE (operands[2]) != CONST_INT)
8338         abort ();
8339       if (INTVAL (operands[2]) == 0xff)
8340         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8341       abort ();
8342
8343     default:
8344       if (! rtx_equal_p (operands[0], operands[1]))
8345         abort ();
8346
8347       return "and{w}\t{%2, %0|%0, %2}";
8348     }
8349 }
8350   [(set_attr "type" "alu,alu,imovx")
8351    (set_attr "length_immediate" "*,*,0")
8352    (set_attr "mode" "HI,HI,SI")])
8353
8354 (define_insn "*andhi_2"
8355   [(set (reg 17)
8356         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357                          (match_operand:HI 2 "general_operand" "rim,ri"))
8358                  (const_int 0)))
8359    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360         (and:HI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCNOmode)
8362    && ix86_binary_operator_ok (AND, HImode, operands)"
8363   "and{w}\t{%2, %0|%0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "mode" "HI")])
8366
8367 (define_expand "andqi3"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370                 (match_operand:QI 2 "general_operand" "")))
8371    (clobber (reg:CC 17))]
8372   "TARGET_QIMODE_MATH"
8373   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8376 (define_insn "*andqi_1"
8377   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380    (clobber (reg:CC 17))]
8381   "ix86_binary_operator_ok (AND, QImode, operands)"
8382   "@
8383    and{b}\t{%2, %0|%0, %2}
8384    and{b}\t{%2, %0|%0, %2}
8385    and{l}\t{%k2, %k0|%k0, %k2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_1_slp"
8390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391         (and:QI (match_dup 0)
8392                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393    (clobber (reg:CC 17))]
8394   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396   "and{b}\t{%1, %0|%0, %1}"
8397   [(set_attr "type" "alu1")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_2"
8401   [(set (reg 17)
8402         (compare (and:QI
8403                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405                  (const_int 0)))
8406    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407         (and:QI (match_dup 1) (match_dup 2)))]
8408   "ix86_match_ccmode (insn, CCNOmode)
8409    && ix86_binary_operator_ok (AND, QImode, operands)"
8410 {
8411   if (which_alternative == 2)
8412     {
8413       if (GET_CODE (operands[2]) == CONST_INT
8414           && (INTVAL (operands[2]) & 0xffffff00))
8415         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8416       return "and{l}\t{%2, %k0|%k0, %2}";
8417     }
8418   return "and{b}\t{%2, %0|%0, %2}";
8419 }
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "QI,QI,SI")])
8422
8423 (define_insn "*andqi_2_slp"
8424   [(set (reg 17)
8425         (compare (and:QI
8426                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8427                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8428                  (const_int 0)))
8429    (set (strict_low_part (match_dup 0))
8430         (and:QI (match_dup 0) (match_dup 1)))]
8431   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8432    && ix86_match_ccmode (insn, CCNOmode)
8433    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8434   "and{b}\t{%1, %0|%0, %1}"
8435   [(set_attr "type" "alu1")
8436    (set_attr "mode" "QI")])
8437
8438 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8439 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8440 ;; for a QImode operand, which of course failed.
8441
8442 (define_insn "andqi_ext_0"
8443   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (and:SI 
8447           (zero_extract:SI
8448             (match_operand 1 "ext_register_operand" "0")
8449             (const_int 8)
8450             (const_int 8))
8451           (match_operand 2 "const_int_operand" "n")))
8452    (clobber (reg:CC 17))]
8453   ""
8454   "and{b}\t{%2, %h0|%h0, %2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "length_immediate" "1")
8457    (set_attr "mode" "QI")])
8458
8459 ;; Generated by peephole translating test to and.  This shows up
8460 ;; often in fp comparisons.
8461
8462 (define_insn "*andqi_ext_0_cc"
8463   [(set (reg 17)
8464         (compare
8465           (and:SI
8466             (zero_extract:SI
8467               (match_operand 1 "ext_register_operand" "0")
8468               (const_int 8)
8469               (const_int 8))
8470             (match_operand 2 "const_int_operand" "n"))
8471           (const_int 0)))
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_dup 1)
8478             (const_int 8)
8479             (const_int 8))
8480           (match_dup 2)))]
8481   "ix86_match_ccmode (insn, CCNOmode)"
8482   "and{b}\t{%2, %h0|%h0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "length_immediate" "1")
8485    (set_attr "mode" "QI")])
8486
8487 (define_insn "*andqi_ext_1"
8488   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489                          (const_int 8)
8490                          (const_int 8))
8491         (and:SI 
8492           (zero_extract:SI
8493             (match_operand 1 "ext_register_operand" "0")
8494             (const_int 8)
8495             (const_int 8))
8496           (zero_extend:SI
8497             (match_operand:QI 2 "general_operand" "Qm"))))
8498    (clobber (reg:CC 17))]
8499   "!TARGET_64BIT"
8500   "and{b}\t{%2, %h0|%h0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "length_immediate" "0")
8503    (set_attr "mode" "QI")])
8504
8505 (define_insn "*andqi_ext_1_rex64"
8506   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507                          (const_int 8)
8508                          (const_int 8))
8509         (and:SI 
8510           (zero_extract:SI
8511             (match_operand 1 "ext_register_operand" "0")
8512             (const_int 8)
8513             (const_int 8))
8514           (zero_extend:SI
8515             (match_operand 2 "ext_register_operand" "Q"))))
8516    (clobber (reg:CC 17))]
8517   "TARGET_64BIT"
8518   "and{b}\t{%2, %h0|%h0, %2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "length_immediate" "0")
8521    (set_attr "mode" "QI")])
8522
8523 (define_insn "*andqi_ext_2"
8524   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8525                          (const_int 8)
8526                          (const_int 8))
8527         (and:SI
8528           (zero_extract:SI
8529             (match_operand 1 "ext_register_operand" "%0")
8530             (const_int 8)
8531             (const_int 8))
8532           (zero_extract:SI
8533             (match_operand 2 "ext_register_operand" "Q")
8534             (const_int 8)
8535             (const_int 8))))
8536    (clobber (reg:CC 17))]
8537   ""
8538   "and{b}\t{%h2, %h0|%h0, %h2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "length_immediate" "0")
8541    (set_attr "mode" "QI")])
8542
8543 ;; Convert wide AND instructions with immediate operand to shorter QImode
8544 ;; equivalents when possible.
8545 ;; Don't do the splitting with memory operands, since it introduces risk
8546 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8547 ;; for size, but that can (should?) be handled by generic code instead.
8548 (define_split
8549   [(set (match_operand 0 "register_operand" "")
8550         (and (match_operand 1 "register_operand" "")
8551              (match_operand 2 "const_int_operand" "")))
8552    (clobber (reg:CC 17))]
8553    "reload_completed
8554     && QI_REG_P (operands[0])
8555     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8556     && !(~INTVAL (operands[2]) & ~(255 << 8))
8557     && GET_MODE (operands[0]) != QImode"
8558   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8559                    (and:SI (zero_extract:SI (match_dup 1)
8560                                             (const_int 8) (const_int 8))
8561                            (match_dup 2)))
8562               (clobber (reg:CC 17))])]
8563   "operands[0] = gen_lowpart (SImode, operands[0]);
8564    operands[1] = gen_lowpart (SImode, operands[1]);
8565    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8566
8567 ;; Since AND can be encoded with sign extended immediate, this is only
8568 ;; profitable when 7th bit is not set.
8569 (define_split
8570   [(set (match_operand 0 "register_operand" "")
8571         (and (match_operand 1 "general_operand" "")
8572              (match_operand 2 "const_int_operand" "")))
8573    (clobber (reg:CC 17))]
8574    "reload_completed
8575     && ANY_QI_REG_P (operands[0])
8576     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8577     && !(~INTVAL (operands[2]) & ~255)
8578     && !(INTVAL (operands[2]) & 128)
8579     && GET_MODE (operands[0]) != QImode"
8580   [(parallel [(set (strict_low_part (match_dup 0))
8581                    (and:QI (match_dup 1)
8582                            (match_dup 2)))
8583               (clobber (reg:CC 17))])]
8584   "operands[0] = gen_lowpart (QImode, operands[0]);
8585    operands[1] = gen_lowpart (QImode, operands[1]);
8586    operands[2] = gen_lowpart (QImode, operands[2]);")
8587 \f
8588 ;; Logical inclusive OR instructions
8589
8590 ;; %%% This used to optimize known byte-wide and operations to memory.
8591 ;; If this is considered useful, it should be done with splitters.
8592
8593 (define_expand "iordi3"
8594   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8595         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8596                 (match_operand:DI 2 "x86_64_general_operand" "")))
8597    (clobber (reg:CC 17))]
8598   "TARGET_64BIT"
8599   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8600
8601 (define_insn "*iordi_1_rex64"
8602   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8603         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8604                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8605    (clobber (reg:CC 17))]
8606   "TARGET_64BIT
8607    && ix86_binary_operator_ok (IOR, DImode, operands)"
8608   "or{q}\t{%2, %0|%0, %2}"
8609   [(set_attr "type" "alu")
8610    (set_attr "mode" "DI")])
8611
8612 (define_insn "*iordi_2_rex64"
8613   [(set (reg 17)
8614         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8615                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8616                  (const_int 0)))
8617    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8618         (ior:DI (match_dup 1) (match_dup 2)))]
8619   "TARGET_64BIT
8620    && ix86_match_ccmode (insn, CCNOmode)
8621    && ix86_binary_operator_ok (IOR, DImode, operands)"
8622   "or{q}\t{%2, %0|%0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "DI")])
8625
8626 (define_insn "*iordi_3_rex64"
8627   [(set (reg 17)
8628         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8629                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8630                  (const_int 0)))
8631    (clobber (match_scratch:DI 0 "=r"))]
8632   "TARGET_64BIT
8633    && ix86_match_ccmode (insn, CCNOmode)
8634    && ix86_binary_operator_ok (IOR, DImode, operands)"
8635   "or{q}\t{%2, %0|%0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "DI")])
8638
8639
8640 (define_expand "iorsi3"
8641   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8642         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8643                 (match_operand:SI 2 "general_operand" "")))
8644    (clobber (reg:CC 17))]
8645   ""
8646   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8647
8648 (define_insn "*iorsi_1"
8649   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8650         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8651                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8652    (clobber (reg:CC 17))]
8653   "ix86_binary_operator_ok (IOR, SImode, operands)"
8654   "or{l}\t{%2, %0|%0, %2}"
8655   [(set_attr "type" "alu")
8656    (set_attr "mode" "SI")])
8657
8658 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8659 (define_insn "*iorsi_1_zext"
8660   [(set (match_operand:DI 0 "register_operand" "=rm")
8661         (zero_extend:DI
8662           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8663                   (match_operand:SI 2 "general_operand" "rim"))))
8664    (clobber (reg:CC 17))]
8665   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8666   "or{l}\t{%2, %k0|%k0, %2}"
8667   [(set_attr "type" "alu")
8668    (set_attr "mode" "SI")])
8669
8670 (define_insn "*iorsi_1_zext_imm"
8671   [(set (match_operand:DI 0 "register_operand" "=rm")
8672         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8673                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8674    (clobber (reg:CC 17))]
8675   "TARGET_64BIT"
8676   "or{l}\t{%2, %k0|%k0, %2}"
8677   [(set_attr "type" "alu")
8678    (set_attr "mode" "SI")])
8679
8680 (define_insn "*iorsi_2"
8681   [(set (reg 17)
8682         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8683                          (match_operand:SI 2 "general_operand" "rim,ri"))
8684                  (const_int 0)))
8685    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8686         (ior:SI (match_dup 1) (match_dup 2)))]
8687   "ix86_match_ccmode (insn, CCNOmode)
8688    && ix86_binary_operator_ok (IOR, SImode, operands)"
8689   "or{l}\t{%2, %0|%0, %2}"
8690   [(set_attr "type" "alu")
8691    (set_attr "mode" "SI")])
8692
8693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8694 ;; ??? Special case for immediate operand is missing - it is tricky.
8695 (define_insn "*iorsi_2_zext"
8696   [(set (reg 17)
8697         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8698                          (match_operand:SI 2 "general_operand" "rim"))
8699                  (const_int 0)))
8700    (set (match_operand:DI 0 "register_operand" "=r")
8701         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8702   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8703    && ix86_binary_operator_ok (IOR, SImode, operands)"
8704   "or{l}\t{%2, %k0|%k0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "mode" "SI")])
8707
8708 (define_insn "*iorsi_2_zext_imm"
8709   [(set (reg 17)
8710         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8711                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8712                  (const_int 0)))
8713    (set (match_operand:DI 0 "register_operand" "=r")
8714         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8715   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8716    && ix86_binary_operator_ok (IOR, SImode, operands)"
8717   "or{l}\t{%2, %k0|%k0, %2}"
8718   [(set_attr "type" "alu")
8719    (set_attr "mode" "SI")])
8720
8721 (define_insn "*iorsi_3"
8722   [(set (reg 17)
8723         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8724                          (match_operand:SI 2 "general_operand" "rim"))
8725                  (const_int 0)))
8726    (clobber (match_scratch:SI 0 "=r"))]
8727   "ix86_match_ccmode (insn, CCNOmode)
8728    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8729   "or{l}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "SI")])
8732
8733 (define_expand "iorhi3"
8734   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8735         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8736                 (match_operand:HI 2 "general_operand" "")))
8737    (clobber (reg:CC 17))]
8738   "TARGET_HIMODE_MATH"
8739   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8740
8741 (define_insn "*iorhi_1"
8742   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8743         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8744                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8745    (clobber (reg:CC 17))]
8746   "ix86_binary_operator_ok (IOR, HImode, operands)"
8747   "or{w}\t{%2, %0|%0, %2}"
8748   [(set_attr "type" "alu")
8749    (set_attr "mode" "HI")])
8750
8751 (define_insn "*iorhi_2"
8752   [(set (reg 17)
8753         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8754                          (match_operand:HI 2 "general_operand" "rim,ri"))
8755                  (const_int 0)))
8756    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8757         (ior:HI (match_dup 1) (match_dup 2)))]
8758   "ix86_match_ccmode (insn, CCNOmode)
8759    && ix86_binary_operator_ok (IOR, HImode, operands)"
8760   "or{w}\t{%2, %0|%0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "HI")])
8763
8764 (define_insn "*iorhi_3"
8765   [(set (reg 17)
8766         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8767                          (match_operand:HI 2 "general_operand" "rim"))
8768                  (const_int 0)))
8769    (clobber (match_scratch:HI 0 "=r"))]
8770   "ix86_match_ccmode (insn, CCNOmode)
8771    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8772   "or{w}\t{%2, %0|%0, %2}"
8773   [(set_attr "type" "alu")
8774    (set_attr "mode" "HI")])
8775
8776 (define_expand "iorqi3"
8777   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8778         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8779                 (match_operand:QI 2 "general_operand" "")))
8780    (clobber (reg:CC 17))]
8781   "TARGET_QIMODE_MATH"
8782   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8783
8784 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8785 (define_insn "*iorqi_1"
8786   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8787         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8788                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8789    (clobber (reg:CC 17))]
8790   "ix86_binary_operator_ok (IOR, QImode, operands)"
8791   "@
8792    or{b}\t{%2, %0|%0, %2}
8793    or{b}\t{%2, %0|%0, %2}
8794    or{l}\t{%k2, %k0|%k0, %k2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "mode" "QI,QI,SI")])
8797
8798 (define_insn "*iorqi_1_slp"
8799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8800         (ior:QI (match_dup 0)
8801                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8802    (clobber (reg:CC 17))]
8803   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8804    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8805   "or{b}\t{%1, %0|%0, %1}"
8806   [(set_attr "type" "alu1")
8807    (set_attr "mode" "QI")])
8808
8809 (define_insn "*iorqi_2"
8810   [(set (reg 17)
8811         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8812                          (match_operand:QI 2 "general_operand" "qim,qi"))
8813                  (const_int 0)))
8814    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8815         (ior:QI (match_dup 1) (match_dup 2)))]
8816   "ix86_match_ccmode (insn, CCNOmode)
8817    && ix86_binary_operator_ok (IOR, QImode, operands)"
8818   "or{b}\t{%2, %0|%0, %2}"
8819   [(set_attr "type" "alu")
8820    (set_attr "mode" "QI")])
8821
8822 (define_insn "*iorqi_2_slp"
8823   [(set (reg 17)
8824         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8825                          (match_operand:QI 1 "general_operand" "qim,qi"))
8826                  (const_int 0)))
8827    (set (strict_low_part (match_dup 0))
8828         (ior:QI (match_dup 0) (match_dup 1)))]
8829   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8830    && ix86_match_ccmode (insn, CCNOmode)
8831    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8832   "or{b}\t{%1, %0|%0, %1}"
8833   [(set_attr "type" "alu1")
8834    (set_attr "mode" "QI")])
8835
8836 (define_insn "*iorqi_3"
8837   [(set (reg 17)
8838         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8839                          (match_operand:QI 2 "general_operand" "qim"))
8840                  (const_int 0)))
8841    (clobber (match_scratch:QI 0 "=q"))]
8842   "ix86_match_ccmode (insn, CCNOmode)
8843    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8844   "or{b}\t{%2, %0|%0, %2}"
8845   [(set_attr "type" "alu")
8846    (set_attr "mode" "QI")])
8847
8848 (define_insn "iorqi_ext_0"
8849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8850                          (const_int 8)
8851                          (const_int 8))
8852         (ior:SI 
8853           (zero_extract:SI
8854             (match_operand 1 "ext_register_operand" "0")
8855             (const_int 8)
8856             (const_int 8))
8857           (match_operand 2 "const_int_operand" "n")))
8858    (clobber (reg:CC 17))]
8859   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8860   "or{b}\t{%2, %h0|%h0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "length_immediate" "1")
8863    (set_attr "mode" "QI")])
8864
8865 (define_insn "*iorqi_ext_1"
8866   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8867                          (const_int 8)
8868                          (const_int 8))
8869         (ior:SI 
8870           (zero_extract:SI
8871             (match_operand 1 "ext_register_operand" "0")
8872             (const_int 8)
8873             (const_int 8))
8874           (zero_extend:SI
8875             (match_operand:QI 2 "general_operand" "Qm"))))
8876    (clobber (reg:CC 17))]
8877   "!TARGET_64BIT
8878    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8879   "or{b}\t{%2, %h0|%h0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "length_immediate" "0")
8882    (set_attr "mode" "QI")])
8883
8884 (define_insn "*iorqi_ext_1_rex64"
8885   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8886                          (const_int 8)
8887                          (const_int 8))
8888         (ior:SI 
8889           (zero_extract:SI
8890             (match_operand 1 "ext_register_operand" "0")
8891             (const_int 8)
8892             (const_int 8))
8893           (zero_extend:SI
8894             (match_operand 2 "ext_register_operand" "Q"))))
8895    (clobber (reg:CC 17))]
8896   "TARGET_64BIT
8897    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8898   "or{b}\t{%2, %h0|%h0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "length_immediate" "0")
8901    (set_attr "mode" "QI")])
8902
8903 (define_insn "*iorqi_ext_2"
8904   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8905                          (const_int 8)
8906                          (const_int 8))
8907         (ior:SI 
8908           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8909                            (const_int 8)
8910                            (const_int 8))
8911           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8912                            (const_int 8)
8913                            (const_int 8))))
8914    (clobber (reg:CC 17))]
8915   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8916   "ior{b}\t{%h2, %h0|%h0, %h2}"
8917   [(set_attr "type" "alu")
8918    (set_attr "length_immediate" "0")
8919    (set_attr "mode" "QI")])
8920
8921 (define_split
8922   [(set (match_operand 0 "register_operand" "")
8923         (ior (match_operand 1 "register_operand" "")
8924              (match_operand 2 "const_int_operand" "")))
8925    (clobber (reg:CC 17))]
8926    "reload_completed
8927     && QI_REG_P (operands[0])
8928     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8929     && !(INTVAL (operands[2]) & ~(255 << 8))
8930     && GET_MODE (operands[0]) != QImode"
8931   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8932                    (ior:SI (zero_extract:SI (match_dup 1)
8933                                             (const_int 8) (const_int 8))
8934                            (match_dup 2)))
8935               (clobber (reg:CC 17))])]
8936   "operands[0] = gen_lowpart (SImode, operands[0]);
8937    operands[1] = gen_lowpart (SImode, operands[1]);
8938    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8939
8940 ;; Since OR can be encoded with sign extended immediate, this is only
8941 ;; profitable when 7th bit is set.
8942 (define_split
8943   [(set (match_operand 0 "register_operand" "")
8944         (ior (match_operand 1 "general_operand" "")
8945              (match_operand 2 "const_int_operand" "")))
8946    (clobber (reg:CC 17))]
8947    "reload_completed
8948     && ANY_QI_REG_P (operands[0])
8949     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8950     && !(INTVAL (operands[2]) & ~255)
8951     && (INTVAL (operands[2]) & 128)
8952     && GET_MODE (operands[0]) != QImode"
8953   [(parallel [(set (strict_low_part (match_dup 0))
8954                    (ior:QI (match_dup 1)
8955                            (match_dup 2)))
8956               (clobber (reg:CC 17))])]
8957   "operands[0] = gen_lowpart (QImode, operands[0]);
8958    operands[1] = gen_lowpart (QImode, operands[1]);
8959    operands[2] = gen_lowpart (QImode, operands[2]);")
8960 \f
8961 ;; Logical XOR instructions
8962
8963 ;; %%% This used to optimize known byte-wide and operations to memory.
8964 ;; If this is considered useful, it should be done with splitters.
8965
8966 (define_expand "xordi3"
8967   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8968         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8969                 (match_operand:DI 2 "x86_64_general_operand" "")))
8970    (clobber (reg:CC 17))]
8971   "TARGET_64BIT"
8972   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8973
8974 (define_insn "*xordi_1_rex64"
8975   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8976         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8977                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8978    (clobber (reg:CC 17))]
8979   "TARGET_64BIT
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_2_rex64"
8988   [(set (reg 17)
8989         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8990                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8991                  (const_int 0)))
8992    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8993         (xor:DI (match_dup 1) (match_dup 2)))]
8994   "TARGET_64BIT
8995    && ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (XOR, DImode, operands)"
8997   "@
8998    xor{q}\t{%2, %0|%0, %2} 
8999    xor{q}\t{%2, %0|%0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "DI,DI")])
9002
9003 (define_insn "*xordi_3_rex64"
9004   [(set (reg 17)
9005         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9006                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9007                  (const_int 0)))
9008    (clobber (match_scratch:DI 0 "=r"))]
9009   "TARGET_64BIT
9010    && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, DImode, operands)"
9012   "xor{q}\t{%2, %0|%0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "DI")])
9015
9016 (define_expand "xorsi3"
9017   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9018         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9019                 (match_operand:SI 2 "general_operand" "")))
9020    (clobber (reg:CC 17))]
9021   ""
9022   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9023
9024 (define_insn "*xorsi_1"
9025   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9026         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9027                 (match_operand:SI 2 "general_operand" "ri,rm")))
9028    (clobber (reg:CC 17))]
9029   "ix86_binary_operator_ok (XOR, SImode, operands)"
9030   "xor{l}\t{%2, %0|%0, %2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "mode" "SI")])
9033
9034 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9035 ;; Add speccase for immediates
9036 (define_insn "*xorsi_1_zext"
9037   [(set (match_operand:DI 0 "register_operand" "=r")
9038         (zero_extend:DI
9039           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9040                   (match_operand:SI 2 "general_operand" "rim"))))
9041    (clobber (reg:CC 17))]
9042   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9043   "xor{l}\t{%2, %k0|%k0, %2}"
9044   [(set_attr "type" "alu")
9045    (set_attr "mode" "SI")])
9046
9047 (define_insn "*xorsi_1_zext_imm"
9048   [(set (match_operand:DI 0 "register_operand" "=r")
9049         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9050                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9051    (clobber (reg:CC 17))]
9052   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9053   "xor{l}\t{%2, %k0|%k0, %2}"
9054   [(set_attr "type" "alu")
9055    (set_attr "mode" "SI")])
9056
9057 (define_insn "*xorsi_2"
9058   [(set (reg 17)
9059         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9060                          (match_operand:SI 2 "general_operand" "rim,ri"))
9061                  (const_int 0)))
9062    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9063         (xor:SI (match_dup 1) (match_dup 2)))]
9064   "ix86_match_ccmode (insn, CCNOmode)
9065    && ix86_binary_operator_ok (XOR, SImode, operands)"
9066   "xor{l}\t{%2, %0|%0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "mode" "SI")])
9069
9070 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9071 ;; ??? Special case for immediate operand is missing - it is tricky.
9072 (define_insn "*xorsi_2_zext"
9073   [(set (reg 17)
9074         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9075                          (match_operand:SI 2 "general_operand" "rim"))
9076                  (const_int 0)))
9077    (set (match_operand:DI 0 "register_operand" "=r")
9078         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9079   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9080    && ix86_binary_operator_ok (XOR, SImode, operands)"
9081   "xor{l}\t{%2, %k0|%k0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "mode" "SI")])
9084
9085 (define_insn "*xorsi_2_zext_imm"
9086   [(set (reg 17)
9087         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9088                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9089                  (const_int 0)))
9090    (set (match_operand:DI 0 "register_operand" "=r")
9091         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9093    && ix86_binary_operator_ok (XOR, SImode, operands)"
9094   "xor{l}\t{%2, %k0|%k0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "SI")])
9097
9098 (define_insn "*xorsi_3"
9099   [(set (reg 17)
9100         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9101                          (match_operand:SI 2 "general_operand" "rim"))
9102                  (const_int 0)))
9103    (clobber (match_scratch:SI 0 "=r"))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9106   "xor{l}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "SI")])
9109
9110 (define_expand "xorhi3"
9111   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9112         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9113                 (match_operand:HI 2 "general_operand" "")))
9114    (clobber (reg:CC 17))]
9115   "TARGET_HIMODE_MATH"
9116   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9117
9118 (define_insn "*xorhi_1"
9119   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9120         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9121                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9122    (clobber (reg:CC 17))]
9123   "ix86_binary_operator_ok (XOR, HImode, operands)"
9124   "xor{w}\t{%2, %0|%0, %2}"
9125   [(set_attr "type" "alu")
9126    (set_attr "mode" "HI")])
9127
9128 (define_insn "*xorhi_2"
9129   [(set (reg 17)
9130         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9131                          (match_operand:HI 2 "general_operand" "rim,ri"))
9132                  (const_int 0)))
9133    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9134         (xor:HI (match_dup 1) (match_dup 2)))]
9135   "ix86_match_ccmode (insn, CCNOmode)
9136    && ix86_binary_operator_ok (XOR, HImode, operands)"
9137   "xor{w}\t{%2, %0|%0, %2}"
9138   [(set_attr "type" "alu")
9139    (set_attr "mode" "HI")])
9140
9141 (define_insn "*xorhi_3"
9142   [(set (reg 17)
9143         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9144                          (match_operand:HI 2 "general_operand" "rim"))
9145                  (const_int 0)))
9146    (clobber (match_scratch:HI 0 "=r"))]
9147   "ix86_match_ccmode (insn, CCNOmode)
9148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9149   "xor{w}\t{%2, %0|%0, %2}"
9150   [(set_attr "type" "alu")
9151    (set_attr "mode" "HI")])
9152
9153 (define_expand "xorqi3"
9154   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9155         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9156                 (match_operand:QI 2 "general_operand" "")))
9157    (clobber (reg:CC 17))]
9158   "TARGET_QIMODE_MATH"
9159   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9160
9161 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9162 (define_insn "*xorqi_1"
9163   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9164         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9165                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9166    (clobber (reg:CC 17))]
9167   "ix86_binary_operator_ok (XOR, QImode, operands)"
9168   "@
9169    xor{b}\t{%2, %0|%0, %2}
9170    xor{b}\t{%2, %0|%0, %2}
9171    xor{l}\t{%k2, %k0|%k0, %k2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "QI,QI,SI")])
9174
9175 (define_insn "*xorqi_1_slp"
9176   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9177         (xor:QI (match_dup 0)
9178                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9179    (clobber (reg:CC 17))]
9180   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9181    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9182   "xor{b}\t{%1, %0|%0, %1}"
9183   [(set_attr "type" "alu1")
9184    (set_attr "mode" "QI")])
9185
9186 (define_insn "xorqi_ext_0"
9187   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9188                          (const_int 8)
9189                          (const_int 8))
9190         (xor:SI 
9191           (zero_extract:SI
9192             (match_operand 1 "ext_register_operand" "0")
9193             (const_int 8)
9194             (const_int 8))
9195           (match_operand 2 "const_int_operand" "n")))
9196    (clobber (reg:CC 17))]
9197   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9198   "xor{b}\t{%2, %h0|%h0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "length_immediate" "1")
9201    (set_attr "mode" "QI")])
9202
9203 (define_insn "*xorqi_ext_1"
9204   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9205                          (const_int 8)
9206                          (const_int 8))
9207         (xor:SI 
9208           (zero_extract:SI
9209             (match_operand 1 "ext_register_operand" "0")
9210             (const_int 8)
9211             (const_int 8))
9212           (zero_extend:SI
9213             (match_operand:QI 2 "general_operand" "Qm"))))
9214    (clobber (reg:CC 17))]
9215   "!TARGET_64BIT
9216    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9217   "xor{b}\t{%2, %h0|%h0, %2}"
9218   [(set_attr "type" "alu")
9219    (set_attr "length_immediate" "0")
9220    (set_attr "mode" "QI")])
9221
9222 (define_insn "*xorqi_ext_1_rex64"
9223   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9224                          (const_int 8)
9225                          (const_int 8))
9226         (xor:SI 
9227           (zero_extract:SI
9228             (match_operand 1 "ext_register_operand" "0")
9229             (const_int 8)
9230             (const_int 8))
9231           (zero_extend:SI
9232             (match_operand 2 "ext_register_operand" "Q"))))
9233    (clobber (reg:CC 17))]
9234   "TARGET_64BIT
9235    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9236   "xor{b}\t{%2, %h0|%h0, %2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "length_immediate" "0")
9239    (set_attr "mode" "QI")])
9240
9241 (define_insn "*xorqi_ext_2"
9242   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9243                          (const_int 8)
9244                          (const_int 8))
9245         (xor:SI 
9246           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9247                            (const_int 8)
9248                            (const_int 8))
9249           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9250                            (const_int 8)
9251                            (const_int 8))))
9252    (clobber (reg:CC 17))]
9253   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9254   "xor{b}\t{%h2, %h0|%h0, %h2}"
9255   [(set_attr "type" "alu")
9256    (set_attr "length_immediate" "0")
9257    (set_attr "mode" "QI")])
9258
9259 (define_insn "*xorqi_cc_1"
9260   [(set (reg 17)
9261         (compare
9262           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9263                   (match_operand:QI 2 "general_operand" "qim,qi"))
9264           (const_int 0)))
9265    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9266         (xor:QI (match_dup 1) (match_dup 2)))]
9267   "ix86_match_ccmode (insn, CCNOmode)
9268    && ix86_binary_operator_ok (XOR, QImode, operands)"
9269   "xor{b}\t{%2, %0|%0, %2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "mode" "QI")])
9272
9273 (define_insn "*xorqi_2_slp"
9274   [(set (reg 17)
9275         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9276                          (match_operand:QI 1 "general_operand" "qim,qi"))
9277                  (const_int 0)))
9278    (set (strict_low_part (match_dup 0))
9279         (xor:QI (match_dup 0) (match_dup 1)))]
9280   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9281    && ix86_match_ccmode (insn, CCNOmode)
9282    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9283   "xor{b}\t{%1, %0|%0, %1}"
9284   [(set_attr "type" "alu1")
9285    (set_attr "mode" "QI")])
9286
9287 (define_insn "*xorqi_cc_2"
9288   [(set (reg 17)
9289         (compare
9290           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9291                   (match_operand:QI 2 "general_operand" "qim"))
9292           (const_int 0)))
9293    (clobber (match_scratch:QI 0 "=q"))]
9294   "ix86_match_ccmode (insn, CCNOmode)
9295    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9296   "xor{b}\t{%2, %0|%0, %2}"
9297   [(set_attr "type" "alu")
9298    (set_attr "mode" "QI")])
9299
9300 (define_insn "*xorqi_cc_ext_1"
9301   [(set (reg 17)
9302         (compare
9303           (xor:SI
9304             (zero_extract:SI
9305               (match_operand 1 "ext_register_operand" "0")
9306               (const_int 8)
9307               (const_int 8))
9308             (match_operand:QI 2 "general_operand" "qmn"))
9309           (const_int 0)))
9310    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9311                          (const_int 8)
9312                          (const_int 8))
9313         (xor:SI 
9314           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9315           (match_dup 2)))]
9316   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9317   "xor{b}\t{%2, %h0|%h0, %2}"
9318   [(set_attr "type" "alu")
9319    (set_attr "mode" "QI")])
9320
9321 (define_insn "*xorqi_cc_ext_1_rex64"
9322   [(set (reg 17)
9323         (compare
9324           (xor:SI
9325             (zero_extract:SI
9326               (match_operand 1 "ext_register_operand" "0")
9327               (const_int 8)
9328               (const_int 8))
9329             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9330           (const_int 0)))
9331    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9332                          (const_int 8)
9333                          (const_int 8))
9334         (xor:SI 
9335           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9336           (match_dup 2)))]
9337   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9338   "xor{b}\t{%2, %h0|%h0, %2}"
9339   [(set_attr "type" "alu")
9340    (set_attr "mode" "QI")])
9341
9342 (define_expand "xorqi_cc_ext_1"
9343   [(parallel [
9344      (set (reg:CCNO 17)
9345           (compare:CCNO
9346             (xor:SI
9347               (zero_extract:SI
9348                 (match_operand 1 "ext_register_operand" "")
9349                 (const_int 8)
9350                 (const_int 8))
9351               (match_operand:QI 2 "general_operand" ""))
9352             (const_int 0)))
9353      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9354                            (const_int 8)
9355                            (const_int 8))
9356           (xor:SI 
9357             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9358             (match_dup 2)))])]
9359   ""
9360   "")
9361
9362 (define_split
9363   [(set (match_operand 0 "register_operand" "")
9364         (xor (match_operand 1 "register_operand" "")
9365              (match_operand 2 "const_int_operand" "")))
9366    (clobber (reg:CC 17))]
9367    "reload_completed
9368     && QI_REG_P (operands[0])
9369     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9370     && !(INTVAL (operands[2]) & ~(255 << 8))
9371     && GET_MODE (operands[0]) != QImode"
9372   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9373                    (xor:SI (zero_extract:SI (match_dup 1)
9374                                             (const_int 8) (const_int 8))
9375                            (match_dup 2)))
9376               (clobber (reg:CC 17))])]
9377   "operands[0] = gen_lowpart (SImode, operands[0]);
9378    operands[1] = gen_lowpart (SImode, operands[1]);
9379    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9380
9381 ;; Since XOR can be encoded with sign extended immediate, this is only
9382 ;; profitable when 7th bit is set.
9383 (define_split
9384   [(set (match_operand 0 "register_operand" "")
9385         (xor (match_operand 1 "general_operand" "")
9386              (match_operand 2 "const_int_operand" "")))
9387    (clobber (reg:CC 17))]
9388    "reload_completed
9389     && ANY_QI_REG_P (operands[0])
9390     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9391     && !(INTVAL (operands[2]) & ~255)
9392     && (INTVAL (operands[2]) & 128)
9393     && GET_MODE (operands[0]) != QImode"
9394   [(parallel [(set (strict_low_part (match_dup 0))
9395                    (xor:QI (match_dup 1)
9396                            (match_dup 2)))
9397               (clobber (reg:CC 17))])]
9398   "operands[0] = gen_lowpart (QImode, operands[0]);
9399    operands[1] = gen_lowpart (QImode, operands[1]);
9400    operands[2] = gen_lowpart (QImode, operands[2]);")
9401 \f
9402 ;; Negation instructions
9403
9404 (define_expand "negdi2"
9405   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9406                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9407               (clobber (reg:CC 17))])]
9408   ""
9409   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9410
9411 (define_insn "*negdi2_1"
9412   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9413         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9414    (clobber (reg:CC 17))]
9415   "!TARGET_64BIT
9416    && ix86_unary_operator_ok (NEG, DImode, operands)"
9417   "#")
9418
9419 (define_split
9420   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9421         (neg:DI (match_operand:DI 1 "general_operand" "")))
9422    (clobber (reg:CC 17))]
9423   "!TARGET_64BIT && reload_completed"
9424   [(parallel
9425     [(set (reg:CCZ 17)
9426           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9427      (set (match_dup 0) (neg:SI (match_dup 2)))])
9428    (parallel
9429     [(set (match_dup 1)
9430           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9431                             (match_dup 3))
9432                    (const_int 0)))
9433      (clobber (reg:CC 17))])
9434    (parallel
9435     [(set (match_dup 1)
9436           (neg:SI (match_dup 1)))
9437      (clobber (reg:CC 17))])]
9438   "split_di (operands+1, 1, operands+2, operands+3);
9439    split_di (operands+0, 1, operands+0, operands+1);")
9440
9441 (define_insn "*negdi2_1_rex64"
9442   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9443         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9444    (clobber (reg:CC 17))]
9445   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9446   "neg{q}\t%0"
9447   [(set_attr "type" "negnot")
9448    (set_attr "mode" "DI")])
9449
9450 ;; The problem with neg is that it does not perform (compare x 0),
9451 ;; it really performs (compare 0 x), which leaves us with the zero
9452 ;; flag being the only useful item.
9453
9454 (define_insn "*negdi2_cmpz_rex64"
9455   [(set (reg:CCZ 17)
9456         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9457                      (const_int 0)))
9458    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9459         (neg:DI (match_dup 1)))]
9460   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9461   "neg{q}\t%0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "DI")])
9464
9465
9466 (define_expand "negsi2"
9467   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9468                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9469               (clobber (reg:CC 17))])]
9470   ""
9471   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9472
9473 (define_insn "*negsi2_1"
9474   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9475         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9476    (clobber (reg:CC 17))]
9477   "ix86_unary_operator_ok (NEG, SImode, operands)"
9478   "neg{l}\t%0"
9479   [(set_attr "type" "negnot")
9480    (set_attr "mode" "SI")])
9481
9482 ;; Combine is quite creative about this pattern.
9483 (define_insn "*negsi2_1_zext"
9484   [(set (match_operand:DI 0 "register_operand" "=r")
9485         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9486                                         (const_int 32)))
9487                      (const_int 32)))
9488    (clobber (reg:CC 17))]
9489   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490   "neg{l}\t%k0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "SI")])
9493
9494 ;; The problem with neg is that it does not perform (compare x 0),
9495 ;; it really performs (compare 0 x), which leaves us with the zero
9496 ;; flag being the only useful item.
9497
9498 (define_insn "*negsi2_cmpz"
9499   [(set (reg:CCZ 17)
9500         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9501                      (const_int 0)))
9502    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9503         (neg:SI (match_dup 1)))]
9504   "ix86_unary_operator_ok (NEG, SImode, operands)"
9505   "neg{l}\t%0"
9506   [(set_attr "type" "negnot")
9507    (set_attr "mode" "SI")])
9508
9509 (define_insn "*negsi2_cmpz_zext"
9510   [(set (reg:CCZ 17)
9511         (compare:CCZ (lshiftrt:DI
9512                        (neg:DI (ashift:DI
9513                                  (match_operand:DI 1 "register_operand" "0")
9514                                  (const_int 32)))
9515                        (const_int 32))
9516                      (const_int 0)))
9517    (set (match_operand:DI 0 "register_operand" "=r")
9518         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9519                                         (const_int 32)))
9520                      (const_int 32)))]
9521   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9522   "neg{l}\t%k0"
9523   [(set_attr "type" "negnot")
9524    (set_attr "mode" "SI")])
9525
9526 (define_expand "neghi2"
9527   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9528                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9529               (clobber (reg:CC 17))])]
9530   "TARGET_HIMODE_MATH"
9531   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9532
9533 (define_insn "*neghi2_1"
9534   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9535         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9536    (clobber (reg:CC 17))]
9537   "ix86_unary_operator_ok (NEG, HImode, operands)"
9538   "neg{w}\t%0"
9539   [(set_attr "type" "negnot")
9540    (set_attr "mode" "HI")])
9541
9542 (define_insn "*neghi2_cmpz"
9543   [(set (reg:CCZ 17)
9544         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9545                      (const_int 0)))
9546    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9547         (neg:HI (match_dup 1)))]
9548   "ix86_unary_operator_ok (NEG, HImode, operands)"
9549   "neg{w}\t%0"
9550   [(set_attr "type" "negnot")
9551    (set_attr "mode" "HI")])
9552
9553 (define_expand "negqi2"
9554   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9555                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9556               (clobber (reg:CC 17))])]
9557   "TARGET_QIMODE_MATH"
9558   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9559
9560 (define_insn "*negqi2_1"
9561   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9562         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9563    (clobber (reg:CC 17))]
9564   "ix86_unary_operator_ok (NEG, QImode, operands)"
9565   "neg{b}\t%0"
9566   [(set_attr "type" "negnot")
9567    (set_attr "mode" "QI")])
9568
9569 (define_insn "*negqi2_cmpz"
9570   [(set (reg:CCZ 17)
9571         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9572                      (const_int 0)))
9573    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9574         (neg:QI (match_dup 1)))]
9575   "ix86_unary_operator_ok (NEG, QImode, operands)"
9576   "neg{b}\t%0"
9577   [(set_attr "type" "negnot")
9578    (set_attr "mode" "QI")])
9579
9580 ;; Changing of sign for FP values is doable using integer unit too.
9581
9582 (define_expand "negsf2"
9583   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9584                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9585               (clobber (reg:CC 17))])]
9586   "TARGET_80387"
9587   "if (TARGET_SSE)
9588      {
9589        /* In case operand is in memory,  we will not use SSE.  */
9590        if (memory_operand (operands[0], VOIDmode)
9591            && rtx_equal_p (operands[0], operands[1]))
9592          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9593        else
9594         {
9595           /* Using SSE is tricky, since we need bitwise negation of -0
9596              in register.  */
9597           rtx reg = gen_reg_rtx (SFmode);
9598           rtx dest = operands[0];
9599           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9600
9601           operands[1] = force_reg (SFmode, operands[1]);
9602           operands[0] = force_reg (SFmode, operands[0]);
9603           reg = force_reg (V4SFmode,
9604                            gen_rtx_CONST_VECTOR (V4SFmode,
9605                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9606                                         CONST0_RTX (SFmode),
9607                                         CONST0_RTX (SFmode))));
9608           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9609           if (dest != operands[0])
9610             emit_move_insn (dest, operands[0]);
9611         }
9612        DONE;
9613      }
9614    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9615
9616 (define_insn "negsf2_memory"
9617   [(set (match_operand:SF 0 "memory_operand" "=m")
9618         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9619    (clobber (reg:CC 17))]
9620   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9621   "#")
9622
9623 (define_insn "negsf2_ifs"
9624   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9625         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9626    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9627    (clobber (reg:CC 17))]
9628   "TARGET_SSE
9629    && (reload_in_progress || reload_completed
9630        || (register_operand (operands[0], VOIDmode)
9631            && register_operand (operands[1], VOIDmode)))"
9632   "#")
9633
9634 (define_split
9635   [(set (match_operand:SF 0 "memory_operand" "")
9636         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9637    (use (match_operand:SF 2 "" ""))
9638    (clobber (reg:CC 17))]
9639   ""
9640   [(parallel [(set (match_dup 0)
9641                    (neg:SF (match_dup 1)))
9642               (clobber (reg:CC 17))])])
9643
9644 (define_split
9645   [(set (match_operand:SF 0 "register_operand" "")
9646         (neg:SF (match_operand:SF 1 "register_operand" "")))
9647    (use (match_operand:V4SF 2 "" ""))
9648    (clobber (reg:CC 17))]
9649   "reload_completed && !SSE_REG_P (operands[0])"
9650   [(parallel [(set (match_dup 0)
9651                    (neg:SF (match_dup 1)))
9652               (clobber (reg:CC 17))])])
9653
9654 (define_split
9655   [(set (match_operand:SF 0 "register_operand" "")
9656         (neg:SF (match_operand:SF 1 "register_operand" "")))
9657    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9658    (clobber (reg:CC 17))]
9659   "reload_completed && SSE_REG_P (operands[0])"
9660   [(set (subreg:TI (match_dup 0) 0)
9661         (xor:TI (match_dup 1)
9662                 (match_dup 2)))]
9663 {
9664   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9665   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9666   if (operands_match_p (operands[0], operands[2]))
9667     {
9668       rtx tmp;
9669       tmp = operands[1];
9670       operands[1] = operands[2];
9671       operands[2] = tmp;
9672     }
9673 })
9674
9675
9676 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9677 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9678 ;; to itself.
9679 (define_insn "*negsf2_if"
9680   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9681         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9682    (clobber (reg:CC 17))]
9683   "TARGET_80387 && !TARGET_SSE
9684    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9685   "#")
9686
9687 (define_split
9688   [(set (match_operand:SF 0 "fp_register_operand" "")
9689         (neg:SF (match_operand:SF 1 "register_operand" "")))
9690    (clobber (reg:CC 17))]
9691   "TARGET_80387 && reload_completed"
9692   [(set (match_dup 0)
9693         (neg:SF (match_dup 1)))]
9694   "")
9695
9696 (define_split
9697   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9698         (neg:SF (match_operand:SF 1 "register_operand" "")))
9699    (clobber (reg:CC 17))]
9700   "TARGET_80387 && reload_completed"
9701   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9702               (clobber (reg:CC 17))])]
9703   "operands[1] = gen_int_mode (0x80000000, SImode);
9704    operands[0] = gen_lowpart (SImode, operands[0]);")
9705
9706 (define_split
9707   [(set (match_operand 0 "memory_operand" "")
9708         (neg (match_operand 1 "memory_operand" "")))
9709    (clobber (reg:CC 17))]
9710   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9711   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9712               (clobber (reg:CC 17))])]
9713 {
9714   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9715
9716   if (GET_MODE (operands[1]) == XFmode)
9717     size = 10;
9718   operands[0] = adjust_address (operands[0], QImode, size - 1);
9719   operands[1] = gen_int_mode (0x80, QImode);
9720 })
9721
9722 (define_expand "negdf2"
9723   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9724                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9725               (clobber (reg:CC 17))])]
9726   "TARGET_80387"
9727   "if (TARGET_SSE2)
9728      {
9729        /* In case operand is in memory,  we will not use SSE.  */
9730        if (memory_operand (operands[0], VOIDmode)
9731            && rtx_equal_p (operands[0], operands[1]))
9732          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9733        else
9734         {
9735           /* Using SSE is tricky, since we need bitwise negation of -0
9736              in register.  */
9737           rtx reg;
9738 #if HOST_BITS_PER_WIDE_INT >= 64
9739           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9740 #else
9741           rtx imm = immed_double_const (0, 0x80000000, DImode);
9742 #endif
9743           rtx dest = operands[0];
9744
9745           operands[1] = force_reg (DFmode, operands[1]);
9746           operands[0] = force_reg (DFmode, operands[0]);
9747           imm = gen_lowpart (DFmode, imm);
9748           reg = force_reg (V2DFmode,
9749                            gen_rtx_CONST_VECTOR (V2DFmode,
9750                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9751           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9752           if (dest != operands[0])
9753             emit_move_insn (dest, operands[0]);
9754         }
9755        DONE;
9756      }
9757    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9758
9759 (define_insn "negdf2_memory"
9760   [(set (match_operand:DF 0 "memory_operand" "=m")
9761         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9762    (clobber (reg:CC 17))]
9763   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9764   "#")
9765
9766 (define_insn "negdf2_ifs"
9767   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9768         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9769    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9770    (clobber (reg:CC 17))]
9771   "!TARGET_64BIT && TARGET_SSE2
9772    && (reload_in_progress || reload_completed
9773        || (register_operand (operands[0], VOIDmode)
9774            && register_operand (operands[1], VOIDmode)))"
9775   "#")
9776
9777 (define_insn "*negdf2_ifs_rex64"
9778   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9779         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9780    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9781    (clobber (reg:CC 17))]
9782   "TARGET_64BIT && TARGET_SSE2
9783    && (reload_in_progress || reload_completed
9784        || (register_operand (operands[0], VOIDmode)
9785            && register_operand (operands[1], VOIDmode)))"
9786   "#")
9787
9788 (define_split
9789   [(set (match_operand:DF 0 "memory_operand" "")
9790         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9791    (use (match_operand:V2DF 2 "" ""))
9792    (clobber (reg:CC 17))]
9793   ""
9794   [(parallel [(set (match_dup 0)
9795                    (neg:DF (match_dup 1)))
9796               (clobber (reg:CC 17))])])
9797
9798 (define_split
9799   [(set (match_operand:DF 0 "register_operand" "")
9800         (neg:DF (match_operand:DF 1 "register_operand" "")))
9801    (use (match_operand:V2DF 2 "" ""))
9802    (clobber (reg:CC 17))]
9803   "reload_completed && !SSE_REG_P (operands[0])
9804    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9805   [(parallel [(set (match_dup 0)
9806                    (neg:DF (match_dup 1)))
9807               (clobber (reg:CC 17))])])
9808
9809 (define_split
9810   [(set (match_operand:DF 0 "register_operand" "")
9811         (neg:DF (match_operand:DF 1 "register_operand" "")))
9812    (use (match_operand:V2DF 2 "" ""))
9813    (clobber (reg:CC 17))]
9814   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9815   [(parallel [(set (match_dup 0)
9816                    (xor:DI (match_dup 1) (match_dup 2)))
9817               (clobber (reg:CC 17))])]
9818    "operands[0] = gen_lowpart (DImode, operands[0]);
9819     operands[1] = gen_lowpart (DImode, operands[1]);
9820     operands[2] = gen_lowpart (DImode, operands[2]);")
9821
9822 (define_split
9823   [(set (match_operand:DF 0 "register_operand" "")
9824         (neg:DF (match_operand:DF 1 "register_operand" "")))
9825    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9826    (clobber (reg:CC 17))]
9827   "reload_completed && SSE_REG_P (operands[0])"
9828   [(set (subreg:TI (match_dup 0) 0)
9829         (xor:TI (match_dup 1)
9830                 (match_dup 2)))]
9831 {
9832   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9833   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9834   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9835   /* Avoid possible reformatting on the operands.  */
9836   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9837     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9838   if (operands_match_p (operands[0], operands[2]))
9839     {
9840       rtx tmp;
9841       tmp = operands[1];
9842       operands[1] = operands[2];
9843       operands[2] = tmp;
9844     }
9845 })
9846
9847 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9848 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9849 ;; to itself.
9850 (define_insn "*negdf2_if"
9851   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9852         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9853    (clobber (reg:CC 17))]
9854   "!TARGET_64BIT && TARGET_80387
9855    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9856   "#")
9857
9858 ;; FIXME: We should to allow integer registers here.  Problem is that
9859 ;; we need another scratch register to get constant from.
9860 ;; Forcing constant to mem if no register available in peep2 should be
9861 ;; safe even for PIC mode, because of RIP relative addressing.
9862 (define_insn "*negdf2_if_rex64"
9863   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9864         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9865    (clobber (reg:CC 17))]
9866   "TARGET_64BIT && TARGET_80387
9867    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9868   "#")
9869
9870 (define_split
9871   [(set (match_operand:DF 0 "fp_register_operand" "")
9872         (neg:DF (match_operand:DF 1 "register_operand" "")))
9873    (clobber (reg:CC 17))]
9874   "TARGET_80387 && reload_completed"
9875   [(set (match_dup 0)
9876         (neg:DF (match_dup 1)))]
9877   "")
9878
9879 (define_split
9880   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9881         (neg:DF (match_operand:DF 1 "register_operand" "")))
9882    (clobber (reg:CC 17))]
9883   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9884   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9885               (clobber (reg:CC 17))])]
9886   "operands[4] = gen_int_mode (0x80000000, SImode);
9887    split_di (operands+0, 1, operands+2, operands+3);")
9888
9889 (define_expand "negxf2"
9890   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9891                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9892               (clobber (reg:CC 17))])]
9893   "TARGET_80387"
9894   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9895
9896 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9897 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9898 ;; to itself.
9899 (define_insn "*negxf2_if"
9900   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9901         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9902    (clobber (reg:CC 17))]
9903   "TARGET_80387
9904    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9905   "#")
9906
9907 (define_split
9908   [(set (match_operand:XF 0 "fp_register_operand" "")
9909         (neg:XF (match_operand:XF 1 "register_operand" "")))
9910    (clobber (reg:CC 17))]
9911   "TARGET_80387 && reload_completed"
9912   [(set (match_dup 0)
9913         (neg:XF (match_dup 1)))]
9914   "")
9915
9916 (define_split
9917   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9918         (neg:XF (match_operand:XF 1 "register_operand" "")))
9919    (clobber (reg:CC 17))]
9920   "TARGET_80387 && reload_completed"
9921   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9922               (clobber (reg:CC 17))])]
9923   "operands[1] = GEN_INT (0x8000);
9924    operands[0] = gen_rtx_REG (SImode,
9925                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9926
9927 ;; Conditionalize these after reload. If they matches before reload, we 
9928 ;; lose the clobber and ability to use integer instructions.
9929
9930 (define_insn "*negsf2_1"
9931   [(set (match_operand:SF 0 "register_operand" "=f")
9932         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9933   "TARGET_80387 && reload_completed"
9934   "fchs"
9935   [(set_attr "type" "fsgn")
9936    (set_attr "mode" "SF")
9937    (set_attr "ppro_uops" "few")])
9938
9939 (define_insn "*negdf2_1"
9940   [(set (match_operand:DF 0 "register_operand" "=f")
9941         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9942   "TARGET_80387 && reload_completed"
9943   "fchs"
9944   [(set_attr "type" "fsgn")
9945    (set_attr "mode" "DF")
9946    (set_attr "ppro_uops" "few")])
9947
9948 (define_insn "*negextendsfdf2"
9949   [(set (match_operand:DF 0 "register_operand" "=f")
9950         (neg:DF (float_extend:DF
9951                   (match_operand:SF 1 "register_operand" "0"))))]
9952   "TARGET_80387"
9953   "fchs"
9954   [(set_attr "type" "fsgn")
9955    (set_attr "mode" "DF")
9956    (set_attr "ppro_uops" "few")])
9957
9958 (define_insn "*negxf2_1"
9959   [(set (match_operand:XF 0 "register_operand" "=f")
9960         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9961   "TARGET_80387 && reload_completed"
9962   "fchs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")
9965    (set_attr "ppro_uops" "few")])
9966
9967 (define_insn "*negextenddfxf2"
9968   [(set (match_operand:XF 0 "register_operand" "=f")
9969         (neg:XF (float_extend:XF
9970                   (match_operand:DF 1 "register_operand" "0"))))]
9971   "TARGET_80387"
9972   "fchs"
9973   [(set_attr "type" "fsgn")
9974    (set_attr "mode" "XF")
9975    (set_attr "ppro_uops" "few")])
9976
9977 (define_insn "*negextendsfxf2"
9978   [(set (match_operand:XF 0 "register_operand" "=f")
9979         (neg:XF (float_extend:XF
9980                   (match_operand:SF 1 "register_operand" "0"))))]
9981   "TARGET_80387"
9982   "fchs"
9983   [(set_attr "type" "fsgn")
9984    (set_attr "mode" "XF")
9985    (set_attr "ppro_uops" "few")])
9986 \f
9987 ;; Absolute value instructions
9988
9989 (define_expand "abssf2"
9990   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9991                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9992               (clobber (reg:CC 17))])]
9993   "TARGET_80387"
9994   "if (TARGET_SSE)
9995      {
9996        /* In case operand is in memory,  we will not use SSE.  */
9997        if (memory_operand (operands[0], VOIDmode)
9998            && rtx_equal_p (operands[0], operands[1]))
9999          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10000        else
10001         {
10002           /* Using SSE is tricky, since we need bitwise negation of -0
10003              in register.  */
10004           rtx reg = gen_reg_rtx (V4SFmode);
10005           rtx dest = operands[0];
10006           rtx imm;
10007
10008           operands[1] = force_reg (SFmode, operands[1]);
10009           operands[0] = force_reg (SFmode, operands[0]);
10010           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10011           reg = force_reg (V4SFmode,
10012                            gen_rtx_CONST_VECTOR (V4SFmode,
10013                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10014                                       CONST0_RTX (SFmode),
10015                                       CONST0_RTX (SFmode))));
10016           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10017           if (dest != operands[0])
10018             emit_move_insn (dest, operands[0]);
10019         }
10020        DONE;
10021      }
10022    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10023
10024 (define_insn "abssf2_memory"
10025   [(set (match_operand:SF 0 "memory_operand" "=m")
10026         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10027    (clobber (reg:CC 17))]
10028   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10029   "#")
10030
10031 (define_insn "abssf2_ifs"
10032   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10033         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10034    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10035    (clobber (reg:CC 17))]
10036   "TARGET_SSE
10037    && (reload_in_progress || reload_completed
10038        || (register_operand (operands[0], VOIDmode)
10039             && register_operand (operands[1], VOIDmode)))"
10040   "#")
10041
10042 (define_split
10043   [(set (match_operand:SF 0 "memory_operand" "")
10044         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10045    (use (match_operand:V4SF 2 "" ""))
10046    (clobber (reg:CC 17))]
10047   ""
10048   [(parallel [(set (match_dup 0)
10049                    (abs:SF (match_dup 1)))
10050               (clobber (reg:CC 17))])])
10051
10052 (define_split
10053   [(set (match_operand:SF 0 "register_operand" "")
10054         (abs:SF (match_operand:SF 1 "register_operand" "")))
10055    (use (match_operand:V4SF 2 "" ""))
10056    (clobber (reg:CC 17))]
10057   "reload_completed && !SSE_REG_P (operands[0])"
10058   [(parallel [(set (match_dup 0)
10059                    (abs:SF (match_dup 1)))
10060               (clobber (reg:CC 17))])])
10061
10062 (define_split
10063   [(set (match_operand:SF 0 "register_operand" "")
10064         (abs:SF (match_operand:SF 1 "register_operand" "")))
10065    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10066    (clobber (reg:CC 17))]
10067   "reload_completed && SSE_REG_P (operands[0])"
10068   [(set (subreg:TI (match_dup 0) 0)
10069         (and:TI (match_dup 1)
10070                 (match_dup 2)))]
10071 {
10072   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10073   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10074   if (operands_match_p (operands[0], operands[2]))
10075     {
10076       rtx tmp;
10077       tmp = operands[1];
10078       operands[1] = operands[2];
10079       operands[2] = tmp;
10080     }
10081 })
10082
10083 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10084 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10085 ;; to itself.
10086 (define_insn "*abssf2_if"
10087   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10088         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10089    (clobber (reg:CC 17))]
10090   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10091   "#")
10092
10093 (define_split
10094   [(set (match_operand:SF 0 "fp_register_operand" "")
10095         (abs:SF (match_operand:SF 1 "register_operand" "")))
10096    (clobber (reg:CC 17))]
10097   "TARGET_80387 && reload_completed"
10098   [(set (match_dup 0)
10099         (abs:SF (match_dup 1)))]
10100   "")
10101
10102 (define_split
10103   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10104         (abs:SF (match_operand:SF 1 "register_operand" "")))
10105    (clobber (reg:CC 17))]
10106   "TARGET_80387 && reload_completed"
10107   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10108               (clobber (reg:CC 17))])]
10109   "operands[1] = gen_int_mode (~0x80000000, SImode);
10110    operands[0] = gen_lowpart (SImode, operands[0]);")
10111
10112 (define_split
10113   [(set (match_operand 0 "memory_operand" "")
10114         (abs (match_operand 1 "memory_operand" "")))
10115    (clobber (reg:CC 17))]
10116   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10117   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10118               (clobber (reg:CC 17))])]
10119 {
10120   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10121
10122   if (GET_MODE (operands[1]) == XFmode)
10123     size = 10;
10124   operands[0] = adjust_address (operands[0], QImode, size - 1);
10125   operands[1] = gen_int_mode (~0x80, QImode);
10126 })
10127
10128 (define_expand "absdf2"
10129   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10130                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10131               (clobber (reg:CC 17))])]
10132   "TARGET_80387"
10133   "if (TARGET_SSE2)
10134      {
10135        /* In case operand is in memory,  we will not use SSE.  */
10136        if (memory_operand (operands[0], VOIDmode)
10137            && rtx_equal_p (operands[0], operands[1]))
10138          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10139        else
10140         {
10141           /* Using SSE is tricky, since we need bitwise negation of -0
10142              in register.  */
10143           rtx reg = gen_reg_rtx (V2DFmode);
10144 #if HOST_BITS_PER_WIDE_INT >= 64
10145           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10146 #else
10147           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10148 #endif
10149           rtx dest = operands[0];
10150
10151           operands[1] = force_reg (DFmode, operands[1]);
10152           operands[0] = force_reg (DFmode, operands[0]);
10153
10154           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10155           imm = gen_lowpart (DFmode, imm);
10156           reg = force_reg (V2DFmode,
10157                            gen_rtx_CONST_VECTOR (V2DFmode,
10158                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10159           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10160           if (dest != operands[0])
10161             emit_move_insn (dest, operands[0]);
10162         }
10163        DONE;
10164      }
10165    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10166
10167 (define_insn "absdf2_memory"
10168   [(set (match_operand:DF 0 "memory_operand" "=m")
10169         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10170    (clobber (reg:CC 17))]
10171   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10172   "#")
10173
10174 (define_insn "absdf2_ifs"
10175   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10176         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10177    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10178    (clobber (reg:CC 17))]
10179   "!TARGET_64BIT && TARGET_SSE2
10180    && (reload_in_progress || reload_completed
10181        || (register_operand (operands[0], VOIDmode)
10182            && register_operand (operands[1], VOIDmode)))"
10183   "#")
10184
10185 (define_insn "*absdf2_ifs_rex64"
10186   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10187         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10188    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10189    (clobber (reg:CC 17))]
10190   "TARGET_64BIT && TARGET_SSE2
10191    && (reload_in_progress || reload_completed
10192        || (register_operand (operands[0], VOIDmode)
10193            && register_operand (operands[1], VOIDmode)))"
10194   "#")
10195
10196 (define_split
10197   [(set (match_operand:DF 0 "memory_operand" "")
10198         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10199    (use (match_operand:V2DF 2 "" ""))
10200    (clobber (reg:CC 17))]
10201   ""
10202   [(parallel [(set (match_dup 0)
10203                    (abs:DF (match_dup 1)))
10204               (clobber (reg:CC 17))])])
10205
10206 (define_split
10207   [(set (match_operand:DF 0 "register_operand" "")
10208         (abs:DF (match_operand:DF 1 "register_operand" "")))
10209    (use (match_operand:V2DF 2 "" ""))
10210    (clobber (reg:CC 17))]
10211   "reload_completed && !SSE_REG_P (operands[0])"
10212   [(parallel [(set (match_dup 0)
10213                    (abs:DF (match_dup 1)))
10214               (clobber (reg:CC 17))])])
10215
10216 (define_split
10217   [(set (match_operand:DF 0 "register_operand" "")
10218         (abs:DF (match_operand:DF 1 "register_operand" "")))
10219    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10220    (clobber (reg:CC 17))]
10221   "reload_completed && SSE_REG_P (operands[0])"
10222   [(set (subreg:TI (match_dup 0) 0)
10223         (and:TI (match_dup 1)
10224                 (match_dup 2)))]
10225 {
10226   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10227   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10228   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10229   /* Avoid possible reformatting on the operands.  */
10230   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10231     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10232   if (operands_match_p (operands[0], operands[2]))
10233     {
10234       rtx tmp;
10235       tmp = operands[1];
10236       operands[1] = operands[2];
10237       operands[2] = tmp;
10238     }
10239 })
10240
10241
10242 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10243 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10244 ;; to itself.
10245 (define_insn "*absdf2_if"
10246   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10247         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10248    (clobber (reg:CC 17))]
10249   "!TARGET_64BIT && TARGET_80387
10250    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10251   "#")
10252
10253 ;; FIXME: We should to allow integer registers here.  Problem is that
10254 ;; we need another scratch register to get constant from.
10255 ;; Forcing constant to mem if no register available in peep2 should be
10256 ;; safe even for PIC mode, because of RIP relative addressing.
10257 (define_insn "*absdf2_if_rex64"
10258   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10259         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10260    (clobber (reg:CC 17))]
10261   "TARGET_64BIT && TARGET_80387
10262    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10263   "#")
10264
10265 (define_split
10266   [(set (match_operand:DF 0 "fp_register_operand" "")
10267         (abs:DF (match_operand:DF 1 "register_operand" "")))
10268    (clobber (reg:CC 17))]
10269   "TARGET_80387 && reload_completed"
10270   [(set (match_dup 0)
10271         (abs:DF (match_dup 1)))]
10272   "")
10273
10274 (define_split
10275   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10276         (abs:DF (match_operand:DF 1 "register_operand" "")))
10277    (clobber (reg:CC 17))]
10278   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10279   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10280               (clobber (reg:CC 17))])]
10281   "operands[4] = gen_int_mode (~0x80000000, SImode);
10282    split_di (operands+0, 1, operands+2, operands+3);")
10283
10284 (define_expand "absxf2"
10285   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10286                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10287               (clobber (reg:CC 17))])]
10288   "TARGET_80387"
10289   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10290
10291 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10292 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10293 ;; to itself.
10294 (define_insn "*absxf2_if"
10295   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10296         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10297    (clobber (reg:CC 17))]
10298   "TARGET_80387
10299    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10300   "#")
10301
10302 (define_split
10303   [(set (match_operand:XF 0 "fp_register_operand" "")
10304         (abs:XF (match_operand:XF 1 "register_operand" "")))
10305    (clobber (reg:CC 17))]
10306   "TARGET_80387 && reload_completed"
10307   [(set (match_dup 0)
10308         (abs:XF (match_dup 1)))]
10309   "")
10310
10311 (define_split
10312   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10313         (abs:XF (match_operand:XF 1 "register_operand" "")))
10314    (clobber (reg:CC 17))]
10315   "TARGET_80387 && reload_completed"
10316   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10317               (clobber (reg:CC 17))])]
10318   "operands[1] = GEN_INT (~0x8000);
10319    operands[0] = gen_rtx_REG (SImode,
10320                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10321
10322 (define_insn "*abssf2_1"
10323   [(set (match_operand:SF 0 "register_operand" "=f")
10324         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10325   "TARGET_80387 && reload_completed"
10326   "fabs"
10327   [(set_attr "type" "fsgn")
10328    (set_attr "mode" "SF")])
10329
10330 (define_insn "*absdf2_1"
10331   [(set (match_operand:DF 0 "register_operand" "=f")
10332         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10333   "TARGET_80387 && reload_completed"
10334   "fabs"
10335   [(set_attr "type" "fsgn")
10336    (set_attr "mode" "DF")])
10337
10338 (define_insn "*absextendsfdf2"
10339   [(set (match_operand:DF 0 "register_operand" "=f")
10340         (abs:DF (float_extend:DF
10341                   (match_operand:SF 1 "register_operand" "0"))))]
10342   "TARGET_80387"
10343   "fabs"
10344   [(set_attr "type" "fsgn")
10345    (set_attr "mode" "DF")])
10346
10347 (define_insn "*absxf2_1"
10348   [(set (match_operand:XF 0 "register_operand" "=f")
10349         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10350   "TARGET_80387 && reload_completed"
10351   "fabs"
10352   [(set_attr "type" "fsgn")
10353    (set_attr "mode" "DF")])
10354
10355 (define_insn "*absextenddfxf2"
10356   [(set (match_operand:XF 0 "register_operand" "=f")
10357         (abs:XF (float_extend:XF
10358           (match_operand:DF 1 "register_operand" "0"))))]
10359   "TARGET_80387"
10360   "fabs"
10361   [(set_attr "type" "fsgn")
10362    (set_attr "mode" "XF")])
10363
10364 (define_insn "*absextendsfxf2"
10365   [(set (match_operand:XF 0 "register_operand" "=f")
10366         (abs:XF (float_extend:XF
10367           (match_operand:SF 1 "register_operand" "0"))))]
10368   "TARGET_80387"
10369   "fabs"
10370   [(set_attr "type" "fsgn")
10371    (set_attr "mode" "XF")])
10372 \f
10373 ;; One complement instructions
10374
10375 (define_expand "one_cmpldi2"
10376   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10377         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10378   "TARGET_64BIT"
10379   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10380
10381 (define_insn "*one_cmpldi2_1_rex64"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10383         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10384   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10385   "not{q}\t%0"
10386   [(set_attr "type" "negnot")
10387    (set_attr "mode" "DI")])
10388
10389 (define_insn "*one_cmpldi2_2_rex64"
10390   [(set (reg 17)
10391         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10392                  (const_int 0)))
10393    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10394         (not:DI (match_dup 1)))]
10395   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10396    && ix86_unary_operator_ok (NOT, DImode, operands)"
10397   "#"
10398   [(set_attr "type" "alu1")
10399    (set_attr "mode" "DI")])
10400
10401 (define_split
10402   [(set (reg 17)
10403         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10404                  (const_int 0)))
10405    (set (match_operand:DI 0 "nonimmediate_operand" "")
10406         (not:DI (match_dup 1)))]
10407   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10408   [(parallel [(set (reg:CCNO 17)
10409                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10410                                  (const_int 0)))
10411               (set (match_dup 0)
10412                    (xor:DI (match_dup 1) (const_int -1)))])]
10413   "")
10414
10415 (define_expand "one_cmplsi2"
10416   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10417         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10418   ""
10419   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10420
10421 (define_insn "*one_cmplsi2_1"
10422   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10423         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10424   "ix86_unary_operator_ok (NOT, SImode, operands)"
10425   "not{l}\t%0"
10426   [(set_attr "type" "negnot")
10427    (set_attr "mode" "SI")])
10428
10429 ;; ??? Currently never generated - xor is used instead.
10430 (define_insn "*one_cmplsi2_1_zext"
10431   [(set (match_operand:DI 0 "register_operand" "=r")
10432         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10433   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10434   "not{l}\t%k0"
10435   [(set_attr "type" "negnot")
10436    (set_attr "mode" "SI")])
10437
10438 (define_insn "*one_cmplsi2_2"
10439   [(set (reg 17)
10440         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10441                  (const_int 0)))
10442    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10443         (not:SI (match_dup 1)))]
10444   "ix86_match_ccmode (insn, CCNOmode)
10445    && ix86_unary_operator_ok (NOT, SImode, operands)"
10446   "#"
10447   [(set_attr "type" "alu1")
10448    (set_attr "mode" "SI")])
10449
10450 (define_split
10451   [(set (reg 17)
10452         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10453                  (const_int 0)))
10454    (set (match_operand:SI 0 "nonimmediate_operand" "")
10455         (not:SI (match_dup 1)))]
10456   "ix86_match_ccmode (insn, CCNOmode)"
10457   [(parallel [(set (reg:CCNO 17)
10458                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10459                                  (const_int 0)))
10460               (set (match_dup 0)
10461                    (xor:SI (match_dup 1) (const_int -1)))])]
10462   "")
10463
10464 ;; ??? Currently never generated - xor is used instead.
10465 (define_insn "*one_cmplsi2_2_zext"
10466   [(set (reg 17)
10467         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10468                  (const_int 0)))
10469    (set (match_operand:DI 0 "register_operand" "=r")
10470         (zero_extend:DI (not:SI (match_dup 1))))]
10471   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10472    && ix86_unary_operator_ok (NOT, SImode, operands)"
10473   "#"
10474   [(set_attr "type" "alu1")
10475    (set_attr "mode" "SI")])
10476
10477 (define_split
10478   [(set (reg 17)
10479         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10480                  (const_int 0)))
10481    (set (match_operand:DI 0 "register_operand" "")
10482         (zero_extend:DI (not:SI (match_dup 1))))]
10483   "ix86_match_ccmode (insn, CCNOmode)"
10484   [(parallel [(set (reg:CCNO 17)
10485                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10486                                  (const_int 0)))
10487               (set (match_dup 0)
10488                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10489   "")
10490
10491 (define_expand "one_cmplhi2"
10492   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10493         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10494   "TARGET_HIMODE_MATH"
10495   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10496
10497 (define_insn "*one_cmplhi2_1"
10498   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10499         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10500   "ix86_unary_operator_ok (NOT, HImode, operands)"
10501   "not{w}\t%0"
10502   [(set_attr "type" "negnot")
10503    (set_attr "mode" "HI")])
10504
10505 (define_insn "*one_cmplhi2_2"
10506   [(set (reg 17)
10507         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10508                  (const_int 0)))
10509    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10510         (not:HI (match_dup 1)))]
10511   "ix86_match_ccmode (insn, CCNOmode)
10512    && ix86_unary_operator_ok (NEG, HImode, operands)"
10513   "#"
10514   [(set_attr "type" "alu1")
10515    (set_attr "mode" "HI")])
10516
10517 (define_split
10518   [(set (reg 17)
10519         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10520                  (const_int 0)))
10521    (set (match_operand:HI 0 "nonimmediate_operand" "")
10522         (not:HI (match_dup 1)))]
10523   "ix86_match_ccmode (insn, CCNOmode)"
10524   [(parallel [(set (reg:CCNO 17)
10525                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10526                                  (const_int 0)))
10527               (set (match_dup 0)
10528                    (xor:HI (match_dup 1) (const_int -1)))])]
10529   "")
10530
10531 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10532 (define_expand "one_cmplqi2"
10533   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10534         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10535   "TARGET_QIMODE_MATH"
10536   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10537
10538 (define_insn "*one_cmplqi2_1"
10539   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10540         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10541   "ix86_unary_operator_ok (NOT, QImode, operands)"
10542   "@
10543    not{b}\t%0
10544    not{l}\t%k0"
10545   [(set_attr "type" "negnot")
10546    (set_attr "mode" "QI,SI")])
10547
10548 (define_insn "*one_cmplqi2_2"
10549   [(set (reg 17)
10550         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10551                  (const_int 0)))
10552    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10553         (not:QI (match_dup 1)))]
10554   "ix86_match_ccmode (insn, CCNOmode)
10555    && ix86_unary_operator_ok (NOT, QImode, operands)"
10556   "#"
10557   [(set_attr "type" "alu1")
10558    (set_attr "mode" "QI")])
10559
10560 (define_split
10561   [(set (reg 17)
10562         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10563                  (const_int 0)))
10564    (set (match_operand:QI 0 "nonimmediate_operand" "")
10565         (not:QI (match_dup 1)))]
10566   "ix86_match_ccmode (insn, CCNOmode)"
10567   [(parallel [(set (reg:CCNO 17)
10568                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10569                                  (const_int 0)))
10570               (set (match_dup 0)
10571                    (xor:QI (match_dup 1) (const_int -1)))])]
10572   "")
10573 \f
10574 ;; Arithmetic shift instructions
10575
10576 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10577 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10578 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10579 ;; from the assembler input.
10580 ;;
10581 ;; This instruction shifts the target reg/mem as usual, but instead of
10582 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10583 ;; is a left shift double, bits are taken from the high order bits of
10584 ;; reg, else if the insn is a shift right double, bits are taken from the
10585 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10586 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10587 ;;
10588 ;; Since sh[lr]d does not change the `reg' operand, that is done
10589 ;; separately, making all shifts emit pairs of shift double and normal
10590 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10591 ;; support a 63 bit shift, each shift where the count is in a reg expands
10592 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10593 ;;
10594 ;; If the shift count is a constant, we need never emit more than one
10595 ;; shift pair, instead using moves and sign extension for counts greater
10596 ;; than 31.
10597
10598 (define_expand "ashldi3"
10599   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10600                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10601                               (match_operand:QI 2 "nonmemory_operand" "")))
10602               (clobber (reg:CC 17))])]
10603   ""
10604 {
10605   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10606     {
10607       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10608       DONE;
10609     }
10610   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10611   DONE;
10612 })
10613
10614 (define_insn "*ashldi3_1_rex64"
10615   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10616         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10617                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10618    (clobber (reg:CC 17))]
10619   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10620 {
10621   switch (get_attr_type (insn))
10622     {
10623     case TYPE_ALU:
10624       if (operands[2] != const1_rtx)
10625         abort ();
10626       if (!rtx_equal_p (operands[0], operands[1]))
10627         abort ();
10628       return "add{q}\t{%0, %0|%0, %0}";
10629
10630     case TYPE_LEA:
10631       if (GET_CODE (operands[2]) != CONST_INT
10632           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10633         abort ();
10634       operands[1] = gen_rtx_MULT (DImode, operands[1],
10635                                   GEN_INT (1 << INTVAL (operands[2])));
10636       return "lea{q}\t{%a1, %0|%0, %a1}";
10637
10638     default:
10639       if (REG_P (operands[2]))
10640         return "sal{q}\t{%b2, %0|%0, %b2}";
10641       else if (operands[2] == const1_rtx
10642                && (TARGET_SHIFT1 || optimize_size))
10643         return "sal{q}\t%0";
10644       else
10645         return "sal{q}\t{%2, %0|%0, %2}";
10646     }
10647 }
10648   [(set (attr "type")
10649      (cond [(eq_attr "alternative" "1")
10650               (const_string "lea")
10651             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10652                           (const_int 0))
10653                       (match_operand 0 "register_operand" ""))
10654                  (match_operand 2 "const1_operand" ""))
10655               (const_string "alu")
10656            ]
10657            (const_string "ishift")))
10658    (set_attr "mode" "DI")])
10659
10660 ;; Convert lea to the lea pattern to avoid flags dependency.
10661 (define_split
10662   [(set (match_operand:DI 0 "register_operand" "")
10663         (ashift:DI (match_operand:DI 1 "register_operand" "")
10664                    (match_operand:QI 2 "immediate_operand" "")))
10665    (clobber (reg:CC 17))]
10666   "TARGET_64BIT && reload_completed
10667    && true_regnum (operands[0]) != true_regnum (operands[1])"
10668   [(set (match_dup 0)
10669         (mult:DI (match_dup 1)
10670                  (match_dup 2)))]
10671   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10672
10673 ;; This pattern can't accept a variable shift count, since shifts by
10674 ;; zero don't affect the flags.  We assume that shifts by constant
10675 ;; zero are optimized away.
10676 (define_insn "*ashldi3_cmp_rex64"
10677   [(set (reg 17)
10678         (compare
10679           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10680                      (match_operand:QI 2 "immediate_operand" "e"))
10681           (const_int 0)))
10682    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10683         (ashift:DI (match_dup 1) (match_dup 2)))]
10684   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10685    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10686 {
10687   switch (get_attr_type (insn))
10688     {
10689     case TYPE_ALU:
10690       if (operands[2] != const1_rtx)
10691         abort ();
10692       return "add{q}\t{%0, %0|%0, %0}";
10693
10694     default:
10695       if (REG_P (operands[2]))
10696         return "sal{q}\t{%b2, %0|%0, %b2}";
10697       else if (operands[2] == const1_rtx
10698                && (TARGET_SHIFT1 || optimize_size))
10699         return "sal{q}\t%0";
10700       else
10701         return "sal{q}\t{%2, %0|%0, %2}";
10702     }
10703 }
10704   [(set (attr "type")
10705      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706                           (const_int 0))
10707                       (match_operand 0 "register_operand" ""))
10708                  (match_operand 2 "const1_operand" ""))
10709               (const_string "alu")
10710            ]
10711            (const_string "ishift")))
10712    (set_attr "mode" "DI")])
10713
10714 (define_insn "ashldi3_1"
10715   [(set (match_operand:DI 0 "register_operand" "=r")
10716         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10717                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10718    (clobber (match_scratch:SI 3 "=&r"))
10719    (clobber (reg:CC 17))]
10720   "!TARGET_64BIT && TARGET_CMOVE"
10721   "#"
10722   [(set_attr "type" "multi")])
10723
10724 (define_insn "*ashldi3_2"
10725   [(set (match_operand:DI 0 "register_operand" "=r")
10726         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10727                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10728    (clobber (reg:CC 17))]
10729   "!TARGET_64BIT"
10730   "#"
10731   [(set_attr "type" "multi")])
10732
10733 (define_split
10734   [(set (match_operand:DI 0 "register_operand" "")
10735         (ashift:DI (match_operand:DI 1 "register_operand" "")
10736                    (match_operand:QI 2 "nonmemory_operand" "")))
10737    (clobber (match_scratch:SI 3 ""))
10738    (clobber (reg:CC 17))]
10739   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10740   [(const_int 0)]
10741   "ix86_split_ashldi (operands, operands[3]); DONE;")
10742
10743 (define_split
10744   [(set (match_operand:DI 0 "register_operand" "")
10745         (ashift:DI (match_operand:DI 1 "register_operand" "")
10746                    (match_operand:QI 2 "nonmemory_operand" "")))
10747    (clobber (reg:CC 17))]
10748   "!TARGET_64BIT && reload_completed"
10749   [(const_int 0)]
10750   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10751
10752 (define_insn "x86_shld_1"
10753   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10754         (ior:SI (ashift:SI (match_dup 0)
10755                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10756                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10757                   (minus:QI (const_int 32) (match_dup 2)))))
10758    (clobber (reg:CC 17))]
10759   ""
10760   "@
10761    shld{l}\t{%2, %1, %0|%0, %1, %2}
10762    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10763   [(set_attr "type" "ishift")
10764    (set_attr "prefix_0f" "1")
10765    (set_attr "mode" "SI")
10766    (set_attr "pent_pair" "np")
10767    (set_attr "athlon_decode" "vector")
10768    (set_attr "ppro_uops" "few")])
10769
10770 (define_expand "x86_shift_adj_1"
10771   [(set (reg:CCZ 17)
10772         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10773                              (const_int 32))
10774                      (const_int 0)))
10775    (set (match_operand:SI 0 "register_operand" "")
10776         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10777                          (match_operand:SI 1 "register_operand" "")
10778                          (match_dup 0)))
10779    (set (match_dup 1)
10780         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10781                          (match_operand:SI 3 "register_operand" "r")
10782                          (match_dup 1)))]
10783   "TARGET_CMOVE"
10784   "")
10785
10786 (define_expand "x86_shift_adj_2"
10787   [(use (match_operand:SI 0 "register_operand" ""))
10788    (use (match_operand:SI 1 "register_operand" ""))
10789    (use (match_operand:QI 2 "register_operand" ""))]
10790   ""
10791 {
10792   rtx label = gen_label_rtx ();
10793   rtx tmp;
10794
10795   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10796
10797   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10798   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10799   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10800                               gen_rtx_LABEL_REF (VOIDmode, label),
10801                               pc_rtx);
10802   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10803   JUMP_LABEL (tmp) = label;
10804
10805   emit_move_insn (operands[0], operands[1]);
10806   emit_move_insn (operands[1], const0_rtx);
10807
10808   emit_label (label);
10809   LABEL_NUSES (label) = 1;
10810
10811   DONE;
10812 })
10813
10814 (define_expand "ashlsi3"
10815   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10816         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10817                    (match_operand:QI 2 "nonmemory_operand" "")))
10818    (clobber (reg:CC 17))]
10819   ""
10820   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10821
10822 (define_insn "*ashlsi3_1"
10823   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10824         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10825                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10826    (clobber (reg:CC 17))]
10827   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10828 {
10829   switch (get_attr_type (insn))
10830     {
10831     case TYPE_ALU:
10832       if (operands[2] != const1_rtx)
10833         abort ();
10834       if (!rtx_equal_p (operands[0], operands[1]))
10835         abort ();
10836       return "add{l}\t{%0, %0|%0, %0}";
10837
10838     case TYPE_LEA:
10839       return "#";
10840
10841     default:
10842       if (REG_P (operands[2]))
10843         return "sal{l}\t{%b2, %0|%0, %b2}";
10844       else if (operands[2] == const1_rtx
10845                && (TARGET_SHIFT1 || optimize_size))
10846         return "sal{l}\t%0";
10847       else
10848         return "sal{l}\t{%2, %0|%0, %2}";
10849     }
10850 }
10851   [(set (attr "type")
10852      (cond [(eq_attr "alternative" "1")
10853               (const_string "lea")
10854             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10855                           (const_int 0))
10856                       (match_operand 0 "register_operand" ""))
10857                  (match_operand 2 "const1_operand" ""))
10858               (const_string "alu")
10859            ]
10860            (const_string "ishift")))
10861    (set_attr "mode" "SI")])
10862
10863 ;; Convert lea to the lea pattern to avoid flags dependency.
10864 (define_split
10865   [(set (match_operand 0 "register_operand" "")
10866         (ashift (match_operand 1 "index_register_operand" "")
10867                 (match_operand:QI 2 "const_int_operand" "")))
10868    (clobber (reg:CC 17))]
10869   "reload_completed
10870    && true_regnum (operands[0]) != true_regnum (operands[1])"
10871   [(const_int 0)]
10872 {
10873   rtx pat;
10874   operands[0] = gen_lowpart (SImode, operands[0]);
10875   operands[1] = gen_lowpart (Pmode, operands[1]);
10876   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10877   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10878   if (Pmode != SImode)
10879     pat = gen_rtx_SUBREG (SImode, pat, 0);
10880   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10881   DONE;
10882 })
10883
10884 ;; Rare case of shifting RSP is handled by generating move and shift
10885 (define_split
10886   [(set (match_operand 0 "register_operand" "")
10887         (ashift (match_operand 1 "register_operand" "")
10888                 (match_operand:QI 2 "const_int_operand" "")))
10889    (clobber (reg:CC 17))]
10890   "reload_completed
10891    && true_regnum (operands[0]) != true_regnum (operands[1])"
10892   [(const_int 0)]
10893 {
10894   rtx pat, clob;
10895   emit_move_insn (operands[1], operands[0]);
10896   pat = gen_rtx_SET (VOIDmode, operands[0],
10897                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10898                                      operands[0], operands[2]));
10899   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10900   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10901   DONE;
10902 })
10903
10904 (define_insn "*ashlsi3_1_zext"
10905   [(set (match_operand:DI 0 "register_operand" "=r,r")
10906         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10907                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10908    (clobber (reg:CC 17))]
10909   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10910 {
10911   switch (get_attr_type (insn))
10912     {
10913     case TYPE_ALU:
10914       if (operands[2] != const1_rtx)
10915         abort ();
10916       return "add{l}\t{%k0, %k0|%k0, %k0}";
10917
10918     case TYPE_LEA:
10919       return "#";
10920
10921     default:
10922       if (REG_P (operands[2]))
10923         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10924       else if (operands[2] == const1_rtx
10925                && (TARGET_SHIFT1 || optimize_size))
10926         return "sal{l}\t%k0";
10927       else
10928         return "sal{l}\t{%2, %k0|%k0, %2}";
10929     }
10930 }
10931   [(set (attr "type")
10932      (cond [(eq_attr "alternative" "1")
10933               (const_string "lea")
10934             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935                      (const_int 0))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "SI")])
10941
10942 ;; Convert lea to the lea pattern to avoid flags dependency.
10943 (define_split
10944   [(set (match_operand:DI 0 "register_operand" "")
10945         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10946                                 (match_operand:QI 2 "const_int_operand" ""))))
10947    (clobber (reg:CC 17))]
10948   "TARGET_64BIT && reload_completed
10949    && true_regnum (operands[0]) != true_regnum (operands[1])"
10950   [(set (match_dup 0) (zero_extend:DI
10951                         (subreg:SI (mult:SI (match_dup 1)
10952                                             (match_dup 2)) 0)))]
10953 {
10954   operands[1] = gen_lowpart (Pmode, operands[1]);
10955   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10956 })
10957
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags.  We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashlsi3_cmp"
10962   [(set (reg 17)
10963         (compare
10964           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10965                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10966           (const_int 0)))
10967    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10968         (ashift:SI (match_dup 1) (match_dup 2)))]
10969   "ix86_match_ccmode (insn, CCGOCmode)
10970    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10971 {
10972   switch (get_attr_type (insn))
10973     {
10974     case TYPE_ALU:
10975       if (operands[2] != const1_rtx)
10976         abort ();
10977       return "add{l}\t{%0, %0|%0, %0}";
10978
10979     default:
10980       if (REG_P (operands[2]))
10981         return "sal{l}\t{%b2, %0|%0, %b2}";
10982       else if (operands[2] == const1_rtx
10983                && (TARGET_SHIFT1 || optimize_size))
10984         return "sal{l}\t%0";
10985       else
10986         return "sal{l}\t{%2, %0|%0, %2}";
10987     }
10988 }
10989   [(set (attr "type")
10990      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10991                           (const_int 0))
10992                       (match_operand 0 "register_operand" ""))
10993                  (match_operand 2 "const1_operand" ""))
10994               (const_string "alu")
10995            ]
10996            (const_string "ishift")))
10997    (set_attr "mode" "SI")])
10998
10999 (define_insn "*ashlsi3_cmp_zext"
11000   [(set (reg 17)
11001         (compare
11002           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11003                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11004           (const_int 0)))
11005    (set (match_operand:DI 0 "register_operand" "=r")
11006         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11007   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11008    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11009 {
11010   switch (get_attr_type (insn))
11011     {
11012     case TYPE_ALU:
11013       if (operands[2] != const1_rtx)
11014         abort ();
11015       return "add{l}\t{%k0, %k0|%k0, %k0}";
11016
11017     default:
11018       if (REG_P (operands[2]))
11019         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11020       else if (operands[2] == const1_rtx
11021                && (TARGET_SHIFT1 || optimize_size))
11022         return "sal{l}\t%k0";
11023       else
11024         return "sal{l}\t{%2, %k0|%k0, %2}";
11025     }
11026 }
11027   [(set (attr "type")
11028      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11029                      (const_int 0))
11030                  (match_operand 2 "const1_operand" ""))
11031               (const_string "alu")
11032            ]
11033            (const_string "ishift")))
11034    (set_attr "mode" "SI")])
11035
11036 (define_expand "ashlhi3"
11037   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11038         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11039                    (match_operand:QI 2 "nonmemory_operand" "")))
11040    (clobber (reg:CC 17))]
11041   "TARGET_HIMODE_MATH"
11042   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11043
11044 (define_insn "*ashlhi3_1_lea"
11045   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11046         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11047                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11048    (clobber (reg:CC 17))]
11049   "!TARGET_PARTIAL_REG_STALL
11050    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11051 {
11052   switch (get_attr_type (insn))
11053     {
11054     case TYPE_LEA:
11055       return "#";
11056     case TYPE_ALU:
11057       if (operands[2] != const1_rtx)
11058         abort ();
11059       return "add{w}\t{%0, %0|%0, %0}";
11060
11061     default:
11062       if (REG_P (operands[2]))
11063         return "sal{w}\t{%b2, %0|%0, %b2}";
11064       else if (operands[2] == const1_rtx
11065                && (TARGET_SHIFT1 || optimize_size))
11066         return "sal{w}\t%0";
11067       else
11068         return "sal{w}\t{%2, %0|%0, %2}";
11069     }
11070 }
11071   [(set (attr "type")
11072      (cond [(eq_attr "alternative" "1")
11073               (const_string "lea")
11074             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11075                           (const_int 0))
11076                       (match_operand 0 "register_operand" ""))
11077                  (match_operand 2 "const1_operand" ""))
11078               (const_string "alu")
11079            ]
11080            (const_string "ishift")))
11081    (set_attr "mode" "HI,SI")])
11082
11083 (define_insn "*ashlhi3_1"
11084   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11085         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11086                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11087    (clobber (reg:CC 17))]
11088   "TARGET_PARTIAL_REG_STALL
11089    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11090 {
11091   switch (get_attr_type (insn))
11092     {
11093     case TYPE_ALU:
11094       if (operands[2] != const1_rtx)
11095         abort ();
11096       return "add{w}\t{%0, %0|%0, %0}";
11097
11098     default:
11099       if (REG_P (operands[2]))
11100         return "sal{w}\t{%b2, %0|%0, %b2}";
11101       else if (operands[2] == const1_rtx
11102                && (TARGET_SHIFT1 || optimize_size))
11103         return "sal{w}\t%0";
11104       else
11105         return "sal{w}\t{%2, %0|%0, %2}";
11106     }
11107 }
11108   [(set (attr "type")
11109      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11110                           (const_int 0))
11111                       (match_operand 0 "register_operand" ""))
11112                  (match_operand 2 "const1_operand" ""))
11113               (const_string "alu")
11114            ]
11115            (const_string "ishift")))
11116    (set_attr "mode" "HI")])
11117
11118 ;; This pattern can't accept a variable shift count, since shifts by
11119 ;; zero don't affect the flags.  We assume that shifts by constant
11120 ;; zero are optimized away.
11121 (define_insn "*ashlhi3_cmp"
11122   [(set (reg 17)
11123         (compare
11124           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11125                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11126           (const_int 0)))
11127    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11128         (ashift:HI (match_dup 1) (match_dup 2)))]
11129   "ix86_match_ccmode (insn, CCGOCmode)
11130    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11131 {
11132   switch (get_attr_type (insn))
11133     {
11134     case TYPE_ALU:
11135       if (operands[2] != const1_rtx)
11136         abort ();
11137       return "add{w}\t{%0, %0|%0, %0}";
11138
11139     default:
11140       if (REG_P (operands[2]))
11141         return "sal{w}\t{%b2, %0|%0, %b2}";
11142       else if (operands[2] == const1_rtx
11143                && (TARGET_SHIFT1 || optimize_size))
11144         return "sal{w}\t%0";
11145       else
11146         return "sal{w}\t{%2, %0|%0, %2}";
11147     }
11148 }
11149   [(set (attr "type")
11150      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11151                           (const_int 0))
11152                       (match_operand 0 "register_operand" ""))
11153                  (match_operand 2 "const1_operand" ""))
11154               (const_string "alu")
11155            ]
11156            (const_string "ishift")))
11157    (set_attr "mode" "HI")])
11158
11159 (define_expand "ashlqi3"
11160   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11161         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11162                    (match_operand:QI 2 "nonmemory_operand" "")))
11163    (clobber (reg:CC 17))]
11164   "TARGET_QIMODE_MATH"
11165   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11166
11167 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11168
11169 (define_insn "*ashlqi3_1_lea"
11170   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11171         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11172                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11173    (clobber (reg:CC 17))]
11174   "!TARGET_PARTIAL_REG_STALL
11175    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11176 {
11177   switch (get_attr_type (insn))
11178     {
11179     case TYPE_LEA:
11180       return "#";
11181     case TYPE_ALU:
11182       if (operands[2] != const1_rtx)
11183         abort ();
11184       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11185         return "add{l}\t{%k0, %k0|%k0, %k0}";
11186       else
11187         return "add{b}\t{%0, %0|%0, %0}";
11188
11189     default:
11190       if (REG_P (operands[2]))
11191         {
11192           if (get_attr_mode (insn) == MODE_SI)
11193             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11194           else
11195             return "sal{b}\t{%b2, %0|%0, %b2}";
11196         }
11197       else if (operands[2] == const1_rtx
11198                && (TARGET_SHIFT1 || optimize_size))
11199         {
11200           if (get_attr_mode (insn) == MODE_SI)
11201             return "sal{l}\t%0";
11202           else
11203             return "sal{b}\t%0";
11204         }
11205       else
11206         {
11207           if (get_attr_mode (insn) == MODE_SI)
11208             return "sal{l}\t{%2, %k0|%k0, %2}";
11209           else
11210             return "sal{b}\t{%2, %0|%0, %2}";
11211         }
11212     }
11213 }
11214   [(set (attr "type")
11215      (cond [(eq_attr "alternative" "2")
11216               (const_string "lea")
11217             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218                           (const_int 0))
11219                       (match_operand 0 "register_operand" ""))
11220                  (match_operand 2 "const1_operand" ""))
11221               (const_string "alu")
11222            ]
11223            (const_string "ishift")))
11224    (set_attr "mode" "QI,SI,SI")])
11225
11226 (define_insn "*ashlqi3_1"
11227   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11228         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11229                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11230    (clobber (reg:CC 17))]
11231   "TARGET_PARTIAL_REG_STALL
11232    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11233 {
11234   switch (get_attr_type (insn))
11235     {
11236     case TYPE_ALU:
11237       if (operands[2] != const1_rtx)
11238         abort ();
11239       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11240         return "add{l}\t{%k0, %k0|%k0, %k0}";
11241       else
11242         return "add{b}\t{%0, %0|%0, %0}";
11243
11244     default:
11245       if (REG_P (operands[2]))
11246         {
11247           if (get_attr_mode (insn) == MODE_SI)
11248             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11249           else
11250             return "sal{b}\t{%b2, %0|%0, %b2}";
11251         }
11252       else if (operands[2] == const1_rtx
11253                && (TARGET_SHIFT1 || optimize_size))
11254         {
11255           if (get_attr_mode (insn) == MODE_SI)
11256             return "sal{l}\t%0";
11257           else
11258             return "sal{b}\t%0";
11259         }
11260       else
11261         {
11262           if (get_attr_mode (insn) == MODE_SI)
11263             return "sal{l}\t{%2, %k0|%k0, %2}";
11264           else
11265             return "sal{b}\t{%2, %0|%0, %2}";
11266         }
11267     }
11268 }
11269   [(set (attr "type")
11270      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11271                           (const_int 0))
11272                       (match_operand 0 "register_operand" ""))
11273                  (match_operand 2 "const1_operand" ""))
11274               (const_string "alu")
11275            ]
11276            (const_string "ishift")))
11277    (set_attr "mode" "QI,SI")])
11278
11279 ;; This pattern can't accept a variable shift count, since shifts by
11280 ;; zero don't affect the flags.  We assume that shifts by constant
11281 ;; zero are optimized away.
11282 (define_insn "*ashlqi3_cmp"
11283   [(set (reg 17)
11284         (compare
11285           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11286                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11287           (const_int 0)))
11288    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11289         (ashift:QI (match_dup 1) (match_dup 2)))]
11290   "ix86_match_ccmode (insn, CCGOCmode)
11291    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11292 {
11293   switch (get_attr_type (insn))
11294     {
11295     case TYPE_ALU:
11296       if (operands[2] != const1_rtx)
11297         abort ();
11298       return "add{b}\t{%0, %0|%0, %0}";
11299
11300     default:
11301       if (REG_P (operands[2]))
11302         return "sal{b}\t{%b2, %0|%0, %b2}";
11303       else if (operands[2] == const1_rtx
11304                && (TARGET_SHIFT1 || optimize_size))
11305         return "sal{b}\t%0";
11306       else
11307         return "sal{b}\t{%2, %0|%0, %2}";
11308     }
11309 }
11310   [(set (attr "type")
11311      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11312                           (const_int 0))
11313                       (match_operand 0 "register_operand" ""))
11314                  (match_operand 2 "const1_operand" ""))
11315               (const_string "alu")
11316            ]
11317            (const_string "ishift")))
11318    (set_attr "mode" "QI")])
11319
11320 ;; See comment above `ashldi3' about how this works.
11321
11322 (define_expand "ashrdi3"
11323   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11324                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11325                                 (match_operand:QI 2 "nonmemory_operand" "")))
11326               (clobber (reg:CC 17))])]
11327   ""
11328 {
11329   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11330     {
11331       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11332       DONE;
11333     }
11334   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11335   DONE;
11336 })
11337
11338 (define_insn "ashrdi3_63_rex64"
11339   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11340         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11341                      (match_operand:DI 2 "const_int_operand" "i,i")))
11342    (clobber (reg:CC 17))]
11343   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11344    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11345   "@
11346    {cqto|cqo}
11347    sar{q}\t{%2, %0|%0, %2}"
11348   [(set_attr "type" "imovx,ishift")
11349    (set_attr "prefix_0f" "0,*")
11350    (set_attr "length_immediate" "0,*")
11351    (set_attr "modrm" "0,1")
11352    (set_attr "mode" "DI")])
11353
11354 (define_insn "*ashrdi3_1_one_bit_rex64"
11355   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11356         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11357                      (match_operand:QI 2 "const1_operand" "")))
11358    (clobber (reg:CC 17))]
11359   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11360    && (TARGET_SHIFT1 || optimize_size)"
11361   "sar{q}\t%0"
11362   [(set_attr "type" "ishift")
11363    (set (attr "length") 
11364      (if_then_else (match_operand:DI 0 "register_operand" "") 
11365         (const_string "2")
11366         (const_string "*")))])
11367
11368 (define_insn "*ashrdi3_1_rex64"
11369   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11370         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11371                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11372    (clobber (reg:CC 17))]
11373   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11374   "@
11375    sar{q}\t{%2, %0|%0, %2}
11376    sar{q}\t{%b2, %0|%0, %b2}"
11377   [(set_attr "type" "ishift")
11378    (set_attr "mode" "DI")])
11379
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags.  We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11384   [(set (reg 17)
11385         (compare
11386           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387                        (match_operand:QI 2 "const1_operand" ""))
11388           (const_int 0)))
11389    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11391   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392    && (TARGET_SHIFT1 || optimize_size)
11393    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11394   "sar{q}\t%0"
11395   [(set_attr "type" "ishift")
11396    (set (attr "length") 
11397      (if_then_else (match_operand:DI 0 "register_operand" "") 
11398         (const_string "2")
11399         (const_string "*")))])
11400
11401 ;; This pattern can't accept a variable shift count, since shifts by
11402 ;; zero don't affect the flags.  We assume that shifts by constant
11403 ;; zero are optimized away.
11404 (define_insn "*ashrdi3_cmp_rex64"
11405   [(set (reg 17)
11406         (compare
11407           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11408                        (match_operand:QI 2 "const_int_operand" "n"))
11409           (const_int 0)))
11410    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11412   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11413    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11414   "sar{q}\t{%2, %0|%0, %2}"
11415   [(set_attr "type" "ishift")
11416    (set_attr "mode" "DI")])
11417
11418
11419 (define_insn "ashrdi3_1"
11420   [(set (match_operand:DI 0 "register_operand" "=r")
11421         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11422                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11423    (clobber (match_scratch:SI 3 "=&r"))
11424    (clobber (reg:CC 17))]
11425   "!TARGET_64BIT && TARGET_CMOVE"
11426   "#"
11427   [(set_attr "type" "multi")])
11428
11429 (define_insn "*ashrdi3_2"
11430   [(set (match_operand:DI 0 "register_operand" "=r")
11431         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11432                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11433    (clobber (reg:CC 17))]
11434   "!TARGET_64BIT"
11435   "#"
11436   [(set_attr "type" "multi")])
11437
11438 (define_split
11439   [(set (match_operand:DI 0 "register_operand" "")
11440         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11441                      (match_operand:QI 2 "nonmemory_operand" "")))
11442    (clobber (match_scratch:SI 3 ""))
11443    (clobber (reg:CC 17))]
11444   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11445   [(const_int 0)]
11446   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11447
11448 (define_split
11449   [(set (match_operand:DI 0 "register_operand" "")
11450         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11451                      (match_operand:QI 2 "nonmemory_operand" "")))
11452    (clobber (reg:CC 17))]
11453   "!TARGET_64BIT && reload_completed"
11454   [(const_int 0)]
11455   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11456
11457 (define_insn "x86_shrd_1"
11458   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11459         (ior:SI (ashiftrt:SI (match_dup 0)
11460                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11461                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11462                   (minus:QI (const_int 32) (match_dup 2)))))
11463    (clobber (reg:CC 17))]
11464   ""
11465   "@
11466    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11467    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11468   [(set_attr "type" "ishift")
11469    (set_attr "prefix_0f" "1")
11470    (set_attr "pent_pair" "np")
11471    (set_attr "ppro_uops" "few")
11472    (set_attr "mode" "SI")])
11473
11474 (define_expand "x86_shift_adj_3"
11475   [(use (match_operand:SI 0 "register_operand" ""))
11476    (use (match_operand:SI 1 "register_operand" ""))
11477    (use (match_operand:QI 2 "register_operand" ""))]
11478   ""
11479 {
11480   rtx label = gen_label_rtx ();
11481   rtx tmp;
11482
11483   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11484
11485   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11486   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11487   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11488                               gen_rtx_LABEL_REF (VOIDmode, label),
11489                               pc_rtx);
11490   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11491   JUMP_LABEL (tmp) = label;
11492
11493   emit_move_insn (operands[0], operands[1]);
11494   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11495
11496   emit_label (label);
11497   LABEL_NUSES (label) = 1;
11498
11499   DONE;
11500 })
11501
11502 (define_insn "ashrsi3_31"
11503   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11504         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11505                      (match_operand:SI 2 "const_int_operand" "i,i")))
11506    (clobber (reg:CC 17))]
11507   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11508    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11509   "@
11510    {cltd|cdq}
11511    sar{l}\t{%2, %0|%0, %2}"
11512   [(set_attr "type" "imovx,ishift")
11513    (set_attr "prefix_0f" "0,*")
11514    (set_attr "length_immediate" "0,*")
11515    (set_attr "modrm" "0,1")
11516    (set_attr "mode" "SI")])
11517
11518 (define_insn "*ashrsi3_31_zext"
11519   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11520         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11521                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11522    (clobber (reg:CC 17))]
11523   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11524    && INTVAL (operands[2]) == 31
11525    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11526   "@
11527    {cltd|cdq}
11528    sar{l}\t{%2, %k0|%k0, %2}"
11529   [(set_attr "type" "imovx,ishift")
11530    (set_attr "prefix_0f" "0,*")
11531    (set_attr "length_immediate" "0,*")
11532    (set_attr "modrm" "0,1")
11533    (set_attr "mode" "SI")])
11534
11535 (define_expand "ashrsi3"
11536   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11537         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11538                      (match_operand:QI 2 "nonmemory_operand" "")))
11539    (clobber (reg:CC 17))]
11540   ""
11541   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11542
11543 (define_insn "*ashrsi3_1_one_bit"
11544   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11545         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11546                      (match_operand:QI 2 "const1_operand" "")))
11547    (clobber (reg:CC 17))]
11548   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11549    && (TARGET_SHIFT1 || optimize_size)"
11550   "sar{l}\t%0"
11551   [(set_attr "type" "ishift")
11552    (set (attr "length") 
11553      (if_then_else (match_operand:SI 0 "register_operand" "") 
11554         (const_string "2")
11555         (const_string "*")))])
11556
11557 (define_insn "*ashrsi3_1_one_bit_zext"
11558   [(set (match_operand:DI 0 "register_operand" "=r")
11559         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11560                                      (match_operand:QI 2 "const1_operand" ""))))
11561    (clobber (reg:CC 17))]
11562   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11563    && (TARGET_SHIFT1 || optimize_size)"
11564   "sar{l}\t%k0"
11565   [(set_attr "type" "ishift")
11566    (set_attr "length" "2")])
11567
11568 (define_insn "*ashrsi3_1"
11569   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11570         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11571                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11572    (clobber (reg:CC 17))]
11573   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11574   "@
11575    sar{l}\t{%2, %0|%0, %2}
11576    sar{l}\t{%b2, %0|%0, %b2}"
11577   [(set_attr "type" "ishift")
11578    (set_attr "mode" "SI")])
11579
11580 (define_insn "*ashrsi3_1_zext"
11581   [(set (match_operand:DI 0 "register_operand" "=r,r")
11582         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11583                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11584    (clobber (reg:CC 17))]
11585   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586   "@
11587    sar{l}\t{%2, %k0|%k0, %2}
11588    sar{l}\t{%b2, %k0|%k0, %b2}"
11589   [(set_attr "type" "ishift")
11590    (set_attr "mode" "SI")])
11591
11592 ;; This pattern can't accept a variable shift count, since shifts by
11593 ;; zero don't affect the flags.  We assume that shifts by constant
11594 ;; zero are optimized away.
11595 (define_insn "*ashrsi3_one_bit_cmp"
11596   [(set (reg 17)
11597         (compare
11598           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11599                        (match_operand:QI 2 "const1_operand" ""))
11600           (const_int 0)))
11601    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11602         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11603   "ix86_match_ccmode (insn, CCGOCmode)
11604    && (TARGET_SHIFT1 || optimize_size)
11605    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606   "sar{l}\t%0"
11607   [(set_attr "type" "ishift")
11608    (set (attr "length") 
11609      (if_then_else (match_operand:SI 0 "register_operand" "") 
11610         (const_string "2")
11611         (const_string "*")))])
11612
11613 (define_insn "*ashrsi3_one_bit_cmp_zext"
11614   [(set (reg 17)
11615         (compare
11616           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11617                        (match_operand:QI 2 "const1_operand" ""))
11618           (const_int 0)))
11619    (set (match_operand:DI 0 "register_operand" "=r")
11620         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11621   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11622    && (TARGET_SHIFT1 || optimize_size)
11623    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11624   "sar{l}\t%k0"
11625   [(set_attr "type" "ishift")
11626    (set_attr "length" "2")])
11627
11628 ;; This pattern can't accept a variable shift count, since shifts by
11629 ;; zero don't affect the flags.  We assume that shifts by constant
11630 ;; zero are optimized away.
11631 (define_insn "*ashrsi3_cmp"
11632   [(set (reg 17)
11633         (compare
11634           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11635                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11636           (const_int 0)))
11637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11638         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11639   "ix86_match_ccmode (insn, CCGOCmode)
11640    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11641   "sar{l}\t{%2, %0|%0, %2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "SI")])
11644
11645 (define_insn "*ashrsi3_cmp_zext"
11646   [(set (reg 17)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11649                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11650           (const_int 0)))
11651    (set (match_operand:DI 0 "register_operand" "=r")
11652         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11653   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "sar{l}\t{%2, %k0|%k0, %2}"
11656   [(set_attr "type" "ishift")
11657    (set_attr "mode" "SI")])
11658
11659 (define_expand "ashrhi3"
11660   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11661         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11662                      (match_operand:QI 2 "nonmemory_operand" "")))
11663    (clobber (reg:CC 17))]
11664   "TARGET_HIMODE_MATH"
11665   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11666
11667 (define_insn "*ashrhi3_1_one_bit"
11668   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11669         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11670                      (match_operand:QI 2 "const1_operand" "")))
11671    (clobber (reg:CC 17))]
11672   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11673    && (TARGET_SHIFT1 || optimize_size)"
11674   "sar{w}\t%0"
11675   [(set_attr "type" "ishift")
11676    (set (attr "length") 
11677      (if_then_else (match_operand 0 "register_operand" "") 
11678         (const_string "2")
11679         (const_string "*")))])
11680
11681 (define_insn "*ashrhi3_1"
11682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11683         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11684                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11685    (clobber (reg:CC 17))]
11686   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11687   "@
11688    sar{w}\t{%2, %0|%0, %2}
11689    sar{w}\t{%b2, %0|%0, %b2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "HI")])
11692
11693 ;; This pattern can't accept a variable shift count, since shifts by
11694 ;; zero don't affect the flags.  We assume that shifts by constant
11695 ;; zero are optimized away.
11696 (define_insn "*ashrhi3_one_bit_cmp"
11697   [(set (reg 17)
11698         (compare
11699           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11700                        (match_operand:QI 2 "const1_operand" ""))
11701           (const_int 0)))
11702    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11703         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11704   "ix86_match_ccmode (insn, CCGOCmode)
11705    && (TARGET_SHIFT1 || optimize_size)
11706    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11707   "sar{w}\t%0"
11708   [(set_attr "type" "ishift")
11709    (set (attr "length") 
11710      (if_then_else (match_operand 0 "register_operand" "") 
11711         (const_string "2")
11712         (const_string "*")))])
11713
11714 ;; This pattern can't accept a variable shift count, since shifts by
11715 ;; zero don't affect the flags.  We assume that shifts by constant
11716 ;; zero are optimized away.
11717 (define_insn "*ashrhi3_cmp"
11718   [(set (reg 17)
11719         (compare
11720           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11721                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11722           (const_int 0)))
11723    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11724         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11725   "ix86_match_ccmode (insn, CCGOCmode)
11726    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11727   "sar{w}\t{%2, %0|%0, %2}"
11728   [(set_attr "type" "ishift")
11729    (set_attr "mode" "HI")])
11730
11731 (define_expand "ashrqi3"
11732   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11733         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11734                      (match_operand:QI 2 "nonmemory_operand" "")))
11735    (clobber (reg:CC 17))]
11736   "TARGET_QIMODE_MATH"
11737   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11738
11739 (define_insn "*ashrqi3_1_one_bit"
11740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11741         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11742                      (match_operand:QI 2 "const1_operand" "")))
11743    (clobber (reg:CC 17))]
11744   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11745    && (TARGET_SHIFT1 || optimize_size)"
11746   "sar{b}\t%0"
11747   [(set_attr "type" "ishift")
11748    (set (attr "length") 
11749      (if_then_else (match_operand 0 "register_operand" "") 
11750         (const_string "2")
11751         (const_string "*")))])
11752
11753 (define_insn "*ashrqi3_1_one_bit_slp"
11754   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11755         (ashiftrt:QI (match_dup 0)
11756                      (match_operand:QI 1 "const1_operand" "")))
11757    (clobber (reg:CC 17))]
11758   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11759    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11760    && (TARGET_SHIFT1 || optimize_size)"
11761   "sar{b}\t%0"
11762   [(set_attr "type" "ishift1")
11763    (set (attr "length") 
11764      (if_then_else (match_operand 0 "register_operand" "") 
11765         (const_string "2")
11766         (const_string "*")))])
11767
11768 (define_insn "*ashrqi3_1"
11769   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11770         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11771                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11772    (clobber (reg:CC 17))]
11773   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11774   "@
11775    sar{b}\t{%2, %0|%0, %2}
11776    sar{b}\t{%b2, %0|%0, %b2}"
11777   [(set_attr "type" "ishift")
11778    (set_attr "mode" "QI")])
11779
11780 (define_insn "*ashrqi3_1_slp"
11781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11782         (ashiftrt:QI (match_dup 0)
11783                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11784    (clobber (reg:CC 17))]
11785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11787   "@
11788    sar{b}\t{%1, %0|%0, %1}
11789    sar{b}\t{%b1, %0|%0, %b1}"
11790   [(set_attr "type" "ishift1")
11791    (set_attr "mode" "QI")])
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrqi3_one_bit_cmp"
11797   [(set (reg 17)
11798         (compare
11799           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const1_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && (TARGET_SHIFT1 || optimize_size)
11806    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11807   "sar{b}\t%0"
11808   [(set_attr "type" "ishift")
11809    (set (attr "length") 
11810      (if_then_else (match_operand 0 "register_operand" "") 
11811         (const_string "2")
11812         (const_string "*")))])
11813
11814 ;; This pattern can't accept a variable shift count, since shifts by
11815 ;; zero don't affect the flags.  We assume that shifts by constant
11816 ;; zero are optimized away.
11817 (define_insn "*ashrqi3_cmp"
11818   [(set (reg 17)
11819         (compare
11820           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11821                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11822           (const_int 0)))
11823    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11824         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11825   "ix86_match_ccmode (insn, CCGOCmode)
11826    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11827   "sar{b}\t{%2, %0|%0, %2}"
11828   [(set_attr "type" "ishift")
11829    (set_attr "mode" "QI")])
11830 \f
11831 ;; Logical shift instructions
11832
11833 ;; See comment above `ashldi3' about how this works.
11834
11835 (define_expand "lshrdi3"
11836   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11837                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11838                                 (match_operand:QI 2 "nonmemory_operand" "")))
11839               (clobber (reg:CC 17))])]
11840   ""
11841 {
11842   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11843     {
11844       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11845       DONE;
11846     }
11847   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11848   DONE;
11849 })
11850
11851 (define_insn "*lshrdi3_1_one_bit_rex64"
11852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11853         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11854                      (match_operand:QI 2 "const1_operand" "")))
11855    (clobber (reg:CC 17))]
11856   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11857    && (TARGET_SHIFT1 || optimize_size)"
11858   "shr{q}\t%0"
11859   [(set_attr "type" "ishift")
11860    (set (attr "length") 
11861      (if_then_else (match_operand:DI 0 "register_operand" "") 
11862         (const_string "2")
11863         (const_string "*")))])
11864
11865 (define_insn "*lshrdi3_1_rex64"
11866   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11867         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11868                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11869    (clobber (reg:CC 17))]
11870   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "@
11872    shr{q}\t{%2, %0|%0, %2}
11873    shr{q}\t{%b2, %0|%0, %b2}"
11874   [(set_attr "type" "ishift")
11875    (set_attr "mode" "DI")])
11876
11877 ;; This pattern can't accept a variable shift count, since shifts by
11878 ;; zero don't affect the flags.  We assume that shifts by constant
11879 ;; zero are optimized away.
11880 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11881   [(set (reg 17)
11882         (compare
11883           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11884                        (match_operand:QI 2 "const1_operand" ""))
11885           (const_int 0)))
11886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11887         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11888   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11889    && (TARGET_SHIFT1 || optimize_size)
11890    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11891   "shr{q}\t%0"
11892   [(set_attr "type" "ishift")
11893    (set (attr "length") 
11894      (if_then_else (match_operand:DI 0 "register_operand" "") 
11895         (const_string "2")
11896         (const_string "*")))])
11897
11898 ;; This pattern can't accept a variable shift count, since shifts by
11899 ;; zero don't affect the flags.  We assume that shifts by constant
11900 ;; zero are optimized away.
11901 (define_insn "*lshrdi3_cmp_rex64"
11902   [(set (reg 17)
11903         (compare
11904           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11905                        (match_operand:QI 2 "const_int_operand" "e"))
11906           (const_int 0)))
11907    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11908         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11909   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11910    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11911   "shr{q}\t{%2, %0|%0, %2}"
11912   [(set_attr "type" "ishift")
11913    (set_attr "mode" "DI")])
11914
11915 (define_insn "lshrdi3_1"
11916   [(set (match_operand:DI 0 "register_operand" "=r")
11917         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11918                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11919    (clobber (match_scratch:SI 3 "=&r"))
11920    (clobber (reg:CC 17))]
11921   "!TARGET_64BIT && TARGET_CMOVE"
11922   "#"
11923   [(set_attr "type" "multi")])
11924
11925 (define_insn "*lshrdi3_2"
11926   [(set (match_operand:DI 0 "register_operand" "=r")
11927         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11928                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11929    (clobber (reg:CC 17))]
11930   "!TARGET_64BIT"
11931   "#"
11932   [(set_attr "type" "multi")])
11933
11934 (define_split 
11935   [(set (match_operand:DI 0 "register_operand" "")
11936         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11937                      (match_operand:QI 2 "nonmemory_operand" "")))
11938    (clobber (match_scratch:SI 3 ""))
11939    (clobber (reg:CC 17))]
11940   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11941   [(const_int 0)]
11942   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11943
11944 (define_split 
11945   [(set (match_operand:DI 0 "register_operand" "")
11946         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11947                      (match_operand:QI 2 "nonmemory_operand" "")))
11948    (clobber (reg:CC 17))]
11949   "!TARGET_64BIT && reload_completed"
11950   [(const_int 0)]
11951   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11952
11953 (define_expand "lshrsi3"
11954   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11955         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11956                      (match_operand:QI 2 "nonmemory_operand" "")))
11957    (clobber (reg:CC 17))]
11958   ""
11959   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11960
11961 (define_insn "*lshrsi3_1_one_bit"
11962   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11963         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11964                      (match_operand:QI 2 "const1_operand" "")))
11965    (clobber (reg:CC 17))]
11966   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11967    && (TARGET_SHIFT1 || optimize_size)"
11968   "shr{l}\t%0"
11969   [(set_attr "type" "ishift")
11970    (set (attr "length") 
11971      (if_then_else (match_operand:SI 0 "register_operand" "") 
11972         (const_string "2")
11973         (const_string "*")))])
11974
11975 (define_insn "*lshrsi3_1_one_bit_zext"
11976   [(set (match_operand:DI 0 "register_operand" "=r")
11977         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11978                      (match_operand:QI 2 "const1_operand" "")))
11979    (clobber (reg:CC 17))]
11980   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981    && (TARGET_SHIFT1 || optimize_size)"
11982   "shr{l}\t%k0"
11983   [(set_attr "type" "ishift")
11984    (set_attr "length" "2")])
11985
11986 (define_insn "*lshrsi3_1"
11987   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11989                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990    (clobber (reg:CC 17))]
11991   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11992   "@
11993    shr{l}\t{%2, %0|%0, %2}
11994    shr{l}\t{%b2, %0|%0, %b2}"
11995   [(set_attr "type" "ishift")
11996    (set_attr "mode" "SI")])
11997
11998 (define_insn "*lshrsi3_1_zext"
11999   [(set (match_operand:DI 0 "register_operand" "=r,r")
12000         (zero_extend:DI
12001           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12002                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12003    (clobber (reg:CC 17))]
12004   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005   "@
12006    shr{l}\t{%2, %k0|%k0, %2}
12007    shr{l}\t{%b2, %k0|%k0, %b2}"
12008   [(set_attr "type" "ishift")
12009    (set_attr "mode" "SI")])
12010
12011 ;; This pattern can't accept a variable shift count, since shifts by
12012 ;; zero don't affect the flags.  We assume that shifts by constant
12013 ;; zero are optimized away.
12014 (define_insn "*lshrsi3_one_bit_cmp"
12015   [(set (reg 17)
12016         (compare
12017           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12018                        (match_operand:QI 2 "const1_operand" ""))
12019           (const_int 0)))
12020    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12021         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12022   "ix86_match_ccmode (insn, CCGOCmode)
12023    && (TARGET_SHIFT1 || optimize_size)
12024    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12025   "shr{l}\t%0"
12026   [(set_attr "type" "ishift")
12027    (set (attr "length") 
12028      (if_then_else (match_operand:SI 0 "register_operand" "") 
12029         (const_string "2")
12030         (const_string "*")))])
12031
12032 (define_insn "*lshrsi3_cmp_one_bit_zext"
12033   [(set (reg 17)
12034         (compare
12035           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12036                        (match_operand:QI 2 "const1_operand" ""))
12037           (const_int 0)))
12038    (set (match_operand:DI 0 "register_operand" "=r")
12039         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12040   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12041    && (TARGET_SHIFT1 || optimize_size)
12042    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12043   "shr{l}\t%k0"
12044   [(set_attr "type" "ishift")
12045    (set_attr "length" "2")])
12046
12047 ;; This pattern can't accept a variable shift count, since shifts by
12048 ;; zero don't affect the flags.  We assume that shifts by constant
12049 ;; zero are optimized away.
12050 (define_insn "*lshrsi3_cmp"
12051   [(set (reg 17)
12052         (compare
12053           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12054                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12055           (const_int 0)))
12056    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12057         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12058   "ix86_match_ccmode (insn, CCGOCmode)
12059    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12060   "shr{l}\t{%2, %0|%0, %2}"
12061   [(set_attr "type" "ishift")
12062    (set_attr "mode" "SI")])
12063
12064 (define_insn "*lshrsi3_cmp_zext"
12065   [(set (reg 17)
12066         (compare
12067           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12068                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12069           (const_int 0)))
12070    (set (match_operand:DI 0 "register_operand" "=r")
12071         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12072   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12073    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12074   "shr{l}\t{%2, %k0|%k0, %2}"
12075   [(set_attr "type" "ishift")
12076    (set_attr "mode" "SI")])
12077
12078 (define_expand "lshrhi3"
12079   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12080         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12081                      (match_operand:QI 2 "nonmemory_operand" "")))
12082    (clobber (reg:CC 17))]
12083   "TARGET_HIMODE_MATH"
12084   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12085
12086 (define_insn "*lshrhi3_1_one_bit"
12087   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12089                      (match_operand:QI 2 "const1_operand" "")))
12090    (clobber (reg:CC 17))]
12091   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12092    && (TARGET_SHIFT1 || optimize_size)"
12093   "shr{w}\t%0"
12094   [(set_attr "type" "ishift")
12095    (set (attr "length") 
12096      (if_then_else (match_operand 0 "register_operand" "") 
12097         (const_string "2")
12098         (const_string "*")))])
12099
12100 (define_insn "*lshrhi3_1"
12101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12102         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104    (clobber (reg:CC 17))]
12105   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12106   "@
12107    shr{w}\t{%2, %0|%0, %2}
12108    shr{w}\t{%b2, %0|%0, %b2}"
12109   [(set_attr "type" "ishift")
12110    (set_attr "mode" "HI")])
12111
12112 ;; This pattern can't accept a variable shift count, since shifts by
12113 ;; zero don't affect the flags.  We assume that shifts by constant
12114 ;; zero are optimized away.
12115 (define_insn "*lshrhi3_one_bit_cmp"
12116   [(set (reg 17)
12117         (compare
12118           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12119                        (match_operand:QI 2 "const1_operand" ""))
12120           (const_int 0)))
12121    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12122         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12123   "ix86_match_ccmode (insn, CCGOCmode)
12124    && (TARGET_SHIFT1 || optimize_size)
12125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12126   "shr{w}\t%0"
12127   [(set_attr "type" "ishift")
12128    (set (attr "length") 
12129      (if_then_else (match_operand:SI 0 "register_operand" "") 
12130         (const_string "2")
12131         (const_string "*")))])
12132
12133 ;; This pattern can't accept a variable shift count, since shifts by
12134 ;; zero don't affect the flags.  We assume that shifts by constant
12135 ;; zero are optimized away.
12136 (define_insn "*lshrhi3_cmp"
12137   [(set (reg 17)
12138         (compare
12139           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12140                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12141           (const_int 0)))
12142    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12143         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12144   "ix86_match_ccmode (insn, CCGOCmode)
12145    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12146   "shr{w}\t{%2, %0|%0, %2}"
12147   [(set_attr "type" "ishift")
12148    (set_attr "mode" "HI")])
12149
12150 (define_expand "lshrqi3"
12151   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12152         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC 17))]
12155   "TARGET_QIMODE_MATH"
12156   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12157
12158 (define_insn "*lshrqi3_1_one_bit"
12159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12160         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12161                      (match_operand:QI 2 "const1_operand" "")))
12162    (clobber (reg:CC 17))]
12163   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12164    && (TARGET_SHIFT1 || optimize_size)"
12165   "shr{b}\t%0"
12166   [(set_attr "type" "ishift")
12167    (set (attr "length") 
12168      (if_then_else (match_operand 0 "register_operand" "") 
12169         (const_string "2")
12170         (const_string "*")))])
12171
12172 (define_insn "*lshrqi3_1_one_bit_slp"
12173   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12174         (lshiftrt:QI (match_dup 0)
12175                      (match_operand:QI 1 "const1_operand" "")))
12176    (clobber (reg:CC 17))]
12177   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12178    && (TARGET_SHIFT1 || optimize_size)"
12179   "shr{b}\t%0"
12180   [(set_attr "type" "ishift1")
12181    (set (attr "length") 
12182      (if_then_else (match_operand 0 "register_operand" "") 
12183         (const_string "2")
12184         (const_string "*")))])
12185
12186 (define_insn "*lshrqi3_1"
12187   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190    (clobber (reg:CC 17))]
12191   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12192   "@
12193    shr{b}\t{%2, %0|%0, %2}
12194    shr{b}\t{%b2, %0|%0, %b2}"
12195   [(set_attr "type" "ishift")
12196    (set_attr "mode" "QI")])
12197
12198 (define_insn "*lshrqi3_1_slp"
12199   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12200         (lshiftrt:QI (match_dup 0)
12201                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12202    (clobber (reg:CC 17))]
12203   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12204    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12205   "@
12206    shr{b}\t{%1, %0|%0, %1}
12207    shr{b}\t{%b1, %0|%0, %b1}"
12208   [(set_attr "type" "ishift1")
12209    (set_attr "mode" "QI")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags.  We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrqi2_one_bit_cmp"
12215   [(set (reg 17)
12216         (compare
12217           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218                        (match_operand:QI 2 "const1_operand" ""))
12219           (const_int 0)))
12220    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12222   "ix86_match_ccmode (insn, CCGOCmode)
12223    && (TARGET_SHIFT1 || optimize_size)
12224    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12225   "shr{b}\t%0"
12226   [(set_attr "type" "ishift")
12227    (set (attr "length") 
12228      (if_then_else (match_operand:SI 0 "register_operand" "") 
12229         (const_string "2")
12230         (const_string "*")))])
12231
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags.  We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*lshrqi2_cmp"
12236   [(set (reg 17)
12237         (compare
12238           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12239                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12240           (const_int 0)))
12241    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12242         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12243   "ix86_match_ccmode (insn, CCGOCmode)
12244    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12245   "shr{b}\t{%2, %0|%0, %2}"
12246   [(set_attr "type" "ishift")
12247    (set_attr "mode" "QI")])
12248 \f
12249 ;; Rotate instructions
12250
12251 (define_expand "rotldi3"
12252   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12253         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12254                    (match_operand:QI 2 "nonmemory_operand" "")))
12255    (clobber (reg:CC 17))]
12256   "TARGET_64BIT"
12257   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12258
12259 (define_insn "*rotlsi3_1_one_bit_rex64"
12260   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12261         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12262                    (match_operand:QI 2 "const1_operand" "")))
12263    (clobber (reg:CC 17))]
12264   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12265    && (TARGET_SHIFT1 || optimize_size)"
12266   "rol{q}\t%0"
12267   [(set_attr "type" "rotate")
12268    (set (attr "length") 
12269      (if_then_else (match_operand:DI 0 "register_operand" "") 
12270         (const_string "2")
12271         (const_string "*")))])
12272
12273 (define_insn "*rotldi3_1_rex64"
12274   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12275         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12276                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12277    (clobber (reg:CC 17))]
12278   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12279   "@
12280    rol{q}\t{%2, %0|%0, %2}
12281    rol{q}\t{%b2, %0|%0, %b2}"
12282   [(set_attr "type" "rotate")
12283    (set_attr "mode" "DI")])
12284
12285 (define_expand "rotlsi3"
12286   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12287         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12288                    (match_operand:QI 2 "nonmemory_operand" "")))
12289    (clobber (reg:CC 17))]
12290   ""
12291   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12292
12293 (define_insn "*rotlsi3_1_one_bit"
12294   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12295         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12296                    (match_operand:QI 2 "const1_operand" "")))
12297    (clobber (reg:CC 17))]
12298   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12299    && (TARGET_SHIFT1 || optimize_size)"
12300   "rol{l}\t%0"
12301   [(set_attr "type" "rotate")
12302    (set (attr "length") 
12303      (if_then_else (match_operand:SI 0 "register_operand" "") 
12304         (const_string "2")
12305         (const_string "*")))])
12306
12307 (define_insn "*rotlsi3_1_one_bit_zext"
12308   [(set (match_operand:DI 0 "register_operand" "=r")
12309         (zero_extend:DI
12310           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12311                      (match_operand:QI 2 "const1_operand" ""))))
12312    (clobber (reg:CC 17))]
12313   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12314    && (TARGET_SHIFT1 || optimize_size)"
12315   "rol{l}\t%k0"
12316   [(set_attr "type" "rotate")
12317    (set_attr "length" "2")])
12318
12319 (define_insn "*rotlsi3_1"
12320   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12321         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12322                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12323    (clobber (reg:CC 17))]
12324   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12325   "@
12326    rol{l}\t{%2, %0|%0, %2}
12327    rol{l}\t{%b2, %0|%0, %b2}"
12328   [(set_attr "type" "rotate")
12329    (set_attr "mode" "SI")])
12330
12331 (define_insn "*rotlsi3_1_zext"
12332   [(set (match_operand:DI 0 "register_operand" "=r,r")
12333         (zero_extend:DI
12334           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12335                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12336    (clobber (reg:CC 17))]
12337   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12338   "@
12339    rol{l}\t{%2, %k0|%k0, %2}
12340    rol{l}\t{%b2, %k0|%k0, %b2}"
12341   [(set_attr "type" "rotate")
12342    (set_attr "mode" "SI")])
12343
12344 (define_expand "rotlhi3"
12345   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12346         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12347                    (match_operand:QI 2 "nonmemory_operand" "")))
12348    (clobber (reg:CC 17))]
12349   "TARGET_HIMODE_MATH"
12350   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12351
12352 (define_insn "*rotlhi3_1_one_bit"
12353   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12355                    (match_operand:QI 2 "const1_operand" "")))
12356    (clobber (reg:CC 17))]
12357   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12358    && (TARGET_SHIFT1 || optimize_size)"
12359   "rol{w}\t%0"
12360   [(set_attr "type" "rotate")
12361    (set (attr "length") 
12362      (if_then_else (match_operand 0 "register_operand" "") 
12363         (const_string "2")
12364         (const_string "*")))])
12365
12366 (define_insn "*rotlhi3_1"
12367   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12368         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12369                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370    (clobber (reg:CC 17))]
12371   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12372   "@
12373    rol{w}\t{%2, %0|%0, %2}
12374    rol{w}\t{%b2, %0|%0, %b2}"
12375   [(set_attr "type" "rotate")
12376    (set_attr "mode" "HI")])
12377
12378 (define_expand "rotlqi3"
12379   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12380         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12381                    (match_operand:QI 2 "nonmemory_operand" "")))
12382    (clobber (reg:CC 17))]
12383   "TARGET_QIMODE_MATH"
12384   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12385
12386 (define_insn "*rotlqi3_1_one_bit_slp"
12387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388         (rotate:QI (match_dup 0)
12389                    (match_operand:QI 1 "const1_operand" "")))
12390    (clobber (reg:CC 17))]
12391   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392    && (TARGET_SHIFT1 || optimize_size)"
12393   "rol{b}\t%0"
12394   [(set_attr "type" "rotate1")
12395    (set (attr "length") 
12396      (if_then_else (match_operand 0 "register_operand" "") 
12397         (const_string "2")
12398         (const_string "*")))])
12399
12400 (define_insn "*rotlqi3_1_one_bit"
12401   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12402         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12403                    (match_operand:QI 2 "const1_operand" "")))
12404    (clobber (reg:CC 17))]
12405   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12406    && (TARGET_SHIFT1 || optimize_size)"
12407   "rol{b}\t%0"
12408   [(set_attr "type" "rotate")
12409    (set (attr "length") 
12410      (if_then_else (match_operand 0 "register_operand" "") 
12411         (const_string "2")
12412         (const_string "*")))])
12413
12414 (define_insn "*rotlqi3_1_slp"
12415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12416         (rotate:QI (match_dup 0)
12417                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12418    (clobber (reg:CC 17))]
12419   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12420    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12421   "@
12422    rol{b}\t{%1, %0|%0, %1}
12423    rol{b}\t{%b1, %0|%0, %b1}"
12424   [(set_attr "type" "rotate1")
12425    (set_attr "mode" "QI")])
12426
12427 (define_insn "*rotlqi3_1"
12428   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12429         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12430                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431    (clobber (reg:CC 17))]
12432   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12433   "@
12434    rol{b}\t{%2, %0|%0, %2}
12435    rol{b}\t{%b2, %0|%0, %b2}"
12436   [(set_attr "type" "rotate")
12437    (set_attr "mode" "QI")])
12438
12439 (define_expand "rotrdi3"
12440   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12441         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12442                      (match_operand:QI 2 "nonmemory_operand" "")))
12443    (clobber (reg:CC 17))]
12444   "TARGET_64BIT"
12445   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12446
12447 (define_insn "*rotrdi3_1_one_bit_rex64"
12448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12449         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12450                      (match_operand:QI 2 "const1_operand" "")))
12451    (clobber (reg:CC 17))]
12452   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12453    && (TARGET_SHIFT1 || optimize_size)"
12454   "ror{q}\t%0"
12455   [(set_attr "type" "rotate")
12456    (set (attr "length") 
12457      (if_then_else (match_operand:DI 0 "register_operand" "") 
12458         (const_string "2")
12459         (const_string "*")))])
12460
12461 (define_insn "*rotrdi3_1_rex64"
12462   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12463         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12464                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12465    (clobber (reg:CC 17))]
12466   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12467   "@
12468    ror{q}\t{%2, %0|%0, %2}
12469    ror{q}\t{%b2, %0|%0, %b2}"
12470   [(set_attr "type" "rotate")
12471    (set_attr "mode" "DI")])
12472
12473 (define_expand "rotrsi3"
12474   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12475         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12476                      (match_operand:QI 2 "nonmemory_operand" "")))
12477    (clobber (reg:CC 17))]
12478   ""
12479   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12480
12481 (define_insn "*rotrsi3_1_one_bit"
12482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12483         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12484                      (match_operand:QI 2 "const1_operand" "")))
12485    (clobber (reg:CC 17))]
12486   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12487    && (TARGET_SHIFT1 || optimize_size)"
12488   "ror{l}\t%0"
12489   [(set_attr "type" "rotate")
12490    (set (attr "length") 
12491      (if_then_else (match_operand:SI 0 "register_operand" "") 
12492         (const_string "2")
12493         (const_string "*")))])
12494
12495 (define_insn "*rotrsi3_1_one_bit_zext"
12496   [(set (match_operand:DI 0 "register_operand" "=r")
12497         (zero_extend:DI
12498           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12499                        (match_operand:QI 2 "const1_operand" ""))))
12500    (clobber (reg:CC 17))]
12501   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12502    && (TARGET_SHIFT1 || optimize_size)"
12503   "ror{l}\t%k0"
12504   [(set_attr "type" "rotate")
12505    (set (attr "length") 
12506      (if_then_else (match_operand:SI 0 "register_operand" "") 
12507         (const_string "2")
12508         (const_string "*")))])
12509
12510 (define_insn "*rotrsi3_1"
12511   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12512         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12513                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12514    (clobber (reg:CC 17))]
12515   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12516   "@
12517    ror{l}\t{%2, %0|%0, %2}
12518    ror{l}\t{%b2, %0|%0, %b2}"
12519   [(set_attr "type" "rotate")
12520    (set_attr "mode" "SI")])
12521
12522 (define_insn "*rotrsi3_1_zext"
12523   [(set (match_operand:DI 0 "register_operand" "=r,r")
12524         (zero_extend:DI
12525           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12526                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12527    (clobber (reg:CC 17))]
12528   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12529   "@
12530    ror{l}\t{%2, %k0|%k0, %2}
12531    ror{l}\t{%b2, %k0|%k0, %b2}"
12532   [(set_attr "type" "rotate")
12533    (set_attr "mode" "SI")])
12534
12535 (define_expand "rotrhi3"
12536   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12537         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12538                      (match_operand:QI 2 "nonmemory_operand" "")))
12539    (clobber (reg:CC 17))]
12540   "TARGET_HIMODE_MATH"
12541   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12542
12543 (define_insn "*rotrhi3_one_bit"
12544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12545         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12546                      (match_operand:QI 2 "const1_operand" "")))
12547    (clobber (reg:CC 17))]
12548   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12549    && (TARGET_SHIFT1 || optimize_size)"
12550   "ror{w}\t%0"
12551   [(set_attr "type" "rotate")
12552    (set (attr "length") 
12553      (if_then_else (match_operand 0 "register_operand" "") 
12554         (const_string "2")
12555         (const_string "*")))])
12556
12557 (define_insn "*rotrhi3"
12558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12559         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12560                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561    (clobber (reg:CC 17))]
12562   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12563   "@
12564    ror{w}\t{%2, %0|%0, %2}
12565    ror{w}\t{%b2, %0|%0, %b2}"
12566   [(set_attr "type" "rotate")
12567    (set_attr "mode" "HI")])
12568
12569 (define_expand "rotrqi3"
12570   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12571         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12572                      (match_operand:QI 2 "nonmemory_operand" "")))
12573    (clobber (reg:CC 17))]
12574   "TARGET_QIMODE_MATH"
12575   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12576
12577 (define_insn "*rotrqi3_1_one_bit"
12578   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12579         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12580                      (match_operand:QI 2 "const1_operand" "")))
12581    (clobber (reg:CC 17))]
12582   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12583    && (TARGET_SHIFT1 || optimize_size)"
12584   "ror{b}\t%0"
12585   [(set_attr "type" "rotate")
12586    (set (attr "length") 
12587      (if_then_else (match_operand 0 "register_operand" "") 
12588         (const_string "2")
12589         (const_string "*")))])
12590
12591 (define_insn "*rotrqi3_1_one_bit_slp"
12592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12593         (rotatert:QI (match_dup 0)
12594                      (match_operand:QI 1 "const1_operand" "")))
12595    (clobber (reg:CC 17))]
12596   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12597    && (TARGET_SHIFT1 || optimize_size)"
12598   "ror{b}\t%0"
12599   [(set_attr "type" "rotate1")
12600    (set (attr "length") 
12601      (if_then_else (match_operand 0 "register_operand" "") 
12602         (const_string "2")
12603         (const_string "*")))])
12604
12605 (define_insn "*rotrqi3_1"
12606   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12607         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12608                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12609    (clobber (reg:CC 17))]
12610   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12611   "@
12612    ror{b}\t{%2, %0|%0, %2}
12613    ror{b}\t{%b2, %0|%0, %b2}"
12614   [(set_attr "type" "rotate")
12615    (set_attr "mode" "QI")])
12616
12617 (define_insn "*rotrqi3_1_slp"
12618   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12619         (rotatert:QI (match_dup 0)
12620                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12621    (clobber (reg:CC 17))]
12622   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12623    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12624   "@
12625    ror{b}\t{%1, %0|%0, %1}
12626    ror{b}\t{%b1, %0|%0, %b1}"
12627   [(set_attr "type" "rotate1")
12628    (set_attr "mode" "QI")])
12629 \f
12630 ;; Bit set / bit test instructions
12631
12632 (define_expand "extv"
12633   [(set (match_operand:SI 0 "register_operand" "")
12634         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12635                          (match_operand:SI 2 "immediate_operand" "")
12636                          (match_operand:SI 3 "immediate_operand" "")))]
12637   ""
12638 {
12639   /* Handle extractions from %ah et al.  */
12640   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12641     FAIL;
12642
12643   /* From mips.md: extract_bit_field doesn't verify that our source
12644      matches the predicate, so check it again here.  */
12645   if (! register_operand (operands[1], VOIDmode))
12646     FAIL;
12647 })
12648
12649 (define_expand "extzv"
12650   [(set (match_operand:SI 0 "register_operand" "")
12651         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12652                          (match_operand:SI 2 "immediate_operand" "")
12653                          (match_operand:SI 3 "immediate_operand" "")))]
12654   ""
12655 {
12656   /* Handle extractions from %ah et al.  */
12657   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12658     FAIL;
12659
12660   /* From mips.md: extract_bit_field doesn't verify that our source
12661      matches the predicate, so check it again here.  */
12662   if (! register_operand (operands[1], VOIDmode))
12663     FAIL;
12664 })
12665
12666 (define_expand "insv"
12667   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12668                          (match_operand:SI 1 "immediate_operand" "")
12669                          (match_operand:SI 2 "immediate_operand" ""))
12670         (match_operand:SI 3 "register_operand" ""))]
12671   ""
12672 {
12673   /* Handle extractions from %ah et al.  */
12674   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12675     FAIL;
12676
12677   /* From mips.md: insert_bit_field doesn't verify that our source
12678      matches the predicate, so check it again here.  */
12679   if (! register_operand (operands[0], VOIDmode))
12680     FAIL;
12681 })
12682
12683 ;; %%% bts, btr, btc, bt.
12684 \f
12685 ;; Store-flag instructions.
12686
12687 ;; For all sCOND expanders, also expand the compare or test insn that
12688 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12689
12690 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12691 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12692 ;; way, which can later delete the movzx if only QImode is needed.
12693
12694 (define_expand "seq"
12695   [(set (match_operand:QI 0 "register_operand" "")
12696         (eq:QI (reg:CC 17) (const_int 0)))]
12697   ""
12698   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12699
12700 (define_expand "sne"
12701   [(set (match_operand:QI 0 "register_operand" "")
12702         (ne:QI (reg:CC 17) (const_int 0)))]
12703   ""
12704   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12705
12706 (define_expand "sgt"
12707   [(set (match_operand:QI 0 "register_operand" "")
12708         (gt:QI (reg:CC 17) (const_int 0)))]
12709   ""
12710   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12711
12712 (define_expand "sgtu"
12713   [(set (match_operand:QI 0 "register_operand" "")
12714         (gtu:QI (reg:CC 17) (const_int 0)))]
12715   ""
12716   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12717
12718 (define_expand "slt"
12719   [(set (match_operand:QI 0 "register_operand" "")
12720         (lt:QI (reg:CC 17) (const_int 0)))]
12721   ""
12722   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12723
12724 (define_expand "sltu"
12725   [(set (match_operand:QI 0 "register_operand" "")
12726         (ltu:QI (reg:CC 17) (const_int 0)))]
12727   ""
12728   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12729
12730 (define_expand "sge"
12731   [(set (match_operand:QI 0 "register_operand" "")
12732         (ge:QI (reg:CC 17) (const_int 0)))]
12733   ""
12734   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12735
12736 (define_expand "sgeu"
12737   [(set (match_operand:QI 0 "register_operand" "")
12738         (geu:QI (reg:CC 17) (const_int 0)))]
12739   ""
12740   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12741
12742 (define_expand "sle"
12743   [(set (match_operand:QI 0 "register_operand" "")
12744         (le:QI (reg:CC 17) (const_int 0)))]
12745   ""
12746   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12747
12748 (define_expand "sleu"
12749   [(set (match_operand:QI 0 "register_operand" "")
12750         (leu:QI (reg:CC 17) (const_int 0)))]
12751   ""
12752   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12753
12754 (define_expand "sunordered"
12755   [(set (match_operand:QI 0 "register_operand" "")
12756         (unordered:QI (reg:CC 17) (const_int 0)))]
12757   "TARGET_80387 || TARGET_SSE"
12758   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12759
12760 (define_expand "sordered"
12761   [(set (match_operand:QI 0 "register_operand" "")
12762         (ordered:QI (reg:CC 17) (const_int 0)))]
12763   "TARGET_80387"
12764   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12765
12766 (define_expand "suneq"
12767   [(set (match_operand:QI 0 "register_operand" "")
12768         (uneq:QI (reg:CC 17) (const_int 0)))]
12769   "TARGET_80387 || TARGET_SSE"
12770   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12771
12772 (define_expand "sunge"
12773   [(set (match_operand:QI 0 "register_operand" "")
12774         (unge:QI (reg:CC 17) (const_int 0)))]
12775   "TARGET_80387 || TARGET_SSE"
12776   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12777
12778 (define_expand "sungt"
12779   [(set (match_operand:QI 0 "register_operand" "")
12780         (ungt:QI (reg:CC 17) (const_int 0)))]
12781   "TARGET_80387 || TARGET_SSE"
12782   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12783
12784 (define_expand "sunle"
12785   [(set (match_operand:QI 0 "register_operand" "")
12786         (unle:QI (reg:CC 17) (const_int 0)))]
12787   "TARGET_80387 || TARGET_SSE"
12788   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12789
12790 (define_expand "sunlt"
12791   [(set (match_operand:QI 0 "register_operand" "")
12792         (unlt:QI (reg:CC 17) (const_int 0)))]
12793   "TARGET_80387 || TARGET_SSE"
12794   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12795
12796 (define_expand "sltgt"
12797   [(set (match_operand:QI 0 "register_operand" "")
12798         (ltgt:QI (reg:CC 17) (const_int 0)))]
12799   "TARGET_80387 || TARGET_SSE"
12800   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12801
12802 (define_insn "*setcc_1"
12803   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804         (match_operator:QI 1 "ix86_comparison_operator"
12805           [(reg 17) (const_int 0)]))]
12806   ""
12807   "set%C1\t%0"
12808   [(set_attr "type" "setcc")
12809    (set_attr "mode" "QI")])
12810
12811 (define_insn "setcc_2"
12812   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12813         (match_operator:QI 1 "ix86_comparison_operator"
12814           [(reg 17) (const_int 0)]))]
12815   ""
12816   "set%C1\t%0"
12817   [(set_attr "type" "setcc")
12818    (set_attr "mode" "QI")])
12819
12820 ;; In general it is not safe to assume too much about CCmode registers,
12821 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12822 ;; conditions this is safe on x86, so help combine not create
12823 ;;
12824 ;;      seta    %al
12825 ;;      testb   %al, %al
12826 ;;      sete    %al
12827
12828 (define_split 
12829   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12830         (ne:QI (match_operator 1 "ix86_comparison_operator"
12831                  [(reg 17) (const_int 0)])
12832             (const_int 0)))]
12833   ""
12834   [(set (match_dup 0) (match_dup 1))]
12835 {
12836   PUT_MODE (operands[1], QImode);
12837 })
12838
12839 (define_split 
12840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12841         (ne:QI (match_operator 1 "ix86_comparison_operator"
12842                  [(reg 17) (const_int 0)])
12843             (const_int 0)))]
12844   ""
12845   [(set (match_dup 0) (match_dup 1))]
12846 {
12847   PUT_MODE (operands[1], QImode);
12848 })
12849
12850 (define_split 
12851   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12852         (eq:QI (match_operator 1 "ix86_comparison_operator"
12853                  [(reg 17) (const_int 0)])
12854             (const_int 0)))]
12855   ""
12856   [(set (match_dup 0) (match_dup 1))]
12857 {
12858   rtx new_op1 = copy_rtx (operands[1]);
12859   operands[1] = new_op1;
12860   PUT_MODE (new_op1, QImode);
12861   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12862                                         GET_MODE (XEXP (new_op1, 0))));
12863
12864   /* Make sure that (a) the CCmode we have for the flags is strong
12865      enough for the reversed compare or (b) we have a valid FP compare.  */
12866   if (! ix86_comparison_operator (new_op1, VOIDmode))
12867     FAIL;
12868 })
12869
12870 (define_split 
12871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12872         (eq:QI (match_operator 1 "ix86_comparison_operator"
12873                  [(reg 17) (const_int 0)])
12874             (const_int 0)))]
12875   ""
12876   [(set (match_dup 0) (match_dup 1))]
12877 {
12878   rtx new_op1 = copy_rtx (operands[1]);
12879   operands[1] = new_op1;
12880   PUT_MODE (new_op1, QImode);
12881   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12882                                         GET_MODE (XEXP (new_op1, 0))));
12883
12884   /* Make sure that (a) the CCmode we have for the flags is strong
12885      enough for the reversed compare or (b) we have a valid FP compare.  */
12886   if (! ix86_comparison_operator (new_op1, VOIDmode))
12887     FAIL;
12888 })
12889
12890 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12891 ;; subsequent logical operations are used to imitate conditional moves.
12892 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12893 ;; it directly.  Further holding this value in pseudo register might bring
12894 ;; problem in implicit normalization in spill code.
12895 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12896 ;; instructions after reload by splitting the conditional move patterns.
12897
12898 (define_insn "*sse_setccsf"
12899   [(set (match_operand:SF 0 "register_operand" "=x")
12900         (match_operator:SF 1 "sse_comparison_operator"
12901           [(match_operand:SF 2 "register_operand" "0")
12902            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12903   "TARGET_SSE && reload_completed"
12904   "cmp%D1ss\t{%3, %0|%0, %3}"
12905   [(set_attr "type" "ssecmp")
12906    (set_attr "mode" "SF")])
12907
12908 (define_insn "*sse_setccdf"
12909   [(set (match_operand:DF 0 "register_operand" "=Y")
12910         (match_operator:DF 1 "sse_comparison_operator"
12911           [(match_operand:DF 2 "register_operand" "0")
12912            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12913   "TARGET_SSE2 && reload_completed"
12914   "cmp%D1sd\t{%3, %0|%0, %3}"
12915   [(set_attr "type" "ssecmp")
12916    (set_attr "mode" "DF")])
12917 \f
12918 ;; Basic conditional jump instructions.
12919 ;; We ignore the overflow flag for signed branch instructions.
12920
12921 ;; For all bCOND expanders, also expand the compare or test insn that
12922 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12923
12924 (define_expand "beq"
12925   [(set (pc)
12926         (if_then_else (match_dup 1)
12927                       (label_ref (match_operand 0 "" ""))
12928                       (pc)))]
12929   ""
12930   "ix86_expand_branch (EQ, operands[0]); DONE;")
12931
12932 (define_expand "bne"
12933   [(set (pc)
12934         (if_then_else (match_dup 1)
12935                       (label_ref (match_operand 0 "" ""))
12936                       (pc)))]
12937   ""
12938   "ix86_expand_branch (NE, operands[0]); DONE;")
12939
12940 (define_expand "bgt"
12941   [(set (pc)
12942         (if_then_else (match_dup 1)
12943                       (label_ref (match_operand 0 "" ""))
12944                       (pc)))]
12945   ""
12946   "ix86_expand_branch (GT, operands[0]); DONE;")
12947
12948 (define_expand "bgtu"
12949   [(set (pc)
12950         (if_then_else (match_dup 1)
12951                       (label_ref (match_operand 0 "" ""))
12952                       (pc)))]
12953   ""
12954   "ix86_expand_branch (GTU, operands[0]); DONE;")
12955
12956 (define_expand "blt"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (LT, operands[0]); DONE;")
12963
12964 (define_expand "bltu"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (LTU, operands[0]); DONE;")
12971
12972 (define_expand "bge"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "ix86_expand_branch (GE, operands[0]); DONE;")
12979
12980 (define_expand "bgeu"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   ""
12986   "ix86_expand_branch (GEU, operands[0]); DONE;")
12987
12988 (define_expand "ble"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   ""
12994   "ix86_expand_branch (LE, operands[0]); DONE;")
12995
12996 (define_expand "bleu"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   ""
13002   "ix86_expand_branch (LEU, operands[0]); DONE;")
13003
13004 (define_expand "bunordered"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   "TARGET_80387 || TARGET_SSE"
13010   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13011
13012 (define_expand "bordered"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   "TARGET_80387 || TARGET_SSE"
13018   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13019
13020 (define_expand "buneq"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   "TARGET_80387 || TARGET_SSE"
13026   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13027
13028 (define_expand "bunge"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   "TARGET_80387 || TARGET_SSE"
13034   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13035
13036 (define_expand "bungt"
13037   [(set (pc)
13038         (if_then_else (match_dup 1)
13039                       (label_ref (match_operand 0 "" ""))
13040                       (pc)))]
13041   "TARGET_80387 || TARGET_SSE"
13042   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13043
13044 (define_expand "bunle"
13045   [(set (pc)
13046         (if_then_else (match_dup 1)
13047                       (label_ref (match_operand 0 "" ""))
13048                       (pc)))]
13049   "TARGET_80387 || TARGET_SSE"
13050   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13051
13052 (define_expand "bunlt"
13053   [(set (pc)
13054         (if_then_else (match_dup 1)
13055                       (label_ref (match_operand 0 "" ""))
13056                       (pc)))]
13057   "TARGET_80387 || TARGET_SSE"
13058   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13059
13060 (define_expand "bltgt"
13061   [(set (pc)
13062         (if_then_else (match_dup 1)
13063                       (label_ref (match_operand 0 "" ""))
13064                       (pc)))]
13065   "TARGET_80387 || TARGET_SSE"
13066   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13067
13068 (define_insn "*jcc_1"
13069   [(set (pc)
13070         (if_then_else (match_operator 1 "ix86_comparison_operator"
13071                                       [(reg 17) (const_int 0)])
13072                       (label_ref (match_operand 0 "" ""))
13073                       (pc)))]
13074   ""
13075   "%+j%C1\t%l0"
13076   [(set_attr "type" "ibr")
13077    (set_attr "modrm" "0")
13078    (set (attr "length")
13079            (if_then_else (and (ge (minus (match_dup 0) (pc))
13080                                   (const_int -126))
13081                               (lt (minus (match_dup 0) (pc))
13082                                   (const_int 128)))
13083              (const_int 2)
13084              (const_int 6)))])
13085
13086 (define_insn "*jcc_2"
13087   [(set (pc)
13088         (if_then_else (match_operator 1 "ix86_comparison_operator"
13089                                       [(reg 17) (const_int 0)])
13090                       (pc)
13091                       (label_ref (match_operand 0 "" ""))))]
13092   ""
13093   "%+j%c1\t%l0"
13094   [(set_attr "type" "ibr")
13095    (set_attr "modrm" "0")
13096    (set (attr "length")
13097            (if_then_else (and (ge (minus (match_dup 0) (pc))
13098                                   (const_int -126))
13099                               (lt (minus (match_dup 0) (pc))
13100                                   (const_int 128)))
13101              (const_int 2)
13102              (const_int 6)))])
13103
13104 ;; In general it is not safe to assume too much about CCmode registers,
13105 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13106 ;; conditions this is safe on x86, so help combine not create
13107 ;;
13108 ;;      seta    %al
13109 ;;      testb   %al, %al
13110 ;;      je      Lfoo
13111
13112 (define_split 
13113   [(set (pc)
13114         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13115                                       [(reg 17) (const_int 0)])
13116                           (const_int 0))
13117                       (label_ref (match_operand 1 "" ""))
13118                       (pc)))]
13119   ""
13120   [(set (pc)
13121         (if_then_else (match_dup 0)
13122                       (label_ref (match_dup 1))
13123                       (pc)))]
13124 {
13125   PUT_MODE (operands[0], VOIDmode);
13126 })
13127   
13128 (define_split 
13129   [(set (pc)
13130         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13131                                       [(reg 17) (const_int 0)])
13132                           (const_int 0))
13133                       (label_ref (match_operand 1 "" ""))
13134                       (pc)))]
13135   ""
13136   [(set (pc)
13137         (if_then_else (match_dup 0)
13138                       (label_ref (match_dup 1))
13139                       (pc)))]
13140 {
13141   rtx new_op0 = copy_rtx (operands[0]);
13142   operands[0] = new_op0;
13143   PUT_MODE (new_op0, VOIDmode);
13144   PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13145                                         GET_MODE (XEXP (new_op0, 0))));
13146
13147   /* Make sure that (a) the CCmode we have for the flags is strong
13148      enough for the reversed compare or (b) we have a valid FP compare.  */
13149   if (! ix86_comparison_operator (new_op0, VOIDmode))
13150     FAIL;
13151 })
13152
13153 ;; Define combination compare-and-branch fp compare instructions to use
13154 ;; during early optimization.  Splitting the operation apart early makes
13155 ;; for bad code when we want to reverse the operation.
13156
13157 (define_insn "*fp_jcc_1"
13158   [(set (pc)
13159         (if_then_else (match_operator 0 "comparison_operator"
13160                         [(match_operand 1 "register_operand" "f")
13161                          (match_operand 2 "register_operand" "f")])
13162           (label_ref (match_operand 3 "" ""))
13163           (pc)))
13164    (clobber (reg:CCFP 18))
13165    (clobber (reg:CCFP 17))]
13166   "TARGET_CMOVE && TARGET_80387
13167    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13168    && FLOAT_MODE_P (GET_MODE (operands[1]))
13169    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13170    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171   "#")
13172
13173 (define_insn "*fp_jcc_1_sse"
13174   [(set (pc)
13175         (if_then_else (match_operator 0 "comparison_operator"
13176                         [(match_operand 1 "register_operand" "f#x,x#f")
13177                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13178           (label_ref (match_operand 3 "" ""))
13179           (pc)))
13180    (clobber (reg:CCFP 18))
13181    (clobber (reg:CCFP 17))]
13182   "TARGET_80387
13183    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13185    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186   "#")
13187
13188 (define_insn "*fp_jcc_1_sse_only"
13189   [(set (pc)
13190         (if_then_else (match_operator 0 "comparison_operator"
13191                         [(match_operand 1 "register_operand" "x")
13192                          (match_operand 2 "nonimmediate_operand" "xm")])
13193           (label_ref (match_operand 3 "" ""))
13194           (pc)))
13195    (clobber (reg:CCFP 18))
13196    (clobber (reg:CCFP 17))]
13197   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13198    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13200   "#")
13201
13202 (define_insn "*fp_jcc_2"
13203   [(set (pc)
13204         (if_then_else (match_operator 0 "comparison_operator"
13205                         [(match_operand 1 "register_operand" "f")
13206                          (match_operand 2 "register_operand" "f")])
13207           (pc)
13208           (label_ref (match_operand 3 "" ""))))
13209    (clobber (reg:CCFP 18))
13210    (clobber (reg:CCFP 17))]
13211   "TARGET_CMOVE && TARGET_80387
13212    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13213    && FLOAT_MODE_P (GET_MODE (operands[1]))
13214    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13215    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13216   "#")
13217
13218 (define_insn "*fp_jcc_2_sse"
13219   [(set (pc)
13220         (if_then_else (match_operator 0 "comparison_operator"
13221                         [(match_operand 1 "register_operand" "f#x,x#f")
13222                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13223           (pc)
13224           (label_ref (match_operand 3 "" ""))))
13225    (clobber (reg:CCFP 18))
13226    (clobber (reg:CCFP 17))]
13227   "TARGET_80387
13228    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13229    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13230    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13231   "#")
13232
13233 (define_insn "*fp_jcc_2_sse_only"
13234   [(set (pc)
13235         (if_then_else (match_operator 0 "comparison_operator"
13236                         [(match_operand 1 "register_operand" "x")
13237                          (match_operand 2 "nonimmediate_operand" "xm")])
13238           (pc)
13239           (label_ref (match_operand 3 "" ""))))
13240    (clobber (reg:CCFP 18))
13241    (clobber (reg:CCFP 17))]
13242   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13243    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13244    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13245   "#")
13246
13247 (define_insn "*fp_jcc_3"
13248   [(set (pc)
13249         (if_then_else (match_operator 0 "comparison_operator"
13250                         [(match_operand 1 "register_operand" "f")
13251                          (match_operand 2 "nonimmediate_operand" "fm")])
13252           (label_ref (match_operand 3 "" ""))
13253           (pc)))
13254    (clobber (reg:CCFP 18))
13255    (clobber (reg:CCFP 17))
13256    (clobber (match_scratch:HI 4 "=a"))]
13257   "TARGET_80387
13258    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13259    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13260    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13261    && SELECT_CC_MODE (GET_CODE (operands[0]),
13262                       operands[1], operands[2]) == CCFPmode
13263    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13264   "#")
13265
13266 (define_insn "*fp_jcc_4"
13267   [(set (pc)
13268         (if_then_else (match_operator 0 "comparison_operator"
13269                         [(match_operand 1 "register_operand" "f")
13270                          (match_operand 2 "nonimmediate_operand" "fm")])
13271           (pc)
13272           (label_ref (match_operand 3 "" ""))))
13273    (clobber (reg:CCFP 18))
13274    (clobber (reg:CCFP 17))
13275    (clobber (match_scratch:HI 4 "=a"))]
13276   "TARGET_80387
13277    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13278    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13279    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13280    && SELECT_CC_MODE (GET_CODE (operands[0]),
13281                       operands[1], operands[2]) == CCFPmode
13282    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283   "#")
13284
13285 (define_insn "*fp_jcc_5"
13286   [(set (pc)
13287         (if_then_else (match_operator 0 "comparison_operator"
13288                         [(match_operand 1 "register_operand" "f")
13289                          (match_operand 2 "register_operand" "f")])
13290           (label_ref (match_operand 3 "" ""))
13291           (pc)))
13292    (clobber (reg:CCFP 18))
13293    (clobber (reg:CCFP 17))
13294    (clobber (match_scratch:HI 4 "=a"))]
13295   "TARGET_80387
13296    && FLOAT_MODE_P (GET_MODE (operands[1]))
13297    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299   "#")
13300
13301 (define_insn "*fp_jcc_6"
13302   [(set (pc)
13303         (if_then_else (match_operator 0 "comparison_operator"
13304                         [(match_operand 1 "register_operand" "f")
13305                          (match_operand 2 "register_operand" "f")])
13306           (pc)
13307           (label_ref (match_operand 3 "" ""))))
13308    (clobber (reg:CCFP 18))
13309    (clobber (reg:CCFP 17))
13310    (clobber (match_scratch:HI 4 "=a"))]
13311   "TARGET_80387
13312    && FLOAT_MODE_P (GET_MODE (operands[1]))
13313    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13315   "#")
13316
13317 (define_split
13318   [(set (pc)
13319         (if_then_else (match_operator 0 "comparison_operator"
13320                         [(match_operand 1 "register_operand" "")
13321                          (match_operand 2 "nonimmediate_operand" "")])
13322           (match_operand 3 "" "")
13323           (match_operand 4 "" "")))
13324    (clobber (reg:CCFP 18))
13325    (clobber (reg:CCFP 17))]
13326   "reload_completed"
13327   [(const_int 0)]
13328 {
13329   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330                         operands[3], operands[4], NULL_RTX);
13331   DONE;
13332 })
13333
13334 (define_split
13335   [(set (pc)
13336         (if_then_else (match_operator 0 "comparison_operator"
13337                         [(match_operand 1 "register_operand" "")
13338                          (match_operand 2 "nonimmediate_operand" "")])
13339           (match_operand 3 "" "")
13340           (match_operand 4 "" "")))
13341    (clobber (reg:CCFP 18))
13342    (clobber (reg:CCFP 17))
13343    (clobber (match_scratch:HI 5 "=a"))]
13344   "reload_completed"
13345   [(set (pc)
13346         (if_then_else (match_dup 6)
13347           (match_dup 3)
13348           (match_dup 4)))]
13349 {
13350   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351                         operands[3], operands[4], operands[5]);
13352   DONE;
13353 })
13354 \f
13355 ;; Unconditional and other jump instructions
13356
13357 (define_insn "jump"
13358   [(set (pc)
13359         (label_ref (match_operand 0 "" "")))]
13360   ""
13361   "jmp\t%l0"
13362   [(set_attr "type" "ibr")
13363    (set (attr "length")
13364            (if_then_else (and (ge (minus (match_dup 0) (pc))
13365                                   (const_int -126))
13366                               (lt (minus (match_dup 0) (pc))
13367                                   (const_int 128)))
13368              (const_int 2)
13369              (const_int 5)))
13370    (set_attr "modrm" "0")])
13371
13372 (define_expand "indirect_jump"
13373   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13374   ""
13375   "")
13376
13377 (define_insn "*indirect_jump"
13378   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13379   "!TARGET_64BIT"
13380   "jmp\t%A0"
13381   [(set_attr "type" "ibr")
13382    (set_attr "length_immediate" "0")])
13383
13384 (define_insn "*indirect_jump_rtx64"
13385   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13386   "TARGET_64BIT"
13387   "jmp\t%A0"
13388   [(set_attr "type" "ibr")
13389    (set_attr "length_immediate" "0")])
13390
13391 (define_expand "tablejump"
13392   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13393               (use (label_ref (match_operand 1 "" "")))])]
13394   ""
13395 {
13396   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13397      relative.  Convert the relative address to an absolute address.  */
13398   if (flag_pic)
13399     {
13400       rtx op0, op1;
13401       enum rtx_code code;
13402
13403       if (TARGET_64BIT)
13404         {
13405           code = PLUS;
13406           op0 = operands[0];
13407           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13408         }
13409       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13410         {
13411           code = PLUS;
13412           op0 = operands[0];
13413           op1 = pic_offset_table_rtx;
13414         }
13415       else
13416         {
13417           code = MINUS;
13418           op0 = pic_offset_table_rtx;
13419           op1 = operands[0];
13420         }
13421
13422       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13423                                          OPTAB_DIRECT);
13424     }
13425 })
13426
13427 (define_insn "*tablejump_1"
13428   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13429    (use (label_ref (match_operand 1 "" "")))]
13430   "!TARGET_64BIT"
13431   "jmp\t%A0"
13432   [(set_attr "type" "ibr")
13433    (set_attr "length_immediate" "0")])
13434
13435 (define_insn "*tablejump_1_rtx64"
13436   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13437    (use (label_ref (match_operand 1 "" "")))]
13438   "TARGET_64BIT"
13439   "jmp\t%A0"
13440   [(set_attr "type" "ibr")
13441    (set_attr "length_immediate" "0")])
13442 \f
13443 ;; Loop instruction
13444 ;;
13445 ;; This is all complicated by the fact that since this is a jump insn
13446 ;; we must handle our own reloads.
13447
13448 (define_expand "doloop_end"
13449   [(use (match_operand 0 "" ""))        ; loop pseudo
13450    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13451    (use (match_operand 2 "" ""))        ; max iterations
13452    (use (match_operand 3 "" ""))        ; loop level 
13453    (use (match_operand 4 "" ""))]       ; label
13454   "!TARGET_64BIT && TARGET_USE_LOOP"
13455   "                                 
13456 {
13457   /* Only use cloop on innermost loops.  */
13458   if (INTVAL (operands[3]) > 1)
13459     FAIL;
13460   if (GET_MODE (operands[0]) != SImode)
13461     FAIL;
13462   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13463                                            operands[0]));
13464   DONE;
13465 }")
13466
13467 (define_insn "doloop_end_internal"
13468   [(set (pc)
13469         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13470                           (const_int 1))
13471                       (label_ref (match_operand 0 "" ""))
13472                       (pc)))
13473    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13474         (plus:SI (match_dup 1)
13475                  (const_int -1)))
13476    (clobber (match_scratch:SI 3 "=X,X,r"))
13477    (clobber (reg:CC 17))]
13478   "!TARGET_64BIT && TARGET_USE_LOOP"
13479 {
13480   if (which_alternative != 0)
13481     return "#";
13482   if (get_attr_length (insn) == 2)
13483     return "%+loop\t%l0";
13484   else
13485     return "dec{l}\t%1\;%+jne\t%l0";
13486 }
13487   [(set_attr "ppro_uops" "many")
13488    (set (attr "length")
13489         (if_then_else (and (eq_attr "alternative" "0")
13490                            (and (ge (minus (match_dup 0) (pc))
13491                                     (const_int -126))
13492                                 (lt (minus (match_dup 0) (pc))
13493                                     (const_int 128))))
13494                       (const_int 2)
13495                       (const_int 16)))
13496    ;; We don't know the type before shorten branches.  Optimistically expect
13497    ;; the loop instruction to match.
13498    (set (attr "type") (const_string "ibr"))])
13499
13500 (define_split
13501   [(set (pc)
13502         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13503                           (const_int 1))
13504                       (match_operand 0 "" "")
13505                       (pc)))
13506    (set (match_dup 1)
13507         (plus:SI (match_dup 1)
13508                  (const_int -1)))
13509    (clobber (match_scratch:SI 2 ""))
13510    (clobber (reg:CC 17))]
13511   "!TARGET_64BIT && TARGET_USE_LOOP
13512    && reload_completed
13513    && REGNO (operands[1]) != 2"
13514   [(parallel [(set (reg:CCZ 17)
13515                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13516                                  (const_int 0)))
13517               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13518    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13519                            (match_dup 0)
13520                            (pc)))]
13521   "")
13522   
13523 (define_split
13524   [(set (pc)
13525         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13526                           (const_int 1))
13527                       (match_operand 0 "" "")
13528                       (pc)))
13529    (set (match_operand:SI 2 "nonimmediate_operand" "")
13530         (plus:SI (match_dup 1)
13531                  (const_int -1)))
13532    (clobber (match_scratch:SI 3 ""))
13533    (clobber (reg:CC 17))]
13534   "!TARGET_64BIT && TARGET_USE_LOOP
13535    && reload_completed
13536    && (! REG_P (operands[2])
13537        || ! rtx_equal_p (operands[1], operands[2]))"
13538   [(set (match_dup 3) (match_dup 1))
13539    (parallel [(set (reg:CCZ 17)
13540                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13541                                 (const_int 0)))
13542               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13543    (set (match_dup 2) (match_dup 3))
13544    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13545                            (match_dup 0)
13546                            (pc)))]
13547   "")
13548
13549 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13550
13551 (define_peephole2
13552   [(set (reg 17) (match_operand 0 "" ""))
13553    (set (match_operand:QI 1 "register_operand" "")
13554         (match_operator:QI 2 "ix86_comparison_operator"
13555           [(reg 17) (const_int 0)]))
13556    (set (match_operand 3 "q_regs_operand" "")
13557         (zero_extend (match_dup 1)))]
13558   "(peep2_reg_dead_p (3, operands[1])
13559     || operands_match_p (operands[1], operands[3]))
13560    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13561   [(set (match_dup 4) (match_dup 0))
13562    (set (strict_low_part (match_dup 5))
13563         (match_dup 2))]
13564 {
13565   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13566   operands[5] = gen_lowpart (QImode, operands[3]);
13567   ix86_expand_clear (operands[3]);
13568 })
13569
13570 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13571
13572 (define_peephole2
13573   [(set (reg 17) (match_operand 0 "" ""))
13574    (set (match_operand:QI 1 "register_operand" "")
13575         (match_operator:QI 2 "ix86_comparison_operator"
13576           [(reg 17) (const_int 0)]))
13577    (parallel [(set (match_operand 3 "q_regs_operand" "")
13578                    (zero_extend (match_dup 1)))
13579               (clobber (reg:CC 17))])]
13580   "(peep2_reg_dead_p (3, operands[1])
13581     || operands_match_p (operands[1], operands[3]))
13582    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13583   [(set (match_dup 4) (match_dup 0))
13584    (set (strict_low_part (match_dup 5))
13585         (match_dup 2))]
13586 {
13587   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13588   operands[5] = gen_lowpart (QImode, operands[3]);
13589   ix86_expand_clear (operands[3]);
13590 })
13591 \f
13592 ;; Call instructions.
13593
13594 ;; The predicates normally associated with named expanders are not properly
13595 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13596 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13597
13598 ;; Call subroutine returning no value.
13599
13600 (define_expand "call_pop"
13601   [(parallel [(call (match_operand:QI 0 "" "")
13602                     (match_operand:SI 1 "" ""))
13603               (set (reg:SI 7)
13604                    (plus:SI (reg:SI 7)
13605                             (match_operand:SI 3 "" "")))])]
13606   "!TARGET_64BIT"
13607 {
13608   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13609   DONE;
13610 })
13611
13612 (define_insn "*call_pop_0"
13613   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13614          (match_operand:SI 1 "" ""))
13615    (set (reg:SI 7) (plus:SI (reg:SI 7)
13616                             (match_operand:SI 2 "immediate_operand" "")))]
13617   "!TARGET_64BIT"
13618 {
13619   if (SIBLING_CALL_P (insn))
13620     return "jmp\t%P0";
13621   else
13622     return "call\t%P0";
13623 }
13624   [(set_attr "type" "call")])
13625   
13626 (define_insn "*call_pop_1"
13627   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13628          (match_operand:SI 1 "" ""))
13629    (set (reg:SI 7) (plus:SI (reg:SI 7)
13630                             (match_operand:SI 2 "immediate_operand" "i")))]
13631   "!TARGET_64BIT"
13632 {
13633   if (constant_call_address_operand (operands[0], Pmode))
13634     {
13635       if (SIBLING_CALL_P (insn))
13636         return "jmp\t%P0";
13637       else
13638         return "call\t%P0";
13639     }
13640   if (SIBLING_CALL_P (insn))
13641     return "jmp\t%A0";
13642   else
13643     return "call\t%A0";
13644 }
13645   [(set_attr "type" "call")])
13646
13647 (define_expand "call"
13648   [(call (match_operand:QI 0 "" "")
13649          (match_operand 1 "" ""))
13650    (use (match_operand 2 "" ""))]
13651   ""
13652 {
13653   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13654   DONE;
13655 })
13656
13657 (define_expand "sibcall"
13658   [(call (match_operand:QI 0 "" "")
13659          (match_operand 1 "" ""))
13660    (use (match_operand 2 "" ""))]
13661   ""
13662 {
13663   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13664   DONE;
13665 })
13666
13667 (define_insn "*call_0"
13668   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13669          (match_operand 1 "" ""))]
13670   ""
13671 {
13672   if (SIBLING_CALL_P (insn))
13673     return "jmp\t%P0";
13674   else
13675     return "call\t%P0";
13676 }
13677   [(set_attr "type" "call")])
13678
13679 (define_insn "*call_1"
13680   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13681          (match_operand 1 "" ""))]
13682   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13683 {
13684   if (constant_call_address_operand (operands[0], QImode))
13685     return "call\t%P0";
13686   return "call\t%A0";
13687 }
13688   [(set_attr "type" "call")])
13689
13690 (define_insn "*sibcall_1"
13691   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13692          (match_operand 1 "" ""))]
13693   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13694 {
13695   if (constant_call_address_operand (operands[0], QImode))
13696     return "jmp\t%P0";
13697   return "jmp\t%A0";
13698 }
13699   [(set_attr "type" "call")])
13700
13701 (define_insn "*call_1_rex64"
13702   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13703          (match_operand 1 "" ""))]
13704   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13705 {
13706   if (constant_call_address_operand (operands[0], QImode))
13707     return "call\t%P0";
13708   return "call\t%A0";
13709 }
13710   [(set_attr "type" "call")])
13711
13712 (define_insn "*sibcall_1_rex64"
13713   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13714          (match_operand 1 "" ""))]
13715   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13716   "jmp\t%P0"
13717   [(set_attr "type" "call")])
13718
13719 (define_insn "*sibcall_1_rex64_v"
13720   [(call (mem:QI (reg:DI 40))
13721          (match_operand 0 "" ""))]
13722   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13723   "jmp\t*%%r11"
13724   [(set_attr "type" "call")])
13725
13726
13727 ;; Call subroutine, returning value in operand 0
13728
13729 (define_expand "call_value_pop"
13730   [(parallel [(set (match_operand 0 "" "")
13731                    (call (match_operand:QI 1 "" "")
13732                          (match_operand:SI 2 "" "")))
13733               (set (reg:SI 7)
13734                    (plus:SI (reg:SI 7)
13735                             (match_operand:SI 4 "" "")))])]
13736   "!TARGET_64BIT"
13737 {
13738   ix86_expand_call (operands[0], operands[1], operands[2],
13739                     operands[3], operands[4], 0);
13740   DONE;
13741 })
13742
13743 (define_expand "call_value"
13744   [(set (match_operand 0 "" "")
13745         (call (match_operand:QI 1 "" "")
13746               (match_operand:SI 2 "" "")))
13747    (use (match_operand:SI 3 "" ""))]
13748   ;; Operand 2 not used on the i386.
13749   ""
13750 {
13751   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13752   DONE;
13753 })
13754
13755 (define_expand "sibcall_value"
13756   [(set (match_operand 0 "" "")
13757         (call (match_operand:QI 1 "" "")
13758               (match_operand:SI 2 "" "")))
13759    (use (match_operand:SI 3 "" ""))]
13760   ;; Operand 2 not used on the i386.
13761   ""
13762 {
13763   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13764   DONE;
13765 })
13766
13767 ;; Call subroutine returning any type.
13768
13769 (define_expand "untyped_call"
13770   [(parallel [(call (match_operand 0 "" "")
13771                     (const_int 0))
13772               (match_operand 1 "" "")
13773               (match_operand 2 "" "")])]
13774   ""
13775 {
13776   int i;
13777
13778   /* In order to give reg-stack an easier job in validating two
13779      coprocessor registers as containing a possible return value,
13780      simply pretend the untyped call returns a complex long double
13781      value.  */
13782
13783   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13784                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13785                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13786                     NULL, 0);
13787
13788   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13789     {
13790       rtx set = XVECEXP (operands[2], 0, i);
13791       emit_move_insn (SET_DEST (set), SET_SRC (set));
13792     }
13793
13794   /* The optimizer does not know that the call sets the function value
13795      registers we stored in the result block.  We avoid problems by
13796      claiming that all hard registers are used and clobbered at this
13797      point.  */
13798   emit_insn (gen_blockage (const0_rtx));
13799
13800   DONE;
13801 })
13802 \f
13803 ;; Prologue and epilogue instructions
13804
13805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13806 ;; all of memory.  This blocks insns from being moved across this point.
13807
13808 (define_insn "blockage"
13809   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13810   ""
13811   ""
13812   [(set_attr "length" "0")])
13813
13814 ;; Insn emitted into the body of a function to return from a function.
13815 ;; This is only done if the function's epilogue is known to be simple.
13816 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13817
13818 (define_expand "return"
13819   [(return)]
13820   "ix86_can_use_return_insn_p ()"
13821 {
13822   if (current_function_pops_args)
13823     {
13824       rtx popc = GEN_INT (current_function_pops_args);
13825       emit_jump_insn (gen_return_pop_internal (popc));
13826       DONE;
13827     }
13828 })
13829
13830 (define_insn "return_internal"
13831   [(return)]
13832   "reload_completed"
13833   "ret"
13834   [(set_attr "length" "1")
13835    (set_attr "length_immediate" "0")
13836    (set_attr "modrm" "0")])
13837
13838 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13839 ;; instruction Athlon and K8 have.
13840
13841 (define_insn "return_internal_long"
13842   [(return)
13843    (unspec [(const_int 0)] UNSPEC_REP)]
13844   "reload_completed"
13845   "rep {;} ret"
13846   [(set_attr "length" "1")
13847    (set_attr "length_immediate" "0")
13848    (set_attr "prefix_rep" "1")
13849    (set_attr "modrm" "0")])
13850
13851 (define_insn "return_pop_internal"
13852   [(return)
13853    (use (match_operand:SI 0 "const_int_operand" ""))]
13854   "reload_completed"
13855   "ret\t%0"
13856   [(set_attr "length" "3")
13857    (set_attr "length_immediate" "2")
13858    (set_attr "modrm" "0")])
13859
13860 (define_insn "return_indirect_internal"
13861   [(return)
13862    (use (match_operand:SI 0 "register_operand" "r"))]
13863   "reload_completed"
13864   "jmp\t%A0"
13865   [(set_attr "type" "ibr")
13866    (set_attr "length_immediate" "0")])
13867
13868 (define_insn "nop"
13869   [(const_int 0)]
13870   ""
13871   "nop"
13872   [(set_attr "length" "1")
13873    (set_attr "length_immediate" "0")
13874    (set_attr "modrm" "0")
13875    (set_attr "ppro_uops" "one")])
13876
13877 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13878 ;; branch prediction penalty for the third jump in a 16-byte
13879 ;; block on K8.
13880
13881 (define_insn "align"
13882   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13883   ""
13884 {
13885 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13886   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13887 #else
13888   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13889      The align insn is used to avoid 3 jump instructions in the row to improve
13890      branch prediction and the benefits hardly outweight the cost of extra 8
13891      nops on the average inserted by full alignment pseudo operation.  */
13892 #endif
13893   return "";
13894 }
13895   [(set_attr "length" "16")])
13896
13897 (define_expand "prologue"
13898   [(const_int 1)]
13899   ""
13900   "ix86_expand_prologue (); DONE;")
13901
13902 (define_insn "set_got"
13903   [(set (match_operand:SI 0 "register_operand" "=r")
13904         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13905    (clobber (reg:CC 17))]
13906   "!TARGET_64BIT"
13907   { return output_set_got (operands[0]); }
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "12")])
13910
13911 (define_expand "epilogue"
13912   [(const_int 1)]
13913   ""
13914   "ix86_expand_epilogue (1); DONE;")
13915
13916 (define_expand "sibcall_epilogue"
13917   [(const_int 1)]
13918   ""
13919   "ix86_expand_epilogue (0); DONE;")
13920
13921 (define_expand "eh_return"
13922   [(use (match_operand 0 "register_operand" ""))]
13923   ""
13924 {
13925   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13926
13927   /* Tricky bit: we write the address of the handler to which we will
13928      be returning into someone else's stack frame, one word below the
13929      stack address we wish to restore.  */
13930   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13931   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13932   tmp = gen_rtx_MEM (Pmode, tmp);
13933   emit_move_insn (tmp, ra);
13934
13935   if (Pmode == SImode)
13936     emit_insn (gen_eh_return_si (sa));
13937   else
13938     emit_insn (gen_eh_return_di (sa));
13939   emit_barrier ();
13940   DONE;
13941 })
13942
13943 (define_insn_and_split "eh_return_si"
13944   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13945                     UNSPECV_EH_RETURN)]
13946   "!TARGET_64BIT"
13947   "#"
13948   "reload_completed"
13949   [(const_int 1)]
13950   "ix86_expand_epilogue (2); DONE;")
13951
13952 (define_insn_and_split "eh_return_di"
13953   [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13954                     UNSPECV_EH_RETURN)]
13955   "TARGET_64BIT"
13956   "#"
13957   "reload_completed"
13958   [(const_int 1)]
13959   "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn "leave"
13962   [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13963    (set (reg:SI 6) (mem:SI (reg:SI 6)))
13964    (clobber (mem:BLK (scratch)))]
13965   "!TARGET_64BIT"
13966   "leave"
13967   [(set_attr "type" "leave")])
13968
13969 (define_insn "leave_rex64"
13970   [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13971    (set (reg:DI 6) (mem:DI (reg:DI 6)))
13972    (clobber (mem:BLK (scratch)))]
13973   "TARGET_64BIT"
13974   "leave"
13975   [(set_attr "type" "leave")])
13976 \f
13977 (define_expand "ffssi2"
13978   [(parallel
13979      [(set (match_operand:SI 0 "register_operand" "") 
13980            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13981       (clobber (match_scratch:SI 2 ""))
13982       (clobber (reg:CC 17))])]
13983   ""
13984   "")
13985
13986 (define_insn_and_split "*ffs_cmove"
13987   [(set (match_operand:SI 0 "register_operand" "=r") 
13988         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989    (clobber (match_scratch:SI 2 "=&r"))
13990    (clobber (reg:CC 17))]
13991   "TARGET_CMOVE"
13992   "#"
13993   "&& reload_completed"
13994   [(set (match_dup 2) (const_int -1))
13995    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13996               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13997    (set (match_dup 0) (if_then_else:SI
13998                         (eq (reg:CCZ 17) (const_int 0))
13999                         (match_dup 2)
14000                         (match_dup 0)))
14001    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14002               (clobber (reg:CC 17))])]
14003   "")
14004
14005 (define_insn_and_split "*ffs_no_cmove"
14006   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14007         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14008    (clobber (match_scratch:SI 2 "=&q"))
14009    (clobber (reg:CC 17))]
14010   ""
14011   "#"
14012   "reload_completed"
14013   [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14014               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14015    (set (strict_low_part (match_dup 3))
14016         (eq:QI (reg:CCZ 17) (const_int 0)))
14017    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14018               (clobber (reg:CC 17))])
14019    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14020               (clobber (reg:CC 17))])
14021    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14022               (clobber (reg:CC 17))])]
14023 {
14024   operands[3] = gen_lowpart (QImode, operands[2]);
14025   ix86_expand_clear (operands[2]);
14026 })
14027
14028 (define_insn "*ffssi_1"
14029   [(set (reg:CCZ 17)
14030         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14031                      (const_int 0)))
14032    (set (match_operand:SI 0 "register_operand" "=r")
14033         (ctz:SI (match_dup 1)))]
14034   ""
14035   "bsf{l}\t{%1, %0|%0, %1}"
14036   [(set_attr "prefix_0f" "1")
14037    (set_attr "ppro_uops" "few")])
14038
14039 (define_insn "ctzsi2"
14040   [(set (match_operand:SI 0 "register_operand" "=r")
14041         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14042    (clobber (reg:CC 17))]
14043   ""
14044   "bsf{l}\t{%1, %0|%0, %1}"
14045   [(set_attr "prefix_0f" "1")
14046    (set_attr "ppro_uops" "few")])
14047
14048 (define_expand "clzsi2"
14049   [(parallel
14050      [(set (match_operand:SI 0 "register_operand" "")
14051            (minus:SI (const_int 31)
14052                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14053       (clobber (reg:CC 17))])
14054    (parallel
14055      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14056       (clobber (reg:CC 17))])]
14057   ""
14058   "")
14059
14060 (define_insn "*bsr"
14061   [(set (match_operand:SI 0 "register_operand" "=r")
14062         (minus:SI (const_int 31)
14063                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14064    (clobber (reg:CC 17))]
14065   ""
14066   "bsr{l}\t{%1, %0|%0, %1}"
14067   [(set_attr "prefix_0f" "1")
14068    (set_attr "ppro_uops" "few")])
14069 \f
14070 ;; Thread-local storage patterns for ELF.
14071 ;;
14072 ;; Note that these code sequences must appear exactly as shown
14073 ;; in order to allow linker relaxation.
14074
14075 (define_insn "*tls_global_dynamic_32_gnu"
14076   [(set (match_operand:SI 0 "register_operand" "=a")
14077         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14078                     (match_operand:SI 2 "tls_symbolic_operand" "")
14079                     (match_operand:SI 3 "call_insn_operand" "")]
14080                     UNSPEC_TLS_GD))
14081    (clobber (match_scratch:SI 4 "=d"))
14082    (clobber (match_scratch:SI 5 "=c"))
14083    (clobber (reg:CC 17))]
14084   "!TARGET_64BIT && TARGET_GNU_TLS"
14085   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14086   [(set_attr "type" "multi")
14087    (set_attr "length" "12")])
14088
14089 (define_insn "*tls_global_dynamic_32_sun"
14090   [(set (match_operand:SI 0 "register_operand" "=a")
14091         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14092                     (match_operand:SI 2 "tls_symbolic_operand" "")
14093                     (match_operand:SI 3 "call_insn_operand" "")]
14094                     UNSPEC_TLS_GD))
14095    (clobber (match_scratch:SI 4 "=d"))
14096    (clobber (match_scratch:SI 5 "=c"))
14097    (clobber (reg:CC 17))]
14098   "!TARGET_64BIT && TARGET_SUN_TLS"
14099   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14100         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14101   [(set_attr "type" "multi")
14102    (set_attr "length" "14")])
14103
14104 (define_expand "tls_global_dynamic_32"
14105   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14106                    (unspec:SI
14107                     [(match_dup 2)
14108                      (match_operand:SI 1 "tls_symbolic_operand" "")
14109                      (match_dup 3)]
14110                     UNSPEC_TLS_GD))
14111               (clobber (match_scratch:SI 4 ""))
14112               (clobber (match_scratch:SI 5 ""))
14113               (clobber (reg:CC 17))])]
14114   ""
14115 {
14116   if (flag_pic)
14117     operands[2] = pic_offset_table_rtx;
14118   else
14119     {
14120       operands[2] = gen_reg_rtx (Pmode);
14121       emit_insn (gen_set_got (operands[2]));
14122     }
14123   operands[3] = ix86_tls_get_addr ();
14124 })
14125
14126 (define_insn "*tls_global_dynamic_64"
14127   [(set (match_operand:DI 0 "register_operand" "=a")
14128         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14129                       (match_operand:DI 3 "" "")))
14130    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14131               UNSPEC_TLS_GD)]
14132   "TARGET_64BIT"
14133   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14134   [(set_attr "type" "multi")
14135    (set_attr "length" "16")])
14136
14137 (define_expand "tls_global_dynamic_64"
14138   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14139                    (call (mem:QI (match_dup 2)) (const_int 0)))
14140               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14141                          UNSPEC_TLS_GD)])]
14142   ""
14143 {
14144   operands[2] = ix86_tls_get_addr ();
14145 })
14146
14147 (define_insn "*tls_local_dynamic_base_32_gnu"
14148   [(set (match_operand:SI 0 "register_operand" "=a")
14149         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14150                     (match_operand:SI 2 "call_insn_operand" "")]
14151                    UNSPEC_TLS_LD_BASE))
14152    (clobber (match_scratch:SI 3 "=d"))
14153    (clobber (match_scratch:SI 4 "=c"))
14154    (clobber (reg:CC 17))]
14155   "!TARGET_64BIT && TARGET_GNU_TLS"
14156   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14157   [(set_attr "type" "multi")
14158    (set_attr "length" "11")])
14159
14160 (define_insn "*tls_local_dynamic_base_32_sun"
14161   [(set (match_operand:SI 0 "register_operand" "=a")
14162         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14163                     (match_operand:SI 2 "call_insn_operand" "")]
14164                    UNSPEC_TLS_LD_BASE))
14165    (clobber (match_scratch:SI 3 "=d"))
14166    (clobber (match_scratch:SI 4 "=c"))
14167    (clobber (reg:CC 17))]
14168   "!TARGET_64BIT && TARGET_SUN_TLS"
14169   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14170         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14171   [(set_attr "type" "multi")
14172    (set_attr "length" "13")])
14173
14174 (define_expand "tls_local_dynamic_base_32"
14175   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14176                    (unspec:SI [(match_dup 1) (match_dup 2)]
14177                               UNSPEC_TLS_LD_BASE))
14178               (clobber (match_scratch:SI 3 ""))
14179               (clobber (match_scratch:SI 4 ""))
14180               (clobber (reg:CC 17))])]
14181   ""
14182 {
14183   if (flag_pic)
14184     operands[1] = pic_offset_table_rtx;
14185   else
14186     {
14187       operands[1] = gen_reg_rtx (Pmode);
14188       emit_insn (gen_set_got (operands[1]));
14189     }
14190   operands[2] = ix86_tls_get_addr ();
14191 })
14192
14193 (define_insn "*tls_local_dynamic_base_64"
14194   [(set (match_operand:DI 0 "register_operand" "=a")
14195         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14196                       (match_operand:DI 2 "" "")))
14197    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14198   "TARGET_64BIT"
14199   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14200   [(set_attr "type" "multi")
14201    (set_attr "length" "12")])
14202
14203 (define_expand "tls_local_dynamic_base_64"
14204   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14205                    (call (mem:QI (match_dup 1)) (const_int 0)))
14206               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14207   ""
14208 {
14209   operands[1] = ix86_tls_get_addr ();
14210 })
14211
14212 ;; Local dynamic of a single variable is a lose.  Show combine how
14213 ;; to convert that back to global dynamic.
14214
14215 (define_insn_and_split "*tls_local_dynamic_32_once"
14216   [(set (match_operand:SI 0 "register_operand" "=a")
14217         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14218                              (match_operand:SI 2 "call_insn_operand" "")]
14219                             UNSPEC_TLS_LD_BASE)
14220                  (const:SI (unspec:SI
14221                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14222                             UNSPEC_DTPOFF))))
14223    (clobber (match_scratch:SI 4 "=d"))
14224    (clobber (match_scratch:SI 5 "=c"))
14225    (clobber (reg:CC 17))]
14226   ""
14227   "#"
14228   ""
14229   [(parallel [(set (match_dup 0)
14230                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14231                               UNSPEC_TLS_GD))
14232               (clobber (match_dup 4))
14233               (clobber (match_dup 5))
14234               (clobber (reg:CC 17))])]
14235   "")
14236
14237 ;; Load and add the thread base pointer from %gs:0.
14238
14239 (define_insn "*load_tp_si"
14240   [(set (match_operand:SI 0 "register_operand" "=r")
14241         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14242   "!TARGET_64BIT"
14243   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14244   [(set_attr "type" "imov")
14245    (set_attr "modrm" "0")
14246    (set_attr "length" "7")
14247    (set_attr "memory" "load")
14248    (set_attr "imm_disp" "false")])
14249
14250 (define_insn "*add_tp_si"
14251   [(set (match_operand:SI 0 "register_operand" "=r")
14252         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14253                  (match_operand:SI 1 "register_operand" "0")))
14254    (clobber (reg:CC 17))]
14255   "!TARGET_64BIT"
14256   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14257   [(set_attr "type" "alu")
14258    (set_attr "modrm" "0")
14259    (set_attr "length" "7")
14260    (set_attr "memory" "load")
14261    (set_attr "imm_disp" "false")])
14262
14263 (define_insn "*load_tp_di"
14264   [(set (match_operand:DI 0 "register_operand" "=r")
14265         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14266   "TARGET_64BIT"
14267   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14268   [(set_attr "type" "imov")
14269    (set_attr "modrm" "0")
14270    (set_attr "length" "7")
14271    (set_attr "memory" "load")
14272    (set_attr "imm_disp" "false")])
14273
14274 (define_insn "*add_tp_di"
14275   [(set (match_operand:DI 0 "register_operand" "=r")
14276         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14277                  (match_operand:DI 1 "register_operand" "0")))
14278    (clobber (reg:CC 17))]
14279   "TARGET_64BIT"
14280   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14281   [(set_attr "type" "alu")
14282    (set_attr "modrm" "0")
14283    (set_attr "length" "7")
14284    (set_attr "memory" "load")
14285    (set_attr "imm_disp" "false")])
14286 \f
14287 ;; These patterns match the binary 387 instructions for addM3, subM3,
14288 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14289 ;; SFmode.  The first is the normal insn, the second the same insn but
14290 ;; with one operand a conversion, and the third the same insn but with
14291 ;; the other operand a conversion.  The conversion may be SFmode or
14292 ;; SImode if the target mode DFmode, but only SImode if the target mode
14293 ;; is SFmode.
14294
14295 ;; Gcc is slightly more smart about handling normal two address instructions
14296 ;; so use special patterns for add and mull.
14297 (define_insn "*fop_sf_comm_nosse"
14298   [(set (match_operand:SF 0 "register_operand" "=f")
14299         (match_operator:SF 3 "binary_fp_operator"
14300                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14301                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14302   "TARGET_80387 && !TARGET_SSE_MATH
14303    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14305   "* return output_387_binary_op (insn, operands);"
14306   [(set (attr "type") 
14307         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14308            (const_string "fmul")
14309            (const_string "fop")))
14310    (set_attr "mode" "SF")])
14311
14312 (define_insn "*fop_sf_comm"
14313   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14314         (match_operator:SF 3 "binary_fp_operator"
14315                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14316                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14317   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14318    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14319    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14320   "* return output_387_binary_op (insn, operands);"
14321   [(set (attr "type") 
14322         (if_then_else (eq_attr "alternative" "1")
14323            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14324               (const_string "ssemul")
14325               (const_string "sseadd"))
14326            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14327               (const_string "fmul")
14328               (const_string "fop"))))
14329    (set_attr "mode" "SF")])
14330
14331 (define_insn "*fop_sf_comm_sse"
14332   [(set (match_operand:SF 0 "register_operand" "=x")
14333         (match_operator:SF 3 "binary_fp_operator"
14334                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14335                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14336   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14337    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14338   "* return output_387_binary_op (insn, operands);"
14339   [(set (attr "type") 
14340         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14341            (const_string "ssemul")
14342            (const_string "sseadd")))
14343    (set_attr "mode" "SF")])
14344
14345 (define_insn "*fop_df_comm_nosse"
14346   [(set (match_operand:DF 0 "register_operand" "=f")
14347         (match_operator:DF 3 "binary_fp_operator"
14348                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14349                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14350   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14351    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14353   "* return output_387_binary_op (insn, operands);"
14354   [(set (attr "type") 
14355         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14356            (const_string "fmul")
14357            (const_string "fop")))
14358    (set_attr "mode" "DF")])
14359
14360 (define_insn "*fop_df_comm"
14361   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14362         (match_operator:DF 3 "binary_fp_operator"
14363                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14364                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14365   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14366    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14367    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14368   "* return output_387_binary_op (insn, operands);"
14369   [(set (attr "type") 
14370         (if_then_else (eq_attr "alternative" "1")
14371            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14372               (const_string "ssemul")
14373               (const_string "sseadd"))
14374            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14375               (const_string "fmul")
14376               (const_string "fop"))))
14377    (set_attr "mode" "DF")])
14378
14379 (define_insn "*fop_df_comm_sse"
14380   [(set (match_operand:DF 0 "register_operand" "=Y")
14381         (match_operator:DF 3 "binary_fp_operator"
14382                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14383                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14384   "TARGET_SSE2 && TARGET_SSE_MATH
14385    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14386    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14387   "* return output_387_binary_op (insn, operands);"
14388   [(set (attr "type") 
14389         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14390            (const_string "ssemul")
14391            (const_string "sseadd")))
14392    (set_attr "mode" "DF")])
14393
14394 (define_insn "*fop_xf_comm"
14395   [(set (match_operand:XF 0 "register_operand" "=f")
14396         (match_operator:XF 3 "binary_fp_operator"
14397                         [(match_operand:XF 1 "register_operand" "%0")
14398                          (match_operand:XF 2 "register_operand" "f")]))]
14399   "TARGET_80387
14400    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14401   "* return output_387_binary_op (insn, operands);"
14402   [(set (attr "type") 
14403         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14404            (const_string "fmul")
14405            (const_string "fop")))
14406    (set_attr "mode" "XF")])
14407
14408 (define_insn "*fop_sf_1_nosse"
14409   [(set (match_operand:SF 0 "register_operand" "=f,f")
14410         (match_operator:SF 3 "binary_fp_operator"
14411                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14412                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14413   "TARGET_80387 && !TARGET_SSE_MATH
14414    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14415    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14416   "* return output_387_binary_op (insn, operands);"
14417   [(set (attr "type") 
14418         (cond [(match_operand:SF 3 "mult_operator" "") 
14419                  (const_string "fmul")
14420                (match_operand:SF 3 "div_operator" "") 
14421                  (const_string "fdiv")
14422               ]
14423               (const_string "fop")))
14424    (set_attr "mode" "SF")])
14425
14426 (define_insn "*fop_sf_1"
14427   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14428         (match_operator:SF 3 "binary_fp_operator"
14429                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14430                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14431   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14432    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14433    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434   "* return output_387_binary_op (insn, operands);"
14435   [(set (attr "type") 
14436         (cond [(and (eq_attr "alternative" "2")
14437                     (match_operand:SF 3 "mult_operator" ""))
14438                  (const_string "ssemul")
14439                (and (eq_attr "alternative" "2")
14440                     (match_operand:SF 3 "div_operator" ""))
14441                  (const_string "ssediv")
14442                (eq_attr "alternative" "2")
14443                  (const_string "sseadd")
14444                (match_operand:SF 3 "mult_operator" "") 
14445                  (const_string "fmul")
14446                (match_operand:SF 3 "div_operator" "") 
14447                  (const_string "fdiv")
14448               ]
14449               (const_string "fop")))
14450    (set_attr "mode" "SF")])
14451
14452 (define_insn "*fop_sf_1_sse"
14453   [(set (match_operand:SF 0 "register_operand" "=x")
14454         (match_operator:SF 3 "binary_fp_operator"
14455                         [(match_operand:SF 1 "register_operand" "0")
14456                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14457   "TARGET_SSE_MATH
14458    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14459   "* return output_387_binary_op (insn, operands);"
14460   [(set (attr "type") 
14461         (cond [(match_operand:SF 3 "mult_operator" "")
14462                  (const_string "ssemul")
14463                (match_operand:SF 3 "div_operator" "")
14464                  (const_string "ssediv")
14465               ]
14466               (const_string "sseadd")))
14467    (set_attr "mode" "SF")])
14468
14469 ;; ??? Add SSE splitters for these!
14470 (define_insn "*fop_sf_2"
14471   [(set (match_operand:SF 0 "register_operand" "=f,f")
14472         (match_operator:SF 3 "binary_fp_operator"
14473           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14474            (match_operand:SF 2 "register_operand" "0,0")]))]
14475   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14476   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14477   [(set (attr "type") 
14478         (cond [(match_operand:SF 3 "mult_operator" "") 
14479                  (const_string "fmul")
14480                (match_operand:SF 3 "div_operator" "") 
14481                  (const_string "fdiv")
14482               ]
14483               (const_string "fop")))
14484    (set_attr "fp_int_src" "true")
14485    (set_attr "ppro_uops" "many")
14486    (set_attr "mode" "SI")])
14487
14488 (define_insn "*fop_sf_3"
14489   [(set (match_operand:SF 0 "register_operand" "=f,f")
14490         (match_operator:SF 3 "binary_fp_operator"
14491           [(match_operand:SF 1 "register_operand" "0,0")
14492            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14493   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14494   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14495   [(set (attr "type") 
14496         (cond [(match_operand:SF 3 "mult_operator" "") 
14497                  (const_string "fmul")
14498                (match_operand:SF 3 "div_operator" "") 
14499                  (const_string "fdiv")
14500               ]
14501               (const_string "fop")))
14502    (set_attr "fp_int_src" "true")
14503    (set_attr "ppro_uops" "many")
14504    (set_attr "mode" "SI")])
14505
14506 (define_insn "*fop_df_1_nosse"
14507   [(set (match_operand:DF 0 "register_operand" "=f,f")
14508         (match_operator:DF 3 "binary_fp_operator"
14509                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14510                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14511   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14512    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14513    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14514   "* return output_387_binary_op (insn, operands);"
14515   [(set (attr "type") 
14516         (cond [(match_operand:DF 3 "mult_operator" "") 
14517                  (const_string "fmul")
14518                (match_operand:DF 3 "div_operator" "")
14519                  (const_string "fdiv")
14520               ]
14521               (const_string "fop")))
14522    (set_attr "mode" "DF")])
14523
14524
14525 (define_insn "*fop_df_1"
14526   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14527         (match_operator:DF 3 "binary_fp_operator"
14528                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14529                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14530   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14531    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14532    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14533   "* return output_387_binary_op (insn, operands);"
14534   [(set (attr "type") 
14535         (cond [(and (eq_attr "alternative" "2")
14536                     (match_operand:SF 3 "mult_operator" ""))
14537                  (const_string "ssemul")
14538                (and (eq_attr "alternative" "2")
14539                     (match_operand:SF 3 "div_operator" ""))
14540                  (const_string "ssediv")
14541                (eq_attr "alternative" "2")
14542                  (const_string "sseadd")
14543                (match_operand:DF 3 "mult_operator" "") 
14544                  (const_string "fmul")
14545                (match_operand:DF 3 "div_operator" "") 
14546                  (const_string "fdiv")
14547               ]
14548               (const_string "fop")))
14549    (set_attr "mode" "DF")])
14550
14551 (define_insn "*fop_df_1_sse"
14552   [(set (match_operand:DF 0 "register_operand" "=Y")
14553         (match_operator:DF 3 "binary_fp_operator"
14554                         [(match_operand:DF 1 "register_operand" "0")
14555                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14556   "TARGET_SSE2 && TARGET_SSE_MATH
14557    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14558   "* return output_387_binary_op (insn, operands);"
14559   [(set_attr "mode" "DF")
14560    (set (attr "type") 
14561         (cond [(match_operand:SF 3 "mult_operator" "")
14562                  (const_string "ssemul")
14563                (match_operand:SF 3 "div_operator" "")
14564                  (const_string "ssediv")
14565               ]
14566               (const_string "sseadd")))])
14567
14568 ;; ??? Add SSE splitters for these!
14569 (define_insn "*fop_df_2"
14570   [(set (match_operand:DF 0 "register_operand" "=f,f")
14571         (match_operator:DF 3 "binary_fp_operator"
14572            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14573             (match_operand:DF 2 "register_operand" "0,0")]))]
14574   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14575   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14576   [(set (attr "type") 
14577         (cond [(match_operand:DF 3 "mult_operator" "") 
14578                  (const_string "fmul")
14579                (match_operand:DF 3 "div_operator" "") 
14580                  (const_string "fdiv")
14581               ]
14582               (const_string "fop")))
14583    (set_attr "fp_int_src" "true")
14584    (set_attr "ppro_uops" "many")
14585    (set_attr "mode" "SI")])
14586
14587 (define_insn "*fop_df_3"
14588   [(set (match_operand:DF 0 "register_operand" "=f,f")
14589         (match_operator:DF 3 "binary_fp_operator"
14590            [(match_operand:DF 1 "register_operand" "0,0")
14591             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14592   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594   [(set (attr "type") 
14595         (cond [(match_operand:DF 3 "mult_operator" "") 
14596                  (const_string "fmul")
14597                (match_operand:DF 3 "div_operator" "") 
14598                  (const_string "fdiv")
14599               ]
14600               (const_string "fop")))
14601    (set_attr "fp_int_src" "true")
14602    (set_attr "ppro_uops" "many")
14603    (set_attr "mode" "SI")])
14604
14605 (define_insn "*fop_df_4"
14606   [(set (match_operand:DF 0 "register_operand" "=f,f")
14607         (match_operator:DF 3 "binary_fp_operator"
14608            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14609             (match_operand:DF 2 "register_operand" "0,f")]))]
14610   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14611    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14612   "* return output_387_binary_op (insn, operands);"
14613   [(set (attr "type") 
14614         (cond [(match_operand:DF 3 "mult_operator" "") 
14615                  (const_string "fmul")
14616                (match_operand:DF 3 "div_operator" "") 
14617                  (const_string "fdiv")
14618               ]
14619               (const_string "fop")))
14620    (set_attr "mode" "SF")])
14621
14622 (define_insn "*fop_df_5"
14623   [(set (match_operand:DF 0 "register_operand" "=f,f")
14624         (match_operator:DF 3 "binary_fp_operator"
14625           [(match_operand:DF 1 "register_operand" "0,f")
14626            (float_extend:DF
14627             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14628   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14629   "* return output_387_binary_op (insn, operands);"
14630   [(set (attr "type") 
14631         (cond [(match_operand:DF 3 "mult_operator" "") 
14632                  (const_string "fmul")
14633                (match_operand:DF 3 "div_operator" "") 
14634                  (const_string "fdiv")
14635               ]
14636               (const_string "fop")))
14637    (set_attr "mode" "SF")])
14638
14639 (define_insn "*fop_df_6"
14640   [(set (match_operand:DF 0 "register_operand" "=f,f")
14641         (match_operator:DF 3 "binary_fp_operator"
14642           [(float_extend:DF
14643             (match_operand:SF 1 "register_operand" "0,f"))
14644            (float_extend:DF
14645             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14646   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647   "* return output_387_binary_op (insn, operands);"
14648   [(set (attr "type") 
14649         (cond [(match_operand:DF 3 "mult_operator" "") 
14650                  (const_string "fmul")
14651                (match_operand:DF 3 "div_operator" "") 
14652                  (const_string "fdiv")
14653               ]
14654               (const_string "fop")))
14655    (set_attr "mode" "SF")])
14656
14657 (define_insn "*fop_xf_1"
14658   [(set (match_operand:XF 0 "register_operand" "=f,f")
14659         (match_operator:XF 3 "binary_fp_operator"
14660                         [(match_operand:XF 1 "register_operand" "0,f")
14661                          (match_operand:XF 2 "register_operand" "f,0")]))]
14662   "TARGET_80387
14663    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14664   "* return output_387_binary_op (insn, operands);"
14665   [(set (attr "type") 
14666         (cond [(match_operand:XF 3 "mult_operator" "") 
14667                  (const_string "fmul")
14668                (match_operand:XF 3 "div_operator" "") 
14669                  (const_string "fdiv")
14670               ]
14671               (const_string "fop")))
14672    (set_attr "mode" "XF")])
14673
14674 (define_insn "*fop_xf_2"
14675   [(set (match_operand:XF 0 "register_operand" "=f,f")
14676         (match_operator:XF 3 "binary_fp_operator"
14677            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14678             (match_operand:XF 2 "register_operand" "0,0")]))]
14679   "TARGET_80387 && TARGET_USE_FIOP"
14680   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14681   [(set (attr "type") 
14682         (cond [(match_operand:XF 3 "mult_operator" "") 
14683                  (const_string "fmul")
14684                (match_operand:XF 3 "div_operator" "") 
14685                  (const_string "fdiv")
14686               ]
14687               (const_string "fop")))
14688    (set_attr "fp_int_src" "true")
14689    (set_attr "mode" "SI")
14690    (set_attr "ppro_uops" "many")])
14691
14692 (define_insn "*fop_xf_3"
14693   [(set (match_operand:XF 0 "register_operand" "=f,f")
14694         (match_operator:XF 3 "binary_fp_operator"
14695           [(match_operand:XF 1 "register_operand" "0,0")
14696            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14697   "TARGET_80387 && TARGET_USE_FIOP"
14698   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14699   [(set (attr "type") 
14700         (cond [(match_operand:XF 3 "mult_operator" "") 
14701                  (const_string "fmul")
14702                (match_operand:XF 3 "div_operator" "") 
14703                  (const_string "fdiv")
14704               ]
14705               (const_string "fop")))
14706    (set_attr "fp_int_src" "true")
14707    (set_attr "mode" "SI")
14708    (set_attr "ppro_uops" "many")])
14709
14710 (define_insn "*fop_xf_4"
14711   [(set (match_operand:XF 0 "register_operand" "=f,f")
14712         (match_operator:XF 3 "binary_fp_operator"
14713            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14714             (match_operand:XF 2 "register_operand" "0,f")]))]
14715   "TARGET_80387"
14716   "* return output_387_binary_op (insn, operands);"
14717   [(set (attr "type") 
14718         (cond [(match_operand:XF 3 "mult_operator" "") 
14719                  (const_string "fmul")
14720                (match_operand:XF 3 "div_operator" "") 
14721                  (const_string "fdiv")
14722               ]
14723               (const_string "fop")))
14724    (set_attr "mode" "SF")])
14725
14726 (define_insn "*fop_xf_5"
14727   [(set (match_operand:XF 0 "register_operand" "=f,f")
14728         (match_operator:XF 3 "binary_fp_operator"
14729           [(match_operand:XF 1 "register_operand" "0,f")
14730            (float_extend:XF
14731             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14732   "TARGET_80387"
14733   "* return output_387_binary_op (insn, operands);"
14734   [(set (attr "type") 
14735         (cond [(match_operand:XF 3 "mult_operator" "") 
14736                  (const_string "fmul")
14737                (match_operand:XF 3 "div_operator" "") 
14738                  (const_string "fdiv")
14739               ]
14740               (const_string "fop")))
14741    (set_attr "mode" "SF")])
14742
14743 (define_insn "*fop_xf_6"
14744   [(set (match_operand:XF 0 "register_operand" "=f,f")
14745         (match_operator:XF 3 "binary_fp_operator"
14746           [(float_extend:XF
14747             (match_operand 1 "register_operand" "0,f"))
14748            (float_extend:XF
14749             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14750   "TARGET_80387"
14751   "* return output_387_binary_op (insn, operands);"
14752   [(set (attr "type") 
14753         (cond [(match_operand:XF 3 "mult_operator" "") 
14754                  (const_string "fmul")
14755                (match_operand:XF 3 "div_operator" "") 
14756                  (const_string "fdiv")
14757               ]
14758               (const_string "fop")))
14759    (set_attr "mode" "SF")])
14760
14761 (define_split
14762   [(set (match_operand 0 "register_operand" "")
14763         (match_operator 3 "binary_fp_operator"
14764            [(float (match_operand:SI 1 "register_operand" ""))
14765             (match_operand 2 "register_operand" "")]))]
14766   "TARGET_80387 && reload_completed
14767    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14768   [(const_int 0)]
14769
14770   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14771   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14772   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14773                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14774                                           GET_MODE (operands[3]),
14775                                           operands[4],
14776                                           operands[2])));
14777   ix86_free_from_memory (GET_MODE (operands[1]));
14778   DONE;
14779 })
14780
14781 (define_split
14782   [(set (match_operand 0 "register_operand" "")
14783         (match_operator 3 "binary_fp_operator"
14784            [(match_operand 1 "register_operand" "")
14785             (float (match_operand:SI 2 "register_operand" ""))]))]
14786   "TARGET_80387 && reload_completed
14787    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14788   [(const_int 0)]
14789 {
14790   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14791   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14792   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14793                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14794                                           GET_MODE (operands[3]),
14795                                           operands[1],
14796                                           operands[4])));
14797   ix86_free_from_memory (GET_MODE (operands[2]));
14798   DONE;
14799 })
14800 \f
14801 ;; FPU special functions.
14802
14803 (define_expand "sqrtsf2"
14804   [(set (match_operand:SF 0 "register_operand" "")
14805         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14806   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14807 {
14808   if (!TARGET_SSE_MATH)
14809     operands[1] = force_reg (SFmode, operands[1]);
14810 })
14811
14812 (define_insn "sqrtsf2_1"
14813   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14814         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14815   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14816    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14817   "@
14818    fsqrt
14819    sqrtss\t{%1, %0|%0, %1}"
14820   [(set_attr "type" "fpspc,sse")
14821    (set_attr "mode" "SF,SF")
14822    (set_attr "athlon_decode" "direct,*")])
14823
14824 (define_insn "sqrtsf2_1_sse_only"
14825   [(set (match_operand:SF 0 "register_operand" "=x")
14826         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14827   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14828   "sqrtss\t{%1, %0|%0, %1}"
14829   [(set_attr "type" "sse")
14830    (set_attr "mode" "SF")
14831    (set_attr "athlon_decode" "*")])
14832
14833 (define_insn "sqrtsf2_i387"
14834   [(set (match_operand:SF 0 "register_operand" "=f")
14835         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14836   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14837    && !TARGET_SSE_MATH"
14838   "fsqrt"
14839   [(set_attr "type" "fpspc")
14840    (set_attr "mode" "SF")
14841    (set_attr "athlon_decode" "direct")])
14842
14843 (define_expand "sqrtdf2"
14844   [(set (match_operand:DF 0 "register_operand" "")
14845         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14846   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14847    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14848 {
14849   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14850     operands[1] = force_reg (DFmode, operands[1]);
14851 })
14852
14853 (define_insn "sqrtdf2_1"
14854   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14855         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14856   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14857    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14858   "@
14859    fsqrt
14860    sqrtsd\t{%1, %0|%0, %1}"
14861   [(set_attr "type" "fpspc,sse")
14862    (set_attr "mode" "DF,DF")
14863    (set_attr "athlon_decode" "direct,*")])
14864
14865 (define_insn "sqrtdf2_1_sse_only"
14866   [(set (match_operand:DF 0 "register_operand" "=Y")
14867         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14868   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14869   "sqrtsd\t{%1, %0|%0, %1}"
14870   [(set_attr "type" "sse")
14871    (set_attr "mode" "DF")
14872    (set_attr "athlon_decode" "*")])
14873
14874 (define_insn "sqrtdf2_i387"
14875   [(set (match_operand:DF 0 "register_operand" "=f")
14876         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14877   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14878    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14879   "fsqrt"
14880   [(set_attr "type" "fpspc")
14881    (set_attr "mode" "DF")
14882    (set_attr "athlon_decode" "direct")])
14883
14884 (define_insn "*sqrtextendsfdf2"
14885   [(set (match_operand:DF 0 "register_operand" "=f")
14886         (sqrt:DF (float_extend:DF
14887                   (match_operand:SF 1 "register_operand" "0"))))]
14888   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14889    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14890   "fsqrt"
14891   [(set_attr "type" "fpspc")
14892    (set_attr "mode" "DF")
14893    (set_attr "athlon_decode" "direct")])
14894
14895 (define_insn "sqrtxf2"
14896   [(set (match_operand:XF 0 "register_operand" "=f")
14897         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14898   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14899    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14900   "fsqrt"
14901   [(set_attr "type" "fpspc")
14902    (set_attr "mode" "XF")
14903    (set_attr "athlon_decode" "direct")])
14904
14905 (define_insn "*sqrtextenddfxf2"
14906   [(set (match_operand:XF 0 "register_operand" "=f")
14907         (sqrt:XF (float_extend:XF
14908                   (match_operand:DF 1 "register_operand" "0"))))]
14909   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14910   "fsqrt"
14911   [(set_attr "type" "fpspc")
14912    (set_attr "mode" "XF")
14913    (set_attr "athlon_decode" "direct")])
14914
14915 (define_insn "*sqrtextendsfxf2"
14916   [(set (match_operand:XF 0 "register_operand" "=f")
14917         (sqrt:XF (float_extend:XF
14918                   (match_operand:SF 1 "register_operand" "0"))))]
14919   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14920   "fsqrt"
14921   [(set_attr "type" "fpspc")
14922    (set_attr "mode" "XF")
14923    (set_attr "athlon_decode" "direct")])
14924
14925 (define_insn "sindf2"
14926   [(set (match_operand:DF 0 "register_operand" "=f")
14927         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14928   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14929    && flag_unsafe_math_optimizations"
14930   "fsin"
14931   [(set_attr "type" "fpspc")
14932    (set_attr "mode" "DF")])
14933
14934 (define_insn "sinsf2"
14935   [(set (match_operand:SF 0 "register_operand" "=f")
14936         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14937   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14938    && flag_unsafe_math_optimizations"
14939   "fsin"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "SF")])
14942
14943 (define_insn "*sinextendsfdf2"
14944   [(set (match_operand:DF 0 "register_operand" "=f")
14945         (unspec:DF [(float_extend:DF
14946                      (match_operand:SF 1 "register_operand" "0"))]
14947                    UNSPEC_SIN))]
14948   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14949    && flag_unsafe_math_optimizations"
14950   "fsin"
14951   [(set_attr "type" "fpspc")
14952    (set_attr "mode" "DF")])
14953
14954 (define_insn "sinxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14957   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14958    && flag_unsafe_math_optimizations"
14959   "fsin"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")])
14962
14963 (define_insn "cosdf2"
14964   [(set (match_operand:DF 0 "register_operand" "=f")
14965         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14966   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14967    && flag_unsafe_math_optimizations"
14968   "fcos"
14969   [(set_attr "type" "fpspc")
14970    (set_attr "mode" "DF")])
14971
14972 (define_insn "cossf2"
14973   [(set (match_operand:SF 0 "register_operand" "=f")
14974         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14975   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14976    && flag_unsafe_math_optimizations"
14977   "fcos"
14978   [(set_attr "type" "fpspc")
14979    (set_attr "mode" "SF")])
14980
14981 (define_insn "*cosextendsfdf2"
14982   [(set (match_operand:DF 0 "register_operand" "=f")
14983         (unspec:DF [(float_extend:DF
14984                      (match_operand:SF 1 "register_operand" "0"))]
14985                    UNSPEC_COS))]
14986   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14987    && flag_unsafe_math_optimizations"
14988   "fcos"
14989   [(set_attr "type" "fpspc")
14990    (set_attr "mode" "DF")])
14991
14992 (define_insn "cosxf2"
14993   [(set (match_operand:XF 0 "register_operand" "=f")
14994         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14995   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14996    && flag_unsafe_math_optimizations"
14997   "fcos"
14998   [(set_attr "type" "fpspc")
14999    (set_attr "mode" "XF")])
15000
15001 (define_insn "atan2df3_1"
15002   [(set (match_operand:DF 0 "register_operand" "=f")
15003         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15004                     (match_operand:DF 1 "register_operand" "u")]
15005                    UNSPEC_FPATAN))
15006    (clobber (match_scratch:DF 3 "=1"))]
15007   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15008    && flag_unsafe_math_optimizations"
15009   "fpatan"
15010   [(set_attr "type" "fpspc")
15011    (set_attr "mode" "DF")])
15012
15013 (define_expand "atan2df3"
15014   [(use (match_operand:DF 0 "register_operand" "=f"))
15015    (use (match_operand:DF 2 "register_operand" "0"))
15016    (use (match_operand:DF 1 "register_operand" "u"))]
15017   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15018    && flag_unsafe_math_optimizations"
15019 {
15020   rtx copy = gen_reg_rtx (DFmode);
15021   emit_move_insn (copy, operands[1]);
15022   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15023   DONE;
15024 })
15025
15026 (define_insn "atan2sf3_1"
15027   [(set (match_operand:SF 0 "register_operand" "=f")
15028         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15029                     (match_operand:SF 1 "register_operand" "u")]
15030                    UNSPEC_FPATAN))
15031    (clobber (match_scratch:SF 3 "=1"))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15034   "fpatan"
15035   [(set_attr "type" "fpspc")
15036    (set_attr "mode" "SF")])
15037
15038 (define_expand "atan2sf3"
15039   [(use (match_operand:SF 0 "register_operand" "=f"))
15040    (use (match_operand:SF 2 "register_operand" "0"))
15041    (use (match_operand:SF 1 "register_operand" "u"))]
15042   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15043    && flag_unsafe_math_optimizations"
15044 {
15045   rtx copy = gen_reg_rtx (SFmode);
15046   emit_move_insn (copy, operands[1]);
15047   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15048   DONE;
15049 })
15050
15051 (define_insn "atan2xf3_1"
15052   [(set (match_operand:XF 0 "register_operand" "=f")
15053         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15054                     (match_operand:XF 1 "register_operand" "u")]
15055                    UNSPEC_FPATAN))
15056    (clobber (match_scratch:XF 3 "=1"))]
15057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15058    && flag_unsafe_math_optimizations"
15059   "fpatan"
15060   [(set_attr "type" "fpspc")
15061    (set_attr "mode" "XF")])
15062
15063 (define_expand "atan2xf3"
15064   [(use (match_operand:XF 0 "register_operand" "=f"))
15065    (use (match_operand:XF 2 "register_operand" "0"))
15066    (use (match_operand:XF 1 "register_operand" "u"))]
15067   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068    && flag_unsafe_math_optimizations"
15069 {
15070   rtx copy = gen_reg_rtx (XFmode);
15071   emit_move_insn (copy, operands[1]);
15072   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15073   DONE;
15074 })
15075
15076 (define_insn "*fyl2x_sfxf3"
15077   [(set (match_operand:SF 0 "register_operand" "=f")
15078          (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15079                      (match_operand:XF 1 "register_operand" "u")]
15080                     UNSPEC_FYL2X))
15081    (clobber (match_scratch:SF 3 "=1"))]
15082   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15083    && flag_unsafe_math_optimizations"
15084   "fyl2x"
15085   [(set_attr "type" "fpspc")
15086    (set_attr "mode" "SF")])
15087
15088 (define_insn "*fyl2x_dfxf3"
15089   [(set (match_operand:DF 0 "register_operand" "=f")
15090          (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15091                      (match_operand:XF 1 "register_operand" "u")]
15092                     UNSPEC_FYL2X))
15093    (clobber (match_scratch:DF 3 "=1"))]
15094   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15095    && flag_unsafe_math_optimizations"
15096   "fyl2x"
15097   [(set_attr "type" "fpspc")
15098    (set_attr "mode" "DF")])
15099
15100 (define_insn "*fyl2x_xf3"
15101   [(set (match_operand:XF 0 "register_operand" "=f")
15102         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15103                     (match_operand:XF 1 "register_operand" "u")]
15104                    UNSPEC_FYL2X))
15105    (clobber (match_scratch:XF 3 "=1"))]
15106   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15107    && flag_unsafe_math_optimizations"
15108   "fyl2x"
15109   [(set_attr "type" "fpspc")
15110    (set_attr "mode" "XF")])
15111
15112 (define_expand "logsf2"
15113   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15114                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
15115                                (match_dup 2)] UNSPEC_FYL2X))
15116               (clobber (match_scratch:SF 3 ""))])]
15117   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15118    && flag_unsafe_math_optimizations"
15119 {
15120   rtx temp;
15121
15122   operands[2] = gen_reg_rtx (XFmode);
15123   temp = standard_80387_constant_rtx (4); /* fldln2 */
15124   emit_move_insn (operands[2], temp);
15125 })
15126
15127 (define_expand "logdf2"
15128   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15129                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
15130                                (match_dup 2)] UNSPEC_FYL2X))
15131               (clobber (match_scratch:DF 3 ""))])]
15132   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15133    && flag_unsafe_math_optimizations"
15134 {
15135   rtx temp;
15136
15137   operands[2] = gen_reg_rtx (XFmode);
15138   temp = standard_80387_constant_rtx (4); /* fldln2 */
15139   emit_move_insn (operands[2], temp);
15140 })
15141
15142 (define_expand "logxf2"
15143   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15144                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15145                                (match_dup 2)] UNSPEC_FYL2X))
15146               (clobber (match_scratch:XF 3 ""))])]
15147   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15148    && flag_unsafe_math_optimizations"
15149 {
15150   rtx temp;
15151
15152   operands[2] = gen_reg_rtx (XFmode);
15153   temp = standard_80387_constant_rtx (4); /* fldln2 */
15154   emit_move_insn (operands[2], temp);
15155 })
15156
15157 (define_expand "log10sf2"
15158   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15159                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
15160                                (match_dup 2)] UNSPEC_FYL2X))
15161               (clobber (match_scratch:SF 3 ""))])]
15162   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15163    && flag_unsafe_math_optimizations"
15164 {
15165   rtx temp;
15166
15167   operands[2] = gen_reg_rtx (XFmode);
15168   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15169   emit_move_insn (operands[2], temp);
15170 })
15171
15172 (define_expand "log10df2"
15173   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15174                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
15175                                (match_dup 2)] UNSPEC_FYL2X))
15176               (clobber (match_scratch:DF 3 ""))])]
15177   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15178    && flag_unsafe_math_optimizations"
15179 {
15180   rtx temp;
15181
15182   operands[2] = gen_reg_rtx (XFmode);
15183   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15184   emit_move_insn (operands[2], temp);
15185 })
15186
15187 (define_expand "log10xf2"
15188   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15189                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15190                                (match_dup 2)] UNSPEC_FYL2X))
15191               (clobber (match_scratch:XF 3 ""))])]
15192   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15193    && flag_unsafe_math_optimizations"
15194 {
15195   rtx temp;
15196
15197   operands[2] = gen_reg_rtx (XFmode);
15198   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15199   emit_move_insn (operands[2], temp);
15200 })
15201
15202 (define_expand "log2sf2"
15203   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15204                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
15205                                (match_dup 2)] UNSPEC_FYL2X))
15206               (clobber (match_scratch:SF 3 ""))])]
15207   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208    && flag_unsafe_math_optimizations"
15209 {
15210   operands[2] = gen_reg_rtx (XFmode);
15211   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15212
15213 })
15214
15215 (define_expand "log2df2"
15216   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15217                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
15218                                (match_dup 2)] UNSPEC_FYL2X))
15219               (clobber (match_scratch:DF 3 ""))])]
15220   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15221    && flag_unsafe_math_optimizations"
15222 {
15223   operands[2] = gen_reg_rtx (XFmode);
15224   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15225 })
15226
15227 (define_expand "log2xf2"
15228   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15230                                (match_dup 2)] UNSPEC_FYL2X))
15231               (clobber (match_scratch:XF 3 ""))])]
15232   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15233    && flag_unsafe_math_optimizations"
15234 {
15235   operands[2] = gen_reg_rtx (XFmode);
15236   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15237 })
15238
15239 (define_insn "*fscale_sfxf3"
15240   [(set (match_operand:SF 0 "register_operand" "=f")
15241          (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15242                      (match_operand:XF 1 "register_operand" "u")]
15243                     UNSPEC_FSCALE))
15244    (clobber (match_scratch:SF 3 "=1"))]
15245   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15246    && flag_unsafe_math_optimizations"
15247   "fscale\;fstp\t%y1"
15248   [(set_attr "type" "fpspc")
15249    (set_attr "mode" "SF")])
15250
15251 (define_insn "*fscale_dfxf3"
15252   [(set (match_operand:DF 0 "register_operand" "=f")
15253          (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15254                      (match_operand:XF 1 "register_operand" "u")]
15255                     UNSPEC_FSCALE))
15256    (clobber (match_scratch:DF 3 "=1"))]
15257   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15258    && flag_unsafe_math_optimizations"
15259   "fscale\;fstp\t%y1"
15260   [(set_attr "type" "fpspc")
15261    (set_attr "mode" "DF")])
15262
15263 (define_insn "*fscale_xf3"
15264   [(set (match_operand:XF 0 "register_operand" "=f")
15265         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15266                     (match_operand:XF 1 "register_operand" "u")]
15267                    UNSPEC_FSCALE))
15268    (clobber (match_scratch:XF 3 "=1"))]
15269   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15270    && flag_unsafe_math_optimizations"
15271   "fscale\;fstp\t%y1"
15272   [(set_attr "type" "fpspc")
15273    (set_attr "mode" "XF")])
15274
15275 (define_insn "*frndintxf2"
15276   [(set (match_operand:XF 0 "register_operand" "=f")
15277         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15278          UNSPEC_FRNDINT))]
15279   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15280    && flag_unsafe_math_optimizations"
15281   "frndint"
15282   [(set_attr "type" "fpspc")
15283    (set_attr "mode" "XF")])
15284
15285 (define_insn "*f2xm1xf2"
15286   [(set (match_operand:XF 0 "register_operand" "=f")
15287         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15288          UNSPEC_F2XM1))]
15289   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15290    && flag_unsafe_math_optimizations"
15291   "f2xm1"
15292   [(set_attr "type" "fpspc")
15293    (set_attr "mode" "XF")])
15294
15295 (define_expand "expsf2"
15296   [(set (match_dup 2)
15297         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15298    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15299    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15300    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15301    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15302    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15303    (parallel [(set (match_operand:SF 0 "register_operand" "")
15304                    (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15305               (clobber (match_scratch:SF 5 ""))])]
15306   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15307    && flag_unsafe_math_optimizations"
15308 {
15309   rtx temp;
15310   int i;
15311
15312   for (i=2; i<10; i++)
15313     operands[i] = gen_reg_rtx (XFmode);
15314   temp = standard_80387_constant_rtx (5); /* fldl2e */
15315   emit_move_insn (operands[3], temp);
15316   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15317 })
15318
15319 (define_expand "expdf2"
15320   [(set (match_dup 2)
15321         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15322    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15323    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15324    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15325    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15326    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15327    (parallel [(set (match_operand:DF 0 "register_operand" "")
15328                    (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15329               (clobber (match_scratch:DF 5 ""))])]
15330   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15331    && flag_unsafe_math_optimizations"
15332 {
15333   rtx temp;
15334   int i;
15335
15336   for (i=2; i<10; i++)
15337     operands[i] = gen_reg_rtx (XFmode);
15338   temp = standard_80387_constant_rtx (5); /* fldl2e */
15339   emit_move_insn (operands[3], temp);
15340   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15341 })
15342
15343 (define_expand "expxf2"
15344   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15345                                (match_dup 2)))
15346    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15347    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15348    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15349    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15350    (parallel [(set (match_operand:XF 0 "register_operand" "")
15351                    (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15352               (clobber (match_scratch:XF 5 ""))])]
15353   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15354    && flag_unsafe_math_optimizations"
15355 {
15356   rtx temp;
15357   int i;
15358
15359   for (i=2; i<9; i++)
15360     operands[i] = gen_reg_rtx (XFmode);
15361   temp = standard_80387_constant_rtx (5); /* fldl2e */
15362   emit_move_insn (operands[2], temp);
15363   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15364 })
15365
15366 (define_expand "atansf2"
15367   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15368                    (unspec:SF [(match_dup 2)
15369                                (match_operand:SF 1 "register_operand" "")]
15370                     UNSPEC_FPATAN))
15371               (clobber (match_scratch:SF 3 ""))])]
15372   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373    && flag_unsafe_math_optimizations"
15374 {
15375   operands[2] = gen_reg_rtx (SFmode);
15376   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15377 })
15378
15379 (define_expand "atandf2"
15380   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15381                    (unspec:DF [(match_dup 2)
15382                                (match_operand:DF 1 "register_operand" "")]
15383                     UNSPEC_FPATAN))
15384               (clobber (match_scratch:DF 3 ""))])]
15385   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15386    && flag_unsafe_math_optimizations"
15387 {
15388   operands[2] = gen_reg_rtx (DFmode);
15389   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15390 })
15391
15392 (define_expand "atanxf2"
15393   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15394                    (unspec:XF [(match_dup 2)
15395                                (match_operand:XF 1 "register_operand" "")]
15396                     UNSPEC_FPATAN))
15397               (clobber (match_scratch:XF 3 ""))])]
15398   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15399    && flag_unsafe_math_optimizations"
15400 {
15401   operands[2] = gen_reg_rtx (XFmode);
15402   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15403 })
15404 \f
15405 ;; Block operation instructions
15406
15407 (define_insn "cld"
15408  [(set (reg:SI 19) (const_int 0))]
15409  ""
15410  "cld"
15411   [(set_attr "type" "cld")])
15412
15413 (define_expand "movstrsi"
15414   [(use (match_operand:BLK 0 "memory_operand" ""))
15415    (use (match_operand:BLK 1 "memory_operand" ""))
15416    (use (match_operand:SI 2 "nonmemory_operand" ""))
15417    (use (match_operand:SI 3 "const_int_operand" ""))]
15418   "! optimize_size"
15419 {
15420  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15421    DONE;
15422  else
15423    FAIL;
15424 })
15425
15426 (define_expand "movstrdi"
15427   [(use (match_operand:BLK 0 "memory_operand" ""))
15428    (use (match_operand:BLK 1 "memory_operand" ""))
15429    (use (match_operand:DI 2 "nonmemory_operand" ""))
15430    (use (match_operand:DI 3 "const_int_operand" ""))]
15431   "TARGET_64BIT"
15432 {
15433  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15434    DONE;
15435  else
15436    FAIL;
15437 })
15438
15439 ;; Most CPUs don't like single string operations
15440 ;; Handle this case here to simplify previous expander.
15441
15442 (define_expand "strmov"
15443   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15444    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15445    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15446               (clobber (reg:CC 17))])
15447    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15448               (clobber (reg:CC 17))])]
15449   ""
15450 {
15451   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15452
15453   /* If .md ever supports :P for Pmode, these can be directly
15454      in the pattern above.  */
15455   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15456   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15457
15458   if (TARGET_SINGLE_STRINGOP || optimize_size)
15459     {
15460       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15461                                       operands[2], operands[3],
15462                                       operands[5], operands[6]));
15463       DONE;
15464     }
15465
15466   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15467 })
15468
15469 (define_expand "strmov_singleop"
15470   [(parallel [(set (match_operand 1 "memory_operand" "")
15471                    (match_operand 3 "memory_operand" ""))
15472               (set (match_operand 0 "register_operand" "")
15473                    (match_operand 4 "" ""))
15474               (set (match_operand 2 "register_operand" "")
15475                    (match_operand 5 "" ""))
15476               (use (reg:SI 19))])]
15477   "TARGET_SINGLE_STRINGOP || optimize_size"
15478   "")
15479
15480 (define_insn "*strmovdi_rex_1"
15481   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15482         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15483    (set (match_operand:DI 0 "register_operand" "=D")
15484         (plus:DI (match_dup 2)
15485                  (const_int 8)))
15486    (set (match_operand:DI 1 "register_operand" "=S")
15487         (plus:DI (match_dup 3)
15488                  (const_int 8)))
15489    (use (reg:SI 19))]
15490   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15491   "movsq"
15492   [(set_attr "type" "str")
15493    (set_attr "mode" "DI")
15494    (set_attr "memory" "both")])
15495
15496 (define_insn "*strmovsi_1"
15497   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15498         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15499    (set (match_operand:SI 0 "register_operand" "=D")
15500         (plus:SI (match_dup 2)
15501                  (const_int 4)))
15502    (set (match_operand:SI 1 "register_operand" "=S")
15503         (plus:SI (match_dup 3)
15504                  (const_int 4)))
15505    (use (reg:SI 19))]
15506   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15507   "{movsl|movsd}"
15508   [(set_attr "type" "str")
15509    (set_attr "mode" "SI")
15510    (set_attr "memory" "both")])
15511
15512 (define_insn "*strmovsi_rex_1"
15513   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15514         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15515    (set (match_operand:DI 0 "register_operand" "=D")
15516         (plus:DI (match_dup 2)
15517                  (const_int 4)))
15518    (set (match_operand:DI 1 "register_operand" "=S")
15519         (plus:DI (match_dup 3)
15520                  (const_int 4)))
15521    (use (reg:SI 19))]
15522   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15523   "{movsl|movsd}"
15524   [(set_attr "type" "str")
15525    (set_attr "mode" "SI")
15526    (set_attr "memory" "both")])
15527
15528 (define_insn "*strmovhi_1"
15529   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15530         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15531    (set (match_operand:SI 0 "register_operand" "=D")
15532         (plus:SI (match_dup 2)
15533                  (const_int 2)))
15534    (set (match_operand:SI 1 "register_operand" "=S")
15535         (plus:SI (match_dup 3)
15536                  (const_int 2)))
15537    (use (reg:SI 19))]
15538   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15539   "movsw"
15540   [(set_attr "type" "str")
15541    (set_attr "memory" "both")
15542    (set_attr "mode" "HI")])
15543
15544 (define_insn "*strmovhi_rex_1"
15545   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15546         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15547    (set (match_operand:DI 0 "register_operand" "=D")
15548         (plus:DI (match_dup 2)
15549                  (const_int 2)))
15550    (set (match_operand:DI 1 "register_operand" "=S")
15551         (plus:DI (match_dup 3)
15552                  (const_int 2)))
15553    (use (reg:SI 19))]
15554   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15555   "movsw"
15556   [(set_attr "type" "str")
15557    (set_attr "memory" "both")
15558    (set_attr "mode" "HI")])
15559
15560 (define_insn "*strmovqi_1"
15561   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15562         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15563    (set (match_operand:SI 0 "register_operand" "=D")
15564         (plus:SI (match_dup 2)
15565                  (const_int 1)))
15566    (set (match_operand:SI 1 "register_operand" "=S")
15567         (plus:SI (match_dup 3)
15568                  (const_int 1)))
15569    (use (reg:SI 19))]
15570   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15571   "movsb"
15572   [(set_attr "type" "str")
15573    (set_attr "memory" "both")
15574    (set_attr "mode" "QI")])
15575
15576 (define_insn "*strmovqi_rex_1"
15577   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15578         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15579    (set (match_operand:DI 0 "register_operand" "=D")
15580         (plus:DI (match_dup 2)
15581                  (const_int 1)))
15582    (set (match_operand:DI 1 "register_operand" "=S")
15583         (plus:DI (match_dup 3)
15584                  (const_int 1)))
15585    (use (reg:SI 19))]
15586   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15587   "movsb"
15588   [(set_attr "type" "str")
15589    (set_attr "memory" "both")
15590    (set_attr "mode" "QI")])
15591
15592 (define_expand "rep_mov"
15593   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15594               (set (match_operand 0 "register_operand" "")
15595                    (match_operand 5 "" ""))
15596               (set (match_operand 2 "register_operand" "")
15597                    (match_operand 6 "" ""))
15598               (set (match_operand 1 "memory_operand" "")
15599                    (match_operand 3 "memory_operand" ""))
15600               (use (match_dup 4))
15601               (use (reg:SI 19))])]
15602   ""
15603   "")
15604
15605 (define_insn "*rep_movdi_rex64"
15606   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15607    (set (match_operand:DI 0 "register_operand" "=D") 
15608         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15609                             (const_int 3))
15610                  (match_operand:DI 3 "register_operand" "0")))
15611    (set (match_operand:DI 1 "register_operand" "=S") 
15612         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15613                  (match_operand:DI 4 "register_operand" "1")))
15614    (set (mem:BLK (match_dup 3))
15615         (mem:BLK (match_dup 4)))
15616    (use (match_dup 5))
15617    (use (reg:SI 19))]
15618   "TARGET_64BIT"
15619   "{rep\;movsq|rep movsq}"
15620   [(set_attr "type" "str")
15621    (set_attr "prefix_rep" "1")
15622    (set_attr "memory" "both")
15623    (set_attr "mode" "DI")])
15624
15625 (define_insn "*rep_movsi"
15626   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15627    (set (match_operand:SI 0 "register_operand" "=D") 
15628         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15629                             (const_int 2))
15630                  (match_operand:SI 3 "register_operand" "0")))
15631    (set (match_operand:SI 1 "register_operand" "=S") 
15632         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15633                  (match_operand:SI 4 "register_operand" "1")))
15634    (set (mem:BLK (match_dup 3))
15635         (mem:BLK (match_dup 4)))
15636    (use (match_dup 5))
15637    (use (reg:SI 19))]
15638   "!TARGET_64BIT"
15639   "{rep\;movsl|rep movsd}"
15640   [(set_attr "type" "str")
15641    (set_attr "prefix_rep" "1")
15642    (set_attr "memory" "both")
15643    (set_attr "mode" "SI")])
15644
15645 (define_insn "*rep_movsi_rex64"
15646   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15647    (set (match_operand:DI 0 "register_operand" "=D") 
15648         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15649                             (const_int 2))
15650                  (match_operand:DI 3 "register_operand" "0")))
15651    (set (match_operand:DI 1 "register_operand" "=S") 
15652         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15653                  (match_operand:DI 4 "register_operand" "1")))
15654    (set (mem:BLK (match_dup 3))
15655         (mem:BLK (match_dup 4)))
15656    (use (match_dup 5))
15657    (use (reg:SI 19))]
15658   "TARGET_64BIT"
15659   "{rep\;movsl|rep movsd}"
15660   [(set_attr "type" "str")
15661    (set_attr "prefix_rep" "1")
15662    (set_attr "memory" "both")
15663    (set_attr "mode" "SI")])
15664
15665 (define_insn "*rep_movqi"
15666   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15667    (set (match_operand:SI 0 "register_operand" "=D") 
15668         (plus:SI (match_operand:SI 3 "register_operand" "0")
15669                  (match_operand:SI 5 "register_operand" "2")))
15670    (set (match_operand:SI 1 "register_operand" "=S") 
15671         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15672    (set (mem:BLK (match_dup 3))
15673         (mem:BLK (match_dup 4)))
15674    (use (match_dup 5))
15675    (use (reg:SI 19))]
15676   "!TARGET_64BIT"
15677   "{rep\;movsb|rep movsb}"
15678   [(set_attr "type" "str")
15679    (set_attr "prefix_rep" "1")
15680    (set_attr "memory" "both")
15681    (set_attr "mode" "SI")])
15682
15683 (define_insn "*rep_movqi_rex64"
15684   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15685    (set (match_operand:DI 0 "register_operand" "=D") 
15686         (plus:DI (match_operand:DI 3 "register_operand" "0")
15687                  (match_operand:DI 5 "register_operand" "2")))
15688    (set (match_operand:DI 1 "register_operand" "=S") 
15689         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15690    (set (mem:BLK (match_dup 3))
15691         (mem:BLK (match_dup 4)))
15692    (use (match_dup 5))
15693    (use (reg:SI 19))]
15694   "TARGET_64BIT"
15695   "{rep\;movsb|rep movsb}"
15696   [(set_attr "type" "str")
15697    (set_attr "prefix_rep" "1")
15698    (set_attr "memory" "both")
15699    (set_attr "mode" "SI")])
15700
15701 (define_expand "clrstrsi"
15702    [(use (match_operand:BLK 0 "memory_operand" ""))
15703     (use (match_operand:SI 1 "nonmemory_operand" ""))
15704     (use (match_operand 2 "const_int_operand" ""))]
15705   ""
15706 {
15707  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15708    DONE;
15709  else
15710    FAIL;
15711 })
15712
15713 (define_expand "clrstrdi"
15714    [(use (match_operand:BLK 0 "memory_operand" ""))
15715     (use (match_operand:DI 1 "nonmemory_operand" ""))
15716     (use (match_operand 2 "const_int_operand" ""))]
15717   "TARGET_64BIT"
15718 {
15719  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15720    DONE;
15721  else
15722    FAIL;
15723 })
15724
15725 ;; Most CPUs don't like single string operations
15726 ;; Handle this case here to simplify previous expander.
15727
15728 (define_expand "strset"
15729   [(set (match_operand 1 "memory_operand" "")
15730         (match_operand 2 "register_operand" ""))
15731    (parallel [(set (match_operand 0 "register_operand" "")
15732                    (match_dup 3))
15733               (clobber (reg:CC 17))])]
15734   ""
15735 {
15736   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15737     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15738
15739   /* If .md ever supports :P for Pmode, this can be directly
15740      in the pattern above.  */
15741   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15742                               GEN_INT (GET_MODE_SIZE (GET_MODE
15743                                                       (operands[2]))));
15744   if (TARGET_SINGLE_STRINGOP || optimize_size)
15745     {
15746       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15747                                       operands[3]));
15748       DONE;
15749     }
15750 })
15751
15752 (define_expand "strset_singleop"
15753   [(parallel [(set (match_operand 1 "memory_operand" "")
15754                    (match_operand 2 "register_operand" ""))
15755               (set (match_operand 0 "register_operand" "")
15756                    (match_operand 3 "" ""))
15757               (use (reg:SI 19))])]
15758   "TARGET_SINGLE_STRINGOP || optimize_size"
15759   "")
15760
15761 (define_insn "*strsetdi_rex_1"
15762   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15763         (match_operand:SI 2 "register_operand" "a"))
15764    (set (match_operand:DI 0 "register_operand" "=D")
15765         (plus:DI (match_dup 1)
15766                  (const_int 8)))
15767    (use (reg:SI 19))]
15768   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15769   "stosq"
15770   [(set_attr "type" "str")
15771    (set_attr "memory" "store")
15772    (set_attr "mode" "DI")])
15773
15774 (define_insn "*strsetsi_1"
15775   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15776         (match_operand:SI 2 "register_operand" "a"))
15777    (set (match_operand:SI 0 "register_operand" "=D")
15778         (plus:SI (match_dup 1)
15779                  (const_int 4)))
15780    (use (reg:SI 19))]
15781   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15782   "{stosl|stosd}"
15783   [(set_attr "type" "str")
15784    (set_attr "memory" "store")
15785    (set_attr "mode" "SI")])
15786
15787 (define_insn "*strsetsi_rex_1"
15788   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15789         (match_operand:SI 2 "register_operand" "a"))
15790    (set (match_operand:DI 0 "register_operand" "=D")
15791         (plus:DI (match_dup 1)
15792                  (const_int 4)))
15793    (use (reg:SI 19))]
15794   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15795   "{stosl|stosd}"
15796   [(set_attr "type" "str")
15797    (set_attr "memory" "store")
15798    (set_attr "mode" "SI")])
15799
15800 (define_insn "*strsethi_1"
15801   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15802         (match_operand:HI 2 "register_operand" "a"))
15803    (set (match_operand:SI 0 "register_operand" "=D")
15804         (plus:SI (match_dup 1)
15805                  (const_int 2)))
15806    (use (reg:SI 19))]
15807   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15808   "stosw"
15809   [(set_attr "type" "str")
15810    (set_attr "memory" "store")
15811    (set_attr "mode" "HI")])
15812
15813 (define_insn "*strsethi_rex_1"
15814   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15815         (match_operand:HI 2 "register_operand" "a"))
15816    (set (match_operand:DI 0 "register_operand" "=D")
15817         (plus:DI (match_dup 1)
15818                  (const_int 2)))
15819    (use (reg:SI 19))]
15820   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15821   "stosw"
15822   [(set_attr "type" "str")
15823    (set_attr "memory" "store")
15824    (set_attr "mode" "HI")])
15825
15826 (define_insn "*strsetqi_1"
15827   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15828         (match_operand:QI 2 "register_operand" "a"))
15829    (set (match_operand:SI 0 "register_operand" "=D")
15830         (plus:SI (match_dup 1)
15831                  (const_int 1)))
15832    (use (reg:SI 19))]
15833   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15834   "stosb"
15835   [(set_attr "type" "str")
15836    (set_attr "memory" "store")
15837    (set_attr "mode" "QI")])
15838
15839 (define_insn "*strsetqi_rex_1"
15840   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15841         (match_operand:QI 2 "register_operand" "a"))
15842    (set (match_operand:DI 0 "register_operand" "=D")
15843         (plus:DI (match_dup 1)
15844                  (const_int 1)))
15845    (use (reg:SI 19))]
15846   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15847   "stosb"
15848   [(set_attr "type" "str")
15849    (set_attr "memory" "store")
15850    (set_attr "mode" "QI")])
15851
15852 (define_expand "rep_stos"
15853   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15854               (set (match_operand 0 "register_operand" "")
15855                    (match_operand 4 "" ""))
15856               (set (match_operand 2 "memory_operand" "") (const_int 0))
15857               (use (match_operand 3 "register_operand" ""))
15858               (use (match_dup 1))
15859               (use (reg:SI 19))])]
15860   ""
15861   "")
15862
15863 (define_insn "*rep_stosdi_rex64"
15864   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15865    (set (match_operand:DI 0 "register_operand" "=D") 
15866         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15867                             (const_int 3))
15868                  (match_operand:DI 3 "register_operand" "0")))
15869    (set (mem:BLK (match_dup 3))
15870         (const_int 0))
15871    (use (match_operand:DI 2 "register_operand" "a"))
15872    (use (match_dup 4))
15873    (use (reg:SI 19))]
15874   "TARGET_64BIT"
15875   "{rep\;stosq|rep stosq}"
15876   [(set_attr "type" "str")
15877    (set_attr "prefix_rep" "1")
15878    (set_attr "memory" "store")
15879    (set_attr "mode" "DI")])
15880
15881 (define_insn "*rep_stossi"
15882   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15883    (set (match_operand:SI 0 "register_operand" "=D") 
15884         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15885                             (const_int 2))
15886                  (match_operand:SI 3 "register_operand" "0")))
15887    (set (mem:BLK (match_dup 3))
15888         (const_int 0))
15889    (use (match_operand:SI 2 "register_operand" "a"))
15890    (use (match_dup 4))
15891    (use (reg:SI 19))]
15892   "!TARGET_64BIT"
15893   "{rep\;stosl|rep stosd}"
15894   [(set_attr "type" "str")
15895    (set_attr "prefix_rep" "1")
15896    (set_attr "memory" "store")
15897    (set_attr "mode" "SI")])
15898
15899 (define_insn "*rep_stossi_rex64"
15900   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15901    (set (match_operand:DI 0 "register_operand" "=D") 
15902         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15903                             (const_int 2))
15904                  (match_operand:DI 3 "register_operand" "0")))
15905    (set (mem:BLK (match_dup 3))
15906         (const_int 0))
15907    (use (match_operand:SI 2 "register_operand" "a"))
15908    (use (match_dup 4))
15909    (use (reg:SI 19))]
15910   "TARGET_64BIT"
15911   "{rep\;stosl|rep stosd}"
15912   [(set_attr "type" "str")
15913    (set_attr "prefix_rep" "1")
15914    (set_attr "memory" "store")
15915    (set_attr "mode" "SI")])
15916
15917 (define_insn "*rep_stosqi"
15918   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15919    (set (match_operand:SI 0 "register_operand" "=D") 
15920         (plus:SI (match_operand:SI 3 "register_operand" "0")
15921                  (match_operand:SI 4 "register_operand" "1")))
15922    (set (mem:BLK (match_dup 3))
15923         (const_int 0))
15924    (use (match_operand:QI 2 "register_operand" "a"))
15925    (use (match_dup 4))
15926    (use (reg:SI 19))]
15927   "!TARGET_64BIT"
15928   "{rep\;stosb|rep stosb}"
15929   [(set_attr "type" "str")
15930    (set_attr "prefix_rep" "1")
15931    (set_attr "memory" "store")
15932    (set_attr "mode" "QI")])
15933
15934 (define_insn "*rep_stosqi_rex64"
15935   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15936    (set (match_operand:DI 0 "register_operand" "=D") 
15937         (plus:DI (match_operand:DI 3 "register_operand" "0")
15938                  (match_operand:DI 4 "register_operand" "1")))
15939    (set (mem:BLK (match_dup 3))
15940         (const_int 0))
15941    (use (match_operand:QI 2 "register_operand" "a"))
15942    (use (match_dup 4))
15943    (use (reg:SI 19))]
15944   "TARGET_64BIT"
15945   "{rep\;stosb|rep stosb}"
15946   [(set_attr "type" "str")
15947    (set_attr "prefix_rep" "1")
15948    (set_attr "memory" "store")
15949    (set_attr "mode" "QI")])
15950
15951 (define_expand "cmpstrsi"
15952   [(set (match_operand:SI 0 "register_operand" "")
15953         (compare:SI (match_operand:BLK 1 "general_operand" "")
15954                     (match_operand:BLK 2 "general_operand" "")))
15955    (use (match_operand 3 "general_operand" ""))
15956    (use (match_operand 4 "immediate_operand" ""))]
15957   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15958 {
15959   rtx addr1, addr2, out, outlow, count, countreg, align;
15960
15961   /* Can't use this if the user has appropriated esi or edi.  */
15962   if (global_regs[4] || global_regs[5])
15963     FAIL;
15964
15965   out = operands[0];
15966   if (GET_CODE (out) != REG)
15967     out = gen_reg_rtx (SImode);
15968
15969   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15970   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15971   if (addr1 != XEXP (operands[1], 0))
15972     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15973   if (addr2 != XEXP (operands[2], 0))
15974     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15975
15976   count = operands[3];
15977   countreg = ix86_zero_extend_to_Pmode (count);
15978
15979   /* %%% Iff we are testing strict equality, we can use known alignment
15980      to good advantage.  This may be possible with combine, particularly
15981      once cc0 is dead.  */
15982   align = operands[4];
15983
15984   emit_insn (gen_cld ());
15985   if (GET_CODE (count) == CONST_INT)
15986     {
15987       if (INTVAL (count) == 0)
15988         {
15989           emit_move_insn (operands[0], const0_rtx);
15990           DONE;
15991         }
15992       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15993                                     operands[1], operands[2]));
15994     }
15995   else
15996     {
15997       if (TARGET_64BIT)
15998         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15999       else
16000         emit_insn (gen_cmpsi_1 (countreg, countreg));
16001       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16002                                  operands[1], operands[2]));
16003     }
16004
16005   outlow = gen_lowpart (QImode, out);
16006   emit_insn (gen_cmpintqi (outlow));
16007   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16008
16009   if (operands[0] != out)
16010     emit_move_insn (operands[0], out);
16011
16012   DONE;
16013 })
16014
16015 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16016
16017 (define_expand "cmpintqi"
16018   [(set (match_dup 1)
16019         (gtu:QI (reg:CC 17) (const_int 0)))
16020    (set (match_dup 2)
16021         (ltu:QI (reg:CC 17) (const_int 0)))
16022    (parallel [(set (match_operand:QI 0 "register_operand" "")
16023                    (minus:QI (match_dup 1)
16024                              (match_dup 2)))
16025               (clobber (reg:CC 17))])]
16026   ""
16027   "operands[1] = gen_reg_rtx (QImode);
16028    operands[2] = gen_reg_rtx (QImode);")
16029
16030 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16031 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16032
16033 (define_expand "cmpstrqi_nz_1"
16034   [(parallel [(set (reg:CC 17)
16035                    (compare:CC (match_operand 4 "memory_operand" "")
16036                                (match_operand 5 "memory_operand" "")))
16037               (use (match_operand 2 "register_operand" ""))
16038               (use (match_operand:SI 3 "immediate_operand" ""))
16039               (use (reg:SI 19))
16040               (clobber (match_operand 0 "register_operand" ""))
16041               (clobber (match_operand 1 "register_operand" ""))
16042               (clobber (match_dup 2))])]
16043   ""
16044   "")
16045
16046 (define_insn "*cmpstrqi_nz_1"
16047   [(set (reg:CC 17)
16048         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16049                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16050    (use (match_operand:SI 6 "register_operand" "2"))
16051    (use (match_operand:SI 3 "immediate_operand" "i"))
16052    (use (reg:SI 19))
16053    (clobber (match_operand:SI 0 "register_operand" "=S"))
16054    (clobber (match_operand:SI 1 "register_operand" "=D"))
16055    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16056   "!TARGET_64BIT"
16057   "repz{\;| }cmpsb"
16058   [(set_attr "type" "str")
16059    (set_attr "mode" "QI")
16060    (set_attr "prefix_rep" "1")])
16061
16062 (define_insn "*cmpstrqi_nz_rex_1"
16063   [(set (reg:CC 17)
16064         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16065                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16066    (use (match_operand:DI 6 "register_operand" "2"))
16067    (use (match_operand:SI 3 "immediate_operand" "i"))
16068    (use (reg:SI 19))
16069    (clobber (match_operand:DI 0 "register_operand" "=S"))
16070    (clobber (match_operand:DI 1 "register_operand" "=D"))
16071    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16072   "TARGET_64BIT"
16073   "repz{\;| }cmpsb"
16074   [(set_attr "type" "str")
16075    (set_attr "mode" "QI")
16076    (set_attr "prefix_rep" "1")])
16077
16078 ;; The same, but the count is not known to not be zero.
16079
16080 (define_expand "cmpstrqi_1"
16081   [(parallel [(set (reg:CC 17)
16082                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16083                                      (const_int 0))
16084                   (compare:CC (match_operand 4 "memory_operand" "")
16085                               (match_operand 5 "memory_operand" ""))
16086                   (const_int 0)))
16087               (use (match_operand:SI 3 "immediate_operand" ""))
16088               (use (reg:CC 17))
16089               (use (reg:SI 19))
16090               (clobber (match_operand 0 "register_operand" ""))
16091               (clobber (match_operand 1 "register_operand" ""))
16092               (clobber (match_dup 2))])]
16093   ""
16094   "")
16095
16096 (define_insn "*cmpstrqi_1"
16097   [(set (reg:CC 17)
16098         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16099                              (const_int 0))
16100           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16101                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16102           (const_int 0)))
16103    (use (match_operand:SI 3 "immediate_operand" "i"))
16104    (use (reg:CC 17))
16105    (use (reg:SI 19))
16106    (clobber (match_operand:SI 0 "register_operand" "=S"))
16107    (clobber (match_operand:SI 1 "register_operand" "=D"))
16108    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16109   "!TARGET_64BIT"
16110   "repz{\;| }cmpsb"
16111   [(set_attr "type" "str")
16112    (set_attr "mode" "QI")
16113    (set_attr "prefix_rep" "1")])
16114
16115 (define_insn "*cmpstrqi_rex_1"
16116   [(set (reg:CC 17)
16117         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16118                              (const_int 0))
16119           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16120                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16121           (const_int 0)))
16122    (use (match_operand:SI 3 "immediate_operand" "i"))
16123    (use (reg:CC 17))
16124    (use (reg:SI 19))
16125    (clobber (match_operand:DI 0 "register_operand" "=S"))
16126    (clobber (match_operand:DI 1 "register_operand" "=D"))
16127    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16128   "TARGET_64BIT"
16129   "repz{\;| }cmpsb"
16130   [(set_attr "type" "str")
16131    (set_attr "mode" "QI")
16132    (set_attr "prefix_rep" "1")])
16133
16134 (define_expand "strlensi"
16135   [(set (match_operand:SI 0 "register_operand" "")
16136         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16137                     (match_operand:QI 2 "immediate_operand" "")
16138                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16139   ""
16140 {
16141  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16142    DONE;
16143  else
16144    FAIL;
16145 })
16146
16147 (define_expand "strlendi"
16148   [(set (match_operand:DI 0 "register_operand" "")
16149         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16150                     (match_operand:QI 2 "immediate_operand" "")
16151                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16152   ""
16153 {
16154  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16155    DONE;
16156  else
16157    FAIL;
16158 })
16159
16160 (define_expand "strlenqi_1"
16161   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16162               (use (reg:SI 19))
16163               (clobber (match_operand 1 "register_operand" ""))
16164               (clobber (reg:CC 17))])]
16165   ""
16166   "")
16167
16168 (define_insn "*strlenqi_1"
16169   [(set (match_operand:SI 0 "register_operand" "=&c")
16170         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16171                     (match_operand:QI 2 "register_operand" "a")
16172                     (match_operand:SI 3 "immediate_operand" "i")
16173                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16174    (use (reg:SI 19))
16175    (clobber (match_operand:SI 1 "register_operand" "=D"))
16176    (clobber (reg:CC 17))]
16177   "!TARGET_64BIT"
16178   "repnz{\;| }scasb"
16179   [(set_attr "type" "str")
16180    (set_attr "mode" "QI")
16181    (set_attr "prefix_rep" "1")])
16182
16183 (define_insn "*strlenqi_rex_1"
16184   [(set (match_operand:DI 0 "register_operand" "=&c")
16185         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16186                     (match_operand:QI 2 "register_operand" "a")
16187                     (match_operand:DI 3 "immediate_operand" "i")
16188                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16189    (use (reg:SI 19))
16190    (clobber (match_operand:DI 1 "register_operand" "=D"))
16191    (clobber (reg:CC 17))]
16192   "TARGET_64BIT"
16193   "repnz{\;| }scasb"
16194   [(set_attr "type" "str")
16195    (set_attr "mode" "QI")
16196    (set_attr "prefix_rep" "1")])
16197
16198 ;; Peephole optimizations to clean up after cmpstr*.  This should be
16199 ;; handled in combine, but it is not currently up to the task.
16200 ;; When used for their truth value, the cmpstr* expanders generate
16201 ;; code like this:
16202 ;;
16203 ;;   repz cmpsb
16204 ;;   seta       %al
16205 ;;   setb       %dl
16206 ;;   cmpb       %al, %dl
16207 ;;   jcc        label
16208 ;;
16209 ;; The intermediate three instructions are unnecessary.
16210
16211 ;; This one handles cmpstr*_nz_1...
16212 (define_peephole2
16213   [(parallel[
16214      (set (reg:CC 17)
16215           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16216                       (mem:BLK (match_operand 5 "register_operand" ""))))
16217      (use (match_operand 6 "register_operand" ""))
16218      (use (match_operand:SI 3 "immediate_operand" ""))
16219      (use (reg:SI 19))
16220      (clobber (match_operand 0 "register_operand" ""))
16221      (clobber (match_operand 1 "register_operand" ""))
16222      (clobber (match_operand 2 "register_operand" ""))])
16223    (set (match_operand:QI 7 "register_operand" "")
16224         (gtu:QI (reg:CC 17) (const_int 0)))
16225    (set (match_operand:QI 8 "register_operand" "")
16226         (ltu:QI (reg:CC 17) (const_int 0)))
16227    (set (reg 17)
16228         (compare (match_dup 7) (match_dup 8)))
16229   ]
16230   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16231   [(parallel[
16232      (set (reg:CC 17)
16233           (compare:CC (mem:BLK (match_dup 4))
16234                       (mem:BLK (match_dup 5))))
16235      (use (match_dup 6))
16236      (use (match_dup 3))
16237      (use (reg:SI 19))
16238      (clobber (match_dup 0))
16239      (clobber (match_dup 1))
16240      (clobber (match_dup 2))])]
16241   "")
16242
16243 ;; ...and this one handles cmpstr*_1.
16244 (define_peephole2
16245   [(parallel[
16246      (set (reg:CC 17)
16247           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16248                                (const_int 0))
16249             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16250                         (mem:BLK (match_operand 5 "register_operand" "")))
16251             (const_int 0)))
16252      (use (match_operand:SI 3 "immediate_operand" ""))
16253      (use (reg:CC 17))
16254      (use (reg:SI 19))
16255      (clobber (match_operand 0 "register_operand" ""))
16256      (clobber (match_operand 1 "register_operand" ""))
16257      (clobber (match_operand 2 "register_operand" ""))])
16258    (set (match_operand:QI 7 "register_operand" "")
16259         (gtu:QI (reg:CC 17) (const_int 0)))
16260    (set (match_operand:QI 8 "register_operand" "")
16261         (ltu:QI (reg:CC 17) (const_int 0)))
16262    (set (reg 17)
16263         (compare (match_dup 7) (match_dup 8)))
16264   ]
16265   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16266   [(parallel[
16267      (set (reg:CC 17)
16268           (if_then_else:CC (ne (match_dup 6)
16269                                (const_int 0))
16270             (compare:CC (mem:BLK (match_dup 4))
16271                         (mem:BLK (match_dup 5)))
16272             (const_int 0)))
16273      (use (match_dup 3))
16274      (use (reg:CC 17))
16275      (use (reg:SI 19))
16276      (clobber (match_dup 0))
16277      (clobber (match_dup 1))
16278      (clobber (match_dup 2))])]
16279   "")
16280
16281
16282 \f
16283 ;; Conditional move instructions.
16284
16285 (define_expand "movdicc"
16286   [(set (match_operand:DI 0 "register_operand" "")
16287         (if_then_else:DI (match_operand 1 "comparison_operator" "")
16288                          (match_operand:DI 2 "general_operand" "")
16289                          (match_operand:DI 3 "general_operand" "")))]
16290   "TARGET_64BIT"
16291   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16292
16293 (define_insn "x86_movdicc_0_m1_rex64"
16294   [(set (match_operand:DI 0 "register_operand" "=r")
16295         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16296           (const_int -1)
16297           (const_int 0)))
16298    (clobber (reg:CC 17))]
16299   "TARGET_64BIT"
16300   "sbb{q}\t%0, %0"
16301   ; Since we don't have the proper number of operands for an alu insn,
16302   ; fill in all the blanks.
16303   [(set_attr "type" "alu")
16304    (set_attr "pent_pair" "pu")
16305    (set_attr "memory" "none")
16306    (set_attr "imm_disp" "false")
16307    (set_attr "mode" "DI")
16308    (set_attr "length_immediate" "0")])
16309
16310 (define_insn "movdicc_c_rex64"
16311   [(set (match_operand:DI 0 "register_operand" "=r,r")
16312         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
16313                                 [(reg 17) (const_int 0)])
16314                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16315                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16316   "TARGET_64BIT && TARGET_CMOVE
16317    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16318   "@
16319    cmov%O2%C1\t{%2, %0|%0, %2}
16320    cmov%O2%c1\t{%3, %0|%0, %3}"
16321   [(set_attr "type" "icmov")
16322    (set_attr "mode" "DI")])
16323
16324 (define_expand "movsicc"
16325   [(set (match_operand:SI 0 "register_operand" "")
16326         (if_then_else:SI (match_operand 1 "comparison_operator" "")
16327                          (match_operand:SI 2 "general_operand" "")
16328                          (match_operand:SI 3 "general_operand" "")))]
16329   ""
16330   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16331
16332 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16333 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16334 ;; So just document what we're doing explicitly.
16335
16336 (define_insn "x86_movsicc_0_m1"
16337   [(set (match_operand:SI 0 "register_operand" "=r")
16338         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16339           (const_int -1)
16340           (const_int 0)))
16341    (clobber (reg:CC 17))]
16342   ""
16343   "sbb{l}\t%0, %0"
16344   ; Since we don't have the proper number of operands for an alu insn,
16345   ; fill in all the blanks.
16346   [(set_attr "type" "alu")
16347    (set_attr "pent_pair" "pu")
16348    (set_attr "memory" "none")
16349    (set_attr "imm_disp" "false")
16350    (set_attr "mode" "SI")
16351    (set_attr "length_immediate" "0")])
16352
16353 (define_insn "*movsicc_noc"
16354   [(set (match_operand:SI 0 "register_operand" "=r,r")
16355         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
16356                                 [(reg 17) (const_int 0)])
16357                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16358                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16359   "TARGET_CMOVE
16360    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16361   "@
16362    cmov%O2%C1\t{%2, %0|%0, %2}
16363    cmov%O2%c1\t{%3, %0|%0, %3}"
16364   [(set_attr "type" "icmov")
16365    (set_attr "mode" "SI")])
16366
16367 (define_expand "movhicc"
16368   [(set (match_operand:HI 0 "register_operand" "")
16369         (if_then_else:HI (match_operand 1 "comparison_operator" "")
16370                          (match_operand:HI 2 "general_operand" "")
16371                          (match_operand:HI 3 "general_operand" "")))]
16372   "TARGET_HIMODE_MATH"
16373   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16374
16375 (define_insn "*movhicc_noc"
16376   [(set (match_operand:HI 0 "register_operand" "=r,r")
16377         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
16378                                 [(reg 17) (const_int 0)])
16379                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16380                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16381   "TARGET_CMOVE
16382    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16383   "@
16384    cmov%O2%C1\t{%2, %0|%0, %2}
16385    cmov%O2%c1\t{%3, %0|%0, %3}"
16386   [(set_attr "type" "icmov")
16387    (set_attr "mode" "HI")])
16388
16389 (define_expand "movqicc"
16390   [(set (match_operand:QI 0 "register_operand" "")
16391         (if_then_else:QI (match_operand 1 "comparison_operator" "")
16392                          (match_operand:QI 2 "general_operand" "")
16393                          (match_operand:QI 3 "general_operand" "")))]
16394   "TARGET_QIMODE_MATH"
16395   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16396
16397 (define_insn_and_split "*movqicc_noc"
16398   [(set (match_operand:QI 0 "register_operand" "=r,r")
16399         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16400                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16401                       (match_operand:QI 2 "register_operand" "r,0")
16402                       (match_operand:QI 3 "register_operand" "0,r")))]
16403   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16404   "#"
16405   "&& reload_completed"
16406   [(set (match_dup 0)
16407         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16408                       (match_dup 2)
16409                       (match_dup 3)))]
16410   "operands[0] = gen_lowpart (SImode, operands[0]);
16411    operands[2] = gen_lowpart (SImode, operands[2]);
16412    operands[3] = gen_lowpart (SImode, operands[3]);"
16413   [(set_attr "type" "icmov")
16414    (set_attr "mode" "SI")])
16415
16416 (define_expand "movsfcc"
16417   [(set (match_operand:SF 0 "register_operand" "")
16418         (if_then_else:SF (match_operand 1 "comparison_operator" "")
16419                          (match_operand:SF 2 "register_operand" "")
16420                          (match_operand:SF 3 "register_operand" "")))]
16421   "TARGET_CMOVE"
16422   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16423
16424 (define_insn "*movsfcc_1"
16425   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16426         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
16427                                 [(reg 17) (const_int 0)])
16428                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16429                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16430   "TARGET_CMOVE
16431    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16432   "@
16433    fcmov%F1\t{%2, %0|%0, %2}
16434    fcmov%f1\t{%3, %0|%0, %3}
16435    cmov%O2%C1\t{%2, %0|%0, %2}
16436    cmov%O2%c1\t{%3, %0|%0, %3}"
16437   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16438    (set_attr "mode" "SF,SF,SI,SI")])
16439
16440 (define_expand "movdfcc"
16441   [(set (match_operand:DF 0 "register_operand" "")
16442         (if_then_else:DF (match_operand 1 "comparison_operator" "")
16443                          (match_operand:DF 2 "register_operand" "")
16444                          (match_operand:DF 3 "register_operand" "")))]
16445   "TARGET_CMOVE"
16446   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16447
16448 (define_insn "*movdfcc_1"
16449   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16450         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16451                                 [(reg 17) (const_int 0)])
16452                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16453                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16454   "!TARGET_64BIT && TARGET_CMOVE
16455    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16456   "@
16457    fcmov%F1\t{%2, %0|%0, %2}
16458    fcmov%f1\t{%3, %0|%0, %3}
16459    #
16460    #"
16461   [(set_attr "type" "fcmov,fcmov,multi,multi")
16462    (set_attr "mode" "DF")])
16463
16464 (define_insn "*movdfcc_1_rex64"
16465   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16466         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16467                                 [(reg 17) (const_int 0)])
16468                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16469                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16470   "TARGET_64BIT && TARGET_CMOVE
16471    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16472   "@
16473    fcmov%F1\t{%2, %0|%0, %2}
16474    fcmov%f1\t{%3, %0|%0, %3}
16475    cmov%O2%C1\t{%2, %0|%0, %2}
16476    cmov%O2%c1\t{%3, %0|%0, %3}"
16477   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478    (set_attr "mode" "DF")])
16479
16480 (define_split
16481   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16482         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16483                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16484                       (match_operand:DF 2 "nonimmediate_operand" "")
16485                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16486   "!TARGET_64BIT && reload_completed"
16487   [(set (match_dup 2)
16488         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16489                       (match_dup 5)
16490                       (match_dup 7)))
16491    (set (match_dup 3)
16492         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16493                       (match_dup 6)
16494                       (match_dup 8)))]
16495   "split_di (operands+2, 1, operands+5, operands+6);
16496    split_di (operands+3, 1, operands+7, operands+8);
16497    split_di (operands, 1, operands+2, operands+3);")
16498
16499 (define_expand "movxfcc"
16500   [(set (match_operand:XF 0 "register_operand" "")
16501         (if_then_else:XF (match_operand 1 "comparison_operator" "")
16502                          (match_operand:XF 2 "register_operand" "")
16503                          (match_operand:XF 3 "register_operand" "")))]
16504   "TARGET_CMOVE"
16505   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16506
16507 (define_insn "*movxfcc_1"
16508   [(set (match_operand:XF 0 "register_operand" "=f,f")
16509         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16510                                 [(reg 17) (const_int 0)])
16511                       (match_operand:XF 2 "register_operand" "f,0")
16512                       (match_operand:XF 3 "register_operand" "0,f")))]
16513   "TARGET_CMOVE"
16514   "@
16515    fcmov%F1\t{%2, %0|%0, %2}
16516    fcmov%f1\t{%3, %0|%0, %3}"
16517   [(set_attr "type" "fcmov")
16518    (set_attr "mode" "XF")])
16519
16520 (define_expand "minsf3"
16521   [(parallel [
16522      (set (match_operand:SF 0 "register_operand" "")
16523           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16524                                (match_operand:SF 2 "nonimmediate_operand" ""))
16525                            (match_dup 1)
16526                            (match_dup 2)))
16527      (clobber (reg:CC 17))])]
16528   "TARGET_SSE"
16529   "")
16530
16531 (define_insn "*minsf"
16532   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16533         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16534                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16535                          (match_dup 1)
16536                          (match_dup 2)))
16537    (clobber (reg:CC 17))]
16538   "TARGET_SSE && TARGET_IEEE_FP"
16539   "#")
16540
16541 (define_insn "*minsf_nonieee"
16542   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16543         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16544                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16545                          (match_dup 1)
16546                          (match_dup 2)))
16547    (clobber (reg:CC 17))]
16548   "TARGET_SSE && !TARGET_IEEE_FP
16549    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16550   "#")
16551
16552 (define_split
16553   [(set (match_operand:SF 0 "register_operand" "")
16554         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16555                              (match_operand:SF 2 "nonimmediate_operand" ""))
16556                          (match_operand:SF 3 "register_operand" "")
16557                          (match_operand:SF 4 "nonimmediate_operand" "")))
16558    (clobber (reg:CC 17))]
16559   "SSE_REG_P (operands[0]) && reload_completed
16560    && ((operands_match_p (operands[1], operands[3])
16561         && operands_match_p (operands[2], operands[4]))
16562        || (operands_match_p (operands[1], operands[4])
16563            && operands_match_p (operands[2], operands[3])))"
16564   [(set (match_dup 0)
16565         (if_then_else:SF (lt (match_dup 1)
16566                              (match_dup 2))
16567                          (match_dup 1)
16568                          (match_dup 2)))])
16569
16570 ;; Conditional addition patterns
16571 (define_expand "addqicc"
16572   [(match_operand:QI 0 "register_operand" "")
16573    (match_operand 1 "comparison_operator" "")
16574    (match_operand:QI 2 "register_operand" "")
16575    (match_operand:QI 3 "const_int_operand" "")]
16576   ""
16577   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16578
16579 (define_expand "addhicc"
16580   [(match_operand:HI 0 "register_operand" "")
16581    (match_operand 1 "comparison_operator" "")
16582    (match_operand:HI 2 "register_operand" "")
16583    (match_operand:HI 3 "const_int_operand" "")]
16584   ""
16585   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16586
16587 (define_expand "addsicc"
16588   [(match_operand:SI 0 "register_operand" "")
16589    (match_operand 1 "comparison_operator" "")
16590    (match_operand:SI 2 "register_operand" "")
16591    (match_operand:SI 3 "const_int_operand" "")]
16592   ""
16593   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16594
16595 (define_expand "adddicc"
16596   [(match_operand:DI 0 "register_operand" "")
16597    (match_operand 1 "comparison_operator" "")
16598    (match_operand:DI 2 "register_operand" "")
16599    (match_operand:DI 3 "const_int_operand" "")]
16600   "TARGET_64BIT"
16601   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16602
16603 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16604
16605 (define_split
16606   [(set (match_operand:SF 0 "fp_register_operand" "")
16607         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16608                              (match_operand:SF 2 "register_operand" ""))
16609                          (match_operand:SF 3 "register_operand" "")
16610                          (match_operand:SF 4 "register_operand" "")))
16611    (clobber (reg:CC 17))]
16612   "reload_completed
16613    && ((operands_match_p (operands[1], operands[3])
16614         && operands_match_p (operands[2], operands[4]))
16615        || (operands_match_p (operands[1], operands[4])
16616            && operands_match_p (operands[2], operands[3])))"
16617   [(set (reg:CCFP 17)
16618         (compare:CCFP (match_dup 2)
16619                       (match_dup 1)))
16620    (set (match_dup 0)
16621         (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16622                          (match_dup 1)
16623                          (match_dup 2)))])
16624
16625 (define_insn "*minsf_sse"
16626   [(set (match_operand:SF 0 "register_operand" "=x")
16627         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16628                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16629                          (match_dup 1)
16630                          (match_dup 2)))]
16631   "TARGET_SSE && reload_completed"
16632   "minss\t{%2, %0|%0, %2}"
16633   [(set_attr "type" "sse")
16634    (set_attr "mode" "SF")])
16635
16636 (define_expand "mindf3"
16637   [(parallel [
16638      (set (match_operand:DF 0 "register_operand" "")
16639           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16640                                (match_operand:DF 2 "nonimmediate_operand" ""))
16641                            (match_dup 1)
16642                            (match_dup 2)))
16643      (clobber (reg:CC 17))])]
16644   "TARGET_SSE2 && TARGET_SSE_MATH"
16645   "#")
16646
16647 (define_insn "*mindf"
16648   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16649         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16650                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16651                          (match_dup 1)
16652                          (match_dup 2)))
16653    (clobber (reg:CC 17))]
16654   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16655   "#")
16656
16657 (define_insn "*mindf_nonieee"
16658   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16659         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16660                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16661                          (match_dup 1)
16662                          (match_dup 2)))
16663    (clobber (reg:CC 17))]
16664   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16665    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16666   "#")
16667
16668 (define_split
16669   [(set (match_operand:DF 0 "register_operand" "")
16670         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16671                              (match_operand:DF 2 "nonimmediate_operand" ""))
16672                          (match_operand:DF 3 "register_operand" "")
16673                          (match_operand:DF 4 "nonimmediate_operand" "")))
16674    (clobber (reg:CC 17))]
16675   "SSE_REG_P (operands[0]) && reload_completed
16676    && ((operands_match_p (operands[1], operands[3])
16677         && operands_match_p (operands[2], operands[4]))
16678        || (operands_match_p (operands[1], operands[4])
16679            && operands_match_p (operands[2], operands[3])))"
16680   [(set (match_dup 0)
16681         (if_then_else:DF (lt (match_dup 1)
16682                              (match_dup 2))
16683                          (match_dup 1)
16684                          (match_dup 2)))])
16685
16686 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16687 (define_split
16688   [(set (match_operand:DF 0 "fp_register_operand" "")
16689         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16690                              (match_operand:DF 2 "register_operand" ""))
16691                          (match_operand:DF 3 "register_operand" "")
16692                          (match_operand:DF 4 "register_operand" "")))
16693    (clobber (reg:CC 17))]
16694   "reload_completed
16695    && ((operands_match_p (operands[1], operands[3])
16696         && operands_match_p (operands[2], operands[4]))
16697        || (operands_match_p (operands[1], operands[4])
16698            && operands_match_p (operands[2], operands[3])))"
16699   [(set (reg:CCFP 17)
16700         (compare:CCFP (match_dup 2)
16701                       (match_dup 1)))
16702    (set (match_dup 0)
16703         (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16704                          (match_dup 1)
16705                          (match_dup 2)))])
16706
16707 (define_insn "*mindf_sse"
16708   [(set (match_operand:DF 0 "register_operand" "=Y")
16709         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16710                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16711                          (match_dup 1)
16712                          (match_dup 2)))]
16713   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16714   "minsd\t{%2, %0|%0, %2}"
16715   [(set_attr "type" "sse")
16716    (set_attr "mode" "DF")])
16717
16718 (define_expand "maxsf3"
16719   [(parallel [
16720      (set (match_operand:SF 0 "register_operand" "")
16721           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16722                                (match_operand:SF 2 "nonimmediate_operand" ""))
16723                            (match_dup 1)
16724                            (match_dup 2)))
16725      (clobber (reg:CC 17))])]
16726   "TARGET_SSE"
16727   "#")
16728
16729 (define_insn "*maxsf"
16730   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16731         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16732                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16733                          (match_dup 1)
16734                          (match_dup 2)))
16735    (clobber (reg:CC 17))]
16736   "TARGET_SSE && TARGET_IEEE_FP"
16737   "#")
16738
16739 (define_insn "*maxsf_nonieee"
16740   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16741         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16742                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16743                          (match_dup 1)
16744                          (match_dup 2)))
16745    (clobber (reg:CC 17))]
16746   "TARGET_SSE && !TARGET_IEEE_FP
16747    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16748   "#")
16749
16750 (define_split
16751   [(set (match_operand:SF 0 "register_operand" "")
16752         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16753                              (match_operand:SF 2 "nonimmediate_operand" ""))
16754                          (match_operand:SF 3 "register_operand" "")
16755                          (match_operand:SF 4 "nonimmediate_operand" "")))
16756    (clobber (reg:CC 17))]
16757   "SSE_REG_P (operands[0]) && reload_completed
16758    && ((operands_match_p (operands[1], operands[3])
16759         && operands_match_p (operands[2], operands[4]))
16760        || (operands_match_p (operands[1], operands[4])
16761            && operands_match_p (operands[2], operands[3])))"
16762   [(set (match_dup 0)
16763         (if_then_else:SF (gt (match_dup 1)
16764                              (match_dup 2))
16765                          (match_dup 1)
16766                          (match_dup 2)))])
16767
16768 (define_split
16769   [(set (match_operand:SF 0 "fp_register_operand" "")
16770         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16771                              (match_operand:SF 2 "register_operand" ""))
16772                          (match_operand:SF 3 "register_operand" "")
16773                          (match_operand:SF 4 "register_operand" "")))
16774    (clobber (reg:CC 17))]
16775   "reload_completed
16776    && ((operands_match_p (operands[1], operands[3])
16777         && operands_match_p (operands[2], operands[4]))
16778        || (operands_match_p (operands[1], operands[4])
16779            && operands_match_p (operands[2], operands[3])))"
16780   [(set (reg:CCFP 17)
16781         (compare:CCFP (match_dup 1)
16782                       (match_dup 2)))
16783    (set (match_dup 0)
16784         (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16785                          (match_dup 1)
16786                          (match_dup 2)))])
16787
16788 (define_insn "*maxsf_sse"
16789   [(set (match_operand:SF 0 "register_operand" "=x")
16790         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16791                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16792                          (match_dup 1)
16793                          (match_dup 2)))]
16794   "TARGET_SSE && reload_completed"
16795   "maxss\t{%2, %0|%0, %2}"
16796   [(set_attr "type" "sse")
16797    (set_attr "mode" "SF")])
16798
16799 (define_expand "maxdf3"
16800   [(parallel [
16801      (set (match_operand:DF 0 "register_operand" "")
16802           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16803                                (match_operand:DF 2 "nonimmediate_operand" ""))
16804                            (match_dup 1)
16805                            (match_dup 2)))
16806      (clobber (reg:CC 17))])]
16807   "TARGET_SSE2 && TARGET_SSE_MATH"
16808   "#")
16809
16810 (define_insn "*maxdf"
16811   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16812         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16813                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16814                          (match_dup 1)
16815                          (match_dup 2)))
16816    (clobber (reg:CC 17))]
16817   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16818   "#")
16819
16820 (define_insn "*maxdf_nonieee"
16821   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16822         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16823                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16824                          (match_dup 1)
16825                          (match_dup 2)))
16826    (clobber (reg:CC 17))]
16827   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16828    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16829   "#")
16830
16831 (define_split
16832   [(set (match_operand:DF 0 "register_operand" "")
16833         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16834                              (match_operand:DF 2 "nonimmediate_operand" ""))
16835                          (match_operand:DF 3 "register_operand" "")
16836                          (match_operand:DF 4 "nonimmediate_operand" "")))
16837    (clobber (reg:CC 17))]
16838   "SSE_REG_P (operands[0]) && reload_completed
16839    && ((operands_match_p (operands[1], operands[3])
16840         && operands_match_p (operands[2], operands[4]))
16841        || (operands_match_p (operands[1], operands[4])
16842            && operands_match_p (operands[2], operands[3])))"
16843   [(set (match_dup 0)
16844         (if_then_else:DF (gt (match_dup 1)
16845                              (match_dup 2))
16846                          (match_dup 1)
16847                          (match_dup 2)))])
16848
16849 (define_split
16850   [(set (match_operand:DF 0 "fp_register_operand" "")
16851         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16852                              (match_operand:DF 2 "register_operand" ""))
16853                          (match_operand:DF 3 "register_operand" "")
16854                          (match_operand:DF 4 "register_operand" "")))
16855    (clobber (reg:CC 17))]
16856   "reload_completed
16857    && ((operands_match_p (operands[1], operands[3])
16858         && operands_match_p (operands[2], operands[4]))
16859        || (operands_match_p (operands[1], operands[4])
16860            && operands_match_p (operands[2], operands[3])))"
16861   [(set (reg:CCFP 17)
16862         (compare:CCFP (match_dup 1)
16863                       (match_dup 2)))
16864    (set (match_dup 0)
16865         (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16866                          (match_dup 1)
16867                          (match_dup 2)))])
16868
16869 (define_insn "*maxdf_sse"
16870   [(set (match_operand:DF 0 "register_operand" "=Y")
16871         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16872                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16873                          (match_dup 1)
16874                          (match_dup 2)))]
16875   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16876   "maxsd\t{%2, %0|%0, %2}"
16877   [(set_attr "type" "sse")
16878    (set_attr "mode" "DF")])
16879 \f
16880 ;; Misc patterns (?)
16881
16882 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16883 ;; Otherwise there will be nothing to keep
16884 ;; 
16885 ;; [(set (reg ebp) (reg esp))]
16886 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16887 ;;  (clobber (eflags)]
16888 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16889 ;;
16890 ;; in proper program order.
16891 (define_insn "pro_epilogue_adjust_stack_1"
16892   [(set (match_operand:SI 0 "register_operand" "=r,r")
16893         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16894                  (match_operand:SI 2 "immediate_operand" "i,i")))
16895    (clobber (reg:CC 17))
16896    (clobber (mem:BLK (scratch)))]
16897   "!TARGET_64BIT"
16898 {
16899   switch (get_attr_type (insn))
16900     {
16901     case TYPE_IMOV:
16902       return "mov{l}\t{%1, %0|%0, %1}";
16903
16904     case TYPE_ALU:
16905       if (GET_CODE (operands[2]) == CONST_INT
16906           && (INTVAL (operands[2]) == 128
16907               || (INTVAL (operands[2]) < 0
16908                   && INTVAL (operands[2]) != -128)))
16909         {
16910           operands[2] = GEN_INT (-INTVAL (operands[2]));
16911           return "sub{l}\t{%2, %0|%0, %2}";
16912         }
16913       return "add{l}\t{%2, %0|%0, %2}";
16914
16915     case TYPE_LEA:
16916       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16917       return "lea{l}\t{%a2, %0|%0, %a2}";
16918
16919     default:
16920       abort ();
16921     }
16922 }
16923   [(set (attr "type")
16924         (cond [(eq_attr "alternative" "0")
16925                  (const_string "alu")
16926                (match_operand:SI 2 "const0_operand" "")
16927                  (const_string "imov")
16928               ]
16929               (const_string "lea")))
16930    (set_attr "mode" "SI")])
16931
16932 (define_insn "pro_epilogue_adjust_stack_rex64"
16933   [(set (match_operand:DI 0 "register_operand" "=r,r")
16934         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16935                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16936    (clobber (reg:CC 17))
16937    (clobber (mem:BLK (scratch)))]
16938   "TARGET_64BIT"
16939 {
16940   switch (get_attr_type (insn))
16941     {
16942     case TYPE_IMOV:
16943       return "mov{q}\t{%1, %0|%0, %1}";
16944
16945     case TYPE_ALU:
16946       if (GET_CODE (operands[2]) == CONST_INT
16947           /* Avoid overflows.  */
16948           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16949           && (INTVAL (operands[2]) == 128
16950               || (INTVAL (operands[2]) < 0
16951                   && INTVAL (operands[2]) != -128)))
16952         {
16953           operands[2] = GEN_INT (-INTVAL (operands[2]));
16954           return "sub{q}\t{%2, %0|%0, %2}";
16955         }
16956       return "add{q}\t{%2, %0|%0, %2}";
16957
16958     case TYPE_LEA:
16959       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16960       return "lea{q}\t{%a2, %0|%0, %a2}";
16961
16962     default:
16963       abort ();
16964     }
16965 }
16966   [(set (attr "type")
16967         (cond [(eq_attr "alternative" "0")
16968                  (const_string "alu")
16969                (match_operand:DI 2 "const0_operand" "")
16970                  (const_string "imov")
16971               ]
16972               (const_string "lea")))
16973    (set_attr "mode" "DI")])
16974
16975 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16976   [(set (match_operand:DI 0 "register_operand" "=r,r")
16977         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16978                  (match_operand:DI 3 "immediate_operand" "i,i")))
16979    (use (match_operand:DI 2 "register_operand" "r,r"))
16980    (clobber (reg:CC 17))
16981    (clobber (mem:BLK (scratch)))]
16982   "TARGET_64BIT"
16983 {
16984   switch (get_attr_type (insn))
16985     {
16986     case TYPE_ALU:
16987       return "add{q}\t{%2, %0|%0, %2}";
16988
16989     case TYPE_LEA:
16990       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16991       return "lea{q}\t{%a2, %0|%0, %a2}";
16992
16993     default:
16994       abort ();
16995     }
16996 }
16997   [(set_attr "type" "alu,lea")
16998    (set_attr "mode" "DI")])
16999
17000 ;; Placeholder for the conditional moves.  This one is split either to SSE
17001 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
17002 ;; fact is that compares supported by the cmp??ss instructions are exactly
17003 ;; swapped of those supported by cmove sequence.
17004 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17005 ;; supported by i387 comparisons and we do need to emit two conditional moves
17006 ;; in tandem.
17007
17008 (define_insn "sse_movsfcc"
17009   [(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")
17010         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17011                         [(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")
17012                          (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")])
17013                       (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")
17014                       (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")))
17015    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17016    (clobber (reg:CC 17))]
17017   "TARGET_SSE
17018    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17019    /* Avoid combine from being smart and converting min/max
17020       instruction patterns into conditional moves.  */
17021    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17022         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17023        || !rtx_equal_p (operands[4], operands[2])
17024        || !rtx_equal_p (operands[5], operands[3]))
17025    && (!TARGET_IEEE_FP
17026        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17027   "#")
17028
17029 (define_insn "sse_movsfcc_eq"
17030   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17031         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17032                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17033                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17034                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17035    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17036    (clobber (reg:CC 17))]
17037   "TARGET_SSE
17038    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17039   "#")
17040
17041 (define_insn "sse_movdfcc"
17042   [(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")
17043         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17044                         [(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")
17045                          (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")])
17046                       (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")
17047                       (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")))
17048    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17049    (clobber (reg:CC 17))]
17050   "TARGET_SSE2
17051    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17052    /* Avoid combine from being smart and converting min/max
17053       instruction patterns into conditional moves.  */
17054    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17055         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17056        || !rtx_equal_p (operands[4], operands[2])
17057        || !rtx_equal_p (operands[5], operands[3]))
17058    && (!TARGET_IEEE_FP
17059        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17060   "#")
17061
17062 (define_insn "sse_movdfcc_eq"
17063   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17064         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17065                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17066                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17067                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17068    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17069    (clobber (reg:CC 17))]
17070   "TARGET_SSE
17071    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17072   "#")
17073
17074 ;; For non-sse moves just expand the usual cmove sequence.
17075 (define_split
17076   [(set (match_operand 0 "register_operand" "")
17077         (if_then_else (match_operator 1 "comparison_operator"
17078                         [(match_operand 4 "nonimmediate_operand" "")
17079                          (match_operand 5 "register_operand" "")])
17080                       (match_operand 2 "nonimmediate_operand" "")
17081                       (match_operand 3 "nonimmediate_operand" "")))
17082    (clobber (match_operand 6 "" ""))
17083    (clobber (reg:CC 17))]
17084   "!SSE_REG_P (operands[0]) && reload_completed
17085    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17086   [(const_int 0)]
17087 {
17088    ix86_compare_op0 = operands[5];
17089    ix86_compare_op1 = operands[4];
17090    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17091                                  VOIDmode, operands[5], operands[4]);
17092    ix86_expand_fp_movcc (operands);
17093    DONE;
17094 })
17095
17096 ;; Split SSE based conditional move into sequence:
17097 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
17098 ;; and   op2, op0   -  zero op2 if comparison was false
17099 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
17100 ;; or    op2, op0   -  get the nonzero one into the result.
17101 (define_split
17102   [(set (match_operand 0 "register_operand" "")
17103         (if_then_else (match_operator 1 "sse_comparison_operator"
17104                         [(match_operand 4 "register_operand" "")
17105                          (match_operand 5 "nonimmediate_operand" "")])
17106                       (match_operand 2 "register_operand" "")
17107                       (match_operand 3 "register_operand" "")))
17108    (clobber (match_operand 6 "" ""))
17109    (clobber (reg:CC 17))]
17110   "SSE_REG_P (operands[0]) && reload_completed"
17111   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17112    (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17113                                             (subreg:TI (match_dup 4) 0)))
17114    (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17115                                             (subreg:TI (match_dup 3) 0)))
17116    (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17117                                             (subreg:TI (match_dup 7) 0)))]
17118 {
17119   if (GET_MODE (operands[2]) == DFmode
17120       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17121     {
17122       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17123       emit_insn (gen_sse2_unpcklpd (op, op, op));
17124       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17125       emit_insn (gen_sse2_unpcklpd (op, op, op));
17126     }
17127
17128   /* If op2 == op3, op3 would be clobbered before it is used.  */
17129   if (operands_match_p (operands[2], operands[3]))
17130     {
17131       emit_move_insn (operands[0], operands[2]);
17132       DONE;
17133     }
17134
17135   PUT_MODE (operands[1], GET_MODE (operands[0]));
17136   if (operands_match_p (operands[0], operands[4]))
17137     operands[6] = operands[4], operands[7] = operands[2];
17138   else
17139     operands[6] = operands[2], operands[7] = operands[4];
17140 })
17141
17142 ;; Special case of conditional move we can handle effectively.
17143 ;; Do not brother with the integer/floating point case, since these are
17144 ;; bot considerably slower, unlike in the generic case.
17145 (define_insn "*sse_movsfcc_const0_1"
17146   [(set (match_operand:SF 0 "register_operand" "=&x")
17147         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17148                         [(match_operand:SF 4 "register_operand" "0")
17149                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17150                       (match_operand:SF 2 "register_operand" "x")
17151                       (match_operand:SF 3 "const0_operand" "X")))]
17152   "TARGET_SSE"
17153   "#")
17154
17155 (define_insn "*sse_movsfcc_const0_2"
17156   [(set (match_operand:SF 0 "register_operand" "=&x")
17157         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17158                         [(match_operand:SF 4 "register_operand" "0")
17159                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17160                       (match_operand:SF 2 "const0_operand" "X")
17161                       (match_operand:SF 3 "register_operand" "x")))]
17162   "TARGET_SSE"
17163   "#")
17164
17165 (define_insn "*sse_movsfcc_const0_3"
17166   [(set (match_operand:SF 0 "register_operand" "=&x")
17167         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17168                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17169                          (match_operand:SF 5 "register_operand" "0")])
17170                       (match_operand:SF 2 "register_operand" "x")
17171                       (match_operand:SF 3 "const0_operand" "X")))]
17172   "TARGET_SSE"
17173   "#")
17174
17175 (define_insn "*sse_movsfcc_const0_4"
17176   [(set (match_operand:SF 0 "register_operand" "=&x")
17177         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17178                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17179                          (match_operand:SF 5 "register_operand" "0")])
17180                       (match_operand:SF 2 "const0_operand" "X")
17181                       (match_operand:SF 3 "register_operand" "x")))]
17182   "TARGET_SSE"
17183   "#")
17184
17185 (define_insn "*sse_movdfcc_const0_1"
17186   [(set (match_operand:DF 0 "register_operand" "=&Y")
17187         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17188                         [(match_operand:DF 4 "register_operand" "0")
17189                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17190                       (match_operand:DF 2 "register_operand" "Y")
17191                       (match_operand:DF 3 "const0_operand" "X")))]
17192   "TARGET_SSE2"
17193   "#")
17194
17195 (define_insn "*sse_movdfcc_const0_2"
17196   [(set (match_operand:DF 0 "register_operand" "=&Y")
17197         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17198                         [(match_operand:DF 4 "register_operand" "0")
17199                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17200                       (match_operand:DF 2 "const0_operand" "X")
17201                       (match_operand:DF 3 "register_operand" "Y")))]
17202   "TARGET_SSE2"
17203   "#")
17204
17205 (define_insn "*sse_movdfcc_const0_3"
17206   [(set (match_operand:DF 0 "register_operand" "=&Y")
17207         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17208                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17209                          (match_operand:DF 5 "register_operand" "0")])
17210                       (match_operand:DF 2 "register_operand" "Y")
17211                       (match_operand:DF 3 "const0_operand" "X")))]
17212   "TARGET_SSE2"
17213   "#")
17214
17215 (define_insn "*sse_movdfcc_const0_4"
17216   [(set (match_operand:DF 0 "register_operand" "=&Y")
17217         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17218                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17219                          (match_operand:DF 5 "register_operand" "0")])
17220                       (match_operand:DF 2 "const0_operand" "X")
17221                       (match_operand:DF 3 "register_operand" "Y")))]
17222   "TARGET_SSE2"
17223   "#")
17224
17225 (define_split
17226   [(set (match_operand 0 "register_operand" "")
17227         (if_then_else (match_operator 1 "comparison_operator"
17228                         [(match_operand 4 "nonimmediate_operand" "")
17229                          (match_operand 5 "nonimmediate_operand" "")])
17230                       (match_operand 2 "nonmemory_operand" "")
17231                       (match_operand 3 "nonmemory_operand" "")))]
17232   "SSE_REG_P (operands[0]) && reload_completed
17233    && (const0_operand (operands[2], GET_MODE (operands[0]))
17234        || const0_operand (operands[3], GET_MODE (operands[0])))"
17235   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17236    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17237                                             (match_dup 7)))]
17238 {
17239   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17240       && GET_MODE (operands[2]) == DFmode)
17241     {
17242       if (REG_P (operands[2]))
17243         {
17244           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17245           emit_insn (gen_sse2_unpcklpd (op, op, op));
17246         }
17247       if (REG_P (operands[3]))
17248         {
17249           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17250           emit_insn (gen_sse2_unpcklpd (op, op, op));
17251         }
17252     }
17253   PUT_MODE (operands[1], GET_MODE (operands[0]));
17254   if (!sse_comparison_operator (operands[1], VOIDmode)
17255       || !rtx_equal_p (operands[0], operands[4]))
17256     {
17257       rtx tmp = operands[5];
17258       operands[5] = operands[4];
17259       operands[4] = tmp;
17260       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17261     }
17262   if (!rtx_equal_p (operands[0], operands[4]))
17263     abort ();
17264   if (const0_operand (operands[2], GET_MODE (operands[0])))
17265     {
17266       operands[7] = operands[3];
17267       operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17268                                                          0));
17269     }
17270   else
17271     {
17272       operands[7] = operands[2];
17273       operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17274     }
17275   operands[7] = simplify_gen_subreg (TImode, operands[7],
17276                                      GET_MODE (operands[7]), 0);
17277 })
17278
17279 (define_expand "allocate_stack_worker"
17280   [(match_operand:SI 0 "register_operand" "")]
17281   "TARGET_STACK_PROBE"
17282 {
17283   if (reload_completed)
17284     {
17285       if (TARGET_64BIT)
17286         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17287       else
17288         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17289     }
17290   else
17291     {
17292       if (TARGET_64BIT)
17293         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17294       else
17295         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17296     }
17297   DONE;
17298 })
17299
17300 (define_insn "allocate_stack_worker_1"
17301   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17302    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17303    (clobber (match_scratch:SI 1 "=0"))
17304    (clobber (reg:CC 17))]
17305   "!TARGET_64BIT && TARGET_STACK_PROBE"
17306   "call\t__alloca"
17307   [(set_attr "type" "multi")
17308    (set_attr "length" "5")])
17309
17310 (define_expand "allocate_stack_worker_postreload"
17311   [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17312                            UNSPEC_STACK_PROBE)
17313               (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17314               (clobber (match_dup 0))
17315               (clobber (reg:CC 17))])]
17316   ""
17317   "")
17318
17319 (define_insn "allocate_stack_worker_rex64"
17320   [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17321    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17322    (clobber (match_scratch:DI 1 "=0"))
17323    (clobber (reg:CC 17))]
17324   "TARGET_64BIT && TARGET_STACK_PROBE"
17325   "call\t__alloca"
17326   [(set_attr "type" "multi")
17327    (set_attr "length" "5")])
17328
17329 (define_expand "allocate_stack_worker_rex64_postreload"
17330   [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17331                            UNSPEC_STACK_PROBE)
17332               (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17333               (clobber (match_dup 0))
17334               (clobber (reg:CC 17))])]
17335   ""
17336   "")
17337
17338 (define_expand "allocate_stack"
17339   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17340                    (minus:SI (reg:SI 7)
17341                              (match_operand:SI 1 "general_operand" "")))
17342               (clobber (reg:CC 17))])
17343    (parallel [(set (reg:SI 7)
17344                    (minus:SI (reg:SI 7) (match_dup 1)))
17345               (clobber (reg:CC 17))])]
17346   "TARGET_STACK_PROBE"
17347 {
17348 #ifdef CHECK_STACK_LIMIT
17349   if (GET_CODE (operands[1]) == CONST_INT
17350       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17351     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17352                            operands[1]));
17353   else 
17354 #endif
17355     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17356                                                             operands[1])));
17357
17358   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17359   DONE;
17360 })
17361
17362 (define_expand "builtin_setjmp_receiver"
17363   [(label_ref (match_operand 0 "" ""))]
17364   "!TARGET_64BIT && flag_pic"
17365 {
17366   emit_insn (gen_set_got (pic_offset_table_rtx));
17367   DONE;
17368 })
17369 \f
17370 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17371
17372 (define_split
17373   [(set (match_operand 0 "register_operand" "")
17374         (match_operator 3 "promotable_binary_operator"
17375            [(match_operand 1 "register_operand" "")
17376             (match_operand 2 "aligned_operand" "")]))
17377    (clobber (reg:CC 17))]
17378   "! TARGET_PARTIAL_REG_STALL && reload_completed
17379    && ((GET_MODE (operands[0]) == HImode 
17380         && ((!optimize_size && !TARGET_FAST_PREFIX)
17381             || GET_CODE (operands[2]) != CONST_INT
17382             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17383        || (GET_MODE (operands[0]) == QImode 
17384            && (TARGET_PROMOTE_QImode || optimize_size)))"
17385   [(parallel [(set (match_dup 0)
17386                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17387               (clobber (reg:CC 17))])]
17388   "operands[0] = gen_lowpart (SImode, operands[0]);
17389    operands[1] = gen_lowpart (SImode, operands[1]);
17390    if (GET_CODE (operands[3]) != ASHIFT)
17391      operands[2] = gen_lowpart (SImode, operands[2]);
17392    PUT_MODE (operands[3], SImode);")
17393
17394 ; Promote the QImode tests, as i386 has encoding of the AND
17395 ; instruction with 32-bit sign-extended immediate and thus the
17396 ; instruction size is unchanged, except in the %eax case for
17397 ; which it is increased by one byte, hence the ! optimize_size.
17398 (define_split
17399   [(set (reg 17)
17400         (compare (and (match_operand 1 "aligned_operand" "")
17401                       (match_operand 2 "const_int_operand" ""))
17402                  (const_int 0)))
17403    (set (match_operand 0 "register_operand" "")
17404         (and (match_dup 1) (match_dup 2)))]
17405   "! TARGET_PARTIAL_REG_STALL && reload_completed
17406    /* Ensure that the operand will remain sign-extended immediate.  */
17407    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17408    && ! optimize_size
17409    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17410        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17411   [(parallel [(set (reg:CCNO 17)
17412                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17413                                  (const_int 0)))
17414               (set (match_dup 0)
17415                    (and:SI (match_dup 1) (match_dup 2)))])]
17416   "operands[2]
17417      = gen_int_mode (INTVAL (operands[2])
17418                      & GET_MODE_MASK (GET_MODE (operands[0])),
17419                      SImode);
17420    operands[0] = gen_lowpart (SImode, operands[0]);
17421    operands[1] = gen_lowpart (SImode, operands[1]);")
17422
17423 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17424 ; the TEST instruction with 32-bit sign-extended immediate and thus
17425 ; the instruction size would at least double, which is not what we
17426 ; want even with ! optimize_size.
17427 (define_split
17428   [(set (reg 17)
17429         (compare (and (match_operand:HI 0 "aligned_operand" "")
17430                       (match_operand:HI 1 "const_int_operand" ""))
17431                  (const_int 0)))]
17432   "! TARGET_PARTIAL_REG_STALL && reload_completed
17433    /* Ensure that the operand will remain sign-extended immediate.  */
17434    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17435    && ! TARGET_FAST_PREFIX
17436    && ! optimize_size"
17437   [(set (reg:CCNO 17)
17438         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17439                       (const_int 0)))]
17440   "operands[1]
17441      = gen_int_mode (INTVAL (operands[1])
17442                      & GET_MODE_MASK (GET_MODE (operands[0])),
17443                      SImode);
17444    operands[0] = gen_lowpart (SImode, operands[0]);")
17445
17446 (define_split
17447   [(set (match_operand 0 "register_operand" "")
17448         (neg (match_operand 1 "register_operand" "")))
17449    (clobber (reg:CC 17))]
17450   "! TARGET_PARTIAL_REG_STALL && reload_completed
17451    && (GET_MODE (operands[0]) == HImode
17452        || (GET_MODE (operands[0]) == QImode 
17453            && (TARGET_PROMOTE_QImode || optimize_size)))"
17454   [(parallel [(set (match_dup 0)
17455                    (neg:SI (match_dup 1)))
17456               (clobber (reg:CC 17))])]
17457   "operands[0] = gen_lowpart (SImode, operands[0]);
17458    operands[1] = gen_lowpart (SImode, operands[1]);")
17459
17460 (define_split
17461   [(set (match_operand 0 "register_operand" "")
17462         (not (match_operand 1 "register_operand" "")))]
17463   "! TARGET_PARTIAL_REG_STALL && reload_completed
17464    && (GET_MODE (operands[0]) == HImode
17465        || (GET_MODE (operands[0]) == QImode 
17466            && (TARGET_PROMOTE_QImode || optimize_size)))"
17467   [(set (match_dup 0)
17468         (not:SI (match_dup 1)))]
17469   "operands[0] = gen_lowpart (SImode, operands[0]);
17470    operands[1] = gen_lowpart (SImode, operands[1]);")
17471
17472 (define_split 
17473   [(set (match_operand 0 "register_operand" "")
17474         (if_then_else (match_operator 1 "comparison_operator" 
17475                                 [(reg 17) (const_int 0)])
17476                       (match_operand 2 "register_operand" "")
17477                       (match_operand 3 "register_operand" "")))]
17478   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17479    && (GET_MODE (operands[0]) == HImode
17480        || (GET_MODE (operands[0]) == QImode 
17481            && (TARGET_PROMOTE_QImode || optimize_size)))"
17482   [(set (match_dup 0)
17483         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17484   "operands[0] = gen_lowpart (SImode, operands[0]);
17485    operands[2] = gen_lowpart (SImode, operands[2]);
17486    operands[3] = gen_lowpart (SImode, operands[3]);")
17487                         
17488 \f
17489 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17490 ;; transform a complex memory operation into two memory to register operations.
17491
17492 ;; Don't push memory operands
17493 (define_peephole2
17494   [(set (match_operand:SI 0 "push_operand" "")
17495         (match_operand:SI 1 "memory_operand" ""))
17496    (match_scratch:SI 2 "r")]
17497   "! optimize_size && ! TARGET_PUSH_MEMORY"
17498   [(set (match_dup 2) (match_dup 1))
17499    (set (match_dup 0) (match_dup 2))]
17500   "")
17501
17502 (define_peephole2
17503   [(set (match_operand:DI 0 "push_operand" "")
17504         (match_operand:DI 1 "memory_operand" ""))
17505    (match_scratch:DI 2 "r")]
17506   "! optimize_size && ! TARGET_PUSH_MEMORY"
17507   [(set (match_dup 2) (match_dup 1))
17508    (set (match_dup 0) (match_dup 2))]
17509   "")
17510
17511 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17512 ;; SImode pushes.
17513 (define_peephole2
17514   [(set (match_operand:SF 0 "push_operand" "")
17515         (match_operand:SF 1 "memory_operand" ""))
17516    (match_scratch:SF 2 "r")]
17517   "! optimize_size && ! TARGET_PUSH_MEMORY"
17518   [(set (match_dup 2) (match_dup 1))
17519    (set (match_dup 0) (match_dup 2))]
17520   "")
17521
17522 (define_peephole2
17523   [(set (match_operand:HI 0 "push_operand" "")
17524         (match_operand:HI 1 "memory_operand" ""))
17525    (match_scratch:HI 2 "r")]
17526   "! optimize_size && ! TARGET_PUSH_MEMORY"
17527   [(set (match_dup 2) (match_dup 1))
17528    (set (match_dup 0) (match_dup 2))]
17529   "")
17530
17531 (define_peephole2
17532   [(set (match_operand:QI 0 "push_operand" "")
17533         (match_operand:QI 1 "memory_operand" ""))
17534    (match_scratch:QI 2 "q")]
17535   "! optimize_size && ! TARGET_PUSH_MEMORY"
17536   [(set (match_dup 2) (match_dup 1))
17537    (set (match_dup 0) (match_dup 2))]
17538   "")
17539
17540 ;; Don't move an immediate directly to memory when the instruction
17541 ;; gets too big.
17542 (define_peephole2
17543   [(match_scratch:SI 1 "r")
17544    (set (match_operand:SI 0 "memory_operand" "")
17545         (const_int 0))]
17546   "! optimize_size
17547    && ! TARGET_USE_MOV0
17548    && TARGET_SPLIT_LONG_MOVES
17549    && get_attr_length (insn) >= ix86_cost->large_insn
17550    && peep2_regno_dead_p (0, FLAGS_REG)"
17551   [(parallel [(set (match_dup 1) (const_int 0))
17552               (clobber (reg:CC 17))])
17553    (set (match_dup 0) (match_dup 1))]
17554   "")
17555
17556 (define_peephole2
17557   [(match_scratch:HI 1 "r")
17558    (set (match_operand:HI 0 "memory_operand" "")
17559         (const_int 0))]
17560   "! optimize_size
17561    && ! TARGET_USE_MOV0
17562    && TARGET_SPLIT_LONG_MOVES
17563    && get_attr_length (insn) >= ix86_cost->large_insn
17564    && peep2_regno_dead_p (0, FLAGS_REG)"
17565   [(parallel [(set (match_dup 2) (const_int 0))
17566               (clobber (reg:CC 17))])
17567    (set (match_dup 0) (match_dup 1))]
17568   "operands[2] = gen_lowpart (SImode, operands[1]);")
17569
17570 (define_peephole2
17571   [(match_scratch:QI 1 "q")
17572    (set (match_operand:QI 0 "memory_operand" "")
17573         (const_int 0))]
17574   "! optimize_size
17575    && ! TARGET_USE_MOV0
17576    && TARGET_SPLIT_LONG_MOVES
17577    && get_attr_length (insn) >= ix86_cost->large_insn
17578    && peep2_regno_dead_p (0, FLAGS_REG)"
17579   [(parallel [(set (match_dup 2) (const_int 0))
17580               (clobber (reg:CC 17))])
17581    (set (match_dup 0) (match_dup 1))]
17582   "operands[2] = gen_lowpart (SImode, operands[1]);")
17583
17584 (define_peephole2
17585   [(match_scratch:SI 2 "r")
17586    (set (match_operand:SI 0 "memory_operand" "")
17587         (match_operand:SI 1 "immediate_operand" ""))]
17588   "! optimize_size
17589    && get_attr_length (insn) >= ix86_cost->large_insn
17590    && TARGET_SPLIT_LONG_MOVES"
17591   [(set (match_dup 2) (match_dup 1))
17592    (set (match_dup 0) (match_dup 2))]
17593   "")
17594
17595 (define_peephole2
17596   [(match_scratch:HI 2 "r")
17597    (set (match_operand:HI 0 "memory_operand" "")
17598         (match_operand:HI 1 "immediate_operand" ""))]
17599   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17600   && TARGET_SPLIT_LONG_MOVES"
17601   [(set (match_dup 2) (match_dup 1))
17602    (set (match_dup 0) (match_dup 2))]
17603   "")
17604
17605 (define_peephole2
17606   [(match_scratch:QI 2 "q")
17607    (set (match_operand:QI 0 "memory_operand" "")
17608         (match_operand:QI 1 "immediate_operand" ""))]
17609   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17610   && TARGET_SPLIT_LONG_MOVES"
17611   [(set (match_dup 2) (match_dup 1))
17612    (set (match_dup 0) (match_dup 2))]
17613   "")
17614
17615 ;; Don't compare memory with zero, load and use a test instead.
17616 (define_peephole2
17617   [(set (reg 17)
17618         (compare (match_operand:SI 0 "memory_operand" "")
17619                  (const_int 0)))
17620    (match_scratch:SI 3 "r")]
17621   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17622   [(set (match_dup 3) (match_dup 0))
17623    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17624   "")
17625
17626 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17627 ;; Don't split NOTs with a displacement operand, because resulting XOR
17628 ;; will not be pairable anyway.
17629 ;;
17630 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17631 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17632 ;; so this split helps here as well.
17633 ;;
17634 ;; Note: Can't do this as a regular split because we can't get proper
17635 ;; lifetime information then.
17636
17637 (define_peephole2
17638   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17639         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17640   "!optimize_size
17641    && peep2_regno_dead_p (0, FLAGS_REG)
17642    && ((TARGET_PENTIUM 
17643         && (GET_CODE (operands[0]) != MEM
17644             || !memory_displacement_operand (operands[0], SImode)))
17645        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17646   [(parallel [(set (match_dup 0)
17647                    (xor:SI (match_dup 1) (const_int -1)))
17648               (clobber (reg:CC 17))])]
17649   "")
17650
17651 (define_peephole2
17652   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17653         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17654   "!optimize_size
17655    && peep2_regno_dead_p (0, FLAGS_REG)
17656    && ((TARGET_PENTIUM 
17657         && (GET_CODE (operands[0]) != MEM
17658             || !memory_displacement_operand (operands[0], HImode)))
17659        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17660   [(parallel [(set (match_dup 0)
17661                    (xor:HI (match_dup 1) (const_int -1)))
17662               (clobber (reg:CC 17))])]
17663   "")
17664
17665 (define_peephole2
17666   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17667         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17668   "!optimize_size
17669    && peep2_regno_dead_p (0, FLAGS_REG)
17670    && ((TARGET_PENTIUM 
17671         && (GET_CODE (operands[0]) != MEM
17672             || !memory_displacement_operand (operands[0], QImode)))
17673        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17674   [(parallel [(set (match_dup 0)
17675                    (xor:QI (match_dup 1) (const_int -1)))
17676               (clobber (reg:CC 17))])]
17677   "")
17678
17679 ;; Non pairable "test imm, reg" instructions can be translated to
17680 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17681 ;; byte opcode instead of two, have a short form for byte operands),
17682 ;; so do it for other CPUs as well.  Given that the value was dead,
17683 ;; this should not create any new dependencies.  Pass on the sub-word
17684 ;; versions if we're concerned about partial register stalls.
17685
17686 (define_peephole2
17687   [(set (reg 17)
17688         (compare (and:SI (match_operand:SI 0 "register_operand" "")
17689                          (match_operand:SI 1 "immediate_operand" ""))
17690                  (const_int 0)))]
17691   "ix86_match_ccmode (insn, CCNOmode)
17692    && (true_regnum (operands[0]) != 0
17693        || (GET_CODE (operands[1]) == CONST_INT
17694            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17695    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17696   [(parallel
17697      [(set (reg:CCNO 17)
17698            (compare:CCNO (and:SI (match_dup 0)
17699                                  (match_dup 1))
17700                          (const_int 0)))
17701       (set (match_dup 0)
17702            (and:SI (match_dup 0) (match_dup 1)))])]
17703   "")
17704
17705 ;; We don't need to handle HImode case, because it will be promoted to SImode
17706 ;; on ! TARGET_PARTIAL_REG_STALL
17707
17708 (define_peephole2
17709   [(set (reg 17)
17710         (compare (and:QI (match_operand:QI 0 "register_operand" "")
17711                          (match_operand:QI 1 "immediate_operand" ""))
17712                  (const_int 0)))]
17713   "! TARGET_PARTIAL_REG_STALL
17714    && ix86_match_ccmode (insn, CCNOmode)
17715    && true_regnum (operands[0]) != 0
17716    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17717   [(parallel
17718      [(set (reg:CCNO 17)
17719            (compare:CCNO (and:QI (match_dup 0)
17720                                  (match_dup 1))
17721                          (const_int 0)))
17722       (set (match_dup 0)
17723            (and:QI (match_dup 0) (match_dup 1)))])]
17724   "")
17725
17726 (define_peephole2
17727   [(set (reg 17)
17728         (compare
17729           (and:SI
17730             (zero_extract:SI
17731               (match_operand 0 "ext_register_operand" "")
17732               (const_int 8)
17733               (const_int 8))
17734             (match_operand 1 "const_int_operand" ""))
17735           (const_int 0)))]
17736   "! TARGET_PARTIAL_REG_STALL
17737    && ix86_match_ccmode (insn, CCNOmode)
17738    && true_regnum (operands[0]) != 0
17739    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17740   [(parallel [(set (reg:CCNO 17)
17741                    (compare:CCNO
17742                        (and:SI
17743                          (zero_extract:SI
17744                          (match_dup 0)
17745                          (const_int 8)
17746                          (const_int 8))
17747                         (match_dup 1))
17748                    (const_int 0)))
17749               (set (zero_extract:SI (match_dup 0)
17750                                     (const_int 8)
17751                                     (const_int 8))
17752                    (and:SI 
17753                      (zero_extract:SI
17754                        (match_dup 0)
17755                        (const_int 8)
17756                        (const_int 8))
17757                      (match_dup 1)))])]
17758   "")
17759
17760 ;; Don't do logical operations with memory inputs.
17761 (define_peephole2
17762   [(match_scratch:SI 2 "r")
17763    (parallel [(set (match_operand:SI 0 "register_operand" "")
17764                    (match_operator:SI 3 "arith_or_logical_operator"
17765                      [(match_dup 0)
17766                       (match_operand:SI 1 "memory_operand" "")]))
17767               (clobber (reg:CC 17))])]
17768   "! optimize_size && ! TARGET_READ_MODIFY"
17769   [(set (match_dup 2) (match_dup 1))
17770    (parallel [(set (match_dup 0)
17771                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17772               (clobber (reg:CC 17))])]
17773   "")
17774
17775 (define_peephole2
17776   [(match_scratch:SI 2 "r")
17777    (parallel [(set (match_operand:SI 0 "register_operand" "")
17778                    (match_operator:SI 3 "arith_or_logical_operator"
17779                      [(match_operand:SI 1 "memory_operand" "")
17780                       (match_dup 0)]))
17781               (clobber (reg:CC 17))])]
17782   "! optimize_size && ! TARGET_READ_MODIFY"
17783   [(set (match_dup 2) (match_dup 1))
17784    (parallel [(set (match_dup 0)
17785                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17786               (clobber (reg:CC 17))])]
17787   "")
17788
17789 ; Don't do logical operations with memory outputs
17790 ;
17791 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17792 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17793 ; the same decoder scheduling characteristics as the original.
17794
17795 (define_peephole2
17796   [(match_scratch:SI 2 "r")
17797    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17798                    (match_operator:SI 3 "arith_or_logical_operator"
17799                      [(match_dup 0)
17800                       (match_operand:SI 1 "nonmemory_operand" "")]))
17801               (clobber (reg:CC 17))])]
17802   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17803   [(set (match_dup 2) (match_dup 0))
17804    (parallel [(set (match_dup 2)
17805                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17806               (clobber (reg:CC 17))])
17807    (set (match_dup 0) (match_dup 2))]
17808   "")
17809
17810 (define_peephole2
17811   [(match_scratch:SI 2 "r")
17812    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17813                    (match_operator:SI 3 "arith_or_logical_operator"
17814                      [(match_operand:SI 1 "nonmemory_operand" "")
17815                       (match_dup 0)]))
17816               (clobber (reg:CC 17))])]
17817   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17818   [(set (match_dup 2) (match_dup 0))
17819    (parallel [(set (match_dup 2)
17820                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17821               (clobber (reg:CC 17))])
17822    (set (match_dup 0) (match_dup 2))]
17823   "")
17824
17825 ;; Attempt to always use XOR for zeroing registers.
17826 (define_peephole2
17827   [(set (match_operand 0 "register_operand" "")
17828         (const_int 0))]
17829   "(GET_MODE (operands[0]) == QImode
17830     || GET_MODE (operands[0]) == HImode
17831     || GET_MODE (operands[0]) == SImode
17832     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17833    && (! TARGET_USE_MOV0 || optimize_size)
17834    && peep2_regno_dead_p (0, FLAGS_REG)"
17835   [(parallel [(set (match_dup 0) (const_int 0))
17836               (clobber (reg:CC 17))])]
17837   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17838                               operands[0]);")
17839
17840 (define_peephole2
17841   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17842         (const_int 0))]
17843   "(GET_MODE (operands[0]) == QImode
17844     || GET_MODE (operands[0]) == HImode)
17845    && (! TARGET_USE_MOV0 || optimize_size)
17846    && peep2_regno_dead_p (0, FLAGS_REG)"
17847   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17848               (clobber (reg:CC 17))])])
17849
17850 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17851 (define_peephole2
17852   [(set (match_operand 0 "register_operand" "")
17853         (const_int -1))]
17854   "(GET_MODE (operands[0]) == HImode
17855     || GET_MODE (operands[0]) == SImode 
17856     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17857    && (optimize_size || TARGET_PENTIUM)
17858    && peep2_regno_dead_p (0, FLAGS_REG)"
17859   [(parallel [(set (match_dup 0) (const_int -1))
17860               (clobber (reg:CC 17))])]
17861   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17862                               operands[0]);")
17863
17864 ;; Attempt to convert simple leas to adds. These can be created by
17865 ;; move expanders.
17866 (define_peephole2
17867   [(set (match_operand:SI 0 "register_operand" "")
17868         (plus:SI (match_dup 0)
17869                  (match_operand:SI 1 "nonmemory_operand" "")))]
17870   "peep2_regno_dead_p (0, FLAGS_REG)"
17871   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17872               (clobber (reg:CC 17))])]
17873   "")
17874
17875 (define_peephole2
17876   [(set (match_operand:SI 0 "register_operand" "")
17877         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17878                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17879   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17880   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17881               (clobber (reg:CC 17))])]
17882   "operands[2] = gen_lowpart (SImode, operands[2]);")
17883
17884 (define_peephole2
17885   [(set (match_operand:DI 0 "register_operand" "")
17886         (plus:DI (match_dup 0)
17887                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17888   "peep2_regno_dead_p (0, FLAGS_REG)"
17889   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17890               (clobber (reg:CC 17))])]
17891   "")
17892
17893 (define_peephole2
17894   [(set (match_operand:SI 0 "register_operand" "")
17895         (mult:SI (match_dup 0)
17896                  (match_operand:SI 1 "const_int_operand" "")))]
17897   "exact_log2 (INTVAL (operands[1])) >= 0
17898    && peep2_regno_dead_p (0, FLAGS_REG)"
17899   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17900               (clobber (reg:CC 17))])]
17901   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17902
17903 (define_peephole2
17904   [(set (match_operand:DI 0 "register_operand" "")
17905         (mult:DI (match_dup 0)
17906                  (match_operand:DI 1 "const_int_operand" "")))]
17907   "exact_log2 (INTVAL (operands[1])) >= 0
17908    && peep2_regno_dead_p (0, FLAGS_REG)"
17909   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17910               (clobber (reg:CC 17))])]
17911   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17912
17913 (define_peephole2
17914   [(set (match_operand:SI 0 "register_operand" "")
17915         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17916                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17917   "exact_log2 (INTVAL (operands[2])) >= 0
17918    && REGNO (operands[0]) == REGNO (operands[1])
17919    && peep2_regno_dead_p (0, FLAGS_REG)"
17920   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17921               (clobber (reg:CC 17))])]
17922   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17923
17924 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17925 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17926 ;; many CPUs it is also faster, since special hardware to avoid esp
17927 ;; dependencies is present.
17928
17929 ;; While some of these conversions may be done using splitters, we use peepholes
17930 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17931
17932 ;; Convert prologue esp subtractions to push.
17933 ;; We need register to push.  In order to keep verify_flow_info happy we have
17934 ;; two choices
17935 ;; - use scratch and clobber it in order to avoid dependencies
17936 ;; - use already live register
17937 ;; We can't use the second way right now, since there is no reliable way how to
17938 ;; verify that given register is live.  First choice will also most likely in
17939 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17940 ;; call clobbered registers are dead.  We may want to use base pointer as an
17941 ;; alternative when no register is available later.
17942
17943 (define_peephole2
17944   [(match_scratch:SI 0 "r")
17945    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17946               (clobber (reg:CC 17))
17947               (clobber (mem:BLK (scratch)))])]
17948   "optimize_size || !TARGET_SUB_ESP_4"
17949   [(clobber (match_dup 0))
17950    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17951               (clobber (mem:BLK (scratch)))])])
17952
17953 (define_peephole2
17954   [(match_scratch:SI 0 "r")
17955    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17956               (clobber (reg:CC 17))
17957               (clobber (mem:BLK (scratch)))])]
17958   "optimize_size || !TARGET_SUB_ESP_8"
17959   [(clobber (match_dup 0))
17960    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17961    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17962               (clobber (mem:BLK (scratch)))])])
17963
17964 ;; Convert esp subtractions to push.
17965 (define_peephole2
17966   [(match_scratch:SI 0 "r")
17967    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17968               (clobber (reg:CC 17))])]
17969   "optimize_size || !TARGET_SUB_ESP_4"
17970   [(clobber (match_dup 0))
17971    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17972
17973 (define_peephole2
17974   [(match_scratch:SI 0 "r")
17975    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17976               (clobber (reg:CC 17))])]
17977   "optimize_size || !TARGET_SUB_ESP_8"
17978   [(clobber (match_dup 0))
17979    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17980    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17981
17982 ;; Convert epilogue deallocator to pop.
17983 (define_peephole2
17984   [(match_scratch:SI 0 "r")
17985    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17986               (clobber (reg:CC 17))
17987               (clobber (mem:BLK (scratch)))])]
17988   "optimize_size || !TARGET_ADD_ESP_4"
17989   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17990               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17991               (clobber (mem:BLK (scratch)))])]
17992   "")
17993
17994 ;; Two pops case is tricky, since pop causes dependency on destination register.
17995 ;; We use two registers if available.
17996 (define_peephole2
17997   [(match_scratch:SI 0 "r")
17998    (match_scratch:SI 1 "r")
17999    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18000               (clobber (reg:CC 17))
18001               (clobber (mem:BLK (scratch)))])]
18002   "optimize_size || !TARGET_ADD_ESP_8"
18003   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18004               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18005               (clobber (mem:BLK (scratch)))])
18006    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18007               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18008   "")
18009
18010 (define_peephole2
18011   [(match_scratch:SI 0 "r")
18012    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18013               (clobber (reg:CC 17))
18014               (clobber (mem:BLK (scratch)))])]
18015   "optimize_size"
18016   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18017               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18018               (clobber (mem:BLK (scratch)))])
18019    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18020               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18021   "")
18022
18023 ;; Convert esp additions to pop.
18024 (define_peephole2
18025   [(match_scratch:SI 0 "r")
18026    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18027               (clobber (reg:CC 17))])]
18028   ""
18029   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18030               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18031   "")
18032
18033 ;; Two pops case is tricky, since pop causes dependency on destination register.
18034 ;; We use two registers if available.
18035 (define_peephole2
18036   [(match_scratch:SI 0 "r")
18037    (match_scratch:SI 1 "r")
18038    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18039               (clobber (reg:CC 17))])]
18040   ""
18041   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18042               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18043    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18044               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18045   "")
18046
18047 (define_peephole2
18048   [(match_scratch:SI 0 "r")
18049    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18050               (clobber (reg:CC 17))])]
18051   "optimize_size"
18052   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18053               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18054    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18055               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18056   "")
18057 \f
18058 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18059 ;; required and register dies.
18060 (define_peephole2
18061   [(set (reg 17)
18062         (compare (match_operand:SI 0 "register_operand" "")
18063                  (match_operand:SI 1 "incdec_operand" "")))]
18064   "ix86_match_ccmode (insn, CCGCmode)
18065    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18066   [(parallel [(set (reg:CCGC 17)
18067                    (compare:CCGC (match_dup 0)
18068                                  (match_dup 1)))
18069               (clobber (match_dup 0))])]
18070   "")
18071
18072 (define_peephole2
18073   [(set (reg 17)
18074         (compare (match_operand:HI 0 "register_operand" "")
18075                  (match_operand:HI 1 "incdec_operand" "")))]
18076   "ix86_match_ccmode (insn, CCGCmode)
18077    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18078   [(parallel [(set (reg:CCGC 17)
18079                    (compare:CCGC (match_dup 0)
18080                                  (match_dup 1)))
18081               (clobber (match_dup 0))])]
18082   "")
18083
18084 (define_peephole2
18085   [(set (reg 17)
18086         (compare (match_operand:QI 0 "register_operand" "")
18087                  (match_operand:QI 1 "incdec_operand" "")))]
18088   "ix86_match_ccmode (insn, CCGCmode)
18089    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18090   [(parallel [(set (reg:CCGC 17)
18091                    (compare:CCGC (match_dup 0)
18092                                  (match_dup 1)))
18093               (clobber (match_dup 0))])]
18094   "")
18095
18096 ;; Convert compares with 128 to shorter add -128
18097 (define_peephole2
18098   [(set (reg 17)
18099         (compare (match_operand:SI 0 "register_operand" "")
18100                  (const_int 128)))]
18101   "ix86_match_ccmode (insn, CCGCmode)
18102    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18103   [(parallel [(set (reg:CCGC 17)
18104                    (compare:CCGC (match_dup 0)
18105                                  (const_int 128)))
18106               (clobber (match_dup 0))])]
18107   "")
18108
18109 (define_peephole2
18110   [(set (reg 17)
18111         (compare (match_operand:HI 0 "register_operand" "")
18112                  (const_int 128)))]
18113   "ix86_match_ccmode (insn, CCGCmode)
18114    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18115   [(parallel [(set (reg:CCGC 17)
18116                    (compare:CCGC (match_dup 0)
18117                                  (const_int 128)))
18118               (clobber (match_dup 0))])]
18119   "")
18120 \f
18121 (define_peephole2
18122   [(match_scratch:DI 0 "r")
18123    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18124               (clobber (reg:CC 17))
18125               (clobber (mem:BLK (scratch)))])]
18126   "optimize_size || !TARGET_SUB_ESP_4"
18127   [(clobber (match_dup 0))
18128    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18129               (clobber (mem:BLK (scratch)))])])
18130
18131 (define_peephole2
18132   [(match_scratch:DI 0 "r")
18133    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18134               (clobber (reg:CC 17))
18135               (clobber (mem:BLK (scratch)))])]
18136   "optimize_size || !TARGET_SUB_ESP_8"
18137   [(clobber (match_dup 0))
18138    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18139    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18140               (clobber (mem:BLK (scratch)))])])
18141
18142 ;; Convert esp subtractions to push.
18143 (define_peephole2
18144   [(match_scratch:DI 0 "r")
18145    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18146               (clobber (reg:CC 17))])]
18147   "optimize_size || !TARGET_SUB_ESP_4"
18148   [(clobber (match_dup 0))
18149    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18150
18151 (define_peephole2
18152   [(match_scratch:DI 0 "r")
18153    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18154               (clobber (reg:CC 17))])]
18155   "optimize_size || !TARGET_SUB_ESP_8"
18156   [(clobber (match_dup 0))
18157    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18158    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18159
18160 ;; Convert epilogue deallocator to pop.
18161 (define_peephole2
18162   [(match_scratch:DI 0 "r")
18163    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18164               (clobber (reg:CC 17))
18165               (clobber (mem:BLK (scratch)))])]
18166   "optimize_size || !TARGET_ADD_ESP_4"
18167   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18168               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18169               (clobber (mem:BLK (scratch)))])]
18170   "")
18171
18172 ;; Two pops case is tricky, since pop causes dependency on destination register.
18173 ;; We use two registers if available.
18174 (define_peephole2
18175   [(match_scratch:DI 0 "r")
18176    (match_scratch:DI 1 "r")
18177    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18178               (clobber (reg:CC 17))
18179               (clobber (mem:BLK (scratch)))])]
18180   "optimize_size || !TARGET_ADD_ESP_8"
18181   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18182               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18183               (clobber (mem:BLK (scratch)))])
18184    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18185               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18186   "")
18187
18188 (define_peephole2
18189   [(match_scratch:DI 0 "r")
18190    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18191               (clobber (reg:CC 17))
18192               (clobber (mem:BLK (scratch)))])]
18193   "optimize_size"
18194   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18195               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18196               (clobber (mem:BLK (scratch)))])
18197    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18198               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18199   "")
18200
18201 ;; Convert esp additions to pop.
18202 (define_peephole2
18203   [(match_scratch:DI 0 "r")
18204    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18205               (clobber (reg:CC 17))])]
18206   ""
18207   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18208               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18209   "")
18210
18211 ;; Two pops case is tricky, since pop causes dependency on destination register.
18212 ;; We use two registers if available.
18213 (define_peephole2
18214   [(match_scratch:DI 0 "r")
18215    (match_scratch:DI 1 "r")
18216    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18217               (clobber (reg:CC 17))])]
18218   ""
18219   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18220               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18221    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18222               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18223   "")
18224
18225 (define_peephole2
18226   [(match_scratch:DI 0 "r")
18227    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18228               (clobber (reg:CC 17))])]
18229   "optimize_size"
18230   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18231               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18232    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18233               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18234   "")
18235 \f
18236 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18237 ;; imul $32bit_imm, reg, reg is direct decoded.
18238 (define_peephole2
18239   [(match_scratch:DI 3 "r")
18240    (parallel [(set (match_operand:DI 0 "register_operand" "")
18241                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18242                             (match_operand:DI 2 "immediate_operand" "")))
18243               (clobber (reg:CC 17))])]
18244   "TARGET_K8 && !optimize_size
18245    && (GET_CODE (operands[2]) != CONST_INT
18246        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18247   [(set (match_dup 3) (match_dup 1))
18248    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18249               (clobber (reg:CC 17))])]
18250 "")
18251
18252 (define_peephole2
18253   [(match_scratch:SI 3 "r")
18254    (parallel [(set (match_operand:SI 0 "register_operand" "")
18255                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18256                             (match_operand:SI 2 "immediate_operand" "")))
18257               (clobber (reg:CC 17))])]
18258   "TARGET_K8 && !optimize_size
18259    && (GET_CODE (operands[2]) != CONST_INT
18260        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18261   [(set (match_dup 3) (match_dup 1))
18262    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18263               (clobber (reg:CC 17))])]
18264 "")
18265
18266 (define_peephole2
18267   [(match_scratch:SI 3 "r")
18268    (parallel [(set (match_operand:DI 0 "register_operand" "")
18269                    (zero_extend:DI
18270                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18271                               (match_operand:SI 2 "immediate_operand" ""))))
18272               (clobber (reg:CC 17))])]
18273   "TARGET_K8 && !optimize_size
18274    && (GET_CODE (operands[2]) != CONST_INT
18275        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18276   [(set (match_dup 3) (match_dup 1))
18277    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18278               (clobber (reg:CC 17))])]
18279 "")
18280
18281 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18282 ;; Convert it into imul reg, reg
18283 ;; It would be better to force assembler to encode instruction using long
18284 ;; immediate, but there is apparently no way to do so.
18285 (define_peephole2
18286   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18287                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18288                             (match_operand:DI 2 "const_int_operand" "")))
18289               (clobber (reg:CC 17))])
18290    (match_scratch:DI 3 "r")]
18291   "TARGET_K8 && !optimize_size
18292    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18293   [(set (match_dup 3) (match_dup 2))
18294    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18295               (clobber (reg:CC 17))])]
18296 {
18297   if (!rtx_equal_p (operands[0], operands[1]))
18298     emit_move_insn (operands[0], operands[1]);
18299 })
18300
18301 (define_peephole2
18302   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18303                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18304                             (match_operand:SI 2 "const_int_operand" "")))
18305               (clobber (reg:CC 17))])
18306    (match_scratch:SI 3 "r")]
18307   "TARGET_K8 && !optimize_size
18308    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18309   [(set (match_dup 3) (match_dup 2))
18310    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18311               (clobber (reg:CC 17))])]
18312 {
18313   if (!rtx_equal_p (operands[0], operands[1]))
18314     emit_move_insn (operands[0], operands[1]);
18315 })
18316
18317 (define_peephole2
18318   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18319                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18320                             (match_operand:HI 2 "immediate_operand" "")))
18321               (clobber (reg:CC 17))])
18322    (match_scratch:HI 3 "r")]
18323   "TARGET_K8 && !optimize_size"
18324   [(set (match_dup 3) (match_dup 2))
18325    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18326               (clobber (reg:CC 17))])]
18327 {
18328   if (!rtx_equal_p (operands[0], operands[1]))
18329     emit_move_insn (operands[0], operands[1]);
18330 })
18331 \f
18332 ;; Call-value patterns last so that the wildcard operand does not
18333 ;; disrupt insn-recog's switch tables.
18334
18335 (define_insn "*call_value_pop_0"
18336   [(set (match_operand 0 "" "")
18337         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18338               (match_operand:SI 2 "" "")))
18339    (set (reg:SI 7) (plus:SI (reg:SI 7)
18340                             (match_operand:SI 3 "immediate_operand" "")))]
18341   "!TARGET_64BIT"
18342 {
18343   if (SIBLING_CALL_P (insn))
18344     return "jmp\t%P1";
18345   else
18346     return "call\t%P1";
18347 }
18348   [(set_attr "type" "callv")])
18349
18350 (define_insn "*call_value_pop_1"
18351   [(set (match_operand 0 "" "")
18352         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18353               (match_operand:SI 2 "" "")))
18354    (set (reg:SI 7) (plus:SI (reg:SI 7)
18355                             (match_operand:SI 3 "immediate_operand" "i")))]
18356   "!TARGET_64BIT"
18357 {
18358   if (constant_call_address_operand (operands[1], QImode))
18359     {
18360       if (SIBLING_CALL_P (insn))
18361         return "jmp\t%P1";
18362       else
18363         return "call\t%P1";
18364     }
18365   if (SIBLING_CALL_P (insn))
18366     return "jmp\t%A1";
18367   else
18368     return "call\t%A1";
18369 }
18370   [(set_attr "type" "callv")])
18371
18372 (define_insn "*call_value_0"
18373   [(set (match_operand 0 "" "")
18374         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18375               (match_operand:SI 2 "" "")))]
18376   "!TARGET_64BIT"
18377 {
18378   if (SIBLING_CALL_P (insn))
18379     return "jmp\t%P1";
18380   else
18381     return "call\t%P1";
18382 }
18383   [(set_attr "type" "callv")])
18384
18385 (define_insn "*call_value_0_rex64"
18386   [(set (match_operand 0 "" "")
18387         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18388               (match_operand:DI 2 "const_int_operand" "")))]
18389   "TARGET_64BIT"
18390 {
18391   if (SIBLING_CALL_P (insn))
18392     return "jmp\t%P1";
18393   else
18394     return "call\t%P1";
18395 }
18396   [(set_attr "type" "callv")])
18397
18398 (define_insn "*call_value_1"
18399   [(set (match_operand 0 "" "")
18400         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18401               (match_operand:SI 2 "" "")))]
18402   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18403 {
18404   if (constant_call_address_operand (operands[1], QImode))
18405     return "call\t%P1";
18406   return "call\t%*%1";
18407 }
18408   [(set_attr "type" "callv")])
18409
18410 (define_insn "*sibcall_value_1"
18411   [(set (match_operand 0 "" "")
18412         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18413               (match_operand:SI 2 "" "")))]
18414   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18415 {
18416   if (constant_call_address_operand (operands[1], QImode))
18417     return "jmp\t%P1";
18418   return "jmp\t%*%1";
18419 }
18420   [(set_attr "type" "callv")])
18421
18422 (define_insn "*call_value_1_rex64"
18423   [(set (match_operand 0 "" "")
18424         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18425               (match_operand:DI 2 "" "")))]
18426   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18427 {
18428   if (constant_call_address_operand (operands[1], QImode))
18429     return "call\t%P1";
18430   return "call\t%A1";
18431 }
18432   [(set_attr "type" "callv")])
18433
18434 (define_insn "*sibcall_value_1_rex64"
18435   [(set (match_operand 0 "" "")
18436         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18437               (match_operand:DI 2 "" "")))]
18438   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18439   "jmp\t%P1"
18440   [(set_attr "type" "callv")])
18441
18442 (define_insn "*sibcall_value_1_rex64_v"
18443   [(set (match_operand 0 "" "")
18444         (call (mem:QI (reg:DI 40))
18445               (match_operand:DI 1 "" "")))]
18446   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18447   "jmp\t*%%r11"
18448   [(set_attr "type" "callv")])
18449 \f
18450 (define_insn "trap"
18451   [(trap_if (const_int 1) (const_int 5))]
18452   ""
18453   "int\t$5")
18454
18455 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18456 ;;; for the sake of bounds checking.  By emitting bounds checks as
18457 ;;; conditional traps rather than as conditional jumps around
18458 ;;; unconditional traps we avoid introducing spurious basic-block
18459 ;;; boundaries and facilitate elimination of redundant checks.  In
18460 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18461 ;;; interrupt 5.
18462 ;;; 
18463 ;;; FIXME: Static branch prediction rules for ix86 are such that
18464 ;;; forward conditional branches predict as untaken.  As implemented
18465 ;;; below, pseudo conditional traps violate that rule.  We should use
18466 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18467 ;;; section loaded at the end of the text segment and branch forward
18468 ;;; there on bounds-failure, and then jump back immediately (in case
18469 ;;; the system chooses to ignore bounds violations, or to report
18470 ;;; violations and continue execution).
18471
18472 (define_expand "conditional_trap"
18473   [(trap_if (match_operator 0 "comparison_operator"
18474              [(match_dup 2) (const_int 0)])
18475             (match_operand 1 "const_int_operand" ""))]
18476   ""
18477 {
18478   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18479                               ix86_expand_compare (GET_CODE (operands[0]),
18480                                                    NULL, NULL),
18481                               operands[1]));
18482   DONE;
18483 })
18484
18485 (define_insn "*conditional_trap_1"
18486   [(trap_if (match_operator 0 "comparison_operator"
18487              [(reg 17) (const_int 0)])
18488             (match_operand 1 "const_int_operand" ""))]
18489   ""
18490 {
18491   operands[2] = gen_label_rtx ();
18492   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18493   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18494                              CODE_LABEL_NUMBER (operands[2]));
18495   RET;
18496 })
18497
18498         ;; Pentium III SIMD instructions.
18499
18500 ;; Moves for SSE/MMX regs.
18501
18502 (define_insn "movv4sf_internal"
18503   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18504         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18505   "TARGET_SSE"
18506   "@
18507     xorps\t%0, %0
18508     movaps\t{%1, %0|%0, %1}
18509     movaps\t{%1, %0|%0, %1}"
18510   [(set_attr "type" "ssemov")
18511    (set_attr "mode" "V4SF")])
18512
18513 (define_split
18514   [(set (match_operand:V4SF 0 "register_operand" "")
18515         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18516   "TARGET_SSE"
18517   [(set (match_dup 0)
18518         (vec_merge:V4SF
18519          (vec_duplicate:V4SF (match_dup 1))
18520          (match_dup 2)
18521          (const_int 1)))]
18522 {
18523   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18524   operands[2] = CONST0_RTX (V4SFmode);
18525 })
18526
18527 (define_insn "movv4si_internal"
18528   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18529         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18530   "TARGET_SSE"
18531 {
18532   switch (which_alternative)
18533     {
18534     case 0:
18535       if (get_attr_mode (insn) == MODE_V4SF)
18536         return "xorps\t%0, %0";
18537       else
18538         return "pxor\t%0, %0";
18539     case 1:
18540     case 2:
18541       if (get_attr_mode (insn) == MODE_V4SF)
18542         return "movaps\t{%1, %0|%0, %1}";
18543       else
18544         return "movdqa\t{%1, %0|%0, %1}";
18545     default:
18546       abort ();
18547     }
18548 }
18549   [(set_attr "type" "ssemov")
18550    (set (attr "mode")
18551         (cond [(eq_attr "alternative" "0,1")
18552                  (if_then_else
18553                    (ne (symbol_ref "optimize_size")
18554                        (const_int 0))
18555                    (const_string "V4SF")
18556                    (const_string "TI"))
18557                (eq_attr "alternative" "2")
18558                  (if_then_else
18559                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18560                             (const_int 0))
18561                         (ne (symbol_ref "optimize_size")
18562                             (const_int 0)))
18563                    (const_string "V4SF")
18564                    (const_string "TI"))]
18565                (const_string "TI")))])
18566
18567 (define_insn "movv2di_internal"
18568   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18569         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18570   "TARGET_SSE2"
18571 {
18572   switch (which_alternative)
18573     {
18574     case 0:
18575       if (get_attr_mode (insn) == MODE_V4SF)
18576         return "xorps\t%0, %0";
18577       else
18578         return "pxor\t%0, %0";
18579     case 1:
18580     case 2:
18581       if (get_attr_mode (insn) == MODE_V4SF)
18582         return "movaps\t{%1, %0|%0, %1}";
18583       else
18584         return "movdqa\t{%1, %0|%0, %1}";
18585     default:
18586       abort ();
18587     }
18588 }
18589   [(set_attr "type" "ssemov")
18590    (set (attr "mode")
18591         (cond [(eq_attr "alternative" "0,1")
18592                  (if_then_else
18593                    (ne (symbol_ref "optimize_size")
18594                        (const_int 0))
18595                    (const_string "V4SF")
18596                    (const_string "TI"))
18597                (eq_attr "alternative" "2")
18598                  (if_then_else
18599                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18600                             (const_int 0))
18601                         (ne (symbol_ref "optimize_size")
18602                             (const_int 0)))
18603                    (const_string "V4SF")
18604                    (const_string "TI"))]
18605                (const_string "TI")))])
18606
18607 (define_split
18608   [(set (match_operand:V2DF 0 "register_operand" "")
18609         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18610   "TARGET_SSE2"
18611   [(set (match_dup 0)
18612         (vec_merge:V2DF
18613          (vec_duplicate:V2DF (match_dup 1))
18614          (match_dup 2)
18615          (const_int 1)))]
18616 {
18617   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18618   operands[2] = CONST0_RTX (V2DFmode);
18619 })
18620
18621 (define_insn "movv8qi_internal"
18622   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18623         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18624   "TARGET_MMX
18625    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18626   "@
18627     pxor\t%0, %0
18628     movq\t{%1, %0|%0, %1}
18629     movq\t{%1, %0|%0, %1}"
18630   [(set_attr "type" "mmxmov")
18631    (set_attr "mode" "DI")])
18632
18633 (define_insn "movv4hi_internal"
18634   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18635         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18636   "TARGET_MMX
18637    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18638   "@
18639     pxor\t%0, %0
18640     movq\t{%1, %0|%0, %1}
18641     movq\t{%1, %0|%0, %1}"
18642   [(set_attr "type" "mmxmov")
18643    (set_attr "mode" "DI")])
18644
18645 (define_insn "movv2si_internal"
18646   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18647         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18648   "TARGET_MMX
18649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18650   "@
18651     pxor\t%0, %0
18652     movq\t{%1, %0|%0, %1}
18653     movq\t{%1, %0|%0, %1}"
18654   [(set_attr "type" "mmxcvt")
18655    (set_attr "mode" "DI")])
18656
18657 (define_insn "movv2sf_internal"
18658   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18659         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18660   "TARGET_3DNOW
18661    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18662   "@
18663     pxor\t%0, %0
18664     movq\t{%1, %0|%0, %1}
18665     movq\t{%1, %0|%0, %1}"
18666   [(set_attr "type" "mmxcvt")
18667    (set_attr "mode" "DI")])
18668
18669 (define_expand "movti"
18670   [(set (match_operand:TI 0 "nonimmediate_operand" "")
18671         (match_operand:TI 1 "nonimmediate_operand" ""))]
18672   "TARGET_SSE || TARGET_64BIT"
18673 {
18674   if (TARGET_64BIT)
18675     ix86_expand_move (TImode, operands);
18676   else
18677     ix86_expand_vector_move (TImode, operands);
18678   DONE;
18679 })
18680
18681 (define_expand "movtf"
18682   [(set (match_operand:TF 0 "nonimmediate_operand" "")
18683         (match_operand:TF 1 "nonimmediate_operand" ""))]
18684   "TARGET_64BIT"
18685 {
18686   if (TARGET_64BIT)
18687     ix86_expand_move (TFmode, operands);
18688   else
18689     ix86_expand_vector_move (TFmode, operands);
18690   DONE;
18691 })
18692
18693 (define_insn "movv2df_internal"
18694   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18695         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18696   "TARGET_SSE2
18697    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18698 {
18699   switch (which_alternative)
18700     {
18701     case 0:
18702       if (get_attr_mode (insn) == MODE_V4SF)
18703         return "xorps\t%0, %0";
18704       else
18705         return "xorpd\t%0, %0";
18706     case 1:
18707     case 2:
18708       if (get_attr_mode (insn) == MODE_V4SF)
18709         return "movaps\t{%1, %0|%0, %1}";
18710       else
18711         return "movapd\t{%1, %0|%0, %1}";
18712     default:
18713       abort ();
18714     }
18715 }
18716   [(set_attr "type" "ssemov")
18717    (set (attr "mode")
18718         (cond [(eq_attr "alternative" "0,1")
18719                  (if_then_else
18720                    (ne (symbol_ref "optimize_size")
18721                        (const_int 0))
18722                    (const_string "V4SF")
18723                    (const_string "V2DF"))
18724                (eq_attr "alternative" "2")
18725                  (if_then_else
18726                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18727                             (const_int 0))
18728                         (ne (symbol_ref "optimize_size")
18729                             (const_int 0)))
18730                    (const_string "V4SF")
18731                    (const_string "V2DF"))]
18732                (const_string "V2DF")))])
18733
18734 (define_insn "movv8hi_internal"
18735   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18736         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18737   "TARGET_SSE2
18738    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18739 {
18740   switch (which_alternative)
18741     {
18742     case 0:
18743       if (get_attr_mode (insn) == MODE_V4SF)
18744         return "xorps\t%0, %0";
18745       else
18746         return "pxor\t%0, %0";
18747     case 1:
18748     case 2:
18749       if (get_attr_mode (insn) == MODE_V4SF)
18750         return "movaps\t{%1, %0|%0, %1}";
18751       else
18752         return "movdqa\t{%1, %0|%0, %1}";
18753     default:
18754       abort ();
18755     }
18756 }
18757   [(set_attr "type" "ssemov")
18758    (set (attr "mode")
18759         (cond [(eq_attr "alternative" "0,1")
18760                  (if_then_else
18761                    (ne (symbol_ref "optimize_size")
18762                        (const_int 0))
18763                    (const_string "V4SF")
18764                    (const_string "TI"))
18765                (eq_attr "alternative" "2")
18766                  (if_then_else
18767                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18768                             (const_int 0))
18769                         (ne (symbol_ref "optimize_size")
18770                             (const_int 0)))
18771                    (const_string "V4SF")
18772                    (const_string "TI"))]
18773                (const_string "TI")))])
18774
18775 (define_insn "movv16qi_internal"
18776   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18777         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18778   "TARGET_SSE2
18779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18780 {
18781   switch (which_alternative)
18782     {
18783     case 0:
18784       if (get_attr_mode (insn) == MODE_V4SF)
18785         return "xorps\t%0, %0";
18786       else
18787         return "pxor\t%0, %0";
18788     case 1:
18789     case 2:
18790       if (get_attr_mode (insn) == MODE_V4SF)
18791         return "movaps\t{%1, %0|%0, %1}";
18792       else
18793         return "movdqa\t{%1, %0|%0, %1}";
18794     default:
18795       abort ();
18796     }
18797 }
18798   [(set_attr "type" "ssemov")
18799    (set (attr "mode")
18800         (cond [(eq_attr "alternative" "0,1")
18801                  (if_then_else
18802                    (ne (symbol_ref "optimize_size")
18803                        (const_int 0))
18804                    (const_string "V4SF")
18805                    (const_string "TI"))
18806                (eq_attr "alternative" "2")
18807                  (if_then_else
18808                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18809                             (const_int 0))
18810                         (ne (symbol_ref "optimize_size")
18811                             (const_int 0)))
18812                    (const_string "V4SF")
18813                    (const_string "TI"))]
18814                (const_string "TI")))])
18815
18816 (define_expand "movv2df"
18817   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18818         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18819   "TARGET_SSE2"
18820 {
18821   ix86_expand_vector_move (V2DFmode, operands);
18822   DONE;
18823 })
18824
18825 (define_expand "movv8hi"
18826   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18827         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18828   "TARGET_SSE2"
18829 {
18830   ix86_expand_vector_move (V8HImode, operands);
18831   DONE;
18832 })
18833
18834 (define_expand "movv16qi"
18835   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18836         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18837   "TARGET_SSE2"
18838 {
18839   ix86_expand_vector_move (V16QImode, operands);
18840   DONE;
18841 })
18842
18843 (define_expand "movv4sf"
18844   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18845         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18846   "TARGET_SSE"
18847 {
18848   ix86_expand_vector_move (V4SFmode, operands);
18849   DONE;
18850 })
18851
18852 (define_expand "movv4si"
18853   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18854         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18855   "TARGET_SSE"
18856 {
18857   ix86_expand_vector_move (V4SImode, operands);
18858   DONE;
18859 })
18860
18861 (define_expand "movv2di"
18862   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18863         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18864   "TARGET_SSE"
18865 {
18866   ix86_expand_vector_move (V2DImode, operands);
18867   DONE;
18868 })
18869
18870 (define_expand "movv2si"
18871   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18872         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18873   "TARGET_MMX"
18874 {
18875   ix86_expand_vector_move (V2SImode, operands);
18876   DONE;
18877 })
18878
18879 (define_expand "movv4hi"
18880   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18881         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18882   "TARGET_MMX"
18883 {
18884   ix86_expand_vector_move (V4HImode, operands);
18885   DONE;
18886 })
18887
18888 (define_expand "movv8qi"
18889   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18890         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18891   "TARGET_MMX"
18892 {
18893   ix86_expand_vector_move (V8QImode, operands);
18894   DONE;
18895 })
18896
18897 (define_expand "movv2sf"
18898   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18899         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18900    "TARGET_3DNOW"
18901 {
18902   ix86_expand_vector_move (V2SFmode, operands);
18903   DONE;
18904 })
18905
18906 (define_insn "*pushti"
18907   [(set (match_operand:TI 0 "push_operand" "=<")
18908         (match_operand:TI 1 "register_operand" "x"))]
18909   "TARGET_SSE"
18910   "#")
18911
18912 (define_insn "*pushv2df"
18913   [(set (match_operand:V2DF 0 "push_operand" "=<")
18914         (match_operand:V2DF 1 "register_operand" "x"))]
18915   "TARGET_SSE"
18916   "#")
18917
18918 (define_insn "*pushv2di"
18919   [(set (match_operand:V2DI 0 "push_operand" "=<")
18920         (match_operand:V2DI 1 "register_operand" "x"))]
18921   "TARGET_SSE2"
18922   "#")
18923
18924 (define_insn "*pushv8hi"
18925   [(set (match_operand:V8HI 0 "push_operand" "=<")
18926         (match_operand:V8HI 1 "register_operand" "x"))]
18927   "TARGET_SSE2"
18928   "#")
18929
18930 (define_insn "*pushv16qi"
18931   [(set (match_operand:V16QI 0 "push_operand" "=<")
18932         (match_operand:V16QI 1 "register_operand" "x"))]
18933   "TARGET_SSE2"
18934   "#")
18935
18936 (define_insn "*pushv4sf"
18937   [(set (match_operand:V4SF 0 "push_operand" "=<")
18938         (match_operand:V4SF 1 "register_operand" "x"))]
18939   "TARGET_SSE"
18940   "#")
18941
18942 (define_insn "*pushv4si"
18943   [(set (match_operand:V4SI 0 "push_operand" "=<")
18944         (match_operand:V4SI 1 "register_operand" "x"))]
18945   "TARGET_SSE2"
18946   "#")
18947
18948 (define_insn "*pushv2si"
18949   [(set (match_operand:V2SI 0 "push_operand" "=<")
18950         (match_operand:V2SI 1 "register_operand" "y"))]
18951   "TARGET_MMX"
18952   "#")
18953
18954 (define_insn "*pushv4hi"
18955   [(set (match_operand:V4HI 0 "push_operand" "=<")
18956         (match_operand:V4HI 1 "register_operand" "y"))]
18957   "TARGET_MMX"
18958   "#")
18959
18960 (define_insn "*pushv8qi"
18961   [(set (match_operand:V8QI 0 "push_operand" "=<")
18962         (match_operand:V8QI 1 "register_operand" "y"))]
18963   "TARGET_MMX"
18964   "#")
18965
18966 (define_insn "*pushv2sf"
18967   [(set (match_operand:V2SF 0 "push_operand" "=<")
18968         (match_operand:V2SF 1 "register_operand" "y"))]
18969   "TARGET_3DNOW"
18970   "#")
18971
18972 (define_split
18973   [(set (match_operand 0 "push_operand" "")
18974         (match_operand 1 "register_operand" ""))]
18975   "!TARGET_64BIT && reload_completed
18976    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18977   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18978    (set (match_dup 2) (match_dup 1))]
18979   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18980                                  stack_pointer_rtx);
18981    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18982
18983 (define_split
18984   [(set (match_operand 0 "push_operand" "")
18985         (match_operand 1 "register_operand" ""))]
18986   "TARGET_64BIT && reload_completed
18987    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18988   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18989    (set (match_dup 2) (match_dup 1))]
18990   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18991                                  stack_pointer_rtx);
18992    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18993
18994
18995 (define_insn "movti_internal"
18996   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18997         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18998   "TARGET_SSE && !TARGET_64BIT
18999    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19000 {
19001   switch (which_alternative)
19002     {
19003     case 0:
19004       if (get_attr_mode (insn) == MODE_V4SF)
19005         return "xorps\t%0, %0";
19006       else
19007         return "pxor\t%0, %0";
19008     case 1:
19009     case 2:
19010       if (get_attr_mode (insn) == MODE_V4SF)
19011         return "movaps\t{%1, %0|%0, %1}";
19012       else
19013         return "movdqa\t{%1, %0|%0, %1}";
19014     default:
19015       abort ();
19016     }
19017 }
19018   [(set_attr "type" "ssemov,ssemov,ssemov")
19019    (set (attr "mode")
19020         (cond [(eq_attr "alternative" "0,1")
19021                  (if_then_else
19022                    (ne (symbol_ref "optimize_size")
19023                        (const_int 0))
19024                    (const_string "V4SF")
19025                    (const_string "TI"))
19026                (eq_attr "alternative" "2")
19027                  (if_then_else
19028                    (ne (symbol_ref "optimize_size")
19029                        (const_int 0))
19030                    (const_string "V4SF")
19031                    (const_string "TI"))]
19032                (const_string "TI")))])
19033
19034 (define_insn "*movti_rex64"
19035   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19036         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19037   "TARGET_64BIT
19038    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19039 {
19040   switch (which_alternative)
19041     {
19042     case 0:
19043     case 1:
19044       return "#";
19045     case 2:
19046       if (get_attr_mode (insn) == MODE_V4SF)
19047         return "xorps\t%0, %0";
19048       else
19049         return "pxor\t%0, %0";
19050     case 3:
19051     case 4:
19052       if (get_attr_mode (insn) == MODE_V4SF)
19053         return "movaps\t{%1, %0|%0, %1}";
19054       else
19055         return "movdqa\t{%1, %0|%0, %1}";
19056     default:
19057       abort ();
19058     }
19059 }
19060   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19061    (set (attr "mode")
19062         (cond [(eq_attr "alternative" "2,3")
19063                  (if_then_else
19064                    (ne (symbol_ref "optimize_size")
19065                        (const_int 0))
19066                    (const_string "V4SF")
19067                    (const_string "TI"))
19068                (eq_attr "alternative" "4")
19069                  (if_then_else
19070                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19071                             (const_int 0))
19072                         (ne (symbol_ref "optimize_size")
19073                             (const_int 0)))
19074                    (const_string "V4SF")
19075                    (const_string "TI"))]
19076                (const_string "DI")))])
19077
19078 (define_insn "*movtf_rex64"
19079   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19080         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19081   "TARGET_64BIT
19082    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083 {
19084   switch (which_alternative)
19085     {
19086     case 0:
19087     case 1:
19088       return "#";
19089     case 2:
19090       if (get_attr_mode (insn) == MODE_V4SF)
19091         return "xorps\t%0, %0";
19092       else
19093         return "pxor\t%0, %0";
19094     case 3:
19095     case 4:
19096       if (get_attr_mode (insn) == MODE_V4SF)
19097         return "movaps\t{%1, %0|%0, %1}";
19098       else
19099         return "movdqa\t{%1, %0|%0, %1}";
19100     default:
19101       abort ();
19102     }
19103 }
19104   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19105    (set (attr "mode")
19106         (cond [(eq_attr "alternative" "2,3")
19107                  (if_then_else
19108                    (ne (symbol_ref "optimize_size")
19109                        (const_int 0))
19110                    (const_string "V4SF")
19111                    (const_string "TI"))
19112                (eq_attr "alternative" "4")
19113                  (if_then_else
19114                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19115                             (const_int 0))
19116                         (ne (symbol_ref "optimize_size")
19117                             (const_int 0)))
19118                    (const_string "V4SF")
19119                    (const_string "TI"))]
19120                (const_string "DI")))])
19121
19122 (define_split
19123   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19124         (match_operand:TI 1 "general_operand" ""))]
19125   "reload_completed && !SSE_REG_P (operands[0])
19126    && !SSE_REG_P (operands[1])"
19127   [(const_int 0)]
19128   "ix86_split_long_move (operands); DONE;")
19129
19130 (define_split
19131   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19132         (match_operand:TF 1 "general_operand" ""))]
19133   "reload_completed && !SSE_REG_P (operands[0])
19134    && !SSE_REG_P (operands[1])"
19135   [(const_int 0)]
19136   "ix86_split_long_move (operands); DONE;")
19137
19138 ;; These two patterns are useful for specifying exactly whether to use
19139 ;; movaps or movups
19140 (define_expand "sse_movaps"
19141   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19142         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19143                      UNSPEC_MOVA))]
19144   "TARGET_SSE"
19145 {
19146   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19147     {
19148       rtx tmp = gen_reg_rtx (V4SFmode);
19149       emit_insn (gen_sse_movaps (tmp, operands[1]));
19150       emit_move_insn (operands[0], tmp);
19151       DONE;
19152     }
19153 })
19154
19155 (define_insn "*sse_movaps_1"
19156   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19157         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19158                      UNSPEC_MOVA))]
19159   "TARGET_SSE
19160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19161   "movaps\t{%1, %0|%0, %1}"
19162   [(set_attr "type" "ssemov,ssemov")
19163    (set_attr "mode" "V4SF")])
19164
19165 (define_expand "sse_movups"
19166   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19167         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19168                      UNSPEC_MOVU))]
19169   "TARGET_SSE"
19170 {
19171   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19172     {
19173       rtx tmp = gen_reg_rtx (V4SFmode);
19174       emit_insn (gen_sse_movups (tmp, operands[1]));
19175       emit_move_insn (operands[0], tmp);
19176       DONE;
19177     }
19178 })
19179
19180 (define_insn "*sse_movups_1"
19181   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19182         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19183                      UNSPEC_MOVU))]
19184   "TARGET_SSE
19185    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19186   "movups\t{%1, %0|%0, %1}"
19187   [(set_attr "type" "ssecvt,ssecvt")
19188    (set_attr "mode" "V4SF")])
19189
19190 ;; SSE Strange Moves.
19191
19192 (define_insn "sse_movmskps"
19193   [(set (match_operand:SI 0 "register_operand" "=r")
19194         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19195                    UNSPEC_MOVMSK))]
19196   "TARGET_SSE"
19197   "movmskps\t{%1, %0|%0, %1}"
19198   [(set_attr "type" "ssecvt")
19199    (set_attr "mode" "V4SF")])
19200
19201 (define_insn "mmx_pmovmskb"
19202   [(set (match_operand:SI 0 "register_operand" "=r")
19203         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19204                    UNSPEC_MOVMSK))]
19205   "TARGET_SSE || TARGET_3DNOW_A"
19206   "pmovmskb\t{%1, %0|%0, %1}"
19207   [(set_attr "type" "ssecvt")
19208    (set_attr "mode" "V4SF")])
19209
19210
19211 (define_insn "mmx_maskmovq"
19212   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19213         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19214                       (match_operand:V8QI 2 "register_operand" "y")]
19215                      UNSPEC_MASKMOV))]
19216   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19217   ;; @@@ check ordering of operands in intel/nonintel syntax
19218   "maskmovq\t{%2, %1|%1, %2}"
19219   [(set_attr "type" "mmxcvt")
19220    (set_attr "mode" "DI")])
19221
19222 (define_insn "mmx_maskmovq_rex"
19223   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19224         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19225                       (match_operand:V8QI 2 "register_operand" "y")]
19226                      UNSPEC_MASKMOV))]
19227   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19228   ;; @@@ check ordering of operands in intel/nonintel syntax
19229   "maskmovq\t{%2, %1|%1, %2}"
19230   [(set_attr "type" "mmxcvt")
19231    (set_attr "mode" "DI")])
19232
19233 (define_insn "sse_movntv4sf"
19234   [(set (match_operand:V4SF 0 "memory_operand" "=m")
19235         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19236                      UNSPEC_MOVNT))]
19237   "TARGET_SSE"
19238   "movntps\t{%1, %0|%0, %1}"
19239   [(set_attr "type" "ssemov")
19240    (set_attr "mode" "V4SF")])
19241
19242 (define_insn "sse_movntdi"
19243   [(set (match_operand:DI 0 "memory_operand" "=m")
19244         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19245                    UNSPEC_MOVNT))]
19246   "TARGET_SSE || TARGET_3DNOW_A"
19247   "movntq\t{%1, %0|%0, %1}"
19248   [(set_attr "type" "mmxmov")
19249    (set_attr "mode" "DI")])
19250
19251 (define_insn "sse_movhlps"
19252   [(set (match_operand:V4SF 0 "register_operand" "=x")
19253         (vec_merge:V4SF
19254          (match_operand:V4SF 1 "register_operand" "0")
19255          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19256                           (parallel [(const_int 2)
19257                                      (const_int 3)
19258                                      (const_int 0)
19259                                      (const_int 1)]))
19260          (const_int 3)))]
19261   "TARGET_SSE"
19262   "movhlps\t{%2, %0|%0, %2}"
19263   [(set_attr "type" "ssecvt")
19264    (set_attr "mode" "V4SF")])
19265
19266 (define_insn "sse_movlhps"
19267   [(set (match_operand:V4SF 0 "register_operand" "=x")
19268         (vec_merge:V4SF
19269          (match_operand:V4SF 1 "register_operand" "0")
19270          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19271                           (parallel [(const_int 2)
19272                                      (const_int 3)
19273                                      (const_int 0)
19274                                      (const_int 1)]))
19275          (const_int 12)))]
19276   "TARGET_SSE"
19277   "movlhps\t{%2, %0|%0, %2}"
19278   [(set_attr "type" "ssecvt")
19279    (set_attr "mode" "V4SF")])
19280
19281 (define_insn "sse_movhps"
19282   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19283         (vec_merge:V4SF
19284          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19285          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19286          (const_int 12)))]
19287   "TARGET_SSE
19288    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19289   "movhps\t{%2, %0|%0, %2}"
19290   [(set_attr "type" "ssecvt")
19291    (set_attr "mode" "V4SF")])
19292
19293 (define_insn "sse_movlps"
19294   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19295         (vec_merge:V4SF
19296          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19297          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19298          (const_int 3)))]
19299   "TARGET_SSE
19300    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19301   "movlps\t{%2, %0|%0, %2}"
19302   [(set_attr "type" "ssecvt")
19303    (set_attr "mode" "V4SF")])
19304
19305 (define_expand "sse_loadss"
19306   [(match_operand:V4SF 0 "register_operand" "")
19307    (match_operand:SF 1 "memory_operand" "")]
19308   "TARGET_SSE"
19309 {
19310   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19311                                CONST0_RTX (V4SFmode)));
19312   DONE;
19313 })
19314
19315 (define_insn "sse_loadss_1"
19316   [(set (match_operand:V4SF 0 "register_operand" "=x")
19317         (vec_merge:V4SF
19318          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19319          (match_operand:V4SF 2 "const0_operand" "X")
19320          (const_int 1)))]
19321   "TARGET_SSE"
19322   "movss\t{%1, %0|%0, %1}"
19323   [(set_attr "type" "ssemov")
19324    (set_attr "mode" "SF")])
19325
19326 (define_insn "sse_movss"
19327   [(set (match_operand:V4SF 0 "register_operand" "=x")
19328         (vec_merge:V4SF
19329          (match_operand:V4SF 1 "register_operand" "0")
19330          (match_operand:V4SF 2 "register_operand" "x")
19331          (const_int 1)))]
19332   "TARGET_SSE"
19333   "movss\t{%2, %0|%0, %2}"
19334   [(set_attr "type" "ssemov")
19335    (set_attr "mode" "SF")])
19336
19337 (define_insn "sse_storess"
19338   [(set (match_operand:SF 0 "memory_operand" "=m")
19339         (vec_select:SF
19340          (match_operand:V4SF 1 "register_operand" "x")
19341          (parallel [(const_int 0)])))]
19342   "TARGET_SSE"
19343   "movss\t{%1, %0|%0, %1}"
19344   [(set_attr "type" "ssemov")
19345    (set_attr "mode" "SF")])
19346
19347 (define_insn "sse_shufps"
19348   [(set (match_operand:V4SF 0 "register_operand" "=x")
19349         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19350                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19351                       (match_operand:SI 3 "immediate_operand" "i")]
19352                      UNSPEC_SHUFFLE))]
19353   "TARGET_SSE"
19354   ;; @@@ check operand order for intel/nonintel syntax
19355   "shufps\t{%3, %2, %0|%0, %2, %3}"
19356   [(set_attr "type" "ssecvt")
19357    (set_attr "mode" "V4SF")])
19358
19359
19360 ;; SSE arithmetic
19361
19362 (define_insn "addv4sf3"
19363   [(set (match_operand:V4SF 0 "register_operand" "=x")
19364         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19365                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19366   "TARGET_SSE"
19367   "addps\t{%2, %0|%0, %2}"
19368   [(set_attr "type" "sseadd")
19369    (set_attr "mode" "V4SF")])
19370
19371 (define_insn "vmaddv4sf3"
19372   [(set (match_operand:V4SF 0 "register_operand" "=x")
19373         (vec_merge:V4SF
19374          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19375                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19376          (match_dup 1)
19377          (const_int 1)))]
19378   "TARGET_SSE"
19379   "addss\t{%2, %0|%0, %2}"
19380   [(set_attr "type" "sseadd")
19381    (set_attr "mode" "SF")])
19382
19383 (define_insn "subv4sf3"
19384   [(set (match_operand:V4SF 0 "register_operand" "=x")
19385         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19386                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19387   "TARGET_SSE"
19388   "subps\t{%2, %0|%0, %2}"
19389   [(set_attr "type" "sseadd")
19390    (set_attr "mode" "V4SF")])
19391
19392 (define_insn "vmsubv4sf3"
19393   [(set (match_operand:V4SF 0 "register_operand" "=x")
19394         (vec_merge:V4SF
19395          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19396                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19397          (match_dup 1)
19398          (const_int 1)))]
19399   "TARGET_SSE"
19400   "subss\t{%2, %0|%0, %2}"
19401   [(set_attr "type" "sseadd")
19402    (set_attr "mode" "SF")])
19403
19404 (define_insn "mulv4sf3"
19405   [(set (match_operand:V4SF 0 "register_operand" "=x")
19406         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19407                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19408   "TARGET_SSE"
19409   "mulps\t{%2, %0|%0, %2}"
19410   [(set_attr "type" "ssemul")
19411    (set_attr "mode" "V4SF")])
19412
19413 (define_insn "vmmulv4sf3"
19414   [(set (match_operand:V4SF 0 "register_operand" "=x")
19415         (vec_merge:V4SF
19416          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19417                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19418          (match_dup 1)
19419          (const_int 1)))]
19420   "TARGET_SSE"
19421   "mulss\t{%2, %0|%0, %2}"
19422   [(set_attr "type" "ssemul")
19423    (set_attr "mode" "SF")])
19424
19425 (define_insn "divv4sf3"
19426   [(set (match_operand:V4SF 0 "register_operand" "=x")
19427         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19428                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19429   "TARGET_SSE"
19430   "divps\t{%2, %0|%0, %2}"
19431   [(set_attr "type" "ssediv")
19432    (set_attr "mode" "V4SF")])
19433
19434 (define_insn "vmdivv4sf3"
19435   [(set (match_operand:V4SF 0 "register_operand" "=x")
19436         (vec_merge:V4SF
19437          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19438                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19439          (match_dup 1)
19440          (const_int 1)))]
19441   "TARGET_SSE"
19442   "divss\t{%2, %0|%0, %2}"
19443   [(set_attr "type" "ssediv")
19444    (set_attr "mode" "SF")])
19445
19446
19447 ;; SSE square root/reciprocal
19448
19449 (define_insn "rcpv4sf2"
19450   [(set (match_operand:V4SF 0 "register_operand" "=x")
19451         (unspec:V4SF
19452          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19453   "TARGET_SSE"
19454   "rcpps\t{%1, %0|%0, %1}"
19455   [(set_attr "type" "sse")
19456    (set_attr "mode" "V4SF")])
19457
19458 (define_insn "vmrcpv4sf2"
19459   [(set (match_operand:V4SF 0 "register_operand" "=x")
19460         (vec_merge:V4SF
19461          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19462                       UNSPEC_RCP)
19463          (match_operand:V4SF 2 "register_operand" "0")
19464          (const_int 1)))]
19465   "TARGET_SSE"
19466   "rcpss\t{%1, %0|%0, %1}"
19467   [(set_attr "type" "sse")
19468    (set_attr "mode" "SF")])
19469
19470 (define_insn "rsqrtv4sf2"
19471   [(set (match_operand:V4SF 0 "register_operand" "=x")
19472         (unspec:V4SF
19473          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19474   "TARGET_SSE"
19475   "rsqrtps\t{%1, %0|%0, %1}"
19476   [(set_attr "type" "sse")
19477    (set_attr "mode" "V4SF")])
19478
19479 (define_insn "vmrsqrtv4sf2"
19480   [(set (match_operand:V4SF 0 "register_operand" "=x")
19481         (vec_merge:V4SF
19482          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19483                       UNSPEC_RSQRT)
19484          (match_operand:V4SF 2 "register_operand" "0")
19485          (const_int 1)))]
19486   "TARGET_SSE"
19487   "rsqrtss\t{%1, %0|%0, %1}"
19488   [(set_attr "type" "sse")
19489    (set_attr "mode" "SF")])
19490
19491 (define_insn "sqrtv4sf2"
19492   [(set (match_operand:V4SF 0 "register_operand" "=x")
19493         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19494   "TARGET_SSE"
19495   "sqrtps\t{%1, %0|%0, %1}"
19496   [(set_attr "type" "sse")
19497    (set_attr "mode" "V4SF")])
19498
19499 (define_insn "vmsqrtv4sf2"
19500   [(set (match_operand:V4SF 0 "register_operand" "=x")
19501         (vec_merge:V4SF
19502          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19503          (match_operand:V4SF 2 "register_operand" "0")
19504          (const_int 1)))]
19505   "TARGET_SSE"
19506   "sqrtss\t{%1, %0|%0, %1}"
19507   [(set_attr "type" "sse")
19508    (set_attr "mode" "SF")])
19509
19510 ;; SSE logical operations.
19511
19512 ;; SSE defines logical operations on floating point values.  This brings
19513 ;; interesting challenge to RTL representation where logicals are only valid
19514 ;; on integral types.  We deal with this by representing the floating point
19515 ;; logical as logical on arguments casted to TImode as this is what hardware
19516 ;; really does.  Unfortunately hardware requires the type information to be
19517 ;; present and thus we must avoid subregs from being simplified and eliminated
19518 ;; in later compilation phases.
19519 ;;
19520 ;; We have following variants from each instruction:
19521 ;; sse_andsf3 - the operation taking V4SF vector operands
19522 ;;              and doing TImode cast on them
19523 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19524 ;;                      TImode, since backend insist on eliminating casts
19525 ;;                      on memory operands
19526 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19527 ;;                   We can not accept memory operand here as instruction reads
19528 ;;                   whole scalar.  This is generated only post reload by GCC
19529 ;;                   scalar float operations that expands to logicals (fabs)
19530 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19531 ;;                   memory operand.  Eventually combine can be able
19532 ;;                   to synthesize these using splitter.
19533 ;; sse2_anddf3, *sse2_anddf3_memory
19534 ;;              
19535 ;; 
19536 ;; These are not called andti3 etc. because we really really don't want
19537 ;; the compiler to widen DImode ands to TImode ands and then try to move
19538 ;; into DImode subregs of SSE registers, and them together, and move out
19539 ;; of DImode subregs again!
19540 ;; SSE1 single precision floating point logical operation
19541 (define_expand "sse_andv4sf3"
19542   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19543         (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19544                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19545   "TARGET_SSE"
19546   "")
19547
19548 (define_insn "*sse_andv4sf3"
19549   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19550         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19551                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19552   "TARGET_SSE
19553    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19554   "andps\t{%2, %0|%0, %2}"
19555   [(set_attr "type" "sselog")
19556    (set_attr "mode" "V4SF")])
19557
19558 (define_insn "*sse_andsf3"
19559   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19560         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19561                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19562   "TARGET_SSE
19563    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19564   "andps\t{%2, %0|%0, %2}"
19565   [(set_attr "type" "sselog")
19566    (set_attr "mode" "V4SF")])
19567
19568 (define_expand "sse_nandv4sf3"
19569   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19570         (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19571                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19572   "TARGET_SSE"
19573   "")
19574
19575 (define_insn "*sse_nandv4sf3"
19576   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19577         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19578                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19579   "TARGET_SSE"
19580   "andnps\t{%2, %0|%0, %2}"
19581   [(set_attr "type" "sselog")
19582    (set_attr "mode" "V4SF")])
19583
19584 (define_insn "*sse_nandsf3"
19585   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19586         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19587                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19588   "TARGET_SSE"
19589   "andnps\t{%2, %0|%0, %2}"
19590   [(set_attr "type" "sselog")
19591    (set_attr "mode" "V4SF")])
19592
19593 (define_expand "sse_iorv4sf3"
19594   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19595         (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19596                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19597   "TARGET_SSE"
19598   "")
19599
19600 (define_insn "*sse_iorv4sf3"
19601   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19602         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19603                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19604   "TARGET_SSE
19605    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19606   "orps\t{%2, %0|%0, %2}"
19607   [(set_attr "type" "sselog")
19608    (set_attr "mode" "V4SF")])
19609
19610 (define_insn "*sse_iorsf3"
19611   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19612         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19613                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19614   "TARGET_SSE
19615    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19616   "orps\t{%2, %0|%0, %2}"
19617   [(set_attr "type" "sselog")
19618    (set_attr "mode" "V4SF")])
19619
19620 (define_expand "sse_xorv4sf3"
19621   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19622         (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19623                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19624   "TARGET_SSE
19625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19626   "")
19627
19628 (define_insn "*sse_xorv4sf3"
19629   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19630         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19631                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19632   "TARGET_SSE
19633    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19634   "xorps\t{%2, %0|%0, %2}"
19635   [(set_attr "type" "sselog")
19636    (set_attr "mode" "V4SF")])
19637
19638 (define_insn "*sse_xorsf3"
19639   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19640         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19641                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19642   "TARGET_SSE
19643    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19644   "xorps\t{%2, %0|%0, %2}"
19645   [(set_attr "type" "sselog")
19646    (set_attr "mode" "V4SF")])
19647
19648 ;; SSE2 double precision floating point logical operation
19649
19650 (define_expand "sse2_andv2df3"
19651   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19652         (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19653                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19654   "TARGET_SSE2"
19655   "")
19656
19657 (define_insn "*sse2_andv2df3"
19658   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19659         (and: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   "andpd\t{%2, %0|%0, %2}"
19664   [(set_attr "type" "sselog")
19665    (set_attr "mode" "V2DF")])
19666
19667 (define_insn "*sse2_andv2df3"
19668   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19669         (and: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   "andpd\t{%2, %0|%0, %2}"
19674   [(set_attr "type" "sselog")
19675    (set_attr "mode" "V2DF")])
19676
19677 (define_expand "sse2_nandv2df3"
19678   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19679         (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19680                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19681   "TARGET_SSE2"
19682   "")
19683
19684 (define_insn "*sse2_nandv2df3"
19685   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19686         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19687                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19688   "TARGET_SSE2"
19689   "andnpd\t{%2, %0|%0, %2}"
19690   [(set_attr "type" "sselog")
19691    (set_attr "mode" "V2DF")])
19692
19693 (define_insn "*sse_nandti3_df"
19694   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19695         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19696                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19697   "TARGET_SSE2"
19698   "andnpd\t{%2, %0|%0, %2}"
19699   [(set_attr "type" "sselog")
19700    (set_attr "mode" "V2DF")])
19701
19702 (define_expand "sse2_iorv2df3"
19703   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19704         (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19705                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19706   "TARGET_SSE2"
19707   "")
19708
19709 (define_insn "*sse2_iorv2df3"
19710   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19711         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19712                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19713   "TARGET_SSE2
19714    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19715   "orpd\t{%2, %0|%0, %2}"
19716   [(set_attr "type" "sselog")
19717    (set_attr "mode" "V2DF")])
19718
19719 (define_insn "*sse2_iordf3"
19720   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
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   "orpd\t{%2, %0|%0, %2}"
19726   [(set_attr "type" "sselog")
19727    (set_attr "mode" "V2DF")])
19728
19729 (define_expand "sse2_xorv2df3"
19730   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19731         (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19732                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19733   "TARGET_SSE2"
19734   "")
19735
19736 (define_insn "*sse2_xorv2df3"
19737   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19738         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19739                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19740   "TARGET_SSE2
19741    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19742   "xorpd\t{%2, %0|%0, %2}"
19743   [(set_attr "type" "sselog")
19744    (set_attr "mode" "V2DF")])
19745
19746 (define_insn "*sse2_xordf3"
19747   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19748         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19749                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19750   "TARGET_SSE2
19751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19752   "xorpd\t{%2, %0|%0, %2}"
19753   [(set_attr "type" "sselog")
19754    (set_attr "mode" "V2DF")])
19755
19756 ;; SSE2 integral logicals.  These patterns must always come after floating
19757 ;; point ones since we don't want compiler to use integer opcodes on floating
19758 ;; point SSE values to avoid matching of subregs in the match_operand.
19759 (define_insn "*sse2_andti3"
19760   [(set (match_operand:TI 0 "register_operand" "=x")
19761         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19762                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19763   "TARGET_SSE2
19764    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19765   "pand\t{%2, %0|%0, %2}"
19766   [(set_attr "type" "sselog")
19767    (set_attr "mode" "TI")])
19768
19769 (define_insn "sse2_andv2di3"
19770   [(set (match_operand:V2DI 0 "register_operand" "=x")
19771         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19772                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19773   "TARGET_SSE2
19774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19775   "pand\t{%2, %0|%0, %2}"
19776   [(set_attr "type" "sselog")
19777    (set_attr "mode" "TI")])
19778
19779 (define_insn "*sse2_nandti3"
19780   [(set (match_operand:TI 0 "register_operand" "=x")
19781         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19782                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19783   "TARGET_SSE2"
19784   "pandn\t{%2, %0|%0, %2}"
19785   [(set_attr "type" "sselog")
19786    (set_attr "mode" "TI")])
19787
19788 (define_insn "sse2_nandv2di3"
19789   [(set (match_operand:V2DI 0 "register_operand" "=x")
19790         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19791                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19792   "TARGET_SSE2
19793    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19794   "pandn\t{%2, %0|%0, %2}"
19795   [(set_attr "type" "sselog")
19796    (set_attr "mode" "TI")])
19797
19798 (define_insn "*sse2_iorti3"
19799   [(set (match_operand:TI 0 "register_operand" "=x")
19800         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19801                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19802   "TARGET_SSE2
19803    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19804   "por\t{%2, %0|%0, %2}"
19805   [(set_attr "type" "sselog")
19806    (set_attr "mode" "TI")])
19807
19808 (define_insn "sse2_iorv2di3"
19809   [(set (match_operand:V2DI 0 "register_operand" "=x")
19810         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19811                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19812   "TARGET_SSE2
19813    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19814   "por\t{%2, %0|%0, %2}"
19815   [(set_attr "type" "sselog")
19816    (set_attr "mode" "TI")])
19817
19818 (define_insn "*sse2_xorti3"
19819   [(set (match_operand:TI 0 "register_operand" "=x")
19820         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19821                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19822   "TARGET_SSE2
19823    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19824   "pxor\t{%2, %0|%0, %2}"
19825   [(set_attr "type" "sselog")
19826    (set_attr "mode" "TI")])
19827
19828 (define_insn "sse2_xorv2di3"
19829   [(set (match_operand:V2DI 0 "register_operand" "=x")
19830         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19831                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19832   "TARGET_SSE2
19833    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19834   "pxor\t{%2, %0|%0, %2}"
19835   [(set_attr "type" "sselog")
19836    (set_attr "mode" "TI")])
19837
19838 ;; Use xor, but don't show input operands so they aren't live before
19839 ;; this insn.
19840 (define_insn "sse_clrv4sf"
19841   [(set (match_operand:V4SF 0 "register_operand" "=x")
19842         (match_operand:V4SF 1 "const0_operand" "X"))]
19843   "TARGET_SSE"
19844 {
19845   if (get_attr_mode (insn) == MODE_TI)
19846     return "pxor\t{%0, %0|%0, %0}";
19847   else
19848     return "xorps\t{%0, %0|%0, %0}";
19849 }
19850   [(set_attr "type" "sselog")
19851    (set_attr "memory" "none")
19852    (set (attr "mode")
19853         (if_then_else
19854            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19855                          (const_int 0))
19856                      (ne (symbol_ref "TARGET_SSE2")
19857                          (const_int 0)))
19858                 (eq (symbol_ref "optimize_size")
19859                     (const_int 0)))
19860          (const_string "TI")
19861          (const_string "V4SF")))])
19862
19863 ;; Use xor, but don't show input operands so they aren't live before
19864 ;; this insn.
19865 (define_insn "sse_clrv2df"
19866   [(set (match_operand:V2DF 0 "register_operand" "=x")
19867         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19868   "TARGET_SSE2"
19869   "xorpd\t{%0, %0|%0, %0}"
19870   [(set_attr "type" "sselog")
19871    (set_attr "memory" "none")
19872    (set_attr "mode" "V4SF")])
19873
19874 ;; SSE mask-generating compares
19875
19876 (define_insn "maskcmpv4sf3"
19877   [(set (match_operand:V4SI 0 "register_operand" "=x")
19878         (match_operator:V4SI 3 "sse_comparison_operator"
19879                 [(match_operand:V4SF 1 "register_operand" "0")
19880                  (match_operand:V4SF 2 "register_operand" "x")]))]
19881   "TARGET_SSE"
19882   "cmp%D3ps\t{%2, %0|%0, %2}"
19883   [(set_attr "type" "ssecmp")
19884    (set_attr "mode" "V4SF")])
19885
19886 (define_insn "maskncmpv4sf3"
19887   [(set (match_operand:V4SI 0 "register_operand" "=x")
19888         (not:V4SI
19889          (match_operator:V4SI 3 "sse_comparison_operator"
19890                 [(match_operand:V4SF 1 "register_operand" "0")
19891                  (match_operand:V4SF 2 "register_operand" "x")])))]
19892   "TARGET_SSE"
19893 {
19894   if (GET_CODE (operands[3]) == UNORDERED)
19895     return "cmpordps\t{%2, %0|%0, %2}";
19896   else
19897     return "cmpn%D3ps\t{%2, %0|%0, %2}";
19898 }
19899   [(set_attr "type" "ssecmp")
19900    (set_attr "mode" "V4SF")])
19901
19902 (define_insn "vmmaskcmpv4sf3"
19903   [(set (match_operand:V4SI 0 "register_operand" "=x")
19904         (vec_merge:V4SI
19905          (match_operator:V4SI 3 "sse_comparison_operator"
19906                 [(match_operand:V4SF 1 "register_operand" "0")
19907                  (match_operand:V4SF 2 "register_operand" "x")])
19908          (subreg:V4SI (match_dup 1) 0)
19909          (const_int 1)))]
19910   "TARGET_SSE"
19911   "cmp%D3ss\t{%2, %0|%0, %2}"
19912   [(set_attr "type" "ssecmp")
19913    (set_attr "mode" "SF")])
19914
19915 (define_insn "vmmaskncmpv4sf3"
19916   [(set (match_operand:V4SI 0 "register_operand" "=x")
19917         (vec_merge:V4SI
19918          (not:V4SI
19919           (match_operator:V4SI 3 "sse_comparison_operator"
19920                 [(match_operand:V4SF 1 "register_operand" "0")
19921                  (match_operand:V4SF 2 "register_operand" "x")]))
19922          (subreg:V4SI (match_dup 1) 0)
19923          (const_int 1)))]
19924   "TARGET_SSE"
19925 {
19926   if (GET_CODE (operands[3]) == UNORDERED)
19927     return "cmpordss\t{%2, %0|%0, %2}";
19928   else
19929     return "cmpn%D3ss\t{%2, %0|%0, %2}";
19930 }
19931   [(set_attr "type" "ssecmp")
19932    (set_attr "mode" "SF")])
19933
19934 (define_insn "sse_comi"
19935   [(set (reg:CCFP 17)
19936         (compare:CCFP (vec_select:SF
19937                        (match_operand:V4SF 0 "register_operand" "x")
19938                        (parallel [(const_int 0)]))
19939                       (vec_select:SF
19940                        (match_operand:V4SF 1 "register_operand" "x")
19941                        (parallel [(const_int 0)]))))]
19942   "TARGET_SSE"
19943   "comiss\t{%1, %0|%0, %1}"
19944   [(set_attr "type" "ssecomi")
19945    (set_attr "mode" "SF")])
19946
19947 (define_insn "sse_ucomi"
19948   [(set (reg:CCFPU 17)
19949         (compare:CCFPU (vec_select:SF
19950                         (match_operand:V4SF 0 "register_operand" "x")
19951                         (parallel [(const_int 0)]))
19952                        (vec_select:SF
19953                         (match_operand:V4SF 1 "register_operand" "x")
19954                         (parallel [(const_int 0)]))))]
19955   "TARGET_SSE"
19956   "ucomiss\t{%1, %0|%0, %1}"
19957   [(set_attr "type" "ssecomi")
19958    (set_attr "mode" "SF")])
19959
19960
19961 ;; SSE unpack
19962
19963 (define_insn "sse_unpckhps"
19964   [(set (match_operand:V4SF 0 "register_operand" "=x")
19965         (vec_merge:V4SF
19966          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19967                           (parallel [(const_int 2)
19968                                      (const_int 0)
19969                                      (const_int 3)
19970                                      (const_int 1)]))
19971          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19972                           (parallel [(const_int 0)
19973                                      (const_int 2)
19974                                      (const_int 1)
19975                                      (const_int 3)]))
19976          (const_int 5)))]
19977   "TARGET_SSE"
19978   "unpckhps\t{%2, %0|%0, %2}"
19979   [(set_attr "type" "ssecvt")
19980    (set_attr "mode" "V4SF")])
19981
19982 (define_insn "sse_unpcklps"
19983   [(set (match_operand:V4SF 0 "register_operand" "=x")
19984         (vec_merge:V4SF
19985          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19986                           (parallel [(const_int 0)
19987                                      (const_int 2)
19988                                      (const_int 1)
19989                                      (const_int 3)]))
19990          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19991                           (parallel [(const_int 2)
19992                                      (const_int 0)
19993                                      (const_int 3)
19994                                      (const_int 1)]))
19995          (const_int 5)))]
19996   "TARGET_SSE"
19997   "unpcklps\t{%2, %0|%0, %2}"
19998   [(set_attr "type" "ssecvt")
19999    (set_attr "mode" "V4SF")])
20000
20001
20002 ;; SSE min/max
20003
20004 (define_insn "smaxv4sf3"
20005   [(set (match_operand:V4SF 0 "register_operand" "=x")
20006         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20007                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20008   "TARGET_SSE"
20009   "maxps\t{%2, %0|%0, %2}"
20010   [(set_attr "type" "sse")
20011    (set_attr "mode" "V4SF")])
20012
20013 (define_insn "vmsmaxv4sf3"
20014   [(set (match_operand:V4SF 0 "register_operand" "=x")
20015         (vec_merge:V4SF
20016          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20017                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20018          (match_dup 1)
20019          (const_int 1)))]
20020   "TARGET_SSE"
20021   "maxss\t{%2, %0|%0, %2}"
20022   [(set_attr "type" "sse")
20023    (set_attr "mode" "SF")])
20024
20025 (define_insn "sminv4sf3"
20026   [(set (match_operand:V4SF 0 "register_operand" "=x")
20027         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20028                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20029   "TARGET_SSE"
20030   "minps\t{%2, %0|%0, %2}"
20031   [(set_attr "type" "sse")
20032    (set_attr "mode" "V4SF")])
20033
20034 (define_insn "vmsminv4sf3"
20035   [(set (match_operand:V4SF 0 "register_operand" "=x")
20036         (vec_merge:V4SF
20037          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20038                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20039          (match_dup 1)
20040          (const_int 1)))]
20041   "TARGET_SSE"
20042   "minss\t{%2, %0|%0, %2}"
20043   [(set_attr "type" "sse")
20044    (set_attr "mode" "SF")])
20045
20046 ;; SSE <-> integer/MMX conversions
20047
20048 (define_insn "cvtpi2ps"
20049   [(set (match_operand:V4SF 0 "register_operand" "=x")
20050         (vec_merge:V4SF
20051          (match_operand:V4SF 1 "register_operand" "0")
20052          (vec_duplicate:V4SF
20053           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20054          (const_int 12)))]
20055   "TARGET_SSE"
20056   "cvtpi2ps\t{%2, %0|%0, %2}"
20057   [(set_attr "type" "ssecvt")
20058    (set_attr "mode" "V4SF")])
20059
20060 (define_insn "cvtps2pi"
20061   [(set (match_operand:V2SI 0 "register_operand" "=y")
20062         (vec_select:V2SI
20063          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20064          (parallel [(const_int 0) (const_int 1)])))]
20065   "TARGET_SSE"
20066   "cvtps2pi\t{%1, %0|%0, %1}"
20067   [(set_attr "type" "ssecvt")
20068    (set_attr "mode" "V4SF")])
20069
20070 (define_insn "cvttps2pi"
20071   [(set (match_operand:V2SI 0 "register_operand" "=y")
20072         (vec_select:V2SI
20073          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20074                       UNSPEC_FIX)
20075          (parallel [(const_int 0) (const_int 1)])))]
20076   "TARGET_SSE"
20077   "cvttps2pi\t{%1, %0|%0, %1}"
20078   [(set_attr "type" "ssecvt")
20079    (set_attr "mode" "SF")])
20080
20081 (define_insn "cvtsi2ss"
20082   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20083         (vec_merge:V4SF
20084          (match_operand:V4SF 1 "register_operand" "0,0")
20085          (vec_duplicate:V4SF
20086           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20087          (const_int 14)))]
20088   "TARGET_SSE"
20089   "cvtsi2ss\t{%2, %0|%0, %2}"
20090   [(set_attr "type" "sseicvt")
20091    (set_attr "athlon_decode" "vector,double")
20092    (set_attr "mode" "SF")])
20093
20094 (define_insn "cvtsi2ssq"
20095   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20096         (vec_merge:V4SF
20097          (match_operand:V4SF 1 "register_operand" "0,0")
20098          (vec_duplicate:V4SF
20099           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20100          (const_int 14)))]
20101   "TARGET_SSE && TARGET_64BIT"
20102   "cvtsi2ssq\t{%2, %0|%0, %2}"
20103   [(set_attr "type" "sseicvt")
20104    (set_attr "athlon_decode" "vector,double")
20105    (set_attr "mode" "SF")])
20106
20107 (define_insn "cvtss2si"
20108   [(set (match_operand:SI 0 "register_operand" "=r,r")
20109         (vec_select:SI
20110          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20111          (parallel [(const_int 0)])))]
20112   "TARGET_SSE"
20113   "cvtss2si\t{%1, %0|%0, %1}"
20114   [(set_attr "type" "sseicvt")
20115    (set_attr "athlon_decode" "double,vector")
20116    (set_attr "mode" "SI")])
20117
20118 (define_insn "cvtss2siq"
20119   [(set (match_operand:DI 0 "register_operand" "=r,r")
20120         (vec_select:DI
20121          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20122          (parallel [(const_int 0)])))]
20123   "TARGET_SSE"
20124   "cvtss2siq\t{%1, %0|%0, %1}"
20125   [(set_attr "type" "sseicvt")
20126    (set_attr "athlon_decode" "double,vector")
20127    (set_attr "mode" "DI")])
20128
20129 (define_insn "cvttss2si"
20130   [(set (match_operand:SI 0 "register_operand" "=r,r")
20131         (vec_select:SI
20132          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20133                       UNSPEC_FIX)
20134          (parallel [(const_int 0)])))]
20135   "TARGET_SSE"
20136   "cvttss2si\t{%1, %0|%0, %1}"
20137   [(set_attr "type" "sseicvt")
20138    (set_attr "mode" "SF")
20139    (set_attr "athlon_decode" "double,vector")])
20140
20141 (define_insn "cvttss2siq"
20142   [(set (match_operand:DI 0 "register_operand" "=r,r")
20143         (vec_select:DI
20144          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20145                       UNSPEC_FIX)
20146          (parallel [(const_int 0)])))]
20147   "TARGET_SSE && TARGET_64BIT"
20148   "cvttss2siq\t{%1, %0|%0, %1}"
20149   [(set_attr "type" "sseicvt")
20150    (set_attr "mode" "SF")
20151    (set_attr "athlon_decode" "double,vector")])
20152
20153
20154 ;; MMX insns
20155
20156 ;; MMX arithmetic
20157
20158 (define_insn "addv8qi3"
20159   [(set (match_operand:V8QI 0 "register_operand" "=y")
20160         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20161                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20162   "TARGET_MMX"
20163   "paddb\t{%2, %0|%0, %2}"
20164   [(set_attr "type" "mmxadd")
20165    (set_attr "mode" "DI")])
20166
20167 (define_insn "addv4hi3"
20168   [(set (match_operand:V4HI 0 "register_operand" "=y")
20169         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20170                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20171   "TARGET_MMX"
20172   "paddw\t{%2, %0|%0, %2}"
20173   [(set_attr "type" "mmxadd")
20174    (set_attr "mode" "DI")])
20175
20176 (define_insn "addv2si3"
20177   [(set (match_operand:V2SI 0 "register_operand" "=y")
20178         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20179                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20180   "TARGET_MMX"
20181   "paddd\t{%2, %0|%0, %2}"
20182   [(set_attr "type" "mmxadd")
20183    (set_attr "mode" "DI")])
20184
20185 (define_insn "mmx_adddi3"
20186   [(set (match_operand:DI 0 "register_operand" "=y")
20187         (unspec:DI
20188          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20189                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20190          UNSPEC_NOP))]
20191   "TARGET_MMX"
20192   "paddq\t{%2, %0|%0, %2}"
20193   [(set_attr "type" "mmxadd")
20194    (set_attr "mode" "DI")])
20195
20196 (define_insn "ssaddv8qi3"
20197   [(set (match_operand:V8QI 0 "register_operand" "=y")
20198         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20199                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20200   "TARGET_MMX"
20201   "paddsb\t{%2, %0|%0, %2}"
20202   [(set_attr "type" "mmxadd")
20203    (set_attr "mode" "DI")])
20204
20205 (define_insn "ssaddv4hi3"
20206   [(set (match_operand:V4HI 0 "register_operand" "=y")
20207         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20208                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20209   "TARGET_MMX"
20210   "paddsw\t{%2, %0|%0, %2}"
20211   [(set_attr "type" "mmxadd")
20212    (set_attr "mode" "DI")])
20213
20214 (define_insn "usaddv8qi3"
20215   [(set (match_operand:V8QI 0 "register_operand" "=y")
20216         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20217                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20218   "TARGET_MMX"
20219   "paddusb\t{%2, %0|%0, %2}"
20220   [(set_attr "type" "mmxadd")
20221    (set_attr "mode" "DI")])
20222
20223 (define_insn "usaddv4hi3"
20224   [(set (match_operand:V4HI 0 "register_operand" "=y")
20225         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20226                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20227   "TARGET_MMX"
20228   "paddusw\t{%2, %0|%0, %2}"
20229   [(set_attr "type" "mmxadd")
20230    (set_attr "mode" "DI")])
20231
20232 (define_insn "subv8qi3"
20233   [(set (match_operand:V8QI 0 "register_operand" "=y")
20234         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20235                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20236   "TARGET_MMX"
20237   "psubb\t{%2, %0|%0, %2}"
20238   [(set_attr "type" "mmxadd")
20239    (set_attr "mode" "DI")])
20240
20241 (define_insn "subv4hi3"
20242   [(set (match_operand:V4HI 0 "register_operand" "=y")
20243         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20244                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20245   "TARGET_MMX"
20246   "psubw\t{%2, %0|%0, %2}"
20247   [(set_attr "type" "mmxadd")
20248    (set_attr "mode" "DI")])
20249
20250 (define_insn "subv2si3"
20251   [(set (match_operand:V2SI 0 "register_operand" "=y")
20252         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20253                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20254   "TARGET_MMX"
20255   "psubd\t{%2, %0|%0, %2}"
20256   [(set_attr "type" "mmxadd")
20257    (set_attr "mode" "DI")])
20258
20259 (define_insn "mmx_subdi3"
20260   [(set (match_operand:DI 0 "register_operand" "=y")
20261         (unspec:DI
20262          [(minus:DI (match_operand:DI 1 "register_operand" "0")
20263                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20264          UNSPEC_NOP))]
20265   "TARGET_MMX"
20266   "psubq\t{%2, %0|%0, %2}"
20267   [(set_attr "type" "mmxadd")
20268    (set_attr "mode" "DI")])
20269
20270 (define_insn "sssubv8qi3"
20271   [(set (match_operand:V8QI 0 "register_operand" "=y")
20272         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20273                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20274   "TARGET_MMX"
20275   "psubsb\t{%2, %0|%0, %2}"
20276   [(set_attr "type" "mmxadd")
20277    (set_attr "mode" "DI")])
20278
20279 (define_insn "sssubv4hi3"
20280   [(set (match_operand:V4HI 0 "register_operand" "=y")
20281         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20282                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20283   "TARGET_MMX"
20284   "psubsw\t{%2, %0|%0, %2}"
20285   [(set_attr "type" "mmxadd")
20286    (set_attr "mode" "DI")])
20287
20288 (define_insn "ussubv8qi3"
20289   [(set (match_operand:V8QI 0 "register_operand" "=y")
20290         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20291                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20292   "TARGET_MMX"
20293   "psubusb\t{%2, %0|%0, %2}"
20294   [(set_attr "type" "mmxadd")
20295    (set_attr "mode" "DI")])
20296
20297 (define_insn "ussubv4hi3"
20298   [(set (match_operand:V4HI 0 "register_operand" "=y")
20299         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20300                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20301   "TARGET_MMX"
20302   "psubusw\t{%2, %0|%0, %2}"
20303   [(set_attr "type" "mmxadd")
20304    (set_attr "mode" "DI")])
20305
20306 (define_insn "mulv4hi3"
20307   [(set (match_operand:V4HI 0 "register_operand" "=y")
20308         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20309                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20310   "TARGET_MMX"
20311   "pmullw\t{%2, %0|%0, %2}"
20312   [(set_attr "type" "mmxmul")
20313    (set_attr "mode" "DI")])
20314
20315 (define_insn "smulv4hi3_highpart"
20316   [(set (match_operand:V4HI 0 "register_operand" "=y")
20317         (truncate:V4HI
20318          (lshiftrt:V4SI
20319           (mult:V4SI (sign_extend:V4SI
20320                       (match_operand:V4HI 1 "register_operand" "0"))
20321                      (sign_extend:V4SI
20322                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20323           (const_int 16))))]
20324   "TARGET_MMX"
20325   "pmulhw\t{%2, %0|%0, %2}"
20326   [(set_attr "type" "mmxmul")
20327    (set_attr "mode" "DI")])
20328
20329 (define_insn "umulv4hi3_highpart"
20330   [(set (match_operand:V4HI 0 "register_operand" "=y")
20331         (truncate:V4HI
20332          (lshiftrt:V4SI
20333           (mult:V4SI (zero_extend:V4SI
20334                       (match_operand:V4HI 1 "register_operand" "0"))
20335                      (zero_extend:V4SI
20336                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20337           (const_int 16))))]
20338   "TARGET_SSE || TARGET_3DNOW_A"
20339   "pmulhuw\t{%2, %0|%0, %2}"
20340   [(set_attr "type" "mmxmul")
20341    (set_attr "mode" "DI")])
20342
20343 (define_insn "mmx_pmaddwd"
20344   [(set (match_operand:V2SI 0 "register_operand" "=y")
20345         (plus:V2SI
20346          (mult:V2SI
20347           (sign_extend:V2SI
20348            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20349                             (parallel [(const_int 0) (const_int 2)])))
20350           (sign_extend:V2SI
20351            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20352                             (parallel [(const_int 0) (const_int 2)]))))
20353          (mult:V2SI
20354           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20355                                              (parallel [(const_int 1)
20356                                                         (const_int 3)])))
20357           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20358                                              (parallel [(const_int 1)
20359                                                         (const_int 3)]))))))]
20360   "TARGET_MMX"
20361   "pmaddwd\t{%2, %0|%0, %2}"
20362   [(set_attr "type" "mmxmul")
20363    (set_attr "mode" "DI")])
20364
20365
20366 ;; MMX logical operations
20367 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20368 ;; normal code that also wants to use the FPU from getting broken.
20369 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20370 (define_insn "mmx_iordi3"
20371   [(set (match_operand:DI 0 "register_operand" "=y")
20372         (unspec:DI
20373          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20374                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20375          UNSPEC_NOP))]
20376   "TARGET_MMX"
20377   "por\t{%2, %0|%0, %2}"
20378   [(set_attr "type" "mmxadd")
20379    (set_attr "mode" "DI")])
20380
20381 (define_insn "mmx_xordi3"
20382   [(set (match_operand:DI 0 "register_operand" "=y")
20383         (unspec:DI
20384          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20385                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20386          UNSPEC_NOP))]
20387   "TARGET_MMX"
20388   "pxor\t{%2, %0|%0, %2}"
20389   [(set_attr "type" "mmxadd")
20390    (set_attr "mode" "DI")
20391    (set_attr "memory" "none")])
20392
20393 ;; Same as pxor, but don't show input operands so that we don't think
20394 ;; they are live.
20395 (define_insn "mmx_clrdi"
20396   [(set (match_operand:DI 0 "register_operand" "=y")
20397         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20398   "TARGET_MMX"
20399   "pxor\t{%0, %0|%0, %0}"
20400   [(set_attr "type" "mmxadd")
20401    (set_attr "mode" "DI")
20402    (set_attr "memory" "none")])
20403
20404 (define_insn "mmx_anddi3"
20405   [(set (match_operand:DI 0 "register_operand" "=y")
20406         (unspec:DI
20407          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20408                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20409          UNSPEC_NOP))]
20410   "TARGET_MMX"
20411   "pand\t{%2, %0|%0, %2}"
20412   [(set_attr "type" "mmxadd")
20413    (set_attr "mode" "DI")])
20414
20415 (define_insn "mmx_nanddi3"
20416   [(set (match_operand:DI 0 "register_operand" "=y")
20417         (unspec:DI
20418          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20419                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20420          UNSPEC_NOP))]
20421   "TARGET_MMX"
20422   "pandn\t{%2, %0|%0, %2}"
20423   [(set_attr "type" "mmxadd")
20424    (set_attr "mode" "DI")])
20425
20426
20427 ;; MMX unsigned averages/sum of absolute differences
20428
20429 (define_insn "mmx_uavgv8qi3"
20430   [(set (match_operand:V8QI 0 "register_operand" "=y")
20431         (ashiftrt:V8QI
20432          (plus:V8QI (plus:V8QI
20433                      (match_operand:V8QI 1 "register_operand" "0")
20434                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20435                     (const_vector:V8QI [(const_int 1)
20436                                         (const_int 1)
20437                                         (const_int 1)
20438                                         (const_int 1)
20439                                         (const_int 1)
20440                                         (const_int 1)
20441                                         (const_int 1)
20442                                         (const_int 1)]))
20443          (const_int 1)))]
20444   "TARGET_SSE || TARGET_3DNOW_A"
20445   "pavgb\t{%2, %0|%0, %2}"
20446   [(set_attr "type" "mmxshft")
20447    (set_attr "mode" "DI")])
20448
20449 (define_insn "mmx_uavgv4hi3"
20450   [(set (match_operand:V4HI 0 "register_operand" "=y")
20451         (ashiftrt:V4HI
20452          (plus:V4HI (plus:V4HI
20453                      (match_operand:V4HI 1 "register_operand" "0")
20454                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20455                     (const_vector:V4HI [(const_int 1)
20456                                         (const_int 1)
20457                                         (const_int 1)
20458                                         (const_int 1)]))
20459          (const_int 1)))]
20460   "TARGET_SSE || TARGET_3DNOW_A"
20461   "pavgw\t{%2, %0|%0, %2}"
20462   [(set_attr "type" "mmxshft")
20463    (set_attr "mode" "DI")])
20464
20465 (define_insn "mmx_psadbw"
20466   [(set (match_operand:DI 0 "register_operand" "=y")
20467         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20468                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20469                    UNSPEC_PSADBW))]
20470   "TARGET_SSE || TARGET_3DNOW_A"
20471   "psadbw\t{%2, %0|%0, %2}"
20472   [(set_attr "type" "mmxshft")
20473    (set_attr "mode" "DI")])
20474
20475
20476 ;; MMX insert/extract/shuffle
20477
20478 (define_insn "mmx_pinsrw"
20479   [(set (match_operand:V4HI 0 "register_operand" "=y")
20480         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20481                         (vec_duplicate:V4HI
20482                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20483                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20484   "TARGET_SSE || TARGET_3DNOW_A"
20485   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20486   [(set_attr "type" "mmxcvt")
20487    (set_attr "mode" "DI")])
20488
20489 (define_insn "mmx_pextrw"
20490   [(set (match_operand:SI 0 "register_operand" "=r")
20491         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20492                                        (parallel
20493                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20494   "TARGET_SSE || TARGET_3DNOW_A"
20495   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20496   [(set_attr "type" "mmxcvt")
20497    (set_attr "mode" "DI")])
20498
20499 (define_insn "mmx_pshufw"
20500   [(set (match_operand:V4HI 0 "register_operand" "=y")
20501         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20502                       (match_operand:SI 2 "immediate_operand" "i")]
20503                      UNSPEC_SHUFFLE))]
20504   "TARGET_SSE || TARGET_3DNOW_A"
20505   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20506   [(set_attr "type" "mmxcvt")
20507    (set_attr "mode" "DI")])
20508
20509
20510 ;; MMX mask-generating comparisons
20511
20512 (define_insn "eqv8qi3"
20513   [(set (match_operand:V8QI 0 "register_operand" "=y")
20514         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20515                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20516   "TARGET_MMX"
20517   "pcmpeqb\t{%2, %0|%0, %2}"
20518   [(set_attr "type" "mmxcmp")
20519    (set_attr "mode" "DI")])
20520
20521 (define_insn "eqv4hi3"
20522   [(set (match_operand:V4HI 0 "register_operand" "=y")
20523         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20524                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20525   "TARGET_MMX"
20526   "pcmpeqw\t{%2, %0|%0, %2}"
20527   [(set_attr "type" "mmxcmp")
20528    (set_attr "mode" "DI")])
20529
20530 (define_insn "eqv2si3"
20531   [(set (match_operand:V2SI 0 "register_operand" "=y")
20532         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20533                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20534   "TARGET_MMX"
20535   "pcmpeqd\t{%2, %0|%0, %2}"
20536   [(set_attr "type" "mmxcmp")
20537    (set_attr "mode" "DI")])
20538
20539 (define_insn "gtv8qi3"
20540   [(set (match_operand:V8QI 0 "register_operand" "=y")
20541         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20542                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20543   "TARGET_MMX"
20544   "pcmpgtb\t{%2, %0|%0, %2}"
20545   [(set_attr "type" "mmxcmp")
20546    (set_attr "mode" "DI")])
20547
20548 (define_insn "gtv4hi3"
20549   [(set (match_operand:V4HI 0 "register_operand" "=y")
20550         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20551                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20552   "TARGET_MMX"
20553   "pcmpgtw\t{%2, %0|%0, %2}"
20554   [(set_attr "type" "mmxcmp")
20555    (set_attr "mode" "DI")])
20556
20557 (define_insn "gtv2si3"
20558   [(set (match_operand:V2SI 0 "register_operand" "=y")
20559         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20560                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20561   "TARGET_MMX"
20562   "pcmpgtd\t{%2, %0|%0, %2}"
20563   [(set_attr "type" "mmxcmp")
20564    (set_attr "mode" "DI")])
20565
20566
20567 ;; MMX max/min insns
20568
20569 (define_insn "umaxv8qi3"
20570   [(set (match_operand:V8QI 0 "register_operand" "=y")
20571         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20572                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20573   "TARGET_SSE || TARGET_3DNOW_A"
20574   "pmaxub\t{%2, %0|%0, %2}"
20575   [(set_attr "type" "mmxadd")
20576    (set_attr "mode" "DI")])
20577
20578 (define_insn "smaxv4hi3"
20579   [(set (match_operand:V4HI 0 "register_operand" "=y")
20580         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20581                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20582   "TARGET_SSE || TARGET_3DNOW_A"
20583   "pmaxsw\t{%2, %0|%0, %2}"
20584   [(set_attr "type" "mmxadd")
20585    (set_attr "mode" "DI")])
20586
20587 (define_insn "uminv8qi3"
20588   [(set (match_operand:V8QI 0 "register_operand" "=y")
20589         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20590                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20591   "TARGET_SSE || TARGET_3DNOW_A"
20592   "pminub\t{%2, %0|%0, %2}"
20593   [(set_attr "type" "mmxadd")
20594    (set_attr "mode" "DI")])
20595
20596 (define_insn "sminv4hi3"
20597   [(set (match_operand:V4HI 0 "register_operand" "=y")
20598         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20599                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20600   "TARGET_SSE || TARGET_3DNOW_A"
20601   "pminsw\t{%2, %0|%0, %2}"
20602   [(set_attr "type" "mmxadd")
20603    (set_attr "mode" "DI")])
20604
20605
20606 ;; MMX shifts
20607
20608 (define_insn "ashrv4hi3"
20609   [(set (match_operand:V4HI 0 "register_operand" "=y")
20610         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20611                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20612   "TARGET_MMX"
20613   "psraw\t{%2, %0|%0, %2}"
20614   [(set_attr "type" "mmxshft")
20615    (set_attr "mode" "DI")])
20616
20617 (define_insn "ashrv2si3"
20618   [(set (match_operand:V2SI 0 "register_operand" "=y")
20619         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20620                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20621   "TARGET_MMX"
20622   "psrad\t{%2, %0|%0, %2}"
20623   [(set_attr "type" "mmxshft")
20624    (set_attr "mode" "DI")])
20625
20626 (define_insn "lshrv4hi3"
20627   [(set (match_operand:V4HI 0 "register_operand" "=y")
20628         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20629                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20630   "TARGET_MMX"
20631   "psrlw\t{%2, %0|%0, %2}"
20632   [(set_attr "type" "mmxshft")
20633    (set_attr "mode" "DI")])
20634
20635 (define_insn "lshrv2si3"
20636   [(set (match_operand:V2SI 0 "register_operand" "=y")
20637         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20638                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20639   "TARGET_MMX"
20640   "psrld\t{%2, %0|%0, %2}"
20641   [(set_attr "type" "mmxshft")
20642    (set_attr "mode" "DI")])
20643
20644 ;; See logical MMX insns.
20645 (define_insn "mmx_lshrdi3"
20646   [(set (match_operand:DI 0 "register_operand" "=y")
20647         (unspec:DI
20648           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20649                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
20650           UNSPEC_NOP))]
20651   "TARGET_MMX"
20652   "psrlq\t{%2, %0|%0, %2}"
20653   [(set_attr "type" "mmxshft")
20654    (set_attr "mode" "DI")])
20655
20656 (define_insn "ashlv4hi3"
20657   [(set (match_operand:V4HI 0 "register_operand" "=y")
20658         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20659                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20660   "TARGET_MMX"
20661   "psllw\t{%2, %0|%0, %2}"
20662   [(set_attr "type" "mmxshft")
20663    (set_attr "mode" "DI")])
20664
20665 (define_insn "ashlv2si3"
20666   [(set (match_operand:V2SI 0 "register_operand" "=y")
20667         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20668                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20669   "TARGET_MMX"
20670   "pslld\t{%2, %0|%0, %2}"
20671   [(set_attr "type" "mmxshft")
20672    (set_attr "mode" "DI")])
20673
20674 ;; See logical MMX insns.
20675 (define_insn "mmx_ashldi3"
20676   [(set (match_operand:DI 0 "register_operand" "=y")
20677         (unspec:DI
20678          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20679                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
20680          UNSPEC_NOP))]
20681   "TARGET_MMX"
20682   "psllq\t{%2, %0|%0, %2}"
20683   [(set_attr "type" "mmxshft")
20684    (set_attr "mode" "DI")])
20685
20686
20687 ;; MMX pack/unpack insns.
20688
20689 (define_insn "mmx_packsswb"
20690   [(set (match_operand:V8QI 0 "register_operand" "=y")
20691         (vec_concat:V8QI
20692          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20693          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20694   "TARGET_MMX"
20695   "packsswb\t{%2, %0|%0, %2}"
20696   [(set_attr "type" "mmxshft")
20697    (set_attr "mode" "DI")])
20698
20699 (define_insn "mmx_packssdw"
20700   [(set (match_operand:V4HI 0 "register_operand" "=y")
20701         (vec_concat:V4HI
20702          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20703          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20704   "TARGET_MMX"
20705   "packssdw\t{%2, %0|%0, %2}"
20706   [(set_attr "type" "mmxshft")
20707    (set_attr "mode" "DI")])
20708
20709 (define_insn "mmx_packuswb"
20710   [(set (match_operand:V8QI 0 "register_operand" "=y")
20711         (vec_concat:V8QI
20712          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20713          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20714   "TARGET_MMX"
20715   "packuswb\t{%2, %0|%0, %2}"
20716   [(set_attr "type" "mmxshft")
20717    (set_attr "mode" "DI")])
20718
20719 (define_insn "mmx_punpckhbw"
20720   [(set (match_operand:V8QI 0 "register_operand" "=y")
20721         (vec_merge:V8QI
20722          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20723                           (parallel [(const_int 4)
20724                                      (const_int 0)
20725                                      (const_int 5)
20726                                      (const_int 1)
20727                                      (const_int 6)
20728                                      (const_int 2)
20729                                      (const_int 7)
20730                                      (const_int 3)]))
20731          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20732                           (parallel [(const_int 0)
20733                                      (const_int 4)
20734                                      (const_int 1)
20735                                      (const_int 5)
20736                                      (const_int 2)
20737                                      (const_int 6)
20738                                      (const_int 3)
20739                                      (const_int 7)]))
20740          (const_int 85)))]
20741   "TARGET_MMX"
20742   "punpckhbw\t{%2, %0|%0, %2}"
20743   [(set_attr "type" "mmxcvt")
20744    (set_attr "mode" "DI")])
20745
20746 (define_insn "mmx_punpckhwd"
20747   [(set (match_operand:V4HI 0 "register_operand" "=y")
20748         (vec_merge:V4HI
20749          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20750                           (parallel [(const_int 0)
20751                                      (const_int 2)
20752                                      (const_int 1)
20753                                      (const_int 3)]))
20754          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20755                           (parallel [(const_int 2)
20756                                      (const_int 0)
20757                                      (const_int 3)
20758                                      (const_int 1)]))
20759          (const_int 5)))]
20760   "TARGET_MMX"
20761   "punpckhwd\t{%2, %0|%0, %2}"
20762   [(set_attr "type" "mmxcvt")
20763    (set_attr "mode" "DI")])
20764
20765 (define_insn "mmx_punpckhdq"
20766   [(set (match_operand:V2SI 0 "register_operand" "=y")
20767         (vec_merge:V2SI
20768          (match_operand:V2SI 1 "register_operand" "0")
20769          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20770                           (parallel [(const_int 1)
20771                                      (const_int 0)]))
20772          (const_int 1)))]
20773   "TARGET_MMX"
20774   "punpckhdq\t{%2, %0|%0, %2}"
20775   [(set_attr "type" "mmxcvt")
20776    (set_attr "mode" "DI")])
20777
20778 (define_insn "mmx_punpcklbw"
20779   [(set (match_operand:V8QI 0 "register_operand" "=y")
20780         (vec_merge:V8QI
20781          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20782                           (parallel [(const_int 0)
20783                                      (const_int 4)
20784                                      (const_int 1)
20785                                      (const_int 5)
20786                                      (const_int 2)
20787                                      (const_int 6)
20788                                      (const_int 3)
20789                                      (const_int 7)]))
20790          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20791                           (parallel [(const_int 4)
20792                                      (const_int 0)
20793                                      (const_int 5)
20794                                      (const_int 1)
20795                                      (const_int 6)
20796                                      (const_int 2)
20797                                      (const_int 7)
20798                                      (const_int 3)]))
20799          (const_int 85)))]
20800   "TARGET_MMX"
20801   "punpcklbw\t{%2, %0|%0, %2}"
20802   [(set_attr "type" "mmxcvt")
20803    (set_attr "mode" "DI")])
20804
20805 (define_insn "mmx_punpcklwd"
20806   [(set (match_operand:V4HI 0 "register_operand" "=y")
20807         (vec_merge:V4HI
20808          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20809                           (parallel [(const_int 2)
20810                                      (const_int 0)
20811                                      (const_int 3)
20812                                      (const_int 1)]))
20813          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20814                           (parallel [(const_int 0)
20815                                      (const_int 2)
20816                                      (const_int 1)
20817                                      (const_int 3)]))
20818          (const_int 5)))]
20819   "TARGET_MMX"
20820   "punpcklwd\t{%2, %0|%0, %2}"
20821   [(set_attr "type" "mmxcvt")
20822    (set_attr "mode" "DI")])
20823
20824 (define_insn "mmx_punpckldq"
20825   [(set (match_operand:V2SI 0 "register_operand" "=y")
20826         (vec_merge:V2SI
20827          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20828                            (parallel [(const_int 1)
20829                                       (const_int 0)]))
20830          (match_operand:V2SI 2 "register_operand" "y")
20831          (const_int 1)))]
20832   "TARGET_MMX"
20833   "punpckldq\t{%2, %0|%0, %2}"
20834   [(set_attr "type" "mmxcvt")
20835    (set_attr "mode" "DI")])
20836
20837
20838 ;; Miscellaneous stuff
20839
20840 (define_insn "emms"
20841   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20842    (clobber (reg:XF 8))
20843    (clobber (reg:XF 9))
20844    (clobber (reg:XF 10))
20845    (clobber (reg:XF 11))
20846    (clobber (reg:XF 12))
20847    (clobber (reg:XF 13))
20848    (clobber (reg:XF 14))
20849    (clobber (reg:XF 15))
20850    (clobber (reg:DI 29))
20851    (clobber (reg:DI 30))
20852    (clobber (reg:DI 31))
20853    (clobber (reg:DI 32))
20854    (clobber (reg:DI 33))
20855    (clobber (reg:DI 34))
20856    (clobber (reg:DI 35))
20857    (clobber (reg:DI 36))]
20858   "TARGET_MMX"
20859   "emms"
20860   [(set_attr "type" "mmx")
20861    (set_attr "memory" "unknown")])
20862
20863 (define_insn "ldmxcsr"
20864   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20865                     UNSPECV_LDMXCSR)]
20866   "TARGET_SSE"
20867   "ldmxcsr\t%0"
20868   [(set_attr "type" "sse")
20869    (set_attr "memory" "load")])
20870
20871 (define_insn "stmxcsr"
20872   [(set (match_operand:SI 0 "memory_operand" "=m")
20873         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20874   "TARGET_SSE"
20875   "stmxcsr\t%0"
20876   [(set_attr "type" "sse")
20877    (set_attr "memory" "store")])
20878
20879 (define_expand "sfence"
20880   [(set (match_dup 0)
20881         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20882   "TARGET_SSE || TARGET_3DNOW_A"
20883 {
20884   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20885   MEM_VOLATILE_P (operands[0]) = 1;
20886 })
20887
20888 (define_insn "*sfence_insn"
20889   [(set (match_operand:BLK 0 "" "")
20890         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20891   "TARGET_SSE || TARGET_3DNOW_A"
20892   "sfence"
20893   [(set_attr "type" "sse")
20894    (set_attr "memory" "unknown")])
20895
20896 (define_expand "sse_prologue_save"
20897   [(parallel [(set (match_operand:BLK 0 "" "")
20898                    (unspec:BLK [(reg:DI 21)
20899                                 (reg:DI 22)
20900                                 (reg:DI 23)
20901                                 (reg:DI 24)
20902                                 (reg:DI 25)
20903                                 (reg:DI 26)
20904                                 (reg:DI 27)
20905                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20906               (use (match_operand:DI 1 "register_operand" ""))
20907               (use (match_operand:DI 2 "immediate_operand" ""))
20908               (use (label_ref:DI (match_operand 3 "" "")))])]
20909   "TARGET_64BIT"
20910   "")
20911
20912 (define_insn "*sse_prologue_save_insn"
20913   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20914                           (match_operand:DI 4 "const_int_operand" "n")))
20915         (unspec:BLK [(reg:DI 21)
20916                      (reg:DI 22)
20917                      (reg:DI 23)
20918                      (reg:DI 24)
20919                      (reg:DI 25)
20920                      (reg:DI 26)
20921                      (reg:DI 27)
20922                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20923    (use (match_operand:DI 1 "register_operand" "r"))
20924    (use (match_operand:DI 2 "const_int_operand" "i"))
20925    (use (label_ref:DI (match_operand 3 "" "X")))]
20926   "TARGET_64BIT
20927    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20928    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20929   "*
20930 {
20931   int i;
20932   operands[0] = gen_rtx_MEM (Pmode,
20933                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20934   output_asm_insn (\"jmp\\t%A1\", operands);
20935   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20936     {
20937       operands[4] = adjust_address (operands[0], DImode, i*16);
20938       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20939       PUT_MODE (operands[4], TImode);
20940       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20941         output_asm_insn (\"rex\", operands);
20942       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20943     }
20944   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20945                              CODE_LABEL_NUMBER (operands[3]));
20946   RET;
20947 }
20948   "
20949   [(set_attr "type" "other")
20950    (set_attr "length_immediate" "0")
20951    (set_attr "length_address" "0")
20952    (set_attr "length" "135")
20953    (set_attr "memory" "store")
20954    (set_attr "modrm" "0")
20955    (set_attr "mode" "DI")])
20956
20957 ;; 3Dnow! instructions
20958
20959 (define_insn "addv2sf3"
20960   [(set (match_operand:V2SF 0 "register_operand" "=y")
20961         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20962                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20963   "TARGET_3DNOW"
20964   "pfadd\\t{%2, %0|%0, %2}"
20965   [(set_attr "type" "mmxadd")
20966    (set_attr "mode" "V2SF")])
20967
20968 (define_insn "subv2sf3"
20969   [(set (match_operand:V2SF 0 "register_operand" "=y")
20970         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20971                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20972   "TARGET_3DNOW"
20973   "pfsub\\t{%2, %0|%0, %2}"
20974   [(set_attr "type" "mmxadd")
20975    (set_attr "mode" "V2SF")])
20976
20977 (define_insn "subrv2sf3"
20978   [(set (match_operand:V2SF 0 "register_operand" "=y")
20979         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20980                     (match_operand:V2SF 1 "register_operand" "0")))]
20981   "TARGET_3DNOW"
20982   "pfsubr\\t{%2, %0|%0, %2}"
20983   [(set_attr "type" "mmxadd")
20984    (set_attr "mode" "V2SF")])
20985
20986 (define_insn "gtv2sf3"
20987   [(set (match_operand:V2SI 0 "register_operand" "=y")
20988         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20989                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20990  "TARGET_3DNOW"
20991   "pfcmpgt\\t{%2, %0|%0, %2}"
20992   [(set_attr "type" "mmxcmp")
20993    (set_attr "mode" "V2SF")])
20994
20995 (define_insn "gev2sf3"
20996   [(set (match_operand:V2SI 0 "register_operand" "=y")
20997         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20998                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20999   "TARGET_3DNOW"
21000   "pfcmpge\\t{%2, %0|%0, %2}"
21001   [(set_attr "type" "mmxcmp")
21002    (set_attr "mode" "V2SF")])
21003
21004 (define_insn "eqv2sf3"
21005   [(set (match_operand:V2SI 0 "register_operand" "=y")
21006         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21007                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21008   "TARGET_3DNOW"
21009   "pfcmpeq\\t{%2, %0|%0, %2}"
21010   [(set_attr "type" "mmxcmp")
21011    (set_attr "mode" "V2SF")])
21012
21013 (define_insn "pfmaxv2sf3"
21014   [(set (match_operand:V2SF 0 "register_operand" "=y")
21015         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21016                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21017   "TARGET_3DNOW"
21018   "pfmax\\t{%2, %0|%0, %2}"
21019   [(set_attr "type" "mmxadd")
21020    (set_attr "mode" "V2SF")])
21021
21022 (define_insn "pfminv2sf3"
21023   [(set (match_operand:V2SF 0 "register_operand" "=y")
21024         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21025                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21026   "TARGET_3DNOW"
21027   "pfmin\\t{%2, %0|%0, %2}"
21028   [(set_attr "type" "mmxadd")
21029    (set_attr "mode" "V2SF")])
21030
21031 (define_insn "mulv2sf3"
21032   [(set (match_operand:V2SF 0 "register_operand" "=y")
21033         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21034                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21035   "TARGET_3DNOW"
21036   "pfmul\\t{%2, %0|%0, %2}"
21037   [(set_attr "type" "mmxmul")
21038    (set_attr "mode" "V2SF")])
21039
21040 (define_insn "femms"
21041   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21042    (clobber (reg:XF 8))
21043    (clobber (reg:XF 9))
21044    (clobber (reg:XF 10))
21045    (clobber (reg:XF 11))
21046    (clobber (reg:XF 12))
21047    (clobber (reg:XF 13))
21048    (clobber (reg:XF 14))
21049    (clobber (reg:XF 15))
21050    (clobber (reg:DI 29))
21051    (clobber (reg:DI 30))
21052    (clobber (reg:DI 31))
21053    (clobber (reg:DI 32))
21054    (clobber (reg:DI 33))
21055    (clobber (reg:DI 34))
21056    (clobber (reg:DI 35))
21057    (clobber (reg:DI 36))]
21058   "TARGET_3DNOW"
21059   "femms"
21060   [(set_attr "type" "mmx")
21061    (set_attr "memory" "none")]) 
21062
21063 (define_insn "pf2id"
21064   [(set (match_operand:V2SI 0 "register_operand" "=y")
21065         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21066   "TARGET_3DNOW"
21067   "pf2id\\t{%1, %0|%0, %1}"
21068   [(set_attr "type" "mmxcvt")
21069    (set_attr "mode" "V2SF")])
21070
21071 (define_insn "pf2iw"
21072   [(set (match_operand:V2SI 0 "register_operand" "=y")
21073         (sign_extend:V2SI
21074            (ss_truncate:V2HI
21075               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21076   "TARGET_3DNOW_A"
21077   "pf2iw\\t{%1, %0|%0, %1}"
21078   [(set_attr "type" "mmxcvt")
21079    (set_attr "mode" "V2SF")])
21080
21081 (define_insn "pfacc"
21082   [(set (match_operand:V2SF 0 "register_operand" "=y")
21083         (vec_concat:V2SF
21084            (plus:SF
21085               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21086                              (parallel [(const_int  0)]))
21087               (vec_select:SF (match_dup 1)
21088                              (parallel [(const_int 1)])))
21089            (plus:SF
21090               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21091                              (parallel [(const_int  0)]))
21092               (vec_select:SF (match_dup 2)
21093                              (parallel [(const_int 1)])))))]
21094   "TARGET_3DNOW"
21095   "pfacc\\t{%2, %0|%0, %2}"
21096   [(set_attr "type" "mmxadd")
21097    (set_attr "mode" "V2SF")])
21098
21099 (define_insn "pfnacc"
21100   [(set (match_operand:V2SF 0 "register_operand" "=y")
21101         (vec_concat:V2SF
21102            (minus:SF
21103               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21104                              (parallel [(const_int 0)]))
21105               (vec_select:SF (match_dup 1)
21106                              (parallel [(const_int 1)])))
21107            (minus:SF
21108               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21109                              (parallel [(const_int  0)]))
21110               (vec_select:SF (match_dup 2)
21111                              (parallel [(const_int 1)])))))]
21112   "TARGET_3DNOW_A"
21113   "pfnacc\\t{%2, %0|%0, %2}"
21114   [(set_attr "type" "mmxadd")
21115    (set_attr "mode" "V2SF")])
21116
21117 (define_insn "pfpnacc"
21118   [(set (match_operand:V2SF 0 "register_operand" "=y")
21119         (vec_concat:V2SF
21120            (minus:SF
21121               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21122                              (parallel [(const_int 0)]))
21123               (vec_select:SF (match_dup 1)
21124                              (parallel [(const_int 1)])))
21125            (plus:SF
21126               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21127                              (parallel [(const_int 0)]))
21128               (vec_select:SF (match_dup 2)
21129                              (parallel [(const_int 1)])))))]
21130   "TARGET_3DNOW_A"
21131   "pfpnacc\\t{%2, %0|%0, %2}"
21132   [(set_attr "type" "mmxadd")
21133    (set_attr "mode" "V2SF")])
21134
21135 (define_insn "pi2fw"
21136   [(set (match_operand:V2SF 0 "register_operand" "=y")
21137         (float:V2SF
21138            (vec_concat:V2SI
21139               (sign_extend:SI
21140                  (truncate:HI
21141                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21142                                    (parallel [(const_int 0)]))))
21143               (sign_extend:SI
21144                  (truncate:HI
21145                     (vec_select:SI (match_dup 1)
21146                                    (parallel [(const_int  1)])))))))]
21147   "TARGET_3DNOW_A"
21148   "pi2fw\\t{%1, %0|%0, %1}"
21149   [(set_attr "type" "mmxcvt")
21150    (set_attr "mode" "V2SF")])
21151
21152 (define_insn "floatv2si2"
21153   [(set (match_operand:V2SF 0 "register_operand" "=y")
21154         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21155   "TARGET_3DNOW"
21156   "pi2fd\\t{%1, %0|%0, %1}"
21157   [(set_attr "type" "mmxcvt")
21158    (set_attr "mode" "V2SF")])
21159
21160 ;; This insn is identical to pavgb in operation, but the opcode is
21161 ;; different.  To avoid accidentally matching pavgb, use an unspec.
21162
21163 (define_insn "pavgusb"
21164  [(set (match_operand:V8QI 0 "register_operand" "=y")
21165        (unspec:V8QI
21166           [(match_operand:V8QI 1 "register_operand" "0")
21167            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21168           UNSPEC_PAVGUSB))]
21169   "TARGET_3DNOW"
21170   "pavgusb\\t{%2, %0|%0, %2}"
21171   [(set_attr "type" "mmxshft")
21172    (set_attr "mode" "TI")])
21173
21174 ;; 3DNow reciprocal and sqrt
21175  
21176 (define_insn "pfrcpv2sf2"
21177   [(set (match_operand:V2SF 0 "register_operand" "=y")
21178         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21179         UNSPEC_PFRCP))]
21180   "TARGET_3DNOW"
21181   "pfrcp\\t{%1, %0|%0, %1}"
21182   [(set_attr "type" "mmx")
21183    (set_attr "mode" "TI")])
21184
21185 (define_insn "pfrcpit1v2sf3"
21186   [(set (match_operand:V2SF 0 "register_operand" "=y")
21187         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21188                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21189                      UNSPEC_PFRCPIT1))]
21190   "TARGET_3DNOW"
21191   "pfrcpit1\\t{%2, %0|%0, %2}"
21192   [(set_attr "type" "mmx")
21193    (set_attr "mode" "TI")])
21194
21195 (define_insn "pfrcpit2v2sf3"
21196   [(set (match_operand:V2SF 0 "register_operand" "=y")
21197         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21198                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21199                      UNSPEC_PFRCPIT2))]
21200   "TARGET_3DNOW"
21201   "pfrcpit2\\t{%2, %0|%0, %2}"
21202   [(set_attr "type" "mmx")
21203    (set_attr "mode" "TI")])
21204
21205 (define_insn "pfrsqrtv2sf2"
21206   [(set (match_operand:V2SF 0 "register_operand" "=y")
21207         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21208                      UNSPEC_PFRSQRT))]
21209   "TARGET_3DNOW"
21210   "pfrsqrt\\t{%1, %0|%0, %1}"
21211   [(set_attr "type" "mmx")
21212    (set_attr "mode" "TI")])
21213                 
21214 (define_insn "pfrsqit1v2sf3"
21215   [(set (match_operand:V2SF 0 "register_operand" "=y")
21216         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21217                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21218                      UNSPEC_PFRSQIT1))]
21219   "TARGET_3DNOW"
21220   "pfrsqit1\\t{%2, %0|%0, %2}"
21221   [(set_attr "type" "mmx")
21222    (set_attr "mode" "TI")])
21223
21224 (define_insn "pmulhrwv4hi3"
21225   [(set (match_operand:V4HI 0 "register_operand" "=y")
21226         (truncate:V4HI
21227            (lshiftrt:V4SI
21228               (plus:V4SI
21229                  (mult:V4SI
21230                     (sign_extend:V4SI
21231                        (match_operand:V4HI 1 "register_operand" "0"))
21232                     (sign_extend:V4SI
21233                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21234                  (const_vector:V4SI [(const_int 32768)
21235                                      (const_int 32768)
21236                                      (const_int 32768)
21237                                      (const_int 32768)]))
21238               (const_int 16))))]
21239   "TARGET_3DNOW"
21240   "pmulhrw\\t{%2, %0|%0, %2}"
21241   [(set_attr "type" "mmxmul")
21242    (set_attr "mode" "TI")])
21243
21244 (define_insn "pswapdv2si2"
21245   [(set (match_operand:V2SI 0 "register_operand" "=y")
21246         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21247                          (parallel [(const_int 1) (const_int 0)])))]
21248   "TARGET_3DNOW_A"
21249   "pswapd\\t{%1, %0|%0, %1}"
21250   [(set_attr "type" "mmxcvt")
21251    (set_attr "mode" "TI")])
21252
21253 (define_insn "pswapdv2sf2"
21254   [(set (match_operand:V2SF 0 "register_operand" "=y")
21255         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21256                          (parallel [(const_int 1) (const_int 0)])))]
21257   "TARGET_3DNOW_A"
21258   "pswapd\\t{%1, %0|%0, %1}"
21259   [(set_attr "type" "mmxcvt")
21260    (set_attr "mode" "TI")])
21261
21262 (define_expand "prefetch"
21263   [(prefetch (match_operand 0 "address_operand" "")
21264              (match_operand:SI 1 "const_int_operand" "")
21265              (match_operand:SI 2 "const_int_operand" ""))]
21266   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21267 {
21268   int rw = INTVAL (operands[1]);
21269   int locality = INTVAL (operands[2]);
21270
21271   if (rw != 0 && rw != 1)
21272     abort ();
21273   if (locality < 0 || locality > 3)
21274     abort ();
21275   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21276     abort ();
21277
21278   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21279      suported by SSE counterpart or the SSE prefetch is not available
21280      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21281      of locality.  */
21282   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21283     operands[2] = GEN_INT (3);
21284   else
21285     operands[1] = const0_rtx;
21286 })
21287
21288 (define_insn "*prefetch_sse"
21289   [(prefetch (match_operand:SI 0 "address_operand" "p")
21290              (const_int 0)
21291              (match_operand:SI 1 "const_int_operand" ""))]
21292   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21293 {
21294   static const char * const patterns[4] = {
21295    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21296   };
21297
21298   int locality = INTVAL (operands[1]);
21299   if (locality < 0 || locality > 3)
21300     abort ();
21301
21302   return patterns[locality];  
21303 }
21304   [(set_attr "type" "sse")
21305    (set_attr "memory" "none")])
21306
21307 (define_insn "*prefetch_sse_rex"
21308   [(prefetch (match_operand:DI 0 "address_operand" "p")
21309              (const_int 0)
21310              (match_operand:SI 1 "const_int_operand" ""))]
21311   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21312 {
21313   static const char * const patterns[4] = {
21314    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21315   };
21316
21317   int locality = INTVAL (operands[1]);
21318   if (locality < 0 || locality > 3)
21319     abort ();
21320
21321   return patterns[locality];  
21322 }
21323   [(set_attr "type" "sse")
21324    (set_attr "memory" "none")])
21325
21326 (define_insn "*prefetch_3dnow"
21327   [(prefetch (match_operand:SI 0 "address_operand" "p")
21328              (match_operand:SI 1 "const_int_operand" "n")
21329              (const_int 3))]
21330   "TARGET_3DNOW && !TARGET_64BIT"
21331 {
21332   if (INTVAL (operands[1]) == 0)
21333     return "prefetch\t%a0";
21334   else
21335     return "prefetchw\t%a0";
21336 }
21337   [(set_attr "type" "mmx")
21338    (set_attr "memory" "none")])
21339
21340 (define_insn "*prefetch_3dnow_rex"
21341   [(prefetch (match_operand:DI 0 "address_operand" "p")
21342              (match_operand:SI 1 "const_int_operand" "n")
21343              (const_int 3))]
21344   "TARGET_3DNOW && TARGET_64BIT"
21345 {
21346   if (INTVAL (operands[1]) == 0)
21347     return "prefetch\t%a0";
21348   else
21349     return "prefetchw\t%a0";
21350 }
21351   [(set_attr "type" "mmx")
21352    (set_attr "memory" "none")])
21353
21354 ;; SSE2 support
21355
21356 (define_insn "addv2df3"
21357   [(set (match_operand:V2DF 0 "register_operand" "=x")
21358         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21359                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21360   "TARGET_SSE2"
21361   "addpd\t{%2, %0|%0, %2}"
21362   [(set_attr "type" "sseadd")
21363    (set_attr "mode" "V2DF")])
21364
21365 (define_insn "vmaddv2df3"
21366   [(set (match_operand:V2DF 0 "register_operand" "=x")
21367         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21368                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21369                         (match_dup 1)
21370                         (const_int 1)))]
21371   "TARGET_SSE2"
21372   "addsd\t{%2, %0|%0, %2}"
21373   [(set_attr "type" "sseadd")
21374    (set_attr "mode" "DF")])
21375
21376 (define_insn "subv2df3"
21377   [(set (match_operand:V2DF 0 "register_operand" "=x")
21378         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21379                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21380   "TARGET_SSE2"
21381   "subpd\t{%2, %0|%0, %2}"
21382   [(set_attr "type" "sseadd")
21383    (set_attr "mode" "V2DF")])
21384
21385 (define_insn "vmsubv2df3"
21386   [(set (match_operand:V2DF 0 "register_operand" "=x")
21387         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21388                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21389                         (match_dup 1)
21390                         (const_int 1)))]
21391   "TARGET_SSE2"
21392   "subsd\t{%2, %0|%0, %2}"
21393   [(set_attr "type" "sseadd")
21394    (set_attr "mode" "DF")])
21395
21396 (define_insn "mulv2df3"
21397   [(set (match_operand:V2DF 0 "register_operand" "=x")
21398         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21399                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21400   "TARGET_SSE2"
21401   "mulpd\t{%2, %0|%0, %2}"
21402   [(set_attr "type" "ssemul")
21403    (set_attr "mode" "V2DF")])
21404
21405 (define_insn "vmmulv2df3"
21406   [(set (match_operand:V2DF 0 "register_operand" "=x")
21407         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21408                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21409                         (match_dup 1)
21410                         (const_int 1)))]
21411   "TARGET_SSE2"
21412   "mulsd\t{%2, %0|%0, %2}"
21413   [(set_attr "type" "ssemul")
21414    (set_attr "mode" "DF")])
21415
21416 (define_insn "divv2df3"
21417   [(set (match_operand:V2DF 0 "register_operand" "=x")
21418         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21419                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21420   "TARGET_SSE2"
21421   "divpd\t{%2, %0|%0, %2}"
21422   [(set_attr "type" "ssediv")
21423    (set_attr "mode" "V2DF")])
21424
21425 (define_insn "vmdivv2df3"
21426   [(set (match_operand:V2DF 0 "register_operand" "=x")
21427         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21428                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21429                         (match_dup 1)
21430                         (const_int 1)))]
21431   "TARGET_SSE2"
21432   "divsd\t{%2, %0|%0, %2}"
21433   [(set_attr "type" "ssediv")
21434    (set_attr "mode" "DF")])
21435
21436 ;; SSE min/max
21437
21438 (define_insn "smaxv2df3"
21439   [(set (match_operand:V2DF 0 "register_operand" "=x")
21440         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21441                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21442   "TARGET_SSE2"
21443   "maxpd\t{%2, %0|%0, %2}"
21444   [(set_attr "type" "sseadd")
21445    (set_attr "mode" "V2DF")])
21446
21447 (define_insn "vmsmaxv2df3"
21448   [(set (match_operand:V2DF 0 "register_operand" "=x")
21449         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21450                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21451                         (match_dup 1)
21452                         (const_int 1)))]
21453   "TARGET_SSE2"
21454   "maxsd\t{%2, %0|%0, %2}"
21455   [(set_attr "type" "sseadd")
21456    (set_attr "mode" "DF")])
21457
21458 (define_insn "sminv2df3"
21459   [(set (match_operand:V2DF 0 "register_operand" "=x")
21460         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21461                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21462   "TARGET_SSE2"
21463   "minpd\t{%2, %0|%0, %2}"
21464   [(set_attr "type" "sseadd")
21465    (set_attr "mode" "V2DF")])
21466
21467 (define_insn "vmsminv2df3"
21468   [(set (match_operand:V2DF 0 "register_operand" "=x")
21469         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21470                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21471                         (match_dup 1)
21472                         (const_int 1)))]
21473   "TARGET_SSE2"
21474   "minsd\t{%2, %0|%0, %2}"
21475   [(set_attr "type" "sseadd")
21476    (set_attr "mode" "DF")])
21477 ;; SSE2 square root.  There doesn't appear to be an extension for the
21478 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21479
21480 (define_insn "sqrtv2df2"
21481   [(set (match_operand:V2DF 0 "register_operand" "=x")
21482         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21483   "TARGET_SSE2"
21484   "sqrtpd\t{%1, %0|%0, %1}"
21485   [(set_attr "type" "sse")
21486    (set_attr "mode" "V2DF")])
21487
21488 (define_insn "vmsqrtv2df2"
21489   [(set (match_operand:V2DF 0 "register_operand" "=x")
21490         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21491                         (match_operand:V2DF 2 "register_operand" "0")
21492                         (const_int 1)))]
21493   "TARGET_SSE2"
21494   "sqrtsd\t{%1, %0|%0, %1}"
21495   [(set_attr "type" "sse")
21496    (set_attr "mode" "SF")])
21497
21498 ;; SSE mask-generating compares
21499
21500 (define_insn "maskcmpv2df3"
21501   [(set (match_operand:V2DI 0 "register_operand" "=x")
21502         (match_operator:V2DI 3 "sse_comparison_operator"
21503                              [(match_operand:V2DF 1 "register_operand" "0")
21504                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21505   "TARGET_SSE2"
21506   "cmp%D3pd\t{%2, %0|%0, %2}"
21507   [(set_attr "type" "ssecmp")
21508    (set_attr "mode" "V2DF")])
21509
21510 (define_insn "maskncmpv2df3"
21511   [(set (match_operand:V2DI 0 "register_operand" "=x")
21512         (not:V2DI
21513          (match_operator:V2DI 3 "sse_comparison_operator"
21514                               [(match_operand:V2DF 1 "register_operand" "0")
21515                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21516   "TARGET_SSE2"
21517 {
21518   if (GET_CODE (operands[3]) == UNORDERED)
21519     return "cmpordps\t{%2, %0|%0, %2}";
21520   else
21521     return "cmpn%D3pd\t{%2, %0|%0, %2}";
21522 }
21523   [(set_attr "type" "ssecmp")
21524    (set_attr "mode" "V2DF")])
21525
21526 (define_insn "vmmaskcmpv2df3"
21527   [(set (match_operand:V2DI 0 "register_operand" "=x")
21528         (vec_merge:V2DI
21529          (match_operator:V2DI 3 "sse_comparison_operator"
21530                               [(match_operand:V2DF 1 "register_operand" "0")
21531                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21532          (subreg:V2DI (match_dup 1) 0)
21533          (const_int 1)))]
21534   "TARGET_SSE2"
21535   "cmp%D3sd\t{%2, %0|%0, %2}"
21536   [(set_attr "type" "ssecmp")
21537    (set_attr "mode" "DF")])
21538
21539 (define_insn "vmmaskncmpv2df3"
21540   [(set (match_operand:V2DI 0 "register_operand" "=x")
21541         (vec_merge:V2DI
21542          (not:V2DI
21543           (match_operator:V2DI 3 "sse_comparison_operator"
21544                                [(match_operand:V2DF 1 "register_operand" "0")
21545                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21546          (subreg:V2DI (match_dup 1) 0)
21547          (const_int 1)))]
21548   "TARGET_SSE2"
21549 {
21550   if (GET_CODE (operands[3]) == UNORDERED)
21551     return "cmpordsd\t{%2, %0|%0, %2}";
21552   else
21553     return "cmpn%D3sd\t{%2, %0|%0, %2}";
21554 }
21555   [(set_attr "type" "ssecmp")
21556    (set_attr "mode" "DF")])
21557
21558 (define_insn "sse2_comi"
21559   [(set (reg:CCFP 17)
21560         (compare:CCFP (vec_select:DF
21561                        (match_operand:V2DF 0 "register_operand" "x")
21562                        (parallel [(const_int 0)]))
21563                       (vec_select:DF
21564                        (match_operand:V2DF 1 "register_operand" "x")
21565                        (parallel [(const_int 0)]))))]
21566   "TARGET_SSE2"
21567   "comisd\t{%1, %0|%0, %1}"
21568   [(set_attr "type" "ssecomi")
21569    (set_attr "mode" "DF")])
21570
21571 (define_insn "sse2_ucomi"
21572   [(set (reg:CCFPU 17)
21573         (compare:CCFPU (vec_select:DF
21574                          (match_operand:V2DF 0 "register_operand" "x")
21575                          (parallel [(const_int 0)]))
21576                         (vec_select:DF
21577                          (match_operand:V2DF 1 "register_operand" "x")
21578                          (parallel [(const_int 0)]))))]
21579   "TARGET_SSE2"
21580   "ucomisd\t{%1, %0|%0, %1}"
21581   [(set_attr "type" "ssecomi")
21582    (set_attr "mode" "DF")])
21583
21584 ;; SSE Strange Moves.
21585
21586 (define_insn "sse2_movmskpd"
21587   [(set (match_operand:SI 0 "register_operand" "=r")
21588         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21589                    UNSPEC_MOVMSK))]
21590   "TARGET_SSE2"
21591   "movmskpd\t{%1, %0|%0, %1}"
21592   [(set_attr "type" "ssecvt")
21593    (set_attr "mode" "V2DF")])
21594
21595 (define_insn "sse2_pmovmskb"
21596   [(set (match_operand:SI 0 "register_operand" "=r")
21597         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21598                    UNSPEC_MOVMSK))]
21599   "TARGET_SSE2"
21600   "pmovmskb\t{%1, %0|%0, %1}"
21601   [(set_attr "type" "ssecvt")
21602    (set_attr "mode" "V2DF")])
21603
21604 (define_insn "sse2_maskmovdqu"
21605   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21606         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21607                        (match_operand:V16QI 2 "register_operand" "x")]
21608                       UNSPEC_MASKMOV))]
21609   "TARGET_SSE2"
21610   ;; @@@ check ordering of operands in intel/nonintel syntax
21611   "maskmovdqu\t{%2, %1|%1, %2}"
21612   [(set_attr "type" "ssecvt")
21613    (set_attr "mode" "TI")])
21614
21615 (define_insn "sse2_maskmovdqu_rex64"
21616   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21617         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21618                        (match_operand:V16QI 2 "register_operand" "x")]
21619                       UNSPEC_MASKMOV))]
21620   "TARGET_SSE2"
21621   ;; @@@ check ordering of operands in intel/nonintel syntax
21622   "maskmovdqu\t{%2, %1|%1, %2}"
21623   [(set_attr "type" "ssecvt")
21624    (set_attr "mode" "TI")])
21625
21626 (define_insn "sse2_movntv2df"
21627   [(set (match_operand:V2DF 0 "memory_operand" "=m")
21628         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21629                      UNSPEC_MOVNT))]
21630   "TARGET_SSE2"
21631   "movntpd\t{%1, %0|%0, %1}"
21632   [(set_attr "type" "ssecvt")
21633    (set_attr "mode" "V2DF")])
21634
21635 (define_insn "sse2_movntv2di"
21636   [(set (match_operand:V2DI 0 "memory_operand" "=m")
21637         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21638                      UNSPEC_MOVNT))]
21639   "TARGET_SSE2"
21640   "movntdq\t{%1, %0|%0, %1}"
21641   [(set_attr "type" "ssecvt")
21642    (set_attr "mode" "TI")])
21643
21644 (define_insn "sse2_movntsi"
21645   [(set (match_operand:SI 0 "memory_operand" "=m")
21646         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21647                    UNSPEC_MOVNT))]
21648   "TARGET_SSE2"
21649   "movnti\t{%1, %0|%0, %1}"
21650   [(set_attr "type" "ssecvt")
21651    (set_attr "mode" "V2DF")])
21652
21653 ;; SSE <-> integer/MMX conversions
21654
21655 ;; Conversions between SI and SF
21656
21657 (define_insn "cvtdq2ps"
21658   [(set (match_operand:V4SF 0 "register_operand" "=x")
21659         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21660   "TARGET_SSE2"
21661   "cvtdq2ps\t{%1, %0|%0, %1}"
21662   [(set_attr "type" "ssecvt")
21663    (set_attr "mode" "V2DF")])
21664
21665 (define_insn "cvtps2dq"
21666   [(set (match_operand:V4SI 0 "register_operand" "=x")
21667         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21668   "TARGET_SSE2"
21669   "cvtps2dq\t{%1, %0|%0, %1}"
21670   [(set_attr "type" "ssecvt")
21671    (set_attr "mode" "TI")])
21672
21673 (define_insn "cvttps2dq"
21674   [(set (match_operand:V4SI 0 "register_operand" "=x")
21675         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21676                      UNSPEC_FIX))]
21677   "TARGET_SSE2"
21678   "cvttps2dq\t{%1, %0|%0, %1}"
21679   [(set_attr "type" "ssecvt")
21680    (set_attr "mode" "TI")])
21681
21682 ;; Conversions between SI and DF
21683
21684 (define_insn "cvtdq2pd"
21685   [(set (match_operand:V2DF 0 "register_operand" "=x")
21686         (float:V2DF (vec_select:V2SI
21687                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21688                      (parallel
21689                       [(const_int 0)
21690                        (const_int 1)]))))]
21691   "TARGET_SSE2"
21692   "cvtdq2pd\t{%1, %0|%0, %1}"
21693   [(set_attr "type" "ssecvt")
21694    (set_attr "mode" "V2DF")])
21695
21696 (define_insn "cvtpd2dq"
21697   [(set (match_operand:V4SI 0 "register_operand" "=x")
21698         (vec_concat:V4SI
21699          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21700          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21701   "TARGET_SSE2"
21702   "cvtpd2dq\t{%1, %0|%0, %1}"
21703   [(set_attr "type" "ssecvt")
21704    (set_attr "mode" "TI")])
21705
21706 (define_insn "cvttpd2dq"
21707   [(set (match_operand:V4SI 0 "register_operand" "=x")
21708         (vec_concat:V4SI
21709          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21710                       UNSPEC_FIX)
21711          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21712   "TARGET_SSE2"
21713   "cvttpd2dq\t{%1, %0|%0, %1}"
21714   [(set_attr "type" "ssecvt")
21715    (set_attr "mode" "TI")])
21716
21717 (define_insn "cvtpd2pi"
21718   [(set (match_operand:V2SI 0 "register_operand" "=y")
21719         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21720   "TARGET_SSE2"
21721   "cvtpd2pi\t{%1, %0|%0, %1}"
21722   [(set_attr "type" "ssecvt")
21723    (set_attr "mode" "TI")])
21724
21725 (define_insn "cvttpd2pi"
21726   [(set (match_operand:V2SI 0 "register_operand" "=y")
21727         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21728                      UNSPEC_FIX))]
21729   "TARGET_SSE2"
21730   "cvttpd2pi\t{%1, %0|%0, %1}"
21731   [(set_attr "type" "ssecvt")
21732    (set_attr "mode" "TI")])
21733
21734 (define_insn "cvtpi2pd"
21735   [(set (match_operand:V2DF 0 "register_operand" "=x")
21736         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21737   "TARGET_SSE2"
21738   "cvtpi2pd\t{%1, %0|%0, %1}"
21739   [(set_attr "type" "ssecvt")
21740    (set_attr "mode" "TI")])
21741
21742 ;; Conversions between SI and DF
21743
21744 (define_insn "cvtsd2si"
21745   [(set (match_operand:SI 0 "register_operand" "=r,r")
21746         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21747                                (parallel [(const_int 0)]))))]
21748   "TARGET_SSE2"
21749   "cvtsd2si\t{%1, %0|%0, %1}"
21750   [(set_attr "type" "sseicvt")
21751    (set_attr "athlon_decode" "double,vector")
21752    (set_attr "mode" "SI")])
21753
21754 (define_insn "cvtsd2siq"
21755   [(set (match_operand:DI 0 "register_operand" "=r,r")
21756         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21757                                (parallel [(const_int 0)]))))]
21758   "TARGET_SSE2 && TARGET_64BIT"
21759   "cvtsd2siq\t{%1, %0|%0, %1}"
21760   [(set_attr "type" "sseicvt")
21761    (set_attr "athlon_decode" "double,vector")
21762    (set_attr "mode" "DI")])
21763
21764 (define_insn "cvttsd2si"
21765   [(set (match_operand:SI 0 "register_operand" "=r,r")
21766         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21767                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21768   "TARGET_SSE2"
21769   "cvttsd2si\t{%1, %0|%0, %1}"
21770   [(set_attr "type" "sseicvt")
21771    (set_attr "mode" "SI")
21772    (set_attr "athlon_decode" "double,vector")])
21773
21774 (define_insn "cvttsd2siq"
21775   [(set (match_operand:DI 0 "register_operand" "=r,r")
21776         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21777                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21778   "TARGET_SSE2 && TARGET_64BIT"
21779   "cvttsd2siq\t{%1, %0|%0, %1}"
21780   [(set_attr "type" "sseicvt")
21781    (set_attr "mode" "DI")
21782    (set_attr "athlon_decode" "double,vector")])
21783
21784 (define_insn "cvtsi2sd"
21785   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21786         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21787                         (vec_duplicate:V2DF
21788                           (float:DF
21789                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21790                         (const_int 2)))]
21791   "TARGET_SSE2"
21792   "cvtsi2sd\t{%2, %0|%0, %2}"
21793   [(set_attr "type" "sseicvt")
21794    (set_attr "mode" "DF")
21795    (set_attr "athlon_decode" "double,direct")])
21796
21797 (define_insn "cvtsi2sdq"
21798   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21799         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21800                         (vec_duplicate:V2DF
21801                           (float:DF
21802                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21803                         (const_int 2)))]
21804   "TARGET_SSE2 && TARGET_64BIT"
21805   "cvtsi2sdq\t{%2, %0|%0, %2}"
21806   [(set_attr "type" "sseicvt")
21807    (set_attr "mode" "DF")
21808    (set_attr "athlon_decode" "double,direct")])
21809
21810 ;; Conversions between SF and DF
21811
21812 (define_insn "cvtsd2ss"
21813   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21814         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21815                         (vec_duplicate:V4SF
21816                           (float_truncate:V2SF
21817                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21818                         (const_int 14)))]
21819   "TARGET_SSE2"
21820   "cvtsd2ss\t{%2, %0|%0, %2}"
21821   [(set_attr "type" "ssecvt")
21822    (set_attr "athlon_decode" "vector,double")
21823    (set_attr "mode" "SF")])
21824
21825 (define_insn "cvtss2sd"
21826   [(set (match_operand:V2DF 0 "register_operand" "=x")
21827         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21828                         (float_extend:V2DF
21829                           (vec_select:V2SF
21830                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21831                             (parallel [(const_int 0)
21832                                        (const_int 1)])))
21833                         (const_int 2)))]
21834   "TARGET_SSE2"
21835   "cvtss2sd\t{%2, %0|%0, %2}"
21836   [(set_attr "type" "ssecvt")
21837    (set_attr "mode" "DF")])
21838
21839 (define_insn "cvtpd2ps"
21840   [(set (match_operand:V4SF 0 "register_operand" "=x")
21841         (subreg:V4SF
21842           (vec_concat:V4SI
21843             (subreg:V2SI (float_truncate:V2SF
21844                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21845             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21846   "TARGET_SSE2"
21847   "cvtpd2ps\t{%1, %0|%0, %1}"
21848   [(set_attr "type" "ssecvt")
21849    (set_attr "mode" "V4SF")])
21850
21851 (define_insn "cvtps2pd"
21852   [(set (match_operand:V2DF 0 "register_operand" "=x")
21853         (float_extend:V2DF
21854           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21855                            (parallel [(const_int 0)
21856                                       (const_int 1)]))))]
21857   "TARGET_SSE2"
21858   "cvtps2pd\t{%1, %0|%0, %1}"
21859   [(set_attr "type" "ssecvt")
21860    (set_attr "mode" "V2DF")])
21861
21862 ;; SSE2 variants of MMX insns
21863
21864 ;; MMX arithmetic
21865
21866 (define_insn "addv16qi3"
21867   [(set (match_operand:V16QI 0 "register_operand" "=x")
21868         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21869                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21870   "TARGET_SSE2"
21871   "paddb\t{%2, %0|%0, %2}"
21872   [(set_attr "type" "sseiadd")
21873    (set_attr "mode" "TI")])
21874
21875 (define_insn "addv8hi3"
21876   [(set (match_operand:V8HI 0 "register_operand" "=x")
21877         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21878                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21879   "TARGET_SSE2"
21880   "paddw\t{%2, %0|%0, %2}"
21881   [(set_attr "type" "sseiadd")
21882    (set_attr "mode" "TI")])
21883
21884 (define_insn "addv4si3"
21885   [(set (match_operand:V4SI 0 "register_operand" "=x")
21886         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21887                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21888   "TARGET_SSE2"
21889   "paddd\t{%2, %0|%0, %2}"
21890   [(set_attr "type" "sseiadd")
21891    (set_attr "mode" "TI")])
21892
21893 (define_insn "addv2di3"
21894   [(set (match_operand:V2DI 0 "register_operand" "=x")
21895         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21896                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21897   "TARGET_SSE2"
21898   "paddq\t{%2, %0|%0, %2}"
21899   [(set_attr "type" "sseiadd")
21900    (set_attr "mode" "TI")])
21901
21902 (define_insn "ssaddv16qi3"
21903   [(set (match_operand:V16QI 0 "register_operand" "=x")
21904         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21905                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21906   "TARGET_SSE2"
21907   "paddsb\t{%2, %0|%0, %2}"
21908   [(set_attr "type" "sseiadd")
21909    (set_attr "mode" "TI")])
21910
21911 (define_insn "ssaddv8hi3"
21912   [(set (match_operand:V8HI 0 "register_operand" "=x")
21913         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21914                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21915   "TARGET_SSE2"
21916   "paddsw\t{%2, %0|%0, %2}"
21917   [(set_attr "type" "sseiadd")
21918    (set_attr "mode" "TI")])
21919
21920 (define_insn "usaddv16qi3"
21921   [(set (match_operand:V16QI 0 "register_operand" "=x")
21922         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21923                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21924   "TARGET_SSE2"
21925   "paddusb\t{%2, %0|%0, %2}"
21926   [(set_attr "type" "sseiadd")
21927    (set_attr "mode" "TI")])
21928
21929 (define_insn "usaddv8hi3"
21930   [(set (match_operand:V8HI 0 "register_operand" "=x")
21931         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21932                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21933   "TARGET_SSE2"
21934   "paddusw\t{%2, %0|%0, %2}"
21935   [(set_attr "type" "sseiadd")
21936    (set_attr "mode" "TI")])
21937
21938 (define_insn "subv16qi3"
21939   [(set (match_operand:V16QI 0 "register_operand" "=x")
21940         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21941                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21942   "TARGET_SSE2"
21943   "psubb\t{%2, %0|%0, %2}"
21944   [(set_attr "type" "sseiadd")
21945    (set_attr "mode" "TI")])
21946
21947 (define_insn "subv8hi3"
21948   [(set (match_operand:V8HI 0 "register_operand" "=x")
21949         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21950                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21951   "TARGET_SSE2"
21952   "psubw\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "sseiadd")
21954    (set_attr "mode" "TI")])
21955
21956 (define_insn "subv4si3"
21957   [(set (match_operand:V4SI 0 "register_operand" "=x")
21958         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21959                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21960   "TARGET_SSE2"
21961   "psubd\t{%2, %0|%0, %2}"
21962   [(set_attr "type" "sseiadd")
21963    (set_attr "mode" "TI")])
21964
21965 (define_insn "subv2di3"
21966   [(set (match_operand:V2DI 0 "register_operand" "=x")
21967         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21968                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21969   "TARGET_SSE2"
21970   "psubq\t{%2, %0|%0, %2}"
21971   [(set_attr "type" "sseiadd")
21972    (set_attr "mode" "TI")])
21973
21974 (define_insn "sssubv16qi3"
21975   [(set (match_operand:V16QI 0 "register_operand" "=x")
21976         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21977                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21978   "TARGET_SSE2"
21979   "psubsb\t{%2, %0|%0, %2}"
21980   [(set_attr "type" "sseiadd")
21981    (set_attr "mode" "TI")])
21982
21983 (define_insn "sssubv8hi3"
21984   [(set (match_operand:V8HI 0 "register_operand" "=x")
21985         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21986                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21987   "TARGET_SSE2"
21988   "psubsw\t{%2, %0|%0, %2}"
21989   [(set_attr "type" "sseiadd")
21990    (set_attr "mode" "TI")])
21991
21992 (define_insn "ussubv16qi3"
21993   [(set (match_operand:V16QI 0 "register_operand" "=x")
21994         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21995                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21996   "TARGET_SSE2"
21997   "psubusb\t{%2, %0|%0, %2}"
21998   [(set_attr "type" "sseiadd")
21999    (set_attr "mode" "TI")])
22000
22001 (define_insn "ussubv8hi3"
22002   [(set (match_operand:V8HI 0 "register_operand" "=x")
22003         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22004                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22005   "TARGET_SSE2"
22006   "psubusw\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "sseiadd")
22008    (set_attr "mode" "TI")])
22009
22010 (define_insn "mulv8hi3"
22011   [(set (match_operand:V8HI 0 "register_operand" "=x")
22012         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22013                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22014   "TARGET_SSE2"
22015   "pmullw\t{%2, %0|%0, %2}"
22016   [(set_attr "type" "sseimul")
22017    (set_attr "mode" "TI")])
22018
22019 (define_insn "smulv8hi3_highpart"
22020   [(set (match_operand:V8HI 0 "register_operand" "=x")
22021         (truncate:V8HI
22022          (lshiftrt:V8SI
22023           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22024                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22025           (const_int 16))))]
22026   "TARGET_SSE2"
22027   "pmulhw\t{%2, %0|%0, %2}"
22028   [(set_attr "type" "sseimul")
22029    (set_attr "mode" "TI")])
22030
22031 (define_insn "umulv8hi3_highpart"
22032   [(set (match_operand:V8HI 0 "register_operand" "=x")
22033         (truncate:V8HI
22034          (lshiftrt:V8SI
22035           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22036                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22037           (const_int 16))))]
22038   "TARGET_SSE2"
22039   "pmulhuw\t{%2, %0|%0, %2}"
22040   [(set_attr "type" "sseimul")
22041    (set_attr "mode" "TI")])
22042
22043 (define_insn "sse2_umulsidi3"
22044   [(set (match_operand:DI 0 "register_operand" "=y")
22045         (mult:DI (zero_extend:DI (vec_select:SI
22046                                   (match_operand:V2SI 1 "register_operand" "0")
22047                                   (parallel [(const_int 0)])))
22048                  (zero_extend:DI (vec_select:SI
22049                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22050                                   (parallel [(const_int 0)])))))]
22051   "TARGET_SSE2"
22052   "pmuludq\t{%2, %0|%0, %2}"
22053   [(set_attr "type" "sseimul")
22054    (set_attr "mode" "TI")])
22055
22056 (define_insn "sse2_umulv2siv2di3"
22057   [(set (match_operand:V2DI 0 "register_operand" "=x")
22058         (mult:V2DI (zero_extend:V2DI
22059                      (vec_select:V2SI
22060                        (match_operand:V4SI 1 "register_operand" "0")
22061                        (parallel [(const_int 0) (const_int 2)])))
22062                    (zero_extend:V2DI
22063                      (vec_select:V2SI
22064                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22065                        (parallel [(const_int 0) (const_int 2)])))))]
22066   "TARGET_SSE2"
22067   "pmuludq\t{%2, %0|%0, %2}"
22068   [(set_attr "type" "sseimul")
22069    (set_attr "mode" "TI")])
22070
22071 (define_insn "sse2_pmaddwd"
22072   [(set (match_operand:V4SI 0 "register_operand" "=x")
22073         (plus:V4SI
22074          (mult:V4SI
22075           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22076                                              (parallel [(const_int 0)
22077                                                         (const_int 2)
22078                                                         (const_int 4)
22079                                                         (const_int 6)])))
22080           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22081                                              (parallel [(const_int 0)
22082                                                         (const_int 2)
22083                                                         (const_int 4)
22084                                                         (const_int 6)]))))
22085          (mult:V4SI
22086           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22087                                              (parallel [(const_int 1)
22088                                                         (const_int 3)
22089                                                         (const_int 5)
22090                                                         (const_int 7)])))
22091           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22092                                              (parallel [(const_int 1)
22093                                                         (const_int 3)
22094                                                         (const_int 5)
22095                                                         (const_int 7)]))))))]
22096   "TARGET_SSE2"
22097   "pmaddwd\t{%2, %0|%0, %2}"
22098   [(set_attr "type" "sseiadd")
22099    (set_attr "mode" "TI")])
22100
22101 ;; Same as pxor, but don't show input operands so that we don't think
22102 ;; they are live.
22103 (define_insn "sse2_clrti"
22104   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22105   "TARGET_SSE2"
22106 {
22107   if (get_attr_mode (insn) == MODE_TI)
22108     return "pxor\t%0, %0";
22109   else
22110     return "xorps\t%0, %0";
22111 }
22112   [(set_attr "type" "ssemov")
22113    (set_attr "memory" "none")
22114    (set (attr "mode")
22115               (if_then_else
22116                 (ne (symbol_ref "optimize_size")
22117                     (const_int 0))
22118                 (const_string "V4SF")
22119                 (const_string "TI")))])
22120
22121 ;; MMX unsigned averages/sum of absolute differences
22122
22123 (define_insn "sse2_uavgv16qi3"
22124   [(set (match_operand:V16QI 0 "register_operand" "=x")
22125         (ashiftrt:V16QI
22126          (plus:V16QI (plus:V16QI
22127                      (match_operand:V16QI 1 "register_operand" "0")
22128                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22129                      (const_vector:V16QI [(const_int 1) (const_int 1)
22130                                           (const_int 1) (const_int 1)
22131                                           (const_int 1) (const_int 1)
22132                                           (const_int 1) (const_int 1)
22133                                           (const_int 1) (const_int 1)
22134                                           (const_int 1) (const_int 1)
22135                                           (const_int 1) (const_int 1)
22136                                           (const_int 1) (const_int 1)]))
22137          (const_int 1)))]
22138   "TARGET_SSE2"
22139   "pavgb\t{%2, %0|%0, %2}"
22140   [(set_attr "type" "sseiadd")
22141    (set_attr "mode" "TI")])
22142
22143 (define_insn "sse2_uavgv8hi3"
22144   [(set (match_operand:V8HI 0 "register_operand" "=x")
22145         (ashiftrt:V8HI
22146          (plus:V8HI (plus:V8HI
22147                      (match_operand:V8HI 1 "register_operand" "0")
22148                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22149                     (const_vector:V8HI [(const_int 1) (const_int 1)
22150                                         (const_int 1) (const_int 1)
22151                                         (const_int 1) (const_int 1)
22152                                         (const_int 1) (const_int 1)]))
22153          (const_int 1)))]
22154   "TARGET_SSE2"
22155   "pavgw\t{%2, %0|%0, %2}"
22156   [(set_attr "type" "sseiadd")
22157    (set_attr "mode" "TI")])
22158
22159 ;; @@@ this isn't the right representation.
22160 (define_insn "sse2_psadbw"
22161   [(set (match_operand:V2DI 0 "register_operand" "=x")
22162         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22163                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22164                      UNSPEC_PSADBW))]
22165   "TARGET_SSE2"
22166   "psadbw\t{%2, %0|%0, %2}"
22167   [(set_attr "type" "sseiadd")
22168    (set_attr "mode" "TI")])
22169
22170
22171 ;; MMX insert/extract/shuffle
22172
22173 (define_insn "sse2_pinsrw"
22174   [(set (match_operand:V8HI 0 "register_operand" "=x")
22175         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22176                         (vec_duplicate:V8HI
22177                          (truncate:HI
22178                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
22179                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22180   "TARGET_SSE2"
22181   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22182   [(set_attr "type" "ssecvt")
22183    (set_attr "mode" "TI")])
22184
22185 (define_insn "sse2_pextrw"
22186   [(set (match_operand:SI 0 "register_operand" "=r")
22187         (zero_extend:SI
22188           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22189                          (parallel
22190                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22191   "TARGET_SSE2"
22192   "pextrw\t{%2, %1, %0|%0, %1, %2}"
22193   [(set_attr "type" "ssecvt")
22194    (set_attr "mode" "TI")])
22195
22196 (define_insn "sse2_pshufd"
22197   [(set (match_operand:V4SI 0 "register_operand" "=x")
22198         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22199                       (match_operand:SI 2 "immediate_operand" "i")]
22200                      UNSPEC_SHUFFLE))]
22201   "TARGET_SSE2"
22202   "pshufd\t{%2, %1, %0|%0, %1, %2}"
22203   [(set_attr "type" "ssecvt")
22204    (set_attr "mode" "TI")])
22205
22206 (define_insn "sse2_pshuflw"
22207   [(set (match_operand:V8HI 0 "register_operand" "=x")
22208         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22209                       (match_operand:SI 2 "immediate_operand" "i")]
22210                      UNSPEC_PSHUFLW))]
22211   "TARGET_SSE2"
22212   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22213   [(set_attr "type" "ssecvt")
22214    (set_attr "mode" "TI")])
22215
22216 (define_insn "sse2_pshufhw"
22217   [(set (match_operand:V8HI 0 "register_operand" "=x")
22218         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22219                       (match_operand:SI 2 "immediate_operand" "i")]
22220                      UNSPEC_PSHUFHW))]
22221   "TARGET_SSE2"
22222   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22223   [(set_attr "type" "ssecvt")
22224    (set_attr "mode" "TI")])
22225
22226 ;; MMX mask-generating comparisons
22227
22228 (define_insn "eqv16qi3"
22229   [(set (match_operand:V16QI 0 "register_operand" "=x")
22230         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22231                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22232   "TARGET_SSE2"
22233   "pcmpeqb\t{%2, %0|%0, %2}"
22234   [(set_attr "type" "ssecmp")
22235    (set_attr "mode" "TI")])
22236
22237 (define_insn "eqv8hi3"
22238   [(set (match_operand:V8HI 0 "register_operand" "=x")
22239         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22240                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22241   "TARGET_SSE2"
22242   "pcmpeqw\t{%2, %0|%0, %2}"
22243   [(set_attr "type" "ssecmp")
22244    (set_attr "mode" "TI")])
22245
22246 (define_insn "eqv4si3"
22247   [(set (match_operand:V4SI 0 "register_operand" "=x")
22248         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22249                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22250   "TARGET_SSE2"
22251   "pcmpeqd\t{%2, %0|%0, %2}"
22252   [(set_attr "type" "ssecmp")
22253    (set_attr "mode" "TI")])
22254
22255 (define_insn "gtv16qi3"
22256   [(set (match_operand:V16QI 0 "register_operand" "=x")
22257         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22258                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22259   "TARGET_SSE2"
22260   "pcmpgtb\t{%2, %0|%0, %2}"
22261   [(set_attr "type" "ssecmp")
22262    (set_attr "mode" "TI")])
22263
22264 (define_insn "gtv8hi3"
22265   [(set (match_operand:V8HI 0 "register_operand" "=x")
22266         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22267                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22268   "TARGET_SSE2"
22269   "pcmpgtw\t{%2, %0|%0, %2}"
22270   [(set_attr "type" "ssecmp")
22271    (set_attr "mode" "TI")])
22272
22273 (define_insn "gtv4si3"
22274   [(set (match_operand:V4SI 0 "register_operand" "=x")
22275         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22276                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22277   "TARGET_SSE2"
22278   "pcmpgtd\t{%2, %0|%0, %2}"
22279   [(set_attr "type" "ssecmp")
22280    (set_attr "mode" "TI")])
22281
22282
22283 ;; MMX max/min insns
22284
22285 (define_insn "umaxv16qi3"
22286   [(set (match_operand:V16QI 0 "register_operand" "=x")
22287         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22288                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22289   "TARGET_SSE2"
22290   "pmaxub\t{%2, %0|%0, %2}"
22291   [(set_attr "type" "sseiadd")
22292    (set_attr "mode" "TI")])
22293
22294 (define_insn "smaxv8hi3"
22295   [(set (match_operand:V8HI 0 "register_operand" "=x")
22296         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22297                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22298   "TARGET_SSE2"
22299   "pmaxsw\t{%2, %0|%0, %2}"
22300   [(set_attr "type" "sseiadd")
22301    (set_attr "mode" "TI")])
22302
22303 (define_insn "uminv16qi3"
22304   [(set (match_operand:V16QI 0 "register_operand" "=x")
22305         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22306                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22307   "TARGET_SSE2"
22308   "pminub\t{%2, %0|%0, %2}"
22309   [(set_attr "type" "sseiadd")
22310    (set_attr "mode" "TI")])
22311
22312 (define_insn "sminv8hi3"
22313   [(set (match_operand:V8HI 0 "register_operand" "=x")
22314         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22315                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22316   "TARGET_SSE2"
22317   "pminsw\t{%2, %0|%0, %2}"
22318   [(set_attr "type" "sseiadd")
22319    (set_attr "mode" "TI")])
22320
22321
22322 ;; MMX shifts
22323
22324 (define_insn "ashrv8hi3"
22325   [(set (match_operand:V8HI 0 "register_operand" "=x")
22326         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22327                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22328   "TARGET_SSE2"
22329   "psraw\t{%2, %0|%0, %2}"
22330   [(set_attr "type" "sseishft")
22331    (set_attr "mode" "TI")])
22332
22333 (define_insn "ashrv4si3"
22334   [(set (match_operand:V4SI 0 "register_operand" "=x")
22335         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22336                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22337   "TARGET_SSE2"
22338   "psrad\t{%2, %0|%0, %2}"
22339   [(set_attr "type" "sseishft")
22340    (set_attr "mode" "TI")])
22341
22342 (define_insn "lshrv8hi3"
22343   [(set (match_operand:V8HI 0 "register_operand" "=x")
22344         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22345                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22346   "TARGET_SSE2"
22347   "psrlw\t{%2, %0|%0, %2}"
22348   [(set_attr "type" "sseishft")
22349    (set_attr "mode" "TI")])
22350
22351 (define_insn "lshrv4si3"
22352   [(set (match_operand:V4SI 0 "register_operand" "=x")
22353         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22354                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22355   "TARGET_SSE2"
22356   "psrld\t{%2, %0|%0, %2}"
22357   [(set_attr "type" "sseishft")
22358    (set_attr "mode" "TI")])
22359
22360 (define_insn "lshrv2di3"
22361   [(set (match_operand:V2DI 0 "register_operand" "=x")
22362         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22363                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
22364   "TARGET_SSE2"
22365   "psrlq\t{%2, %0|%0, %2}"
22366   [(set_attr "type" "sseishft")
22367    (set_attr "mode" "TI")])
22368
22369 (define_insn "ashlv8hi3"
22370   [(set (match_operand:V8HI 0 "register_operand" "=x")
22371         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22372                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22373   "TARGET_SSE2"
22374   "psllw\t{%2, %0|%0, %2}"
22375   [(set_attr "type" "sseishft")
22376    (set_attr "mode" "TI")])
22377
22378 (define_insn "ashlv4si3"
22379   [(set (match_operand:V4SI 0 "register_operand" "=x")
22380         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22381                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22382   "TARGET_SSE2"
22383   "pslld\t{%2, %0|%0, %2}"
22384   [(set_attr "type" "sseishft")
22385    (set_attr "mode" "TI")])
22386
22387 (define_insn "ashlv2di3"
22388   [(set (match_operand:V2DI 0 "register_operand" "=x")
22389         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22390                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
22391   "TARGET_SSE2"
22392   "psllq\t{%2, %0|%0, %2}"
22393   [(set_attr "type" "sseishft")
22394    (set_attr "mode" "TI")])
22395
22396 (define_insn "ashrv8hi3_ti"
22397   [(set (match_operand:V8HI 0 "register_operand" "=x")
22398         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22399                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22400   "TARGET_SSE2"
22401   "psraw\t{%2, %0|%0, %2}"
22402   [(set_attr "type" "sseishft")
22403    (set_attr "mode" "TI")])
22404
22405 (define_insn "ashrv4si3_ti"
22406   [(set (match_operand:V4SI 0 "register_operand" "=x")
22407         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22408                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22409   "TARGET_SSE2"
22410   "psrad\t{%2, %0|%0, %2}"
22411   [(set_attr "type" "sseishft")
22412    (set_attr "mode" "TI")])
22413
22414 (define_insn "lshrv8hi3_ti"
22415   [(set (match_operand:V8HI 0 "register_operand" "=x")
22416         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22417                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22418   "TARGET_SSE2"
22419   "psrlw\t{%2, %0|%0, %2}"
22420   [(set_attr "type" "sseishft")
22421    (set_attr "mode" "TI")])
22422
22423 (define_insn "lshrv4si3_ti"
22424   [(set (match_operand:V4SI 0 "register_operand" "=x")
22425         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22426                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22427   "TARGET_SSE2"
22428   "psrld\t{%2, %0|%0, %2}"
22429   [(set_attr "type" "sseishft")
22430    (set_attr "mode" "TI")])
22431
22432 (define_insn "lshrv2di3_ti"
22433   [(set (match_operand:V2DI 0 "register_operand" "=x")
22434         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22435                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22436   "TARGET_SSE2"
22437   "psrlq\t{%2, %0|%0, %2}"
22438   [(set_attr "type" "sseishft")
22439    (set_attr "mode" "TI")])
22440
22441 (define_insn "ashlv8hi3_ti"
22442   [(set (match_operand:V8HI 0 "register_operand" "=x")
22443         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22444                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22445   "TARGET_SSE2"
22446   "psllw\t{%2, %0|%0, %2}"
22447   [(set_attr "type" "sseishft")
22448    (set_attr "mode" "TI")])
22449
22450 (define_insn "ashlv4si3_ti"
22451   [(set (match_operand:V4SI 0 "register_operand" "=x")
22452         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22453                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22454   "TARGET_SSE2"
22455   "pslld\t{%2, %0|%0, %2}"
22456   [(set_attr "type" "sseishft")
22457    (set_attr "mode" "TI")])
22458
22459 (define_insn "ashlv2di3_ti"
22460   [(set (match_operand:V2DI 0 "register_operand" "=x")
22461         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22462                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22463   "TARGET_SSE2"
22464   "psllq\t{%2, %0|%0, %2}"
22465   [(set_attr "type" "sseishft")
22466    (set_attr "mode" "TI")])
22467
22468 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22469 ;; we wouldn't need here it since we never generate TImode arithmetic.
22470
22471 ;; There has to be some kind of prize for the weirdest new instruction...
22472 (define_insn "sse2_ashlti3"
22473   [(set (match_operand:TI 0 "register_operand" "=x")
22474         (unspec:TI
22475          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22476                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22477                                (const_int 8)))] UNSPEC_NOP))]
22478   "TARGET_SSE2"
22479   "pslldq\t{%2, %0|%0, %2}"
22480   [(set_attr "type" "sseishft")
22481    (set_attr "mode" "TI")])
22482
22483 (define_insn "sse2_lshrti3"
22484   [(set (match_operand:TI 0 "register_operand" "=x")
22485         (unspec:TI
22486          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22487                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22488                                 (const_int 8)))] UNSPEC_NOP))]
22489   "TARGET_SSE2"
22490   "psrldq\t{%2, %0|%0, %2}"
22491   [(set_attr "type" "sseishft")
22492    (set_attr "mode" "TI")])
22493
22494 ;; SSE unpack
22495
22496 (define_insn "sse2_unpckhpd"
22497   [(set (match_operand:V2DF 0 "register_operand" "=x")
22498         (vec_concat:V2DF
22499          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22500                         (parallel [(const_int 1)]))
22501          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22502                         (parallel [(const_int 1)]))))]
22503   "TARGET_SSE2"
22504   "unpckhpd\t{%2, %0|%0, %2}"
22505   [(set_attr "type" "ssecvt")
22506    (set_attr "mode" "V2DF")])
22507
22508 (define_insn "sse2_unpcklpd"
22509   [(set (match_operand:V2DF 0 "register_operand" "=x")
22510         (vec_concat:V2DF
22511          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22512                         (parallel [(const_int 0)]))
22513          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22514                         (parallel [(const_int 0)]))))]
22515   "TARGET_SSE2"
22516   "unpcklpd\t{%2, %0|%0, %2}"
22517   [(set_attr "type" "ssecvt")
22518    (set_attr "mode" "V2DF")])
22519
22520 ;; MMX pack/unpack insns.
22521
22522 (define_insn "sse2_packsswb"
22523   [(set (match_operand:V16QI 0 "register_operand" "=x")
22524         (vec_concat:V16QI
22525          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22526          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22527   "TARGET_SSE2"
22528   "packsswb\t{%2, %0|%0, %2}"
22529   [(set_attr "type" "ssecvt")
22530    (set_attr "mode" "TI")])
22531
22532 (define_insn "sse2_packssdw"
22533   [(set (match_operand:V8HI 0 "register_operand" "=x")
22534         (vec_concat:V8HI
22535          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22536          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22537   "TARGET_SSE2"
22538   "packssdw\t{%2, %0|%0, %2}"
22539   [(set_attr "type" "ssecvt")
22540    (set_attr "mode" "TI")])
22541
22542 (define_insn "sse2_packuswb"
22543   [(set (match_operand:V16QI 0 "register_operand" "=x")
22544         (vec_concat:V16QI
22545          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22546          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22547   "TARGET_SSE2"
22548   "packuswb\t{%2, %0|%0, %2}"
22549   [(set_attr "type" "ssecvt")
22550    (set_attr "mode" "TI")])
22551
22552 (define_insn "sse2_punpckhbw"
22553   [(set (match_operand:V16QI 0 "register_operand" "=x")
22554         (vec_merge:V16QI
22555          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22556                            (parallel [(const_int 8) (const_int 0)
22557                                       (const_int 9) (const_int 1)
22558                                       (const_int 10) (const_int 2)
22559                                       (const_int 11) (const_int 3)
22560                                       (const_int 12) (const_int 4)
22561                                       (const_int 13) (const_int 5)
22562                                       (const_int 14) (const_int 6)
22563                                       (const_int 15) (const_int 7)]))
22564          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22565                            (parallel [(const_int 0) (const_int 8)
22566                                       (const_int 1) (const_int 9)
22567                                       (const_int 2) (const_int 10)
22568                                       (const_int 3) (const_int 11)
22569                                       (const_int 4) (const_int 12)
22570                                       (const_int 5) (const_int 13)
22571                                       (const_int 6) (const_int 14)
22572                                       (const_int 7) (const_int 15)]))
22573          (const_int 21845)))]
22574   "TARGET_SSE2"
22575   "punpckhbw\t{%2, %0|%0, %2}"
22576   [(set_attr "type" "ssecvt")
22577    (set_attr "mode" "TI")])
22578
22579 (define_insn "sse2_punpckhwd"
22580   [(set (match_operand:V8HI 0 "register_operand" "=x")
22581         (vec_merge:V8HI
22582          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22583                           (parallel [(const_int 4) (const_int 0)
22584                                      (const_int 5) (const_int 1)
22585                                      (const_int 6) (const_int 2)
22586                                      (const_int 7) (const_int 3)]))
22587          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22588                           (parallel [(const_int 0) (const_int 4)
22589                                      (const_int 1) (const_int 5)
22590                                      (const_int 2) (const_int 6)
22591                                      (const_int 3) (const_int 7)]))
22592          (const_int 85)))]
22593   "TARGET_SSE2"
22594   "punpckhwd\t{%2, %0|%0, %2}"
22595   [(set_attr "type" "ssecvt")
22596    (set_attr "mode" "TI")])
22597
22598 (define_insn "sse2_punpckhdq"
22599   [(set (match_operand:V4SI 0 "register_operand" "=x")
22600         (vec_merge:V4SI
22601          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22602                           (parallel [(const_int 2) (const_int 0)
22603                                      (const_int 3) (const_int 1)]))
22604          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22605                           (parallel [(const_int 0) (const_int 2)
22606                                      (const_int 1) (const_int 3)]))
22607          (const_int 5)))]
22608   "TARGET_SSE2"
22609   "punpckhdq\t{%2, %0|%0, %2}"
22610   [(set_attr "type" "ssecvt")
22611    (set_attr "mode" "TI")])
22612
22613 (define_insn "sse2_punpcklbw"
22614   [(set (match_operand:V16QI 0 "register_operand" "=x")
22615         (vec_merge:V16QI
22616          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22617                            (parallel [(const_int 0) (const_int 8)
22618                                       (const_int 1) (const_int 9)
22619                                       (const_int 2) (const_int 10)
22620                                       (const_int 3) (const_int 11)
22621                                       (const_int 4) (const_int 12)
22622                                       (const_int 5) (const_int 13)
22623                                       (const_int 6) (const_int 14)
22624                                       (const_int 7) (const_int 15)]))
22625          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22626                            (parallel [(const_int 8) (const_int 0)
22627                                       (const_int 9) (const_int 1)
22628                                       (const_int 10) (const_int 2)
22629                                       (const_int 11) (const_int 3)
22630                                       (const_int 12) (const_int 4)
22631                                       (const_int 13) (const_int 5)
22632                                       (const_int 14) (const_int 6)
22633                                       (const_int 15) (const_int 7)]))
22634          (const_int 21845)))]
22635   "TARGET_SSE2"
22636   "punpcklbw\t{%2, %0|%0, %2}"
22637   [(set_attr "type" "ssecvt")
22638    (set_attr "mode" "TI")])
22639
22640 (define_insn "sse2_punpcklwd"
22641   [(set (match_operand:V8HI 0 "register_operand" "=x")
22642         (vec_merge:V8HI
22643          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22644                           (parallel [(const_int 0) (const_int 4)
22645                                      (const_int 1) (const_int 5)
22646                                      (const_int 2) (const_int 6)
22647                                      (const_int 3) (const_int 7)]))
22648          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22649                           (parallel [(const_int 4) (const_int 0)
22650                                      (const_int 5) (const_int 1)
22651                                      (const_int 6) (const_int 2)
22652                                      (const_int 7) (const_int 3)]))
22653          (const_int 85)))]
22654   "TARGET_SSE2"
22655   "punpcklwd\t{%2, %0|%0, %2}"
22656   [(set_attr "type" "ssecvt")
22657    (set_attr "mode" "TI")])
22658
22659 (define_insn "sse2_punpckldq"
22660   [(set (match_operand:V4SI 0 "register_operand" "=x")
22661         (vec_merge:V4SI
22662          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22663                           (parallel [(const_int 0) (const_int 2)
22664                                      (const_int 1) (const_int 3)]))
22665          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22666                           (parallel [(const_int 2) (const_int 0)
22667                                      (const_int 3) (const_int 1)]))
22668          (const_int 5)))]
22669   "TARGET_SSE2"
22670   "punpckldq\t{%2, %0|%0, %2}"
22671   [(set_attr "type" "ssecvt")
22672    (set_attr "mode" "TI")])
22673
22674 (define_insn "sse2_punpcklqdq"
22675   [(set (match_operand:V2DI 0 "register_operand" "=x")
22676         (vec_merge:V2DI
22677          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22678                           (parallel [(const_int 1)
22679                                      (const_int 0)]))
22680          (match_operand:V2DI 1 "register_operand" "0")
22681          (const_int 1)))]
22682   "TARGET_SSE2"
22683   "punpcklqdq\t{%2, %0|%0, %2}"
22684   [(set_attr "type" "ssecvt")
22685    (set_attr "mode" "TI")])
22686
22687 (define_insn "sse2_punpckhqdq"
22688   [(set (match_operand:V2DI 0 "register_operand" "=x")
22689         (vec_merge:V2DI
22690          (match_operand:V2DI 1 "register_operand" "0")
22691          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22692                           (parallel [(const_int 1)
22693                                      (const_int 0)]))
22694          (const_int 1)))]
22695   "TARGET_SSE2"
22696   "punpckhqdq\t{%2, %0|%0, %2}"
22697   [(set_attr "type" "ssecvt")
22698    (set_attr "mode" "TI")])
22699
22700 ;; SSE2 moves
22701
22702 (define_insn "sse2_movapd"
22703   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22704         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22705                      UNSPEC_MOVA))]
22706   "TARGET_SSE2
22707    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22708   "movapd\t{%1, %0|%0, %1}"
22709   [(set_attr "type" "ssemov")
22710    (set_attr "mode" "V2DF")])
22711
22712 (define_insn "sse2_movupd"
22713   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22714         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22715                      UNSPEC_MOVU))]
22716   "TARGET_SSE2
22717    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22718   "movupd\t{%1, %0|%0, %1}"
22719   [(set_attr "type" "ssecvt")
22720    (set_attr "mode" "V2DF")])
22721
22722 (define_insn "sse2_movdqa"
22723   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22724         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22725                        UNSPEC_MOVA))]
22726   "TARGET_SSE2
22727    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22728   "movdqa\t{%1, %0|%0, %1}"
22729   [(set_attr "type" "ssemov")
22730    (set_attr "mode" "TI")])
22731
22732 (define_insn "sse2_movdqu"
22733   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22734         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22735                        UNSPEC_MOVU))]
22736   "TARGET_SSE2
22737    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22738   "movdqu\t{%1, %0|%0, %1}"
22739   [(set_attr "type" "ssecvt")
22740    (set_attr "mode" "TI")])
22741
22742 (define_insn "sse2_movdq2q"
22743   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22744         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22745                        (parallel [(const_int 0)])))]
22746   "TARGET_SSE2 && !TARGET_64BIT"
22747   "@
22748    movq\t{%1, %0|%0, %1}
22749    movdq2q\t{%1, %0|%0, %1}"
22750   [(set_attr "type" "ssecvt")
22751    (set_attr "mode" "TI")])
22752
22753 (define_insn "sse2_movdq2q_rex64"
22754   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22755         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22756                        (parallel [(const_int 0)])))]
22757   "TARGET_SSE2 && TARGET_64BIT"
22758   "@
22759    movq\t{%1, %0|%0, %1}
22760    movdq2q\t{%1, %0|%0, %1}
22761    movd\t{%1, %0|%0, %1}"
22762   [(set_attr "type" "ssecvt")
22763    (set_attr "mode" "TI")])
22764
22765 (define_insn "sse2_movq2dq"
22766   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22767         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22768                          (const_int 0)))]
22769   "TARGET_SSE2 && !TARGET_64BIT"
22770   "@
22771    movq\t{%1, %0|%0, %1}
22772    movq2dq\t{%1, %0|%0, %1}"
22773   [(set_attr "type" "ssecvt,ssemov")
22774    (set_attr "mode" "TI")])
22775
22776 (define_insn "sse2_movq2dq_rex64"
22777   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22778         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22779                          (const_int 0)))]
22780   "TARGET_SSE2 && TARGET_64BIT"
22781   "@
22782    movq\t{%1, %0|%0, %1}
22783    movq2dq\t{%1, %0|%0, %1}
22784    movd\t{%1, %0|%0, %1}"
22785   [(set_attr "type" "ssecvt,ssemov,ssecvt")
22786    (set_attr "mode" "TI")])
22787
22788 (define_insn "sse2_movq"
22789   [(set (match_operand:V2DI 0 "register_operand" "=x")
22790         (vec_concat:V2DI (vec_select:DI
22791                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22792                           (parallel [(const_int 0)]))
22793                          (const_int 0)))]
22794   "TARGET_SSE2"
22795   "movq\t{%1, %0|%0, %1}"
22796   [(set_attr "type" "ssemov")
22797    (set_attr "mode" "TI")])
22798
22799 (define_insn "sse2_loadd"
22800   [(set (match_operand:V4SI 0 "register_operand" "=x")
22801         (vec_merge:V4SI
22802          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22803          (const_vector:V4SI [(const_int 0)
22804                              (const_int 0)
22805                              (const_int 0)
22806                              (const_int 0)])
22807          (const_int 1)))]
22808   "TARGET_SSE2"
22809   "movd\t{%1, %0|%0, %1}"
22810   [(set_attr "type" "ssemov")
22811    (set_attr "mode" "TI")])
22812
22813 (define_insn "sse2_stored"
22814   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22815         (vec_select:SI
22816          (match_operand:V4SI 1 "register_operand" "x")
22817          (parallel [(const_int 0)])))]
22818   "TARGET_SSE2"
22819   "movd\t{%1, %0|%0, %1}"
22820   [(set_attr "type" "ssemov")
22821    (set_attr "mode" "TI")])
22822
22823 (define_insn "sse2_movhpd"
22824   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22825         (vec_merge:V2DF
22826          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22827          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22828          (const_int 2)))]
22829   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22830   "movhpd\t{%2, %0|%0, %2}"
22831   [(set_attr "type" "ssecvt")
22832    (set_attr "mode" "V2DF")])
22833
22834 (define_expand "sse2_loadsd"
22835   [(match_operand:V2DF 0 "register_operand" "")
22836    (match_operand:DF 1 "memory_operand" "")]
22837   "TARGET_SSE2"
22838 {
22839   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22840                                 CONST0_RTX (V2DFmode)));
22841   DONE;
22842 })
22843
22844 (define_insn "sse2_loadsd_1"
22845   [(set (match_operand:V2DF 0 "register_operand" "=x")
22846         (vec_merge:V2DF
22847          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22848          (match_operand:V2DF 2 "const0_operand" "X")
22849          (const_int 1)))]
22850   "TARGET_SSE2"
22851   "movsd\t{%1, %0|%0, %1}"
22852   [(set_attr "type" "ssecvt")
22853    (set_attr "mode" "DF")])
22854
22855 (define_insn "sse2_movsd"
22856   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22857         (vec_merge:V2DF
22858          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22859          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22860          (const_int 1)))]
22861   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22862   "@movsd\t{%2, %0|%0, %2}
22863     movlpd\t{%2, %0|%0, %2}
22864     movlpd\t{%2, %0|%0, %2}"
22865   [(set_attr "type" "ssecvt")
22866    (set_attr "mode" "DF,V2DF,V2DF")])
22867
22868 (define_insn "sse2_storesd"
22869   [(set (match_operand:DF 0 "memory_operand" "=m")
22870         (vec_select:DF
22871          (match_operand:V2DF 1 "register_operand" "x")
22872          (parallel [(const_int 0)])))]
22873   "TARGET_SSE2"
22874   "movsd\t{%1, %0|%0, %1}"
22875   [(set_attr "type" "ssecvt")
22876    (set_attr "mode" "DF")])
22877
22878 (define_insn "sse2_shufpd"
22879   [(set (match_operand:V2DF 0 "register_operand" "=x")
22880         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22881                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22882                       (match_operand:SI 3 "immediate_operand" "i")]
22883                      UNSPEC_SHUFFLE))]
22884   "TARGET_SSE2"
22885   ;; @@@ check operand order for intel/nonintel syntax
22886   "shufpd\t{%3, %2, %0|%0, %2, %3}"
22887   [(set_attr "type" "ssecvt")
22888    (set_attr "mode" "V2DF")])
22889
22890 (define_insn "sse2_clflush"
22891   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22892                     UNSPECV_CLFLUSH)]
22893   "TARGET_SSE2"
22894   "clflush %0"
22895   [(set_attr "type" "sse")
22896    (set_attr "memory" "unknown")])
22897
22898 (define_expand "sse2_mfence"
22899   [(set (match_dup 0)
22900         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22901   "TARGET_SSE2"
22902 {
22903   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22904   MEM_VOLATILE_P (operands[0]) = 1;
22905 })
22906
22907 (define_insn "*mfence_insn"
22908   [(set (match_operand:BLK 0 "" "")
22909         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22910   "TARGET_SSE2"
22911   "mfence"
22912   [(set_attr "type" "sse")
22913    (set_attr "memory" "unknown")])
22914
22915 (define_expand "sse2_lfence"
22916   [(set (match_dup 0)
22917         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22918   "TARGET_SSE2"
22919 {
22920   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22921   MEM_VOLATILE_P (operands[0]) = 1;
22922 })
22923
22924 (define_insn "*lfence_insn"
22925   [(set (match_operand:BLK 0 "" "")
22926         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22927   "TARGET_SSE2"
22928   "lfence"
22929   [(set_attr "type" "sse")
22930    (set_attr "memory" "unknown")])
22931
22932 ;; PNI
22933
22934 (define_insn "mwait"
22935   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22936                      (match_operand:SI 1 "register_operand" "c")]
22937                     UNSPECV_MWAIT)]
22938   "TARGET_PNI"
22939   "mwait\t%0, %1"
22940   [(set_attr "length" "3")])
22941
22942 (define_insn "monitor"
22943   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22944                      (match_operand:SI 1 "register_operand" "c")
22945                      (match_operand:SI 2 "register_operand" "d")]
22946                     UNSPECV_MONITOR)]
22947   "TARGET_PNI"
22948   "monitor\t%0, %1, %2"
22949   [(set_attr "length" "3")])
22950
22951 ;; PNI arithmetic
22952
22953 (define_insn "addsubv4sf3"
22954   [(set (match_operand:V4SF 0 "register_operand" "=x")
22955         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22956                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22957                      UNSPEC_ADDSUB))]
22958   "TARGET_PNI"
22959   "addsubps\t{%2, %0|%0, %2}"
22960   [(set_attr "type" "sseadd")
22961    (set_attr "mode" "V4SF")])
22962
22963 (define_insn "addsubv2df3"
22964   [(set (match_operand:V2DF 0 "register_operand" "=x")
22965         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22966                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22967                      UNSPEC_ADDSUB))]
22968   "TARGET_PNI"
22969   "addsubpd\t{%2, %0|%0, %2}"
22970   [(set_attr "type" "sseadd")
22971    (set_attr "mode" "V2DF")])
22972
22973 (define_insn "haddv4sf3"
22974   [(set (match_operand:V4SF 0 "register_operand" "=x")
22975         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22976                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22977                      UNSPEC_HADD))]
22978   "TARGET_PNI"
22979   "haddps\t{%2, %0|%0, %2}"
22980   [(set_attr "type" "sseadd")
22981    (set_attr "mode" "V4SF")])
22982
22983 (define_insn "haddv2df3"
22984   [(set (match_operand:V2DF 0 "register_operand" "=x")
22985         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22986                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22987                      UNSPEC_HADD))]
22988   "TARGET_PNI"
22989   "haddpd\t{%2, %0|%0, %2}"
22990   [(set_attr "type" "sseadd")
22991    (set_attr "mode" "V2DF")])
22992
22993 (define_insn "hsubv4sf3"
22994   [(set (match_operand:V4SF 0 "register_operand" "=x")
22995         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22996                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22997                      UNSPEC_HSUB))]
22998   "TARGET_PNI"
22999   "hsubps\t{%2, %0|%0, %2}"
23000   [(set_attr "type" "sseadd")
23001    (set_attr "mode" "V4SF")])
23002
23003 (define_insn "hsubv2df3"
23004   [(set (match_operand:V2DF 0 "register_operand" "=x")
23005         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23006                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23007                      UNSPEC_HSUB))]
23008   "TARGET_PNI"
23009   "hsubpd\t{%2, %0|%0, %2}"
23010   [(set_attr "type" "sseadd")
23011    (set_attr "mode" "V2DF")])
23012
23013 (define_insn "movshdup"
23014   [(set (match_operand:V4SF 0 "register_operand" "=x")
23015         (unspec:V4SF
23016          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23017   "TARGET_PNI"
23018   "movshdup\t{%1, %0|%0, %1}"
23019   [(set_attr "type" "sse")
23020    (set_attr "mode" "V4SF")])
23021
23022 (define_insn "movsldup"
23023   [(set (match_operand:V4SF 0 "register_operand" "=x")
23024         (unspec:V4SF
23025          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23026   "TARGET_PNI"
23027   "movsldup\t{%1, %0|%0, %1}"
23028   [(set_attr "type" "sse")
23029    (set_attr "mode" "V4SF")])
23030
23031 (define_insn "lddqu"
23032   [(set (match_operand:V16QI 0 "register_operand" "=x")
23033         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23034                        UNSPEC_LDQQU))]
23035   "TARGET_PNI"
23036   "lddqu\t{%1, %0|%0, %1}"
23037   [(set_attr "type" "ssecvt")
23038    (set_attr "mode" "TI")])
23039
23040 (define_insn "loadddup"
23041   [(set (match_operand:V2DF 0 "register_operand" "=x")
23042         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23043   "TARGET_PNI"
23044   "movddup\t{%1, %0|%0, %1}"
23045   [(set_attr "type" "ssecvt")
23046    (set_attr "mode" "DF")])
23047
23048 (define_insn "movddup"
23049   [(set (match_operand:V2DF 0 "register_operand" "=x")
23050         (vec_duplicate:V2DF
23051          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23052                         (parallel [(const_int 0)]))))]
23053   "TARGET_PNI"
23054   "movddup\t{%1, %0|%0, %1}"
23055   [(set_attr "type" "ssecvt")
23056    (set_attr "mode" "DF")])