OSDN Git Service

* i386.md (cmpstr expander): Obey TARGET_INLINE_ALL_STRINGOPS
[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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_PROBE          10)
67    (UNSPEC_STACK_ALLOC          11)
68    (UNSPEC_SET_GOT              12)
69    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70
71    ; TLS support
72    (UNSPEC_TP                   15)
73    (UNSPEC_TLS_GD               16)
74    (UNSPEC_TLS_LD_BASE          17)
75
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_SIN                  21)
79    (UNSPEC_COS                  22)
80    (UNSPEC_FNSTSW               24)
81    (UNSPEC_SAHF                 25)
82    (UNSPEC_FSTCW                26)
83    (UNSPEC_ADD_CARRY            27)
84    (UNSPEC_FLDCW                28)
85
86    ; For SSE/MMX support:
87    (UNSPEC_FIX                  30)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FSCALE               67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
123
124    ; REP instruction
125    (UNSPEC_REP                  75)
126   ])
127
128 (define_constants
129   [(UNSPECV_BLOCKAGE            0)
130    (UNSPECV_EH_RETURN           13)
131    (UNSPECV_EMMS                31)
132    (UNSPECV_LDMXCSR             37)
133    (UNSPECV_STMXCSR             40)
134    (UNSPECV_FEMMS               46)
135    (UNSPECV_CLFLUSH             57)
136    (UNSPECV_ALIGN               68)
137    (UNSPECV_MONITOR             69)
138    (UNSPECV_MWAIT               70)
139   ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first.  This allows for better optimization.  For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type.  This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153   (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type.  Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158   "other,multi,
159    alu,alu1,negnot,imov,imovx,lea,
160    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161    icmp,test,ibr,setcc,icmov,
162    push,pop,call,callv,leave,
163    str,cld,
164    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165    sselog,sseiadd,sseishft,sseimul,
166    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168   (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173   (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178            (const_string "i387")
179          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181            (const_string "sse")
182          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183            (const_string "mmx")
184          (eq_attr "type" "other")
185            (const_string "unknown")]
186          (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191            (const_int 0)
192          (eq_attr "unit" "i387,sse,mmx")
193            (const_int 0)
194          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195                           imul,icmp,push,pop")
196            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197          (eq_attr "type" "imov,test")
198            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199          (eq_attr "type" "call")
200            (if_then_else (match_operand 0 "constant_call_address_operand" "")
201              (const_int 4)
202              (const_int 0))
203          (eq_attr "type" "callv")
204            (if_then_else (match_operand 1 "constant_call_address_operand" "")
205              (const_int 4)
206              (const_int 0))
207          ;; We don't know the size before shorten_branches.  Expect
208          ;; the instruction to fit for better scheduling.
209          (eq_attr "type" "ibr")
210            (const_int 1)
211          ]
212          (symbol_ref "/* Update immediate_length and other attributes! */
213                       abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218            (const_int 0)
219          (and (eq_attr "type" "call")
220               (match_operand 0 "constant_call_address_operand" ""))
221              (const_int 0)
222          (and (eq_attr "type" "callv")
223               (match_operand 1 "constant_call_address_operand" ""))
224              (const_int 0)
225          ]
226          (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230   (if_then_else (ior (eq_attr "mode" "HI")
231                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232     (const_int 1)
233     (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" "" 
237   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238     (const_int 1)
239     (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243   (if_then_else 
244     (ior (eq_attr "type" "imovx,setcc,icmov")
245          (eq_attr "unit" "sse,mmx"))
246     (const_int 1)
247     (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_rex" ""
251   (cond [(and (eq_attr "mode" "DI")
252               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253            (const_int 1)
254          (and (eq_attr "mode" "QI")
255               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256                   (const_int 0)))
257            (const_int 1)
258          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259              (const_int 0))
260            (const_int 1)
261         ]
262         (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266   (cond [(eq_attr "type" "str,cld,leave")
267            (const_int 0)
268          (eq_attr "unit" "i387")
269            (const_int 0)
270          (and (eq_attr "type" "incdec")
271               (ior (match_operand:SI 1 "register_operand" "")
272                    (match_operand:HI 1 "register_operand" "")))
273            (const_int 0)
274          (and (eq_attr "type" "push")
275               (not (match_operand 1 "memory_operand" "")))
276            (const_int 0)
277          (and (eq_attr "type" "pop")
278               (not (match_operand 0 "memory_operand" "")))
279            (const_int 0)
280          (and (eq_attr "type" "imov")
281               (and (match_operand 0 "register_operand" "")
282                    (match_operand 1 "immediate_operand" "")))
283            (const_int 0)
284          (and (eq_attr "type" "call")
285               (match_operand 0 "constant_call_address_operand" ""))
286              (const_int 0)
287          (and (eq_attr "type" "callv")
288               (match_operand 1 "constant_call_address_operand" ""))
289              (const_int 0)
290          ]
291          (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297   (cond [(eq_attr "type" "other,multi,fistp")
298            (const_int 16)
299          (eq_attr "type" "fcmp")
300            (const_int 4)
301          (eq_attr "unit" "i387")
302            (plus (const_int 2)
303                  (plus (attr "prefix_data16")
304                        (attr "length_address")))]
305          (plus (plus (attr "modrm")
306                      (plus (attr "prefix_0f")
307                            (plus (attr "prefix_rex")
308                                  (const_int 1))))
309                (plus (attr "prefix_rep")
310                      (plus (attr "prefix_data16")
311                            (plus (attr "length_immediate")
312                                  (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319   (cond [(eq_attr "type" "other,multi,str")
320            (const_string "unknown")
321          (eq_attr "type" "lea,fcmov,fpspc,cld")
322            (const_string "none")
323          (eq_attr "type" "fistp,leave")
324            (const_string "both")
325          (eq_attr "type" "push")
326            (if_then_else (match_operand 1 "memory_operand" "")
327              (const_string "both")
328              (const_string "store"))
329          (eq_attr "type" "pop")
330            (if_then_else (match_operand 0 "memory_operand" "")
331              (const_string "both")
332              (const_string "load"))
333          (eq_attr "type" "setcc")
334            (if_then_else (match_operand 0 "memory_operand" "")
335              (const_string "store")
336              (const_string "none"))
337          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338            (if_then_else (ior (match_operand 0 "memory_operand" "")
339                               (match_operand 1 "memory_operand" ""))
340              (const_string "load")
341              (const_string "none"))
342          (eq_attr "type" "ibr")
343            (if_then_else (match_operand 0 "memory_operand" "")
344              (const_string "load")
345              (const_string "none"))
346          (eq_attr "type" "call")
347            (if_then_else (match_operand 0 "constant_call_address_operand" "")
348              (const_string "none")
349              (const_string "load"))
350          (eq_attr "type" "callv")
351            (if_then_else (match_operand 1 "constant_call_address_operand" "")
352              (const_string "none")
353              (const_string "load"))
354          (and (eq_attr "type" "alu1,negnot,ishift1")
355               (match_operand 1 "memory_operand" ""))
356            (const_string "both")
357          (and (match_operand 0 "memory_operand" "")
358               (match_operand 1 "memory_operand" ""))
359            (const_string "both")
360          (match_operand 0 "memory_operand" "")
361            (const_string "store")
362          (match_operand 1 "memory_operand" "")
363            (const_string "load")
364          (and (eq_attr "type"
365                  "!alu1,negnot,ishift1,
366                    imov,imovx,icmp,test,
367                    fmov,fcmp,fsgn,
368                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369                    mmx,mmxmov,mmxcmp,mmxcvt")
370               (match_operand 2 "memory_operand" ""))
371            (const_string "load")
372          (and (eq_attr "type" "icmov")
373               (match_operand 3 "memory_operand" ""))
374            (const_string "load")
375         ]
376         (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381   (cond [(eq_attr "type" "other,multi")
382            (const_string "unknown")
383          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384               (and (match_operand 0 "memory_displacement_operand" "")
385                    (match_operand 1 "immediate_operand" "")))
386            (const_string "true")
387          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388               (and (match_operand 0 "memory_displacement_operand" "")
389                    (match_operand 2 "immediate_operand" "")))
390            (const_string "true")
391         ]
392         (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397   (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401   [(set_attr "length" "128")
402    (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416   [(set (reg:CC 17)
417         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418                     (match_operand:DI 1 "x86_64_general_operand" "")))]
419   ""
420 {
421   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422     operands[0] = force_reg (DImode, operands[0]);
423   ix86_compare_op0 = operands[0];
424   ix86_compare_op1 = operands[1];
425   DONE;
426 })
427
428 (define_expand "cmpsi"
429   [(set (reg:CC 17)
430         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431                     (match_operand:SI 1 "general_operand" "")))]
432   ""
433 {
434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435     operands[0] = force_reg (SImode, operands[0]);
436   ix86_compare_op0 = operands[0];
437   ix86_compare_op1 = operands[1];
438   DONE;
439 })
440
441 (define_expand "cmphi"
442   [(set (reg:CC 17)
443         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444                     (match_operand:HI 1 "general_operand" "")))]
445   ""
446 {
447   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448     operands[0] = force_reg (HImode, operands[0]);
449   ix86_compare_op0 = operands[0];
450   ix86_compare_op1 = operands[1];
451   DONE;
452 })
453
454 (define_expand "cmpqi"
455   [(set (reg:CC 17)
456         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457                     (match_operand:QI 1 "general_operand" "")))]
458   "TARGET_QIMODE_MATH"
459 {
460   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461     operands[0] = force_reg (QImode, operands[0]);
462   ix86_compare_op0 = operands[0];
463   ix86_compare_op1 = operands[1];
464   DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468   [(set (reg 17)
469         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470                  (match_operand:DI 1 "const0_operand" "n,n")))]
471   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472   "@
473    test{q}\t{%0, %0|%0, %0}
474    cmp{q}\t{%1, %0|%0, %1}"
475   [(set_attr "type" "test,icmp")
476    (set_attr "length_immediate" "0,1")
477    (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480   [(set (reg 17)
481         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483                  (const_int 0)))]
484   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485   "cmp{q}\t{%1, %0|%0, %1}"
486   [(set_attr "type" "icmp")
487    (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490   [(set (reg:CC 17)
491         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492                     (match_operand:DI 1 "general_operand" "")))]
493   "TARGET_64BIT"
494   "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497   [(set (reg 17)
498         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501   "cmp{q}\t{%1, %0|%0, %1}"
502   [(set_attr "type" "icmp")
503    (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507   [(set (reg 17)
508         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509                  (match_operand:SI 1 "const0_operand" "n,n")))]
510   "ix86_match_ccmode (insn, CCNOmode)"
511   "@
512    test{l}\t{%0, %0|%0, %0}
513    cmp{l}\t{%1, %0|%0, %1}"
514   [(set_attr "type" "test,icmp")
515    (set_attr "length_immediate" "0,1")
516    (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519   [(set (reg 17)
520         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521                            (match_operand:SI 1 "general_operand" "ri,mr"))
522                  (const_int 0)))]
523   "ix86_match_ccmode (insn, CCGOCmode)"
524   "cmp{l}\t{%1, %0|%0, %1}"
525   [(set_attr "type" "icmp")
526    (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529   [(set (reg:CC 17)
530         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531                     (match_operand:SI 1 "general_operand" "ri,mr")))]
532   ""
533   "")
534
535 (define_insn "*cmpsi_1_insn"
536   [(set (reg 17)
537         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538                  (match_operand:SI 1 "general_operand" "ri,mr")))]
539   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540     && ix86_match_ccmode (insn, CCmode)"
541   "cmp{l}\t{%1, %0|%0, %1}"
542   [(set_attr "type" "icmp")
543    (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546   [(set (reg 17)
547         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548                  (match_operand:HI 1 "const0_operand" "n,n")))]
549   "ix86_match_ccmode (insn, CCNOmode)"
550   "@
551    test{w}\t{%0, %0|%0, %0}
552    cmp{w}\t{%1, %0|%0, %1}"
553   [(set_attr "type" "test,icmp")
554    (set_attr "length_immediate" "0,1")
555    (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558   [(set (reg 17)
559         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560                            (match_operand:HI 1 "general_operand" "ri,mr"))
561                  (const_int 0)))]
562   "ix86_match_ccmode (insn, CCGOCmode)"
563   "cmp{w}\t{%1, %0|%0, %1}"
564   [(set_attr "type" "icmp")
565    (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568   [(set (reg 17)
569         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570                  (match_operand:HI 1 "general_operand" "ri,mr")))]
571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572    && ix86_match_ccmode (insn, CCmode)"
573   "cmp{w}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578   [(set (reg 17)
579         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580                  (match_operand:QI 1 "const0_operand" "n,n")))]
581   "ix86_match_ccmode (insn, CCNOmode)"
582   "@
583    test{b}\t{%0, %0|%0, %0}
584    cmp{b}\t{$0, %0|%0, 0}"
585   [(set_attr "type" "test,icmp")
586    (set_attr "length_immediate" "0,1")
587    (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590   [(set (reg 17)
591         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592                  (match_operand:QI 1 "general_operand" "qi,mq")))]
593   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594     && ix86_match_ccmode (insn, CCmode)"
595   "cmp{b}\t{%1, %0|%0, %1}"
596   [(set_attr "type" "icmp")
597    (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600   [(set (reg 17)
601         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602                            (match_operand:QI 1 "general_operand" "qi,mq"))
603                  (const_int 0)))]
604   "ix86_match_ccmode (insn, CCGOCmode)"
605   "cmp{b}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610   [(set (reg 17)
611         (compare
612           (match_operand:QI 0 "general_operand" "Qm")
613           (subreg:QI
614             (zero_extract:SI
615               (match_operand 1 "ext_register_operand" "Q")
616               (const_int 8)
617               (const_int 8)) 0)))]
618   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619   "cmp{b}\t{%h1, %0|%0, %h1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624   [(set (reg 17)
625         (compare
626           (match_operand:QI 0 "register_operand" "Q")
627           (subreg:QI
628             (zero_extract:SI
629               (match_operand 1 "ext_register_operand" "Q")
630               (const_int 8)
631               (const_int 8)) 0)))]
632   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633   "cmp{b}\t{%h1, %0|%0, %h1}"
634   [(set_attr "type" "icmp")
635    (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638   [(set (reg 17)
639         (compare
640           (subreg:QI
641             (zero_extract:SI
642               (match_operand 0 "ext_register_operand" "Q")
643               (const_int 8)
644               (const_int 8)) 0)
645           (match_operand:QI 1 "const0_operand" "n")))]
646   "ix86_match_ccmode (insn, CCNOmode)"
647   "test{b}\t%h0, %h0"
648   [(set_attr "type" "test")
649    (set_attr "length_immediate" "0")
650    (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653   [(set (reg:CC 17)
654         (compare:CC
655           (subreg:QI
656             (zero_extract:SI
657               (match_operand 0 "ext_register_operand" "")
658               (const_int 8)
659               (const_int 8)) 0)
660           (match_operand:QI 1 "general_operand" "")))]
661   ""
662   "")
663
664 (define_insn "cmpqi_ext_3_insn"
665   [(set (reg 17)
666         (compare
667           (subreg:QI
668             (zero_extract:SI
669               (match_operand 0 "ext_register_operand" "Q")
670               (const_int 8)
671               (const_int 8)) 0)
672           (match_operand:QI 1 "general_operand" "Qmn")))]
673   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674   "cmp{b}\t{%1, %h0|%h0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679   [(set (reg 17)
680         (compare
681           (subreg:QI
682             (zero_extract:SI
683               (match_operand 0 "ext_register_operand" "Q")
684               (const_int 8)
685               (const_int 8)) 0)
686           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688   "cmp{b}\t{%1, %h0|%h0, %1}"
689   [(set_attr "type" "icmp")
690    (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693   [(set (reg 17)
694         (compare
695           (subreg:QI
696             (zero_extract:SI
697               (match_operand 0 "ext_register_operand" "Q")
698               (const_int 8)
699               (const_int 8)) 0)
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %h0|%h0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares.  Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716   [(set (reg:CC 17)
717         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719   "TARGET_80387"
720 {
721   ix86_compare_op0 = operands[0];
722   ix86_compare_op1 = operands[1];
723   DONE;
724 })
725
726 (define_expand "cmpdf"
727   [(set (reg:CC 17)
728         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730   "TARGET_80387 || TARGET_SSE2"
731 {
732   ix86_compare_op0 = operands[0];
733   ix86_compare_op1 = operands[1];
734   DONE;
735 })
736
737 (define_expand "cmpsf"
738   [(set (reg:CC 17)
739         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741   "TARGET_80387 || TARGET_SSE"
742 {
743   ix86_compare_op0 = operands[0];
744   ix86_compare_op1 = operands[1];
745   DONE;
746 })
747
748 ;; FP compares, step 1:
749 ;; Set the FP condition codes.
750 ;;
751 ;; CCFPmode     compare with exceptions
752 ;; CCFPUmode    compare with no exceptions
753
754 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755 ;; and that fp moves clobber the condition codes, and that there is
756 ;; currently no way to describe this fact to reg-stack.  So there are
757 ;; no splitters yet for this.
758
759 ;; %%% YIKES!  This scheme does not retain a strong connection between 
760 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761 ;; work!  Only allow tos/mem with tos in op 0.
762 ;;
763 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
764 ;; things aren't as bad as they sound...
765
766 (define_insn "*cmpfp_0"
767   [(set (match_operand:HI 0 "register_operand" "=a")
768         (unspec:HI
769           [(compare:CCFP (match_operand 1 "register_operand" "f")
770                          (match_operand 2 "const0_operand" "X"))]
771           UNSPEC_FNSTSW))]
772   "TARGET_80387
773    && FLOAT_MODE_P (GET_MODE (operands[1]))
774    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775 {
776   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777     return "ftst\;fnstsw\t%0\;fstp\t%y0";
778   else
779     return "ftst\;fnstsw\t%0";
780 }
781   [(set_attr "type" "multi")
782    (set (attr "mode")
783      (cond [(match_operand:SF 1 "" "")
784               (const_string "SF")
785             (match_operand:DF 1 "" "")
786               (const_string "DF")
787            ]
788            (const_string "XF")))])
789
790 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
791 ;; used to manage the reg stack popping would not be preserved.
792
793 (define_insn "*cmpfp_2_sf"
794   [(set (reg:CCFP 18)
795         (compare:CCFP
796           (match_operand:SF 0 "register_operand" "f")
797           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798   "TARGET_80387"
799   "* return output_fp_compare (insn, operands, 0, 0);"
800   [(set_attr "type" "fcmp")
801    (set_attr "mode" "SF")])
802
803 (define_insn "*cmpfp_2_sf_1"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809           UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 2, 0);"
812   [(set_attr "type" "fcmp")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_2_df"
816   [(set (reg:CCFP 18)
817         (compare:CCFP
818           (match_operand:DF 0 "register_operand" "f")
819           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820   "TARGET_80387"
821   "* return output_fp_compare (insn, operands, 0, 0);"
822   [(set_attr "type" "fcmp")
823    (set_attr "mode" "DF")])
824
825 (define_insn "*cmpfp_2_df_1"
826   [(set (match_operand:HI 0 "register_operand" "=a")
827         (unspec:HI
828           [(compare:CCFP
829              (match_operand:DF 1 "register_operand" "f")
830              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831           UNSPEC_FNSTSW))]
832   "TARGET_80387"
833   "* return output_fp_compare (insn, operands, 2, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_2_xf"
838   [(set (reg:CCFP 18)
839         (compare:CCFP
840           (match_operand:XF 0 "register_operand" "f")
841           (match_operand:XF 1 "register_operand" "f")))]
842   "TARGET_80387"
843   "* return output_fp_compare (insn, operands, 0, 0);"
844   [(set_attr "type" "fcmp")
845    (set_attr "mode" "XF")])
846
847 (define_insn "*cmpfp_2_xf_1"
848   [(set (match_operand:HI 0 "register_operand" "=a")
849         (unspec:HI
850           [(compare:CCFP
851              (match_operand:XF 1 "register_operand" "f")
852              (match_operand:XF 2 "register_operand" "f"))]
853           UNSPEC_FNSTSW))]
854   "TARGET_80387"
855   "* return output_fp_compare (insn, operands, 2, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2u"
860   [(set (reg:CCFPU 18)
861         (compare:CCFPU
862           (match_operand 0 "register_operand" "f")
863           (match_operand 1 "register_operand" "f")))]
864   "TARGET_80387
865    && FLOAT_MODE_P (GET_MODE (operands[0]))
866    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867   "* return output_fp_compare (insn, operands, 0, 1);"
868   [(set_attr "type" "fcmp")
869    (set (attr "mode")
870      (cond [(match_operand:SF 1 "" "")
871               (const_string "SF")
872             (match_operand:DF 1 "" "")
873               (const_string "DF")
874            ]
875            (const_string "XF")))])
876
877 (define_insn "*cmpfp_2u_1"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFPU
881              (match_operand 1 "register_operand" "f")
882              (match_operand 2 "register_operand" "f"))]
883           UNSPEC_FNSTSW))]
884   "TARGET_80387
885    && FLOAT_MODE_P (GET_MODE (operands[1]))
886    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887   "* return output_fp_compare (insn, operands, 2, 1);"
888   [(set_attr "type" "multi")
889    (set (attr "mode")
890      (cond [(match_operand:SF 1 "" "")
891               (const_string "SF")
892             (match_operand:DF 1 "" "")
893               (const_string "DF")
894            ]
895            (const_string "XF")))])
896
897 ;; Patterns to match the SImode-in-memory ficom instructions.
898 ;;
899 ;; %%% Play games with accepting gp registers, as otherwise we have to
900 ;; force them to memory during rtl generation, which is no good.  We
901 ;; can get rid of this once we teach reload to do memory input reloads 
902 ;; via pushes.
903
904 (define_insn "*ficom_1"
905   [(set (reg:CCFP 18)
906         (compare:CCFP
907           (match_operand 0 "register_operand" "f,f")
908           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911   "#")
912
913 ;; Split the not-really-implemented gp register case into a
914 ;; push-op-pop sequence.
915 ;;
916 ;; %%% This is most efficient, but am I gonna get in trouble
917 ;; for separating cc0_setter and cc0_user?
918
919 (define_split
920   [(set (reg:CCFP 18)
921         (compare:CCFP
922           (match_operand:SF 0 "register_operand" "")
923           (float (match_operand:SI 1 "register_operand" ""))))]
924   "0 && TARGET_80387 && reload_completed"
925   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932 ;; FP compares, step 2
933 ;; Move the fpsw to ax.
934
935 (define_insn "*x86_fnstsw_1"
936   [(set (match_operand:HI 0 "register_operand" "=a")
937         (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938   "TARGET_80387"
939   "fnstsw\t%0"
940   [(set_attr "length" "2")
941    (set_attr "mode" "SI")
942    (set_attr "unit" "i387")
943    (set_attr "ppro_uops" "few")])
944
945 ;; FP compares, step 3
946 ;; Get ax into flags, general case.
947
948 (define_insn "x86_sahf_1"
949   [(set (reg:CC 17)
950         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951   "!TARGET_64BIT"
952   "sahf"
953   [(set_attr "length" "1")
954    (set_attr "athlon_decode" "vector")
955    (set_attr "mode" "SI")
956    (set_attr "ppro_uops" "one")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i"
961   [(set (reg:CCFP 17)
962         (compare:CCFP (match_operand 0 "register_operand" "f")
963                       (match_operand 1 "register_operand" "f")))]
964   "TARGET_80387 && TARGET_CMOVE
965    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966    && FLOAT_MODE_P (GET_MODE (operands[0]))
967    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968   "* return output_fp_compare (insn, operands, 1, 0);"
969   [(set_attr "type" "fcmp")
970    (set (attr "mode")
971      (cond [(match_operand:SF 1 "" "")
972               (const_string "SF")
973             (match_operand:DF 1 "" "")
974               (const_string "DF")
975            ]
976            (const_string "XF")))
977    (set_attr "athlon_decode" "vector")])
978
979 (define_insn "*cmpfp_i_sse"
980   [(set (reg:CCFP 17)
981         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983   "TARGET_80387
984    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986   "* return output_fp_compare (insn, operands, 1, 0);"
987   [(set_attr "type" "fcmp,ssecomi")
988    (set (attr "mode")
989      (if_then_else (match_operand:SF 1 "" "")
990         (const_string "SF")
991         (const_string "DF")))
992    (set_attr "athlon_decode" "vector")])
993
994 (define_insn "*cmpfp_i_sse_only"
995   [(set (reg:CCFP 17)
996         (compare:CCFP (match_operand 0 "register_operand" "x")
997                       (match_operand 1 "nonimmediate_operand" "xm")))]
998   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")])
1007
1008 (define_insn "*cmpfp_iu"
1009   [(set (reg:CCFPU 17)
1010         (compare:CCFPU (match_operand 0 "register_operand" "f")
1011                        (match_operand 1 "register_operand" "f")))]
1012   "TARGET_80387 && TARGET_CMOVE
1013    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014    && FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 1);"
1017   [(set_attr "type" "fcmp")
1018    (set (attr "mode")
1019      (cond [(match_operand:SF 1 "" "")
1020               (const_string "SF")
1021             (match_operand:DF 1 "" "")
1022               (const_string "DF")
1023            ]
1024            (const_string "XF")))
1025    (set_attr "athlon_decode" "vector")])
1026
1027 (define_insn "*cmpfp_iu_sse"
1028   [(set (reg:CCFPU 17)
1029         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031   "TARGET_80387
1032    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 1);"
1035   [(set_attr "type" "fcmp,ssecomi")
1036    (set (attr "mode")
1037      (if_then_else (match_operand:SF 1 "" "")
1038         (const_string "SF")
1039         (const_string "DF")))
1040    (set_attr "athlon_decode" "vector")])
1041
1042 (define_insn "*cmpfp_iu_sse_only"
1043   [(set (reg:CCFPU 17)
1044         (compare:CCFPU (match_operand 0 "register_operand" "x")
1045                        (match_operand 1 "nonimmediate_operand" "xm")))]
1046   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048   "* return output_fp_compare (insn, operands, 1, 1);"
1049   [(set_attr "type" "ssecomi")
1050    (set (attr "mode")
1051      (if_then_else (match_operand:SF 1 "" "")
1052         (const_string "SF")
1053         (const_string "DF")))
1054    (set_attr "athlon_decode" "vector")])
1055 \f
1056 ;; Move instructions.
1057
1058 ;; General case of fullword move.
1059
1060 (define_expand "movsi"
1061   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062         (match_operand:SI 1 "general_operand" ""))]
1063   ""
1064   "ix86_expand_move (SImode, operands); DONE;")
1065
1066 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1067 ;; general_operand.
1068 ;;
1069 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1070 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072 ;; targets without our curiosities, and it is just as easy to represent
1073 ;; this differently.
1074
1075 (define_insn "*pushsi2"
1076   [(set (match_operand:SI 0 "push_operand" "=<")
1077         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078   "!TARGET_64BIT"
1079   "push{l}\t%1"
1080   [(set_attr "type" "push")
1081    (set_attr "mode" "SI")])
1082
1083 ;; For 64BIT abi we always round up to 8 bytes.
1084 (define_insn "*pushsi2_rex64"
1085   [(set (match_operand:SI 0 "push_operand" "=X")
1086         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087   "TARGET_64BIT"
1088   "push{q}\t%q1"
1089   [(set_attr "type" "push")
1090    (set_attr "mode" "SI")])
1091
1092 (define_insn "*pushsi2_prologue"
1093   [(set (match_operand:SI 0 "push_operand" "=<")
1094         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095    (clobber (mem:BLK (scratch)))]
1096   "!TARGET_64BIT"
1097   "push{l}\t%1"
1098   [(set_attr "type" "push")
1099    (set_attr "mode" "SI")])
1100
1101 (define_insn "*popsi1_epilogue"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103         (mem:SI (reg:SI 7)))
1104    (set (reg:SI 7)
1105         (plus:SI (reg:SI 7) (const_int 4)))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "pop{l}\t%0"
1109   [(set_attr "type" "pop")
1110    (set_attr "mode" "SI")])
1111
1112 (define_insn "popsi1"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI 7)))
1115    (set (reg:SI 7)
1116         (plus:SI (reg:SI 7) (const_int 4)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "*movsi_xor"
1123   [(set (match_operand:SI 0 "register_operand" "=r")
1124         (match_operand:SI 1 "const0_operand" "i"))
1125    (clobber (reg:CC 17))]
1126   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127   "xor{l}\t{%0, %0|%0, %0}"
1128   [(set_attr "type" "alu1")
1129    (set_attr "mode" "SI")
1130    (set_attr "length_immediate" "0")])
1131  
1132 (define_insn "*movsi_or"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "immediate_operand" "i"))
1135    (clobber (reg:CC 17))]
1136   "reload_completed
1137    && operands[1] == constm1_rtx
1138    && (TARGET_PENTIUM || optimize_size)"
1139 {
1140   operands[1] = constm1_rtx;
1141   return "or{l}\t{%1, %0|%0, %1}";
1142 }
1143   [(set_attr "type" "alu1")
1144    (set_attr "mode" "SI")
1145    (set_attr "length_immediate" "1")])
1146
1147 (define_insn "*movsi_1"
1148   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152 {
1153   switch (get_attr_type (insn))
1154     {
1155     case TYPE_SSEMOV:
1156       if (get_attr_mode (insn) == MODE_TI)
1157         return "movdqa\t{%1, %0|%0, %1}";
1158       return "movd\t{%1, %0|%0, %1}";
1159
1160     case TYPE_MMXMOV:
1161       if (get_attr_mode (insn) == MODE_DI)
1162         return "movq\t{%1, %0|%0, %1}";
1163       return "movd\t{%1, %0|%0, %1}";
1164
1165     case TYPE_LEA:
1166       return "lea{l}\t{%1, %0|%0, %1}";
1167
1168     default:
1169       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170         abort();
1171       return "mov{l}\t{%1, %0|%0, %1}";
1172     }
1173 }
1174   [(set (attr "type")
1175      (cond [(eq_attr "alternative" "2,3,4")
1176               (const_string "mmxmov")
1177             (eq_attr "alternative" "5,6,7")
1178               (const_string "ssemov")
1179             (and (ne (symbol_ref "flag_pic") (const_int 0))
1180                  (match_operand:SI 1 "symbolic_operand" ""))
1181               (const_string "lea")
1182            ]
1183            (const_string "imov")))
1184    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186 (define_insn "*movsi_1_nointernunit"
1187   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191 {
1192   switch (get_attr_type (insn))
1193     {
1194     case TYPE_SSEMOV:
1195       if (get_attr_mode (insn) == MODE_TI)
1196         return "movdqa\t{%1, %0|%0, %1}";
1197       return "movd\t{%1, %0|%0, %1}";
1198
1199     case TYPE_MMXMOV:
1200       if (get_attr_mode (insn) == MODE_DI)
1201         return "movq\t{%1, %0|%0, %1}";
1202       return "movd\t{%1, %0|%0, %1}";
1203
1204     case TYPE_LEA:
1205       return "lea{l}\t{%1, %0|%0, %1}";
1206
1207     default:
1208       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209         abort();
1210       return "mov{l}\t{%1, %0|%0, %1}";
1211     }
1212 }
1213   [(set (attr "type")
1214      (cond [(eq_attr "alternative" "2,3,4")
1215               (const_string "mmxmov")
1216             (eq_attr "alternative" "5,6,7")
1217               (const_string "ssemov")
1218             (and (ne (symbol_ref "flag_pic") (const_int 0))
1219                  (match_operand:SI 1 "symbolic_operand" ""))
1220               (const_string "lea")
1221            ]
1222            (const_string "imov")))
1223    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225 ;; Stores and loads of ax to arbitrary constant address.
1226 ;; We fake an second form of instruction to force reload to load address
1227 ;; into register when rax is not available
1228 (define_insn "*movabssi_1_rex64"
1229   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232   "@
1233    movabs{l}\t{%1, %P0|%P0, %1}
1234    mov{l}\t{%1, %a0|%a0, %1}"
1235   [(set_attr "type" "imov")
1236    (set_attr "modrm" "0,*")
1237    (set_attr "length_address" "8,0")
1238    (set_attr "length_immediate" "0,*")
1239    (set_attr "memory" "store")
1240    (set_attr "mode" "SI")])
1241
1242 (define_insn "*movabssi_2_rex64"
1243   [(set (match_operand:SI 0 "register_operand" "=a,r")
1244         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246   "@
1247    movabs{l}\t{%P1, %0|%0, %P1}
1248    mov{l}\t{%a1, %0|%0, %a1}"
1249   [(set_attr "type" "imov")
1250    (set_attr "modrm" "0,*")
1251    (set_attr "length_address" "8,0")
1252    (set_attr "length_immediate" "0")
1253    (set_attr "memory" "load")
1254    (set_attr "mode" "SI")])
1255
1256 (define_insn "*swapsi"
1257   [(set (match_operand:SI 0 "register_operand" "+r")
1258         (match_operand:SI 1 "register_operand" "+r"))
1259    (set (match_dup 1)
1260         (match_dup 0))]
1261   ""
1262   "xchg{l}\t%1, %0"
1263   [(set_attr "type" "imov")
1264    (set_attr "pent_pair" "np")
1265    (set_attr "athlon_decode" "vector")
1266    (set_attr "mode" "SI")
1267    (set_attr "modrm" "0")
1268    (set_attr "ppro_uops" "few")])
1269
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=<,<")
1278         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279   "!TARGET_64BIT"
1280   "@
1281    push{w}\t{|WORD PTR }%1
1282    push{w}\t%1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(and (eq_attr "alternative" "0")
1315                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316                           (const_int 0))
1317                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1318                           (const_int 0))))
1319               (const_string "imov")
1320             (and (eq_attr "alternative" "1,2")
1321                  (match_operand:HI 1 "aligned_operand" ""))
1322               (const_string "imov")
1323             (and (ne (symbol_ref "TARGET_MOVX")
1324                      (const_int 0))
1325                  (eq_attr "alternative" "0,2"))
1326               (const_string "imovx")
1327            ]
1328            (const_string "imov")))
1329     (set (attr "mode")
1330       (cond [(eq_attr "type" "imovx")
1331                (const_string "SI")
1332              (and (eq_attr "alternative" "1,2")
1333                   (match_operand:HI 1 "aligned_operand" ""))
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "0")
1336                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337                            (const_int 0))
1338                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1339                            (const_int 0))))
1340                (const_string "SI")
1341             ]
1342             (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351   "@
1352    movabs{w}\t{%1, %P0|%P0, %1}
1353    mov{w}\t{%1, %a0|%a0, %1}"
1354   [(set_attr "type" "imov")
1355    (set_attr "modrm" "0,*")
1356    (set_attr "length_address" "8,0")
1357    (set_attr "length_immediate" "0,*")
1358    (set_attr "memory" "store")
1359    (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362   [(set (match_operand:HI 0 "register_operand" "=a,r")
1363         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365   "@
1366    movabs{w}\t{%P1, %0|%0, %P1}
1367    mov{w}\t{%a1, %0|%0, %a1}"
1368   [(set_attr "type" "imov")
1369    (set_attr "modrm" "0,*")
1370    (set_attr "length_address" "8,0")
1371    (set_attr "length_immediate" "0")
1372    (set_attr "memory" "load")
1373    (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376   [(set (match_operand:HI 0 "register_operand" "+r")
1377         (match_operand:HI 1 "register_operand" "+r"))
1378    (set (match_dup 1)
1379         (match_dup 0))]
1380   "TARGET_PARTIAL_REG_STALL"
1381   "xchg{w}\t%1, %0"
1382   [(set_attr "type" "imov")
1383    (set_attr "pent_pair" "np")
1384    (set_attr "mode" "HI")
1385    (set_attr "modrm" "0")
1386    (set_attr "ppro_uops" "few")])
1387
1388 (define_insn "*swaphi_2"
1389   [(set (match_operand:HI 0 "register_operand" "+r")
1390         (match_operand:HI 1 "register_operand" "+r"))
1391    (set (match_dup 1)
1392         (match_dup 0))]
1393   "! TARGET_PARTIAL_REG_STALL"
1394   "xchg{l}\t%k1, %k0"
1395   [(set_attr "type" "imov")
1396    (set_attr "pent_pair" "np")
1397    (set_attr "mode" "SI")
1398    (set_attr "modrm" "0")
1399    (set_attr "ppro_uops" "few")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC 17))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X,X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444   "!TARGET_64BIT"
1445   "@
1446    push{w}\t{|word ptr }%1
1447    push{w}\t%w1"
1448   [(set_attr "type" "push")
1449    (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453   [(set (match_operand:QI 0 "push_operand" "=X")
1454         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455   "TARGET_64BIT"
1456   "push{q}\t%q1"
1457   [(set_attr "type" "push")
1458    (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there.  Then we use movzx.
1470 (define_insn "*movqi_1"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1473   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475   switch (get_attr_type (insn))
1476     {
1477     case TYPE_IMOVX:
1478       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1479         abort ();
1480       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481     default:
1482       if (get_attr_mode (insn) == MODE_SI)
1483         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484       else
1485         return "mov{b}\t{%1, %0|%0, %1}";
1486     }
1487 }
1488   [(set (attr "type")
1489      (cond [(and (eq_attr "alternative" "3")
1490                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491                           (const_int 0))
1492                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1493                           (const_int 0))))
1494               (const_string "imov")
1495             (eq_attr "alternative" "3,5")
1496               (const_string "imovx")
1497             (and (ne (symbol_ref "TARGET_MOVX")
1498                      (const_int 0))
1499                  (eq_attr "alternative" "2"))
1500               (const_string "imovx")
1501            ]
1502            (const_string "imov")))
1503    (set (attr "mode")
1504       (cond [(eq_attr "alternative" "3,4,5")
1505                (const_string "SI")
1506              (eq_attr "alternative" "6")
1507                (const_string "QI")
1508              (eq_attr "type" "imovx")
1509                (const_string "SI")
1510              (and (eq_attr "type" "imov")
1511                   (and (eq_attr "alternative" "0,1,2")
1512                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513                            (const_int 0))))
1514                (const_string "SI")
1515              ;; Avoid partial register stalls when not using QImode arithmetic
1516              (and (eq_attr "type" "imov")
1517                   (and (eq_attr "alternative" "0,1,2")
1518                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                 (const_int 0))
1520                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1521                                 (const_int 0)))))
1522                (const_string "SI")
1523            ]
1524            (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527   [(parallel [(match_operand:QI 0 "" "=m")
1528               (match_operand:QI 1 "register_operand" "r")
1529               (match_operand:QI 2 "register_operand" "=&q")])]
1530   ""
1531 {
1532   rtx op0, op1, op2;
1533   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535   if (reg_overlap_mentioned_p (op2, op0))
1536     abort ();
1537   if (! q_regs_operand (op1, QImode))
1538     {
1539       emit_insn (gen_movqi (op2, op1));
1540       op1 = op2;
1541     }
1542   emit_insn (gen_movqi (op0, op1));
1543   DONE;
1544 })
1545
1546 (define_insn "*swapqi"
1547   [(set (match_operand:QI 0 "register_operand" "+r")
1548         (match_operand:QI 1 "register_operand" "+r"))
1549    (set (match_dup 1)
1550         (match_dup 0))]
1551   ""
1552   "xchg{b}\t%1, %0"
1553   [(set_attr "type" "imov")
1554    (set_attr "pent_pair" "np")
1555    (set_attr "mode" "QI")
1556    (set_attr "modrm" "0")
1557    (set_attr "ppro_uops" "few")])
1558
1559 (define_expand "movstrictqi"
1560   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1561         (match_operand:QI 1 "general_operand" ""))]
1562   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1563 {
1564   /* Don't generate memory->memory moves, go through a register.  */
1565   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1566     operands[1] = force_reg (QImode, operands[1]);
1567 })
1568
1569 (define_insn "*movstrictqi_1"
1570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1571         (match_operand:QI 1 "general_operand" "*qn,m"))]
1572   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1573    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1574   "mov{b}\t{%1, %0|%0, %1}"
1575   [(set_attr "type" "imov")
1576    (set_attr "mode" "QI")])
1577
1578 (define_insn "*movstrictqi_xor"
1579   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1580         (match_operand:QI 1 "const0_operand" "i"))
1581    (clobber (reg:CC 17))]
1582   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1583   "xor{b}\t{%0, %0|%0, %0}"
1584   [(set_attr "type" "alu1")
1585    (set_attr "mode" "QI")
1586    (set_attr "length_immediate" "0")])
1587
1588 (define_insn "*movsi_extv_1"
1589   [(set (match_operand:SI 0 "register_operand" "=R")
1590         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1591                          (const_int 8)
1592                          (const_int 8)))]
1593   ""
1594   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1595   [(set_attr "type" "imovx")
1596    (set_attr "mode" "SI")])
1597
1598 (define_insn "*movhi_extv_1"
1599   [(set (match_operand:HI 0 "register_operand" "=R")
1600         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1601                          (const_int 8)
1602                          (const_int 8)))]
1603   ""
1604   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1605   [(set_attr "type" "imovx")
1606    (set_attr "mode" "SI")])
1607
1608 (define_insn "*movqi_extv_1"
1609   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1610         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1611                          (const_int 8)
1612                          (const_int 8)))]
1613   "!TARGET_64BIT"
1614 {
1615   switch (get_attr_type (insn))
1616     {
1617     case TYPE_IMOVX:
1618       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1619     default:
1620       return "mov{b}\t{%h1, %0|%0, %h1}";
1621     }
1622 }
1623   [(set (attr "type")
1624      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1625                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1626                              (ne (symbol_ref "TARGET_MOVX")
1627                                  (const_int 0))))
1628         (const_string "imovx")
1629         (const_string "imov")))
1630    (set (attr "mode")
1631      (if_then_else (eq_attr "type" "imovx")
1632         (const_string "SI")
1633         (const_string "QI")))])
1634
1635 (define_insn "*movqi_extv_1_rex64"
1636   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1637         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638                          (const_int 8)
1639                          (const_int 8)))]
1640   "TARGET_64BIT"
1641 {
1642   switch (get_attr_type (insn))
1643     {
1644     case TYPE_IMOVX:
1645       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1646     default:
1647       return "mov{b}\t{%h1, %0|%0, %h1}";
1648     }
1649 }
1650   [(set (attr "type")
1651      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1652                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1653                              (ne (symbol_ref "TARGET_MOVX")
1654                                  (const_int 0))))
1655         (const_string "imovx")
1656         (const_string "imov")))
1657    (set (attr "mode")
1658      (if_then_else (eq_attr "type" "imovx")
1659         (const_string "SI")
1660         (const_string "QI")))])
1661
1662 ;; Stores and loads of ax to arbitrary constant address.
1663 ;; We fake an second form of instruction to force reload to load address
1664 ;; into register when rax is not available
1665 (define_insn "*movabsqi_1_rex64"
1666   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1667         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1668   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1669   "@
1670    movabs{b}\t{%1, %P0|%P0, %1}
1671    mov{b}\t{%1, %a0|%a0, %1}"
1672   [(set_attr "type" "imov")
1673    (set_attr "modrm" "0,*")
1674    (set_attr "length_address" "8,0")
1675    (set_attr "length_immediate" "0,*")
1676    (set_attr "memory" "store")
1677    (set_attr "mode" "QI")])
1678
1679 (define_insn "*movabsqi_2_rex64"
1680   [(set (match_operand:QI 0 "register_operand" "=a,r")
1681         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1682   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1683   "@
1684    movabs{b}\t{%P1, %0|%0, %P1}
1685    mov{b}\t{%a1, %0|%0, %a1}"
1686   [(set_attr "type" "imov")
1687    (set_attr "modrm" "0,*")
1688    (set_attr "length_address" "8,0")
1689    (set_attr "length_immediate" "0")
1690    (set_attr "memory" "load")
1691    (set_attr "mode" "QI")])
1692
1693 (define_insn "*movsi_extzv_1"
1694   [(set (match_operand:SI 0 "register_operand" "=R")
1695         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1696                          (const_int 8)
1697                          (const_int 8)))]
1698   ""
1699   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1700   [(set_attr "type" "imovx")
1701    (set_attr "mode" "SI")])
1702
1703 (define_insn "*movqi_extzv_2"
1704   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1705         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1706                                     (const_int 8)
1707                                     (const_int 8)) 0))]
1708   "!TARGET_64BIT"
1709 {
1710   switch (get_attr_type (insn))
1711     {
1712     case TYPE_IMOVX:
1713       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1714     default:
1715       return "mov{b}\t{%h1, %0|%0, %h1}";
1716     }
1717 }
1718   [(set (attr "type")
1719      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721                              (ne (symbol_ref "TARGET_MOVX")
1722                                  (const_int 0))))
1723         (const_string "imovx")
1724         (const_string "imov")))
1725    (set (attr "mode")
1726      (if_then_else (eq_attr "type" "imovx")
1727         (const_string "SI")
1728         (const_string "QI")))])
1729
1730 (define_insn "*movqi_extzv_2_rex64"
1731   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "TARGET_64BIT"
1736 {
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1744 }
1745   [(set (attr "type")
1746      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747                         (ne (symbol_ref "TARGET_MOVX")
1748                             (const_int 0)))
1749         (const_string "imovx")
1750         (const_string "imov")))
1751    (set (attr "mode")
1752      (if_then_else (eq_attr "type" "imovx")
1753         (const_string "SI")
1754         (const_string "QI")))])
1755
1756 (define_insn "movsi_insv_1"
1757   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1758                          (const_int 8)
1759                          (const_int 8))
1760         (match_operand:SI 1 "general_operand" "Qmn"))]
1761   "!TARGET_64BIT"
1762   "mov{b}\t{%b1, %h0|%h0, %b1}"
1763   [(set_attr "type" "imov")
1764    (set_attr "mode" "QI")])
1765
1766 (define_insn "*movsi_insv_1_rex64"
1767   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1768                          (const_int 8)
1769                          (const_int 8))
1770         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1771   "TARGET_64BIT"
1772   "mov{b}\t{%b1, %h0|%h0, %b1}"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "QI")])
1775
1776 (define_insn "*movqi_insv_2"
1777   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778                          (const_int 8)
1779                          (const_int 8))
1780         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1781                              (const_int 8))
1782                 (const_int 255)))]
1783   ""
1784   "mov{b}\t{%h1, %h0|%h0, %h1}"
1785   [(set_attr "type" "imov")
1786    (set_attr "mode" "QI")])
1787
1788 (define_expand "movdi"
1789   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1790         (match_operand:DI 1 "general_operand" ""))]
1791   ""
1792   "ix86_expand_move (DImode, operands); DONE;")
1793
1794 (define_insn "*pushdi"
1795   [(set (match_operand:DI 0 "push_operand" "=<")
1796         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1797   "!TARGET_64BIT"
1798   "#")
1799
1800 (define_insn "pushdi2_rex64"
1801   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1802         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1803   "TARGET_64BIT"
1804   "@
1805    push{q}\t%1
1806    #"
1807   [(set_attr "type" "push,multi")
1808    (set_attr "mode" "DI")])
1809
1810 ;; Convert impossible pushes of immediate to existing instructions.
1811 ;; First try to get scratch register and go through it.  In case this
1812 ;; fails, push sign extended lower part first and then overwrite
1813 ;; upper part by 32bit move.
1814 (define_peephole2
1815   [(match_scratch:DI 2 "r")
1816    (set (match_operand:DI 0 "push_operand" "")
1817         (match_operand:DI 1 "immediate_operand" ""))]
1818   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819    && !x86_64_immediate_operand (operands[1], DImode)"
1820   [(set (match_dup 2) (match_dup 1))
1821    (set (match_dup 0) (match_dup 2))]
1822   "")
1823
1824 ;; We need to define this as both peepholer and splitter for case
1825 ;; peephole2 pass is not run.
1826 (define_peephole2
1827   [(set (match_operand:DI 0 "push_operand" "")
1828         (match_operand:DI 1 "immediate_operand" ""))]
1829   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1831   [(set (match_dup 0) (match_dup 1))
1832    (set (match_dup 2) (match_dup 3))]
1833   "split_di (operands + 1, 1, operands + 2, operands + 3);
1834    operands[1] = gen_lowpart (DImode, operands[2]);
1835    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1836                                                     GEN_INT (4)));
1837   ")
1838
1839 (define_split
1840   [(set (match_operand:DI 0 "push_operand" "")
1841         (match_operand:DI 1 "immediate_operand" ""))]
1842   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1843    && !symbolic_operand (operands[1], DImode)
1844    && !x86_64_immediate_operand (operands[1], DImode)"
1845   [(set (match_dup 0) (match_dup 1))
1846    (set (match_dup 2) (match_dup 3))]
1847   "split_di (operands + 1, 1, operands + 2, operands + 3);
1848    operands[1] = gen_lowpart (DImode, operands[2]);
1849    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1850                                                     GEN_INT (4)));
1851   ")
1852
1853 (define_insn "*pushdi2_prologue_rex64"
1854   [(set (match_operand:DI 0 "push_operand" "=<")
1855         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1856    (clobber (mem:BLK (scratch)))]
1857   "TARGET_64BIT"
1858   "push{q}\t%1"
1859   [(set_attr "type" "push")
1860    (set_attr "mode" "DI")])
1861
1862 (define_insn "*popdi1_epilogue_rex64"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864         (mem:DI (reg:DI 7)))
1865    (set (reg:DI 7)
1866         (plus:DI (reg:DI 7) (const_int 8)))
1867    (clobber (mem:BLK (scratch)))]
1868   "TARGET_64BIT"
1869   "pop{q}\t%0"
1870   [(set_attr "type" "pop")
1871    (set_attr "mode" "DI")])
1872
1873 (define_insn "popdi1"
1874   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1875         (mem:DI (reg:DI 7)))
1876    (set (reg:DI 7)
1877         (plus:DI (reg:DI 7) (const_int 8)))]
1878   "TARGET_64BIT"
1879   "pop{q}\t%0"
1880   [(set_attr "type" "pop")
1881    (set_attr "mode" "DI")])
1882
1883 (define_insn "*movdi_xor_rex64"
1884   [(set (match_operand:DI 0 "register_operand" "=r")
1885         (match_operand:DI 1 "const0_operand" "i"))
1886    (clobber (reg:CC 17))]
1887   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1888    && reload_completed"
1889   "xor{l}\t{%k0, %k0|%k0, %k0}"
1890   [(set_attr "type" "alu1")
1891    (set_attr "mode" "SI")
1892    (set_attr "length_immediate" "0")])
1893
1894 (define_insn "*movdi_or_rex64"
1895   [(set (match_operand:DI 0 "register_operand" "=r")
1896         (match_operand:DI 1 "const_int_operand" "i"))
1897    (clobber (reg:CC 17))]
1898   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1899    && reload_completed
1900    && operands[1] == constm1_rtx"
1901 {
1902   operands[1] = constm1_rtx;
1903   return "or{q}\t{%1, %0|%0, %1}";
1904 }
1905   [(set_attr "type" "alu1")
1906    (set_attr "mode" "DI")
1907    (set_attr "length_immediate" "1")])
1908
1909 (define_insn "*movdi_2"
1910   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1911         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1912   "!TARGET_64BIT
1913    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1914   "@
1915    #
1916    #
1917    movq\t{%1, %0|%0, %1}
1918    movq\t{%1, %0|%0, %1}
1919    movq\t{%1, %0|%0, %1}
1920    movdqa\t{%1, %0|%0, %1}
1921    movq\t{%1, %0|%0, %1}"
1922   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1923    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1924
1925 (define_split
1926   [(set (match_operand:DI 0 "push_operand" "")
1927         (match_operand:DI 1 "general_operand" ""))]
1928   "!TARGET_64BIT && reload_completed
1929    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1930   [(const_int 0)]
1931   "ix86_split_long_move (operands); DONE;")
1932
1933 ;; %%% This multiword shite has got to go.
1934 (define_split
1935   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936         (match_operand:DI 1 "general_operand" ""))]
1937   "!TARGET_64BIT && reload_completed
1938    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1939    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1940   [(const_int 0)]
1941   "ix86_split_long_move (operands); DONE;")
1942
1943 (define_insn "*movdi_1_rex64"
1944   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1945         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1946   "TARGET_64BIT
1947    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1948    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1949 {
1950   switch (get_attr_type (insn))
1951     {
1952     case TYPE_SSEMOV:
1953       if (get_attr_mode (insn) == MODE_TI)
1954           return "movdqa\t{%1, %0|%0, %1}";
1955       /* FALLTHRU */
1956     case TYPE_MMXMOV:
1957       /* Moves from and into integer register is done using movd opcode with
1958          REX prefix.  */
1959       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1960           return "movd\t{%1, %0|%0, %1}";
1961       return "movq\t{%1, %0|%0, %1}";
1962     case TYPE_MULTI:
1963       return "#";
1964     case TYPE_LEA:
1965       return "lea{q}\t{%a1, %0|%0, %a1}";
1966     default:
1967       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1968         abort ();
1969       if (get_attr_mode (insn) == MODE_SI)
1970         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1971       else if (which_alternative == 2)
1972         return "movabs{q}\t{%1, %0|%0, %1}";
1973       else
1974         return "mov{q}\t{%1, %0|%0, %1}";
1975     }
1976 }
1977   [(set (attr "type")
1978      (cond [(eq_attr "alternative" "5,6,7")
1979               (const_string "mmxmov")
1980             (eq_attr "alternative" "8,9,10")
1981               (const_string "ssemov")
1982             (eq_attr "alternative" "4")
1983               (const_string "multi")
1984             (and (ne (symbol_ref "flag_pic") (const_int 0))
1985                  (match_operand:DI 1 "symbolic_operand" ""))
1986               (const_string "lea")
1987            ]
1988            (const_string "imov")))
1989    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1990    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1991    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1992
1993 (define_insn "*movdi_1_rex64_nointerunit"
1994   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1995         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1996   "TARGET_64BIT
1997    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1998    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1999 {
2000   switch (get_attr_type (insn))
2001     {
2002     case TYPE_SSEMOV:
2003       if (get_attr_mode (insn) == MODE_TI)
2004           return "movdqa\t{%1, %0|%0, %1}";
2005       /* FALLTHRU */
2006     case TYPE_MMXMOV:
2007       return "movq\t{%1, %0|%0, %1}";
2008     case TYPE_MULTI:
2009       return "#";
2010     case TYPE_LEA:
2011       return "lea{q}\t{%a1, %0|%0, %a1}";
2012     default:
2013       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2014         abort ();
2015       if (get_attr_mode (insn) == MODE_SI)
2016         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2017       else if (which_alternative == 2)
2018         return "movabs{q}\t{%1, %0|%0, %1}";
2019       else
2020         return "mov{q}\t{%1, %0|%0, %1}";
2021     }
2022 }
2023   [(set (attr "type")
2024      (cond [(eq_attr "alternative" "5,6,7")
2025               (const_string "mmxmov")
2026             (eq_attr "alternative" "8,9,10")
2027               (const_string "ssemov")
2028             (eq_attr "alternative" "4")
2029               (const_string "multi")
2030             (and (ne (symbol_ref "flag_pic") (const_int 0))
2031                  (match_operand:DI 1 "symbolic_operand" ""))
2032               (const_string "lea")
2033            ]
2034            (const_string "imov")))
2035    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2036    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2037    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2038
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046   "@
2047    movabs{q}\t{%1, %P0|%P0, %1}
2048    mov{q}\t{%1, %a0|%a0, %1}"
2049   [(set_attr "type" "imov")
2050    (set_attr "modrm" "0,*")
2051    (set_attr "length_address" "8,0")
2052    (set_attr "length_immediate" "0,*")
2053    (set_attr "memory" "store")
2054    (set_attr "mode" "DI")])
2055
2056 (define_insn "*movabsdi_2_rex64"
2057   [(set (match_operand:DI 0 "register_operand" "=a,r")
2058         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060   "@
2061    movabs{q}\t{%P1, %0|%0, %P1}
2062    mov{q}\t{%a1, %0|%0, %a1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "modrm" "0,*")
2065    (set_attr "length_address" "8,0")
2066    (set_attr "length_immediate" "0")
2067    (set_attr "memory" "load")
2068    (set_attr "mode" "DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))]
2081   "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_di (operands, 2, operands + 2, operands + 4);")
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2098    && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode)"
2100   [(set (match_dup 2) (match_dup 3))
2101    (set (match_dup 4) (match_dup 5))]
2102   "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_insn "*swapdi_rex64"
2105   [(set (match_operand:DI 0 "register_operand" "+r")
2106         (match_operand:DI 1 "register_operand" "+r"))
2107    (set (match_dup 1)
2108         (match_dup 0))]
2109   "TARGET_64BIT"
2110   "xchg{q}\t%1, %0"
2111   [(set_attr "type" "imov")
2112    (set_attr "pent_pair" "np")
2113    (set_attr "athlon_decode" "vector")
2114    (set_attr "mode" "DI")
2115    (set_attr "modrm" "0")
2116    (set_attr "ppro_uops" "few")])
2117
2118   
2119 (define_expand "movsf"
2120   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2121         (match_operand:SF 1 "general_operand" ""))]
2122   ""
2123   "ix86_expand_move (SFmode, operands); DONE;")
2124
2125 (define_insn "*pushsf"
2126   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2127         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2128   "!TARGET_64BIT"
2129 {
2130   switch (which_alternative)
2131     {
2132     case 1:
2133       return "push{l}\t%1";
2134
2135     default:
2136       /* This insn should be already splitted before reg-stack.  */
2137       abort ();
2138     }
2139 }
2140   [(set_attr "type" "multi,push,multi")
2141    (set_attr "mode" "SF,SI,SF")])
2142
2143 (define_insn "*pushsf_rex64"
2144   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2145         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2146   "TARGET_64BIT"
2147 {
2148   switch (which_alternative)
2149     {
2150     case 1:
2151       return "push{q}\t%q1";
2152
2153     default:
2154       /* This insn should be already splitted before reg-stack.  */
2155       abort ();
2156     }
2157 }
2158   [(set_attr "type" "multi,push,multi")
2159    (set_attr "mode" "SF,DI,SF")])
2160
2161 (define_split
2162   [(set (match_operand:SF 0 "push_operand" "")
2163         (match_operand:SF 1 "memory_operand" ""))]
2164   "reload_completed
2165    && GET_CODE (operands[1]) == MEM
2166    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2167    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2168   [(set (match_dup 0)
2169         (match_dup 1))]
2170   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2171
2172
2173 ;; %%% Kill this when call knows how to work this out.
2174 (define_split
2175   [(set (match_operand:SF 0 "push_operand" "")
2176         (match_operand:SF 1 "any_fp_register_operand" ""))]
2177   "!TARGET_64BIT"
2178   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2179    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2180
2181 (define_split
2182   [(set (match_operand:SF 0 "push_operand" "")
2183         (match_operand:SF 1 "any_fp_register_operand" ""))]
2184   "TARGET_64BIT"
2185   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2186    (set (mem:SF (reg:DI 7)) (match_dup 1))])
2187
2188 (define_insn "*movsf_1"
2189   [(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")
2190         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2191   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2192    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2193    && (reload_in_progress || reload_completed
2194        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2195        || GET_CODE (operands[1]) != CONST_DOUBLE
2196        || memory_operand (operands[0], SFmode))" 
2197 {
2198   switch (which_alternative)
2199     {
2200     case 0:
2201       if (REG_P (operands[1])
2202           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2203         return "fstp\t%y0";
2204       else if (STACK_TOP_P (operands[0]))
2205         return "fld%z1\t%y1";
2206       else
2207         return "fst\t%y0";
2208
2209     case 1:
2210       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2211         return "fstp%z0\t%y0";
2212       else
2213         return "fst%z0\t%y0";
2214
2215     case 2:
2216       return standard_80387_constant_opcode (operands[1]);
2217
2218     case 3:
2219     case 4:
2220       return "mov{l}\t{%1, %0|%0, %1}";
2221     case 5:
2222       if (get_attr_mode (insn) == MODE_TI)
2223         return "pxor\t%0, %0";
2224       else
2225         return "xorps\t%0, %0";
2226     case 6:
2227       if (get_attr_mode (insn) == MODE_V4SF)
2228         return "movaps\t{%1, %0|%0, %1}";
2229       else
2230         return "movss\t{%1, %0|%0, %1}";
2231     case 7:
2232     case 8:
2233       return "movss\t{%1, %0|%0, %1}";
2234
2235     case 9:
2236     case 10:
2237       return "movd\t{%1, %0|%0, %1}";
2238
2239     case 11:
2240       return "movq\t{%1, %0|%0, %1}";
2241
2242     default:
2243       abort();
2244     }
2245 }
2246   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2247    (set (attr "mode")
2248         (cond [(eq_attr "alternative" "3,4,9,10")
2249                  (const_string "SI")
2250                (eq_attr "alternative" "5")
2251                  (if_then_else
2252                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2253                                  (const_int 0))
2254                              (ne (symbol_ref "TARGET_SSE2")
2255                                  (const_int 0)))
2256                         (eq (symbol_ref "optimize_size")
2257                             (const_int 0)))
2258                    (const_string "TI")
2259                    (const_string "V4SF"))
2260                /* For architectures resolving dependencies on
2261                   whole SSE registers use APS move to break dependency
2262                   chains, otherwise use short move to avoid extra work. 
2263
2264                   Do the same for architectures resolving dependencies on
2265                   the parts.  While in DF mode it is better to always handle
2266                   just register parts, the SF mode is different due to lack
2267                   of instructions to load just part of the register.  It is
2268                   better to maintain the whole registers in single format
2269                   to avoid problems on using packed logical operations.  */
2270                (eq_attr "alternative" "6")
2271                  (if_then_else
2272                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2273                             (const_int 0))
2274                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2275                             (const_int 0)))
2276                    (const_string "V4SF")
2277                    (const_string "SF"))
2278                (eq_attr "alternative" "11")
2279                  (const_string "DI")]
2280                (const_string "SF")))])
2281
2282 (define_insn "*movsf_1_nointerunit"
2283   [(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")
2284         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2285   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2286    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2287    && (reload_in_progress || reload_completed
2288        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289        || GET_CODE (operands[1]) != CONST_DOUBLE
2290        || memory_operand (operands[0], SFmode))" 
2291 {
2292   switch (which_alternative)
2293     {
2294     case 0:
2295       if (REG_P (operands[1])
2296           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297         {
2298           if (REGNO (operands[0]) == FIRST_STACK_REG
2299               && TARGET_USE_FFREEP)
2300             return "ffreep\t%y0";
2301           return "fstp\t%y0";
2302         }
2303       else if (STACK_TOP_P (operands[0]))
2304         return "fld%z1\t%y1";
2305       else
2306         return "fst\t%y0";
2307
2308     case 1:
2309       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2310         return "fstp%z0\t%y0";
2311       else
2312         return "fst%z0\t%y0";
2313
2314     case 2:
2315       return standard_80387_constant_opcode (operands[1]);
2316
2317     case 3:
2318     case 4:
2319       return "mov{l}\t{%1, %0|%0, %1}";
2320     case 5:
2321       if (get_attr_mode (insn) == MODE_TI)
2322         return "pxor\t%0, %0";
2323       else
2324         return "xorps\t%0, %0";
2325     case 6:
2326       if (get_attr_mode (insn) == MODE_V4SF)
2327         return "movaps\t{%1, %0|%0, %1}";
2328       else
2329         return "movss\t{%1, %0|%0, %1}";
2330     case 7:
2331     case 8:
2332       return "movss\t{%1, %0|%0, %1}";
2333
2334     case 9:
2335     case 10:
2336       return "movd\t{%1, %0|%0, %1}";
2337
2338     case 11:
2339       return "movq\t{%1, %0|%0, %1}";
2340
2341     default:
2342       abort();
2343     }
2344 }
2345   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2346    (set (attr "mode")
2347         (cond [(eq_attr "alternative" "3,4,9,10")
2348                  (const_string "SI")
2349                (eq_attr "alternative" "5")
2350                  (if_then_else
2351                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2352                                  (const_int 0))
2353                              (ne (symbol_ref "TARGET_SSE2")
2354                                  (const_int 0)))
2355                         (eq (symbol_ref "optimize_size")
2356                             (const_int 0)))
2357                    (const_string "TI")
2358                    (const_string "V4SF"))
2359                /* For architectures resolving dependencies on
2360                   whole SSE registers use APS move to break dependency
2361                   chains, otherwise use short move to avoid extra work. 
2362
2363                   Do the same for architectures resolving dependencies on
2364                   the parts.  While in DF mode it is better to always handle
2365                   just register parts, the SF mode is different due to lack
2366                   of instructions to load just part of the register.  It is
2367                   better to maintain the whole registers in single format
2368                   to avoid problems on using packed logical operations.  */
2369                (eq_attr "alternative" "6")
2370                  (if_then_else
2371                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2372                             (const_int 0))
2373                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2374                             (const_int 0)))
2375                    (const_string "V4SF")
2376                    (const_string "SF"))
2377                (eq_attr "alternative" "11")
2378                  (const_string "DI")]
2379                (const_string "SF")))])
2380
2381 (define_insn "*swapsf"
2382   [(set (match_operand:SF 0 "register_operand" "+f")
2383         (match_operand:SF 1 "register_operand" "+f"))
2384    (set (match_dup 1)
2385         (match_dup 0))]
2386   "reload_completed || !TARGET_SSE"
2387 {
2388   if (STACK_TOP_P (operands[0]))
2389     return "fxch\t%1";
2390   else
2391     return "fxch\t%0";
2392 }
2393   [(set_attr "type" "fxch")
2394    (set_attr "mode" "SF")])
2395
2396 (define_expand "movdf"
2397   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2398         (match_operand:DF 1 "general_operand" ""))]
2399   ""
2400   "ix86_expand_move (DFmode, operands); DONE;")
2401
2402 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2403 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2404 ;; On the average, pushdf using integers can be still shorter.  Allow this
2405 ;; pattern for optimize_size too.
2406
2407 (define_insn "*pushdf_nointeger"
2408   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2409         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2410   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412   /* This insn should be already splitted before reg-stack.  */
2413   abort ();
2414 }
2415   [(set_attr "type" "multi")
2416    (set_attr "mode" "DF,SI,SI,DF")])
2417
2418 (define_insn "*pushdf_integer"
2419   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2420         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2421   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2422 {
2423   /* This insn should be already splitted before reg-stack.  */
2424   abort ();
2425 }
2426   [(set_attr "type" "multi")
2427    (set_attr "mode" "DF,SI,DF")])
2428
2429 ;; %%% Kill this when call knows how to work this out.
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "any_fp_register_operand" ""))]
2433   "!TARGET_64BIT && reload_completed"
2434   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2435    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2436   "")
2437
2438 (define_split
2439   [(set (match_operand:DF 0 "push_operand" "")
2440         (match_operand:DF 1 "any_fp_register_operand" ""))]
2441   "TARGET_64BIT && reload_completed"
2442   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2443    (set (mem:DF (reg:DI 7)) (match_dup 1))]
2444   "")
2445
2446 (define_split
2447   [(set (match_operand:DF 0 "push_operand" "")
2448         (match_operand:DF 1 "general_operand" ""))]
2449   "reload_completed"
2450   [(const_int 0)]
2451   "ix86_split_long_move (operands); DONE;")
2452
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2456
2457 (define_insn "*movdf_nointeger"
2458   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2459         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2460   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2461    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2462    && (reload_in_progress || reload_completed
2463        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2464        || GET_CODE (operands[1]) != CONST_DOUBLE
2465        || memory_operand (operands[0], DFmode))" 
2466 {
2467   switch (which_alternative)
2468     {
2469     case 0:
2470       if (REG_P (operands[1])
2471           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2472         {
2473           if (REGNO (operands[0]) == FIRST_STACK_REG
2474               && TARGET_USE_FFREEP)
2475             return "ffreep\t%y0";
2476           return "fstp\t%y0";
2477         }
2478       else if (STACK_TOP_P (operands[0]))
2479         return "fld%z1\t%y1";
2480       else
2481         return "fst\t%y0";
2482
2483     case 1:
2484       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2485         return "fstp%z0\t%y0";
2486       else
2487         return "fst%z0\t%y0";
2488
2489     case 2:
2490       return standard_80387_constant_opcode (operands[1]);
2491
2492     case 3:
2493     case 4:
2494       return "#";
2495     case 5:
2496       switch (get_attr_mode (insn))
2497         {
2498         case MODE_V4SF:
2499           return "xorps\t%0, %0";
2500         case MODE_V2DF:
2501           return "xorpd\t%0, %0";
2502         case MODE_TI:
2503           return "pxor\t%0, %0";
2504         default:
2505           abort ();
2506         }
2507     case 6:
2508       switch (get_attr_mode (insn))
2509         {
2510         case MODE_V4SF:
2511           return "movaps\t{%1, %0|%0, %1}";
2512         case MODE_V2DF:
2513           return "movapd\t{%1, %0|%0, %1}";
2514         case MODE_DF:
2515           return "movsd\t{%1, %0|%0, %1}";
2516         default:
2517           abort ();
2518         }
2519     case 7:
2520       if (get_attr_mode (insn) == MODE_V2DF)
2521         return "movlpd\t{%1, %0|%0, %1}";
2522       else
2523         return "movsd\t{%1, %0|%0, %1}";
2524     case 8:
2525       return "movsd\t{%1, %0|%0, %1}";
2526
2527     default:
2528       abort();
2529     }
2530 }
2531   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2532    (set (attr "mode")
2533         (cond [(eq_attr "alternative" "3,4")
2534                  (const_string "SI")
2535                /* xorps is one byte shorter.  */
2536                (eq_attr "alternative" "5")
2537                  (cond [(ne (symbol_ref "optimize_size")
2538                             (const_int 0))
2539                           (const_string "V4SF")
2540                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2541                             (const_int 0))
2542                           (const_string "TI")]
2543                        (const_string "V2DF"))
2544                /* For architectures resolving dependencies on
2545                   whole SSE registers use APD move to break dependency
2546                   chains, otherwise use short move to avoid extra work.
2547
2548                   movaps encodes one byte shorter.  */
2549                (eq_attr "alternative" "6")
2550                  (cond
2551                   [(ne (symbol_ref "optimize_size")
2552                        (const_int 0))
2553                      (const_string "V4SF")
2554                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2555                        (const_int 0))
2556                      (const_string "V2DF")]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2564                        (const_int 0))
2565                    (const_string "V2DF")
2566                    (const_string "DF"))]
2567                (const_string "DF")))])
2568
2569 (define_insn "*movdf_integer"
2570   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2571         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2578 {
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       if (REG_P (operands[1])
2583           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2584         {
2585           if (REGNO (operands[0]) == FIRST_STACK_REG
2586               && TARGET_USE_FFREEP)
2587             return "ffreep\t%y0";
2588           return "fstp\t%y0";
2589         }
2590       else if (STACK_TOP_P (operands[0]))
2591         return "fld%z1\t%y1";
2592       else
2593         return "fst\t%y0";
2594
2595     case 1:
2596       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2597         return "fstp%z0\t%y0";
2598       else
2599         return "fst%z0\t%y0";
2600
2601     case 2:
2602       return standard_80387_constant_opcode (operands[1]);
2603
2604     case 3:
2605     case 4:
2606       return "#";
2607
2608     case 5:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "xorps\t%0, %0";
2613         case MODE_V2DF:
2614           return "xorpd\t%0, %0";
2615         case MODE_TI:
2616           return "pxor\t%0, %0";
2617         default:
2618           abort ();
2619         }
2620     case 6:
2621       switch (get_attr_mode (insn))
2622         {
2623         case MODE_V4SF:
2624           return "movaps\t{%1, %0|%0, %1}";
2625         case MODE_V2DF:
2626           return "movapd\t{%1, %0|%0, %1}";
2627         case MODE_DF:
2628           return "movsd\t{%1, %0|%0, %1}";
2629         default:
2630           abort ();
2631         }
2632     case 7:
2633       if (get_attr_mode (insn) == MODE_V2DF)
2634         return "movlpd\t{%1, %0|%0, %1}";
2635       else
2636         return "movsd\t{%1, %0|%0, %1}";
2637     case 8:
2638       return "movsd\t{%1, %0|%0, %1}";
2639
2640     default:
2641       abort();
2642     }
2643 }
2644   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2645    (set (attr "mode")
2646         (cond [(eq_attr "alternative" "3,4")
2647                  (const_string "SI")
2648                /* xorps is one byte shorter.  */
2649                (eq_attr "alternative" "5")
2650                  (cond [(ne (symbol_ref "optimize_size")
2651                             (const_int 0))
2652                           (const_string "V4SF")
2653                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654                             (const_int 0))
2655                           (const_string "TI")]
2656                        (const_string "V2DF"))
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.  
2660
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                   [(ne (symbol_ref "optimize_size")
2665                        (const_int 0))
2666                      (const_string "V4SF")
2667                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                        (const_int 0))
2669                      (const_string "V2DF")]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2677                        (const_int 0))
2678                    (const_string "V2DF")
2679                    (const_string "DF"))]
2680                (const_string "DF")))])
2681
2682 (define_split
2683   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684         (match_operand:DF 1 "general_operand" ""))]
2685   "reload_completed
2686    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687    && ! (ANY_FP_REG_P (operands[0]) || 
2688          (GET_CODE (operands[0]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690    && ! (ANY_FP_REG_P (operands[1]) || 
2691          (GET_CODE (operands[1]) == SUBREG
2692           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693   [(const_int 0)]
2694   "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697   [(set (match_operand:DF 0 "register_operand" "+f")
2698         (match_operand:DF 1 "register_operand" "+f"))
2699    (set (match_dup 1)
2700         (match_dup 0))]
2701   "reload_completed || !TARGET_SSE2"
2702 {
2703   if (STACK_TOP_P (operands[0]))
2704     return "fxch\t%1";
2705   else
2706     return "fxch\t%0";
2707 }
2708   [(set_attr "type" "fxch")
2709    (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713         (match_operand:XF 1 "general_operand" ""))]
2714   ""
2715   "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;;  handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727   "optimize_size"
2728 {
2729   /* This insn should be already splitted before reg-stack.  */
2730   abort ();
2731 }
2732   [(set_attr "type" "multi")
2733    (set_attr "mode" "XF,SI,SI")])
2734
2735 (define_insn "*pushxf_integer"
2736   [(set (match_operand:XF 0 "push_operand" "=<,<")
2737         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2738   "!optimize_size"
2739 {
2740   /* This insn should be already splitted before reg-stack.  */
2741   abort ();
2742 }
2743   [(set_attr "type" "multi")
2744    (set_attr "mode" "XF,SI")])
2745
2746 (define_split
2747   [(set (match_operand 0 "push_operand" "")
2748         (match_operand 1 "general_operand" ""))]
2749   "reload_completed
2750    && (GET_MODE (operands[0]) == XFmode
2751        || GET_MODE (operands[0]) == DFmode)
2752    && !ANY_FP_REG_P (operands[1])"
2753   [(const_int 0)]
2754   "ix86_split_long_move (operands); DONE;")
2755
2756 (define_split
2757   [(set (match_operand:XF 0 "push_operand" "")
2758         (match_operand:XF 1 "any_fp_register_operand" ""))]
2759   "!TARGET_64BIT"
2760   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2761    (set (mem:XF (reg:SI 7)) (match_dup 1))]
2762   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "TARGET_64BIT"
2768   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2769    (set (mem:XF (reg:DI 7)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 ;; Do not use integer registers when optimizing for size
2773 (define_insn "*movxf_nointeger"
2774   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2776   "optimize_size
2777    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778    && (reload_in_progress || reload_completed
2779        || GET_CODE (operands[1]) != CONST_DOUBLE
2780        || memory_operand (operands[0], XFmode))" 
2781 {
2782   switch (which_alternative)
2783     {
2784     case 0:
2785       if (REG_P (operands[1])
2786           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787         {
2788           if (REGNO (operands[0]) == FIRST_STACK_REG
2789               && TARGET_USE_FFREEP)
2790             return "ffreep\t%y0";
2791           return "fstp\t%y0";
2792         }
2793       else if (STACK_TOP_P (operands[0]))
2794         return "fld%z1\t%y1";
2795       else
2796         return "fst\t%y0";
2797
2798     case 1:
2799       /* There is no non-popping store to memory for XFmode.  So if
2800          we need one, follow the store with a load.  */
2801       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802         return "fstp%z0\t%y0\;fld%z0\t%y0";
2803       else
2804         return "fstp%z0\t%y0";
2805
2806     case 2:
2807       return standard_80387_constant_opcode (operands[1]);
2808
2809     case 3: case 4:
2810       return "#";
2811     }
2812   abort();
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2815    (set_attr "mode" "XF,XF,XF,SI,SI")])
2816
2817 (define_insn "*movxf_integer"
2818   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2819         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2820   "!optimize_size
2821    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2822    && (reload_in_progress || reload_completed
2823        || GET_CODE (operands[1]) != CONST_DOUBLE
2824        || memory_operand (operands[0], XFmode))" 
2825 {
2826   switch (which_alternative)
2827     {
2828     case 0:
2829       if (REG_P (operands[1])
2830           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2831         {
2832           if (REGNO (operands[0]) == FIRST_STACK_REG
2833               && TARGET_USE_FFREEP)
2834             return "ffreep\t%y0";
2835           return "fstp\t%y0";
2836         }
2837       else if (STACK_TOP_P (operands[0]))
2838         return "fld%z1\t%y1";
2839       else
2840         return "fst\t%y0";
2841
2842     case 1:
2843       /* There is no non-popping store to memory for XFmode.  So if
2844          we need one, follow the store with a load.  */
2845       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2846         return "fstp%z0\t%y0\;fld%z0\t%y0";
2847       else
2848         return "fstp%z0\t%y0";
2849
2850     case 2:
2851       return standard_80387_constant_opcode (operands[1]);
2852
2853     case 3: case 4:
2854       return "#";
2855     }
2856   abort();
2857 }
2858   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2859    (set_attr "mode" "XF,XF,XF,SI,SI")])
2860
2861 (define_split
2862   [(set (match_operand 0 "nonimmediate_operand" "")
2863         (match_operand 1 "general_operand" ""))]
2864   "reload_completed
2865    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2866    && GET_MODE (operands[0]) == XFmode
2867    && ! (ANY_FP_REG_P (operands[0]) || 
2868          (GET_CODE (operands[0]) == SUBREG
2869           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2870    && ! (ANY_FP_REG_P (operands[1]) || 
2871          (GET_CODE (operands[1]) == SUBREG
2872           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2873   [(const_int 0)]
2874   "ix86_split_long_move (operands); DONE;")
2875
2876 (define_split
2877   [(set (match_operand 0 "register_operand" "")
2878         (match_operand 1 "memory_operand" ""))]
2879   "reload_completed
2880    && GET_CODE (operands[1]) == MEM
2881    && (GET_MODE (operands[0]) == XFmode
2882        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2883    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2884    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2885    && (!(SSE_REG_P (operands[0]) || 
2886          (GET_CODE (operands[0]) == SUBREG
2887           && SSE_REG_P (SUBREG_REG (operands[0]))))
2888        || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2889    && (!(FP_REG_P (operands[0]) || 
2890          (GET_CODE (operands[0]) == SUBREG
2891           && FP_REG_P (SUBREG_REG (operands[0]))))
2892        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2893   [(set (match_dup 0)
2894         (match_dup 1))]
2895   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2896
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   ""
2903 {
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2908 }
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2911 \f
2912 ;; Zero extension instructions
2913
2914 (define_expand "zero_extendhisi2"
2915   [(set (match_operand:SI 0 "register_operand" "")
2916      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2917   ""
2918 {
2919   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2920     {
2921       operands[1] = force_reg (HImode, operands[1]);
2922       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2923       DONE;
2924     }
2925 })
2926
2927 (define_insn "zero_extendhisi2_and"
2928   [(set (match_operand:SI 0 "register_operand" "=r")
2929      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2930    (clobber (reg:CC 17))]
2931   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2932   "#"
2933   [(set_attr "type" "alu1")
2934    (set_attr "mode" "SI")])
2935
2936 (define_split
2937   [(set (match_operand:SI 0 "register_operand" "")
2938         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2939    (clobber (reg:CC 17))]
2940   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2941   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2942               (clobber (reg:CC 17))])]
2943   "")
2944
2945 (define_insn "*zero_extendhisi2_movzwl"
2946   [(set (match_operand:SI 0 "register_operand" "=r")
2947      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2948   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2949   "movz{wl|x}\t{%1, %0|%0, %1}"
2950   [(set_attr "type" "imovx")
2951    (set_attr "mode" "SI")])
2952
2953 (define_expand "zero_extendqihi2"
2954   [(parallel
2955     [(set (match_operand:HI 0 "register_operand" "")
2956        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2957      (clobber (reg:CC 17))])]
2958   ""
2959   "")
2960
2961 (define_insn "*zero_extendqihi2_and"
2962   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2963      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2964    (clobber (reg:CC 17))]
2965   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2966   "#"
2967   [(set_attr "type" "alu1")
2968    (set_attr "mode" "HI")])
2969
2970 (define_insn "*zero_extendqihi2_movzbw_and"
2971   [(set (match_operand:HI 0 "register_operand" "=r,r")
2972      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2973    (clobber (reg:CC 17))]
2974   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2975   "#"
2976   [(set_attr "type" "imovx,alu1")
2977    (set_attr "mode" "HI")])
2978
2979 (define_insn "*zero_extendqihi2_movzbw"
2980   [(set (match_operand:HI 0 "register_operand" "=r")
2981      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2982   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2983   "movz{bw|x}\t{%1, %0|%0, %1}"
2984   [(set_attr "type" "imovx")
2985    (set_attr "mode" "HI")])
2986
2987 ;; For the movzbw case strip only the clobber
2988 (define_split
2989   [(set (match_operand:HI 0 "register_operand" "")
2990         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2991    (clobber (reg:CC 17))]
2992   "reload_completed 
2993    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2994    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2995   [(set (match_operand:HI 0 "register_operand" "")
2996         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2997
2998 ;; When source and destination does not overlap, clear destination
2999 ;; first and then do the movb
3000 (define_split
3001   [(set (match_operand:HI 0 "register_operand" "")
3002         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3003    (clobber (reg:CC 17))]
3004   "reload_completed
3005    && ANY_QI_REG_P (operands[0])
3006    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3007    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3008   [(set (match_dup 0) (const_int 0))
3009    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3010   "operands[2] = gen_lowpart (QImode, operands[0]);")
3011
3012 ;; Rest is handled by single and.
3013 (define_split
3014   [(set (match_operand:HI 0 "register_operand" "")
3015         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3016    (clobber (reg:CC 17))]
3017   "reload_completed
3018    && true_regnum (operands[0]) == true_regnum (operands[1])"
3019   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3020               (clobber (reg:CC 17))])]
3021   "")
3022
3023 (define_expand "zero_extendqisi2"
3024   [(parallel
3025     [(set (match_operand:SI 0 "register_operand" "")
3026        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3027      (clobber (reg:CC 17))])]
3028   ""
3029   "")
3030
3031 (define_insn "*zero_extendqisi2_and"
3032   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3033      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3034    (clobber (reg:CC 17))]
3035   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3036   "#"
3037   [(set_attr "type" "alu1")
3038    (set_attr "mode" "SI")])
3039
3040 (define_insn "*zero_extendqisi2_movzbw_and"
3041   [(set (match_operand:SI 0 "register_operand" "=r,r")
3042      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3043    (clobber (reg:CC 17))]
3044   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3045   "#"
3046   [(set_attr "type" "imovx,alu1")
3047    (set_attr "mode" "SI")])
3048
3049 (define_insn "*zero_extendqisi2_movzbw"
3050   [(set (match_operand:SI 0 "register_operand" "=r")
3051      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3052   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3053   "movz{bl|x}\t{%1, %0|%0, %1}"
3054   [(set_attr "type" "imovx")
3055    (set_attr "mode" "SI")])
3056
3057 ;; For the movzbl case strip only the clobber
3058 (define_split
3059   [(set (match_operand:SI 0 "register_operand" "")
3060         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3061    (clobber (reg:CC 17))]
3062   "reload_completed 
3063    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3064    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3065   [(set (match_dup 0)
3066         (zero_extend:SI (match_dup 1)))])
3067
3068 ;; When source and destination does not overlap, clear destination
3069 ;; first and then do the movb
3070 (define_split
3071   [(set (match_operand:SI 0 "register_operand" "")
3072         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3073    (clobber (reg:CC 17))]
3074   "reload_completed
3075    && ANY_QI_REG_P (operands[0])
3076    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3077    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3078    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3079   [(set (match_dup 0) (const_int 0))
3080    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3081   "operands[2] = gen_lowpart (QImode, operands[0]);")
3082
3083 ;; Rest is handled by single and.
3084 (define_split
3085   [(set (match_operand:SI 0 "register_operand" "")
3086         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3087    (clobber (reg:CC 17))]
3088   "reload_completed
3089    && true_regnum (operands[0]) == true_regnum (operands[1])"
3090   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3091               (clobber (reg:CC 17))])]
3092   "")
3093
3094 ;; %%% Kill me once multi-word ops are sane.
3095 (define_expand "zero_extendsidi2"
3096   [(set (match_operand:DI 0 "register_operand" "=r")
3097      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3098   ""
3099   "if (!TARGET_64BIT)
3100      {
3101        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3102        DONE;
3103      }
3104   ")
3105
3106 (define_insn "zero_extendsidi2_32"
3107   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3108         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3109    (clobber (reg:CC 17))]
3110   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3111   "@
3112    #
3113    #
3114    #
3115    movd\t{%1, %0|%0, %1}
3116    movd\t{%1, %0|%0, %1}"
3117   [(set_attr "mode" "SI,SI,SI,DI,TI")
3118    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3119
3120 (define_insn "*zero_extendsidi2_32_1"
3121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3122         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3123    (clobber (reg:CC 17))]
3124   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3125   "@
3126    #
3127    #
3128    #
3129    movd\t{%1, %0|%0, %1}
3130    movd\t{%1, %0|%0, %1}"
3131   [(set_attr "mode" "SI,SI,SI,DI,TI")
3132    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3133
3134 (define_insn "zero_extendsidi2_rex64"
3135   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3136      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3137   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3138   "@
3139    mov\t{%k1, %k0|%k0, %k1}
3140    #
3141    movd\t{%1, %0|%0, %1}
3142    movd\t{%1, %0|%0, %1}"
3143   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3144    (set_attr "mode" "SI,DI,DI,TI")])
3145
3146 (define_insn "*zero_extendsidi2_rex64_1"
3147   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3148      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3149   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3150   "@
3151    mov\t{%k1, %k0|%k0, %k1}
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3156    (set_attr "mode" "SI,DI,SI,SI")])
3157
3158 (define_split
3159   [(set (match_operand:DI 0 "memory_operand" "")
3160      (zero_extend:DI (match_dup 0)))]
3161   "TARGET_64BIT"
3162   [(set (match_dup 4) (const_int 0))]
3163   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3164
3165 (define_split 
3166   [(set (match_operand:DI 0 "register_operand" "")
3167         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3168    (clobber (reg:CC 17))]
3169   "!TARGET_64BIT && reload_completed
3170    && true_regnum (operands[0]) == true_regnum (operands[1])"
3171   [(set (match_dup 4) (const_int 0))]
3172   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3173
3174 (define_split 
3175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3176         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3177    (clobber (reg:CC 17))]
3178   "!TARGET_64BIT && reload_completed
3179    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3180   [(set (match_dup 3) (match_dup 1))
3181    (set (match_dup 4) (const_int 0))]
3182   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3183
3184 (define_insn "zero_extendhidi2"
3185   [(set (match_operand:DI 0 "register_operand" "=r,r")
3186      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3187   "TARGET_64BIT"
3188   "@
3189    movz{wl|x}\t{%1, %k0|%k0, %1} 
3190    movz{wq|x}\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx")
3192    (set_attr "mode" "SI,DI")])
3193
3194 (define_insn "zero_extendqidi2"
3195   [(set (match_operand:DI 0 "register_operand" "=r,r")
3196      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3197   "TARGET_64BIT"
3198   "@
3199    movz{bl|x}\t{%1, %k0|%k0, %1} 
3200    movz{bq|x}\t{%1, %0|%0, %1}"
3201   [(set_attr "type" "imovx")
3202    (set_attr "mode" "SI,DI")])
3203 \f
3204 ;; Sign extension instructions
3205
3206 (define_expand "extendsidi2"
3207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3208                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3209               (clobber (reg:CC 17))
3210               (clobber (match_scratch:SI 2 ""))])]
3211   ""
3212 {
3213   if (TARGET_64BIT)
3214     {
3215       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3216       DONE;
3217     }
3218 })
3219
3220 (define_insn "*extendsidi2_1"
3221   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3222         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3223    (clobber (reg:CC 17))
3224    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3225   "!TARGET_64BIT"
3226   "#")
3227
3228 (define_insn "extendsidi2_rex64"
3229   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3230         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3231   "TARGET_64BIT"
3232   "@
3233    {cltq|cdqe}
3234    movs{lq|x}\t{%1,%0|%0, %1}"
3235   [(set_attr "type" "imovx")
3236    (set_attr "mode" "DI")
3237    (set_attr "prefix_0f" "0")
3238    (set_attr "modrm" "0,1")])
3239
3240 (define_insn "extendhidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "TARGET_64BIT"
3244   "movs{wq|x}\t{%1,%0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "DI")])
3247
3248 (define_insn "extendqidi2"
3249   [(set (match_operand:DI 0 "register_operand" "=r")
3250         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3251   "TARGET_64BIT"
3252   "movs{bq|x}\t{%1,%0|%0, %1}"
3253    [(set_attr "type" "imovx")
3254     (set_attr "mode" "DI")])
3255
3256 ;; Extend to memory case when source register does die.
3257 (define_split 
3258   [(set (match_operand:DI 0 "memory_operand" "")
3259         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260    (clobber (reg:CC 17))
3261    (clobber (match_operand:SI 2 "register_operand" ""))]
3262   "(reload_completed
3263     && dead_or_set_p (insn, operands[1])
3264     && !reg_mentioned_p (operands[1], operands[0]))"
3265   [(set (match_dup 3) (match_dup 1))
3266    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3267               (clobber (reg:CC 17))])
3268    (set (match_dup 4) (match_dup 1))]
3269   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3270
3271 ;; Extend to memory case when source register does not 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   [(const_int 0)]
3279 {
3280   split_di (&operands[0], 1, &operands[3], &operands[4]);
3281
3282   emit_move_insn (operands[3], operands[1]);
3283
3284   /* Generate a cltd if possible and doing so it profitable.  */
3285   if (true_regnum (operands[1]) == 0
3286       && true_regnum (operands[2]) == 1
3287       && (optimize_size || TARGET_USE_CLTD))
3288     {
3289       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3290     }
3291   else
3292     {
3293       emit_move_insn (operands[2], operands[1]);
3294       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3295     }
3296   emit_move_insn (operands[4], operands[2]);
3297   DONE;
3298 })
3299
3300 ;; Extend to register case.  Optimize case where source and destination
3301 ;; registers match and cases where we can use cltd.
3302 (define_split 
3303   [(set (match_operand:DI 0 "register_operand" "")
3304         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305    (clobber (reg:CC 17))
3306    (clobber (match_scratch:SI 2 ""))]
3307   "reload_completed"
3308   [(const_int 0)]
3309 {
3310   split_di (&operands[0], 1, &operands[3], &operands[4]);
3311
3312   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3313     emit_move_insn (operands[3], operands[1]);
3314
3315   /* Generate a cltd if possible and doing so it profitable.  */
3316   if (true_regnum (operands[3]) == 0
3317       && (optimize_size || TARGET_USE_CLTD))
3318     {
3319       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3320       DONE;
3321     }
3322
3323   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3324     emit_move_insn (operands[4], operands[1]);
3325
3326   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3327   DONE;
3328 })
3329
3330 (define_insn "extendhisi2"
3331   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3332         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3333   ""
3334 {
3335   switch (get_attr_prefix_0f (insn))
3336     {
3337     case 0:
3338       return "{cwtl|cwde}";
3339     default:
3340       return "movs{wl|x}\t{%1,%0|%0, %1}";
3341     }
3342 }
3343   [(set_attr "type" "imovx")
3344    (set_attr "mode" "SI")
3345    (set (attr "prefix_0f")
3346      ;; movsx is short decodable while cwtl is vector decoded.
3347      (if_then_else (and (eq_attr "cpu" "!k6")
3348                         (eq_attr "alternative" "0"))
3349         (const_string "0")
3350         (const_string "1")))
3351    (set (attr "modrm")
3352      (if_then_else (eq_attr "prefix_0f" "0")
3353         (const_string "0")
3354         (const_string "1")))])
3355
3356 (define_insn "*extendhisi2_zext"
3357   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358         (zero_extend:DI
3359           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3360   "TARGET_64BIT"
3361 {
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3368     }
3369 }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3382
3383 (define_insn "extendqihi2"
3384   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3385         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3386   ""
3387 {
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cbtw|cbw}";
3392     default:
3393       return "movs{bw|x}\t{%1,%0|%0, %1}";
3394     }
3395 }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "HI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3408
3409 (define_insn "extendqisi2"
3410   [(set (match_operand:SI 0 "register_operand" "=r")
3411         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3412   ""
3413   "movs{bl|x}\t{%1,%0|%0, %1}"
3414    [(set_attr "type" "imovx")
3415     (set_attr "mode" "SI")])
3416
3417 (define_insn "*extendqisi2_zext"
3418   [(set (match_operand:DI 0 "register_operand" "=r")
3419         (zero_extend:DI
3420           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3421   "TARGET_64BIT"
3422   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3423    [(set_attr "type" "imovx")
3424     (set_attr "mode" "SI")])
3425 \f
3426 ;; Conversions between float and double.
3427
3428 ;; These are all no-ops in the model used for the 80387.  So just
3429 ;; emit moves.
3430
3431 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3432 (define_insn "*dummy_extendsfdf2"
3433   [(set (match_operand:DF 0 "push_operand" "=<")
3434         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3435   "0"
3436   "#")
3437
3438 (define_split
3439   [(set (match_operand:DF 0 "push_operand" "")
3440         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3441   "!TARGET_64BIT"
3442   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3443    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3444
3445 (define_split
3446   [(set (match_operand:DF 0 "push_operand" "")
3447         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "TARGET_64BIT"
3449   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3450    (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3451
3452 (define_insn "*dummy_extendsfxf2"
3453   [(set (match_operand:XF 0 "push_operand" "=<")
3454         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3455   "0"
3456   "#")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   ""
3462   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3463    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469   "TARGET_64BIT"
3470   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3471    (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   ""
3478   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3479    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485   "TARGET_64BIT"
3486   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3487    (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_expand "extendsfdf2"
3491   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3493   "TARGET_80387 || TARGET_SSE2"
3494 {
3495   /* ??? Needed for compress_float_constant since all fp constants
3496      are LEGITIMATE_CONSTANT_P.  */
3497   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3498     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3499   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3500     operands[1] = force_reg (SFmode, operands[1]);
3501 })
3502
3503 (define_insn "*extendsfdf2_1"
3504   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3505         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3506   "(TARGET_80387 || TARGET_SSE2)
3507    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3508 {
3509   switch (which_alternative)
3510     {
3511     case 0:
3512       if (REG_P (operands[1])
3513           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3514         return "fstp\t%y0";
3515       else if (STACK_TOP_P (operands[0]))
3516         return "fld%z1\t%y1";
3517       else
3518         return "fst\t%y0";
3519
3520     case 1:
3521       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3522         return "fstp%z0\t%y0";
3523
3524       else
3525         return "fst%z0\t%y0";
3526     case 2:
3527       return "cvtss2sd\t{%1, %0|%0, %1}";
3528
3529     default:
3530       abort ();
3531     }
3532 }
3533   [(set_attr "type" "fmov,fmov,ssecvt")
3534    (set_attr "mode" "SF,XF,DF")])
3535
3536 (define_insn "*extendsfdf2_1_sse_only"
3537   [(set (match_operand:DF 0 "register_operand" "=Y")
3538         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3539   "!TARGET_80387 && TARGET_SSE2
3540    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3541   "cvtss2sd\t{%1, %0|%0, %1}"
3542   [(set_attr "type" "ssecvt")
3543    (set_attr "mode" "DF")])
3544
3545 (define_expand "extendsfxf2"
3546   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3547         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3548   "TARGET_80387"
3549 {
3550   /* ??? Needed for compress_float_constant since all fp constants
3551      are LEGITIMATE_CONSTANT_P.  */
3552   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3553     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3554   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3555     operands[1] = force_reg (SFmode, operands[1]);
3556 })
3557
3558 (define_insn "*extendsfxf2_1"
3559   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3560         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3561   "TARGET_80387
3562    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3563 {
3564   switch (which_alternative)
3565     {
3566     case 0:
3567       if (REG_P (operands[1])
3568           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3569         return "fstp\t%y0";
3570       else if (STACK_TOP_P (operands[0]))
3571         return "fld%z1\t%y1";
3572       else
3573         return "fst\t%y0";
3574
3575     case 1:
3576       /* There is no non-popping store to memory for XFmode.  So if
3577          we need one, follow the store with a load.  */
3578       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3579         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3580       else
3581         return "fstp%z0\t%y0";
3582
3583     default:
3584       abort ();
3585     }
3586 }
3587   [(set_attr "type" "fmov")
3588    (set_attr "mode" "SF,XF")])
3589
3590 (define_expand "extenddfxf2"
3591   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3592         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3593   "TARGET_80387"
3594 {
3595   /* ??? Needed for compress_float_constant since all fp constants
3596      are LEGITIMATE_CONSTANT_P.  */
3597   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3598     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3599   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3600     operands[1] = force_reg (DFmode, operands[1]);
3601 })
3602
3603 (define_insn "*extenddfxf2_1"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3605         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3606   "TARGET_80387
3607    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 {
3609   switch (which_alternative)
3610     {
3611     case 0:
3612       if (REG_P (operands[1])
3613           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614         return "fstp\t%y0";
3615       else if (STACK_TOP_P (operands[0]))
3616         return "fld%z1\t%y1";
3617       else
3618         return "fst\t%y0";
3619
3620     case 1:
3621       /* There is no non-popping store to memory for XFmode.  So if
3622          we need one, follow the store with a load.  */
3623       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3625       else
3626         return "fstp%z0\t%y0";
3627
3628     default:
3629       abort ();
3630     }
3631 }
3632   [(set_attr "type" "fmov")
3633    (set_attr "mode" "DF,XF")])
3634
3635 ;; %%% This seems bad bad news.
3636 ;; This cannot output into an f-reg because there is no way to be sure
3637 ;; of truncating in that case.  Otherwise this is just like a simple move
3638 ;; insn.  So we pretend we can output to a reg in order to get better
3639 ;; register preferencing, but we really use a stack slot.
3640
3641 (define_expand "truncdfsf2"
3642   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3643                    (float_truncate:SF
3644                     (match_operand:DF 1 "register_operand" "")))
3645               (clobber (match_dup 2))])]
3646   "TARGET_80387 || TARGET_SSE2"
3647   "
3648    if (TARGET_80387)
3649      operands[2] = assign_386_stack_local (SFmode, 0);
3650    else
3651      {
3652         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3653         DONE;
3654      }
3655 ")
3656
3657 (define_insn "*truncdfsf2_1"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3659         (float_truncate:SF
3660          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3661    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3662   "TARGET_80387 && !TARGET_SSE2"
3663 {
3664   switch (which_alternative)
3665     {
3666     case 0:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671     default:
3672       abort ();
3673     }
3674 }
3675   [(set_attr "type" "fmov,multi,multi,multi")
3676    (set_attr "mode" "SF,SF,SF,SF")])
3677
3678 (define_insn "*truncdfsf2_1_sse"
3679   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3680         (float_truncate:SF
3681          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3682    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3683   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3684 {
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689         return "fstp%z0\t%y0";
3690       else
3691         return "fst%z0\t%y0";
3692     case 4:
3693       return "#";
3694     default:
3695       abort ();
3696     }
3697 }
3698   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3699    (set_attr "mode" "SF,SF,SF,SF,DF")])
3700
3701 (define_insn "*truncdfsf2_1_sse_nooverlap"
3702   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3703         (float_truncate:SF
3704          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3705    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3706   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3707 {
3708   switch (which_alternative)
3709     {
3710     case 0:
3711       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0";
3713       else
3714         return "fst%z0\t%y0";
3715     case 4:
3716       return "#";
3717     default:
3718       abort ();
3719     }
3720 }
3721   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3722    (set_attr "mode" "SF,SF,SF,SF,DF")])
3723
3724 (define_insn "*truncdfsf2_2"
3725   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3726         (float_truncate:SF
3727          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3728   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3729    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3730 {
3731   switch (which_alternative)
3732     {
3733     case 0:
3734     case 1:
3735       return "cvtsd2ss\t{%1, %0|%0, %1}";
3736     case 2:
3737       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738         return "fstp%z0\t%y0";
3739       else
3740         return "fst%z0\t%y0";
3741     default:
3742       abort ();
3743     }
3744 }
3745   [(set_attr "type" "ssecvt,ssecvt,fmov")
3746    (set_attr "athlon_decode" "vector,double,*")
3747    (set_attr "mode" "SF,SF,SF")])
3748
3749 (define_insn "*truncdfsf2_2_nooverlap"
3750   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3751         (float_truncate:SF
3752          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3753   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3755 {
3756   switch (which_alternative)
3757     {
3758     case 0:
3759       return "#";
3760     case 1:
3761       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762         return "fstp%z0\t%y0";
3763       else
3764         return "fst%z0\t%y0";
3765     default:
3766       abort ();
3767     }
3768 }
3769   [(set_attr "type" "ssecvt,fmov")
3770    (set_attr "mode" "DF,SF")])
3771
3772 (define_insn "*truncdfsf2_3"
3773   [(set (match_operand:SF 0 "memory_operand" "=m")
3774         (float_truncate:SF
3775          (match_operand:DF 1 "register_operand" "f")))]
3776   "TARGET_80387"
3777 {
3778   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779     return "fstp%z0\t%y0";
3780   else
3781     return "fst%z0\t%y0";
3782 }
3783   [(set_attr "type" "fmov")
3784    (set_attr "mode" "SF")])
3785
3786 (define_insn "truncdfsf2_sse_only"
3787   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3788         (float_truncate:SF
3789          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3790   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3791   "cvtsd2ss\t{%1, %0|%0, %1}"
3792   [(set_attr "type" "ssecvt")
3793    (set_attr "athlon_decode" "vector,double")
3794    (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_sse_only_nooverlap"
3797   [(set (match_operand:SF 0 "register_operand" "=&Y")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3800   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3801   "#"
3802   [(set_attr "type" "ssecvt")
3803    (set_attr "mode" "DF")])
3804
3805 (define_split
3806   [(set (match_operand:SF 0 "memory_operand" "")
3807         (float_truncate:SF
3808          (match_operand:DF 1 "register_operand" "")))
3809    (clobber (match_operand:SF 2 "memory_operand" ""))]
3810   "TARGET_80387"
3811   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3812   "")
3813
3814 ; Avoid possible reformatting penalty on the destination by first
3815 ; zeroing it out
3816 (define_split
3817   [(set (match_operand:SF 0 "register_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "nonimmediate_operand" "")))
3820    (clobber (match_operand 2 "" ""))]
3821   "TARGET_80387 && reload_completed
3822    && SSE_REG_P (operands[0])
3823    && !STACK_REG_P (operands[1])"
3824   [(const_int 0)]
3825 {
3826   rtx src, dest;
3827   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3828     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3829   else
3830     {
3831       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3832       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3833       /* simplify_gen_subreg refuses to widen memory references.  */
3834       if (GET_CODE (src) == SUBREG)
3835         alter_subreg (&src);
3836       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3837         abort ();
3838       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3839       emit_insn (gen_cvtsd2ss (dest, dest, src));
3840     }
3841   DONE;
3842 })
3843
3844 (define_split
3845   [(set (match_operand:SF 0 "register_operand" "")
3846         (float_truncate:SF
3847          (match_operand:DF 1 "nonimmediate_operand" "")))]
3848   "TARGET_80387 && reload_completed
3849    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3850   [(const_int 0)]
3851 {
3852   rtx src, dest;
3853   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3854   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3855   /* simplify_gen_subreg refuses to widen memory references.  */
3856   if (GET_CODE (src) == SUBREG)
3857     alter_subreg (&src);
3858   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3859     abort ();
3860   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3861   emit_insn (gen_cvtsd2ss (dest, dest, src));
3862   DONE;
3863 })
3864
3865 (define_split
3866   [(set (match_operand:SF 0 "register_operand" "")
3867         (float_truncate:SF
3868          (match_operand:DF 1 "fp_register_operand" "")))
3869    (clobber (match_operand:SF 2 "memory_operand" ""))]
3870   "TARGET_80387 && reload_completed"
3871   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3872    (set (match_dup 0) (match_dup 2))]
3873   "")
3874
3875 (define_expand "truncxfsf2"
3876   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3877                    (float_truncate:SF
3878                     (match_operand:XF 1 "register_operand" "")))
3879               (clobber (match_dup 2))])]
3880   "TARGET_80387"
3881   "operands[2] = assign_386_stack_local (SFmode, 0);")
3882
3883 (define_insn "*truncxfsf2_1"
3884   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3887    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3888   "TARGET_80387"
3889 {
3890   switch (which_alternative)
3891     {
3892     case 0:
3893       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3894         return "fstp%z0\t%y0";
3895       else
3896         return "fst%z0\t%y0";
3897     default:
3898       abort();
3899     }
3900 }
3901   [(set_attr "type" "fmov,multi,multi,multi")
3902    (set_attr "mode" "SF")])
3903
3904 (define_insn "*truncxfsf2_2"
3905   [(set (match_operand:SF 0 "memory_operand" "=m")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f")))]
3908   "TARGET_80387"
3909 {
3910   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911     return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3914 }
3915   [(set_attr "type" "fmov")
3916    (set_attr "mode" "SF")])
3917
3918 (define_split
3919   [(set (match_operand:SF 0 "memory_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387"
3924   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3925   "")
3926
3927 (define_split
3928   [(set (match_operand:SF 0 "register_operand" "")
3929         (float_truncate:SF
3930          (match_operand:XF 1 "register_operand" "")))
3931    (clobber (match_operand:SF 2 "memory_operand" ""))]
3932   "TARGET_80387 && reload_completed"
3933   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3934    (set (match_dup 0) (match_dup 2))]
3935   "")
3936
3937 (define_expand "truncxfdf2"
3938   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3939                    (float_truncate:DF
3940                     (match_operand:XF 1 "register_operand" "")))
3941               (clobber (match_dup 2))])]
3942   "TARGET_80387"
3943   "operands[2] = assign_386_stack_local (DFmode, 0);")
3944
3945 (define_insn "*truncxfdf2_1"
3946   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3947         (float_truncate:DF
3948          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3949    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3950   "TARGET_80387"
3951 {
3952   switch (which_alternative)
3953     {
3954     case 0:
3955       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956         return "fstp%z0\t%y0";
3957       else
3958         return "fst%z0\t%y0";
3959     default:
3960       abort();
3961     }
3962   abort ();
3963 }
3964   [(set_attr "type" "fmov,multi,multi,multi")
3965    (set_attr "mode" "DF")])
3966
3967 (define_insn "*truncxfdf2_2"
3968   [(set (match_operand:DF 0 "memory_operand" "=m")
3969         (float_truncate:DF
3970           (match_operand:XF 1 "register_operand" "f")))]
3971   "TARGET_80387"
3972 {
3973   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974     return "fstp%z0\t%y0";
3975   else
3976     return "fst%z0\t%y0";
3977 }
3978   [(set_attr "type" "fmov")
3979    (set_attr "mode" "DF")])
3980
3981 (define_split
3982   [(set (match_operand:DF 0 "memory_operand" "")
3983         (float_truncate:DF
3984          (match_operand:XF 1 "register_operand" "")))
3985    (clobber (match_operand:DF 2 "memory_operand" ""))]
3986   "TARGET_80387"
3987   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3988   "")
3989
3990 (define_split
3991   [(set (match_operand:DF 0 "register_operand" "")
3992         (float_truncate:DF
3993          (match_operand:XF 1 "register_operand" "")))
3994    (clobber (match_operand:DF 2 "memory_operand" ""))]
3995   "TARGET_80387 && reload_completed"
3996   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3997    (set (match_dup 0) (match_dup 2))]
3998   "")
3999
4000 \f
4001 ;; %%% Break up all these bad boys.
4002
4003 ;; Signed conversion to DImode.
4004
4005 (define_expand "fix_truncxfdi2"
4006   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007         (fix:DI (match_operand:XF 1 "register_operand" "")))]
4008   "TARGET_80387"
4009   "")
4010
4011 (define_expand "fix_truncdfdi2"
4012   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4013         (fix:DI (match_operand:DF 1 "register_operand" "")))]
4014   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4015 {
4016   if (TARGET_64BIT && TARGET_SSE2)
4017    {
4018      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4020      if (out != operands[0])
4021         emit_move_insn (operands[0], out);
4022      DONE;
4023    }
4024 })
4025
4026 (define_expand "fix_truncsfdi2"
4027   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028         (fix:DI (match_operand:SF 1 "register_operand" "")))]
4029   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4030 {
4031   if (TARGET_SSE && TARGET_64BIT)
4032    {
4033      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4034      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4035      if (out != operands[0])
4036         emit_move_insn (operands[0], out);
4037      DONE;
4038    }
4039 })
4040
4041 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4042 ;; of the machinery.
4043 (define_insn_and_split "*fix_truncdi_1"
4044   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4045         (fix:DI (match_operand 1 "register_operand" "f,f")))]
4046   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4047    && !reload_completed && !reload_in_progress
4048    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4049   "#"
4050   "&& 1"
4051   [(const_int 0)]
4052 {
4053   ix86_optimize_mode_switching = 1;
4054   operands[2] = assign_386_stack_local (HImode, 1);
4055   operands[3] = assign_386_stack_local (HImode, 2);
4056   if (memory_operand (operands[0], VOIDmode))
4057     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4058                                        operands[2], operands[3]));
4059   else
4060     {
4061       operands[4] = assign_386_stack_local (DImode, 0);
4062       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4063                                            operands[2], operands[3],
4064                                            operands[4]));
4065     }
4066   DONE;
4067 }
4068   [(set_attr "type" "fistp")
4069    (set_attr "mode" "DI")])
4070
4071 (define_insn "fix_truncdi_nomemory"
4072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4073         (fix:DI (match_operand 1 "register_operand" "f,f")))
4074    (use (match_operand:HI 2 "memory_operand" "m,m"))
4075    (use (match_operand:HI 3 "memory_operand" "m,m"))
4076    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4077    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4078   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4079    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4080   "#"
4081   [(set_attr "type" "fistp")
4082    (set_attr "mode" "DI")])
4083
4084 (define_insn "fix_truncdi_memory"
4085   [(set (match_operand:DI 0 "memory_operand" "=m")
4086         (fix:DI (match_operand 1 "register_operand" "f")))
4087    (use (match_operand:HI 2 "memory_operand" "m"))
4088    (use (match_operand:HI 3 "memory_operand" "m"))
4089    (clobber (match_scratch:DF 4 "=&1f"))]
4090   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4091    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4092   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4093   [(set_attr "type" "fistp")
4094    (set_attr "mode" "DI")])
4095
4096 (define_split 
4097   [(set (match_operand:DI 0 "register_operand" "")
4098         (fix:DI (match_operand 1 "register_operand" "")))
4099    (use (match_operand:HI 2 "memory_operand" ""))
4100    (use (match_operand:HI 3 "memory_operand" ""))
4101    (clobber (match_operand:DI 4 "memory_operand" ""))
4102    (clobber (match_scratch 5 ""))]
4103   "reload_completed"
4104   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4105               (use (match_dup 2))
4106               (use (match_dup 3))
4107               (clobber (match_dup 5))])
4108    (set (match_dup 0) (match_dup 4))]
4109   "")
4110
4111 (define_split 
4112   [(set (match_operand:DI 0 "memory_operand" "")
4113         (fix:DI (match_operand 1 "register_operand" "")))
4114    (use (match_operand:HI 2 "memory_operand" ""))
4115    (use (match_operand:HI 3 "memory_operand" ""))
4116    (clobber (match_operand:DI 4 "memory_operand" ""))
4117    (clobber (match_scratch 5 ""))]
4118   "reload_completed"
4119   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4120               (use (match_dup 2))
4121               (use (match_dup 3))
4122               (clobber (match_dup 5))])]
4123   "")
4124
4125 ;; When SSE available, it is always faster to use it!
4126 (define_insn "fix_truncsfdi_sse"
4127   [(set (match_operand:DI 0 "register_operand" "=r,r")
4128         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_64BIT && TARGET_SSE"
4130   "cvttss2si{q}\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "SF")
4133    (set_attr "athlon_decode" "double,vector")])
4134
4135 ;; Avoid vector decoded form of the instruction.
4136 (define_peephole2
4137   [(match_scratch:SF 2 "x")
4138    (set (match_operand:DI 0 "register_operand" "")
4139         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4140   "TARGET_K8 && !optimize_size"
4141   [(set (match_dup 2) (match_dup 1))
4142    (set (match_dup 0) (fix:DI (match_dup 2)))]
4143   "")
4144
4145 (define_insn "fix_truncdfdi_sse"
4146   [(set (match_operand:DI 0 "register_operand" "=r,r")
4147         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4148   "TARGET_64BIT && TARGET_SSE2"
4149   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4150   [(set_attr "type" "sseicvt,sseicvt")
4151    (set_attr "mode" "DF")
4152    (set_attr "athlon_decode" "double,vector")])
4153
4154 ;; Avoid vector decoded form of the instruction.
4155 (define_peephole2
4156   [(match_scratch:DF 2 "Y")
4157    (set (match_operand:DI 0 "register_operand" "")
4158         (fix:DI (match_operand:DF 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 ;; Signed conversion to SImode.
4165
4166 (define_expand "fix_truncxfsi2"
4167   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4168         (fix:SI (match_operand:XF 1 "register_operand" "")))]
4169   "TARGET_80387"
4170   "")
4171
4172 (define_expand "fix_truncdfsi2"
4173   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4174         (fix:SI (match_operand:DF 1 "register_operand" "")))]
4175   "TARGET_80387 || TARGET_SSE2"
4176 {
4177   if (TARGET_SSE2)
4178    {
4179      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4180      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4181      if (out != operands[0])
4182         emit_move_insn (operands[0], out);
4183      DONE;
4184    }
4185 })
4186
4187 (define_expand "fix_truncsfsi2"
4188   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189         (fix:SI (match_operand:SF 1 "register_operand" "")))]
4190   "TARGET_80387 || TARGET_SSE"
4191 {
4192   if (TARGET_SSE)
4193    {
4194      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4195      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4196      if (out != operands[0])
4197         emit_move_insn (operands[0], out);
4198      DONE;
4199    }
4200 })
4201
4202 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4203 ;; of the machinery.
4204 (define_insn_and_split "*fix_truncsi_1"
4205   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4206         (fix:SI (match_operand 1 "register_operand" "f,f")))]
4207   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4208    && !reload_completed && !reload_in_progress
4209    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4210   "#"
4211   "&& 1"
4212   [(const_int 0)]
4213 {
4214   ix86_optimize_mode_switching = 1;
4215   operands[2] = assign_386_stack_local (HImode, 1);
4216   operands[3] = assign_386_stack_local (HImode, 2);
4217   if (memory_operand (operands[0], VOIDmode))
4218     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4219                                        operands[2], operands[3]));
4220   else
4221     {
4222       operands[4] = assign_386_stack_local (SImode, 0);
4223       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4224                                            operands[2], operands[3],
4225                                            operands[4]));
4226     }
4227   DONE;
4228 }
4229   [(set_attr "type" "fistp")
4230    (set_attr "mode" "SI")])
4231
4232 (define_insn "fix_truncsi_nomemory"
4233   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4234         (fix:SI (match_operand 1 "register_operand" "f,f")))
4235    (use (match_operand:HI 2 "memory_operand" "m,m"))
4236    (use (match_operand:HI 3 "memory_operand" "m,m"))
4237    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4238   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4239    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4240   "#"
4241   [(set_attr "type" "fistp")
4242    (set_attr "mode" "SI")])
4243
4244 (define_insn "fix_truncsi_memory"
4245   [(set (match_operand:SI 0 "memory_operand" "=m")
4246         (fix:SI (match_operand 1 "register_operand" "f")))
4247    (use (match_operand:HI 2 "memory_operand" "m"))
4248    (use (match_operand:HI 3 "memory_operand" "m"))]
4249   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4250    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4251   "* return output_fix_trunc (insn, operands);"
4252   [(set_attr "type" "fistp")
4253    (set_attr "mode" "SI")])
4254
4255 ;; When SSE available, it is always faster to use it!
4256 (define_insn "fix_truncsfsi_sse"
4257   [(set (match_operand:SI 0 "register_operand" "=r,r")
4258         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4259   "TARGET_SSE"
4260   "cvttss2si\t{%1, %0|%0, %1}"
4261   [(set_attr "type" "sseicvt")
4262    (set_attr "mode" "DF")
4263    (set_attr "athlon_decode" "double,vector")])
4264
4265 ;; Avoid vector decoded form of the instruction.
4266 (define_peephole2
4267   [(match_scratch:SF 2 "x")
4268    (set (match_operand:SI 0 "register_operand" "")
4269         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4270   "TARGET_K8 && !optimize_size"
4271   [(set (match_dup 2) (match_dup 1))
4272    (set (match_dup 0) (fix:SI (match_dup 2)))]
4273   "")
4274
4275 (define_insn "fix_truncdfsi_sse"
4276   [(set (match_operand:SI 0 "register_operand" "=r,r")
4277         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4278   "TARGET_SSE2"
4279   "cvttsd2si\t{%1, %0|%0, %1}"
4280   [(set_attr "type" "sseicvt")
4281    (set_attr "mode" "DF")
4282    (set_attr "athlon_decode" "double,vector")])
4283
4284 ;; Avoid vector decoded form of the instruction.
4285 (define_peephole2
4286   [(match_scratch:DF 2 "Y")
4287    (set (match_operand:SI 0 "register_operand" "")
4288         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4289   "TARGET_K8 && !optimize_size"
4290   [(set (match_dup 2) (match_dup 1))
4291    (set (match_dup 0) (fix:SI (match_dup 2)))]
4292   "")
4293
4294 (define_split 
4295   [(set (match_operand:SI 0 "register_operand" "")
4296         (fix:SI (match_operand 1 "register_operand" "")))
4297    (use (match_operand:HI 2 "memory_operand" ""))
4298    (use (match_operand:HI 3 "memory_operand" ""))
4299    (clobber (match_operand:SI 4 "memory_operand" ""))]
4300   "reload_completed"
4301   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4302               (use (match_dup 2))
4303               (use (match_dup 3))])
4304    (set (match_dup 0) (match_dup 4))]
4305   "")
4306
4307 (define_split 
4308   [(set (match_operand:SI 0 "memory_operand" "")
4309         (fix:SI (match_operand 1 "register_operand" "")))
4310    (use (match_operand:HI 2 "memory_operand" ""))
4311    (use (match_operand:HI 3 "memory_operand" ""))
4312    (clobber (match_operand:SI 4 "memory_operand" ""))]
4313   "reload_completed"
4314   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4315               (use (match_dup 2))
4316               (use (match_dup 3))])]
4317   "")
4318
4319 ;; Signed conversion to HImode.
4320
4321 (define_expand "fix_truncxfhi2"
4322   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4323         (fix:HI (match_operand:XF 1 "register_operand" "")))]
4324   "TARGET_80387"
4325   "")
4326
4327 (define_expand "fix_truncdfhi2"
4328   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329         (fix:HI (match_operand:DF 1 "register_operand" "")))]
4330   "TARGET_80387 && !TARGET_SSE2"
4331   "")
4332
4333 (define_expand "fix_truncsfhi2"
4334   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335         (fix:HI (match_operand:SF 1 "register_operand" "")))]
4336   "TARGET_80387 && !TARGET_SSE"
4337   "")
4338
4339 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4340 ;; of the machinery.
4341 (define_insn_and_split "*fix_trunchi_1"
4342   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4343         (fix:HI (match_operand 1 "register_operand" "f,f")))]
4344   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4345    && !reload_completed && !reload_in_progress
4346    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4347   "#"
4348   ""
4349   [(const_int 0)]
4350 {
4351   ix86_optimize_mode_switching = 1;
4352   operands[2] = assign_386_stack_local (HImode, 1);
4353   operands[3] = assign_386_stack_local (HImode, 2);
4354   if (memory_operand (operands[0], VOIDmode))
4355     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4356                                        operands[2], operands[3]));
4357   else
4358     {
4359       operands[4] = assign_386_stack_local (HImode, 0);
4360       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4361                                            operands[2], operands[3],
4362                                            operands[4]));
4363     }
4364   DONE;
4365 }
4366   [(set_attr "type" "fistp")
4367    (set_attr "mode" "HI")])
4368
4369 (define_insn "fix_trunchi_nomemory"
4370   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4371         (fix:HI (match_operand 1 "register_operand" "f,f")))
4372    (use (match_operand:HI 2 "memory_operand" "m,m"))
4373    (use (match_operand:HI 3 "memory_operand" "m,m"))
4374    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4375   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4376    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4377   "#"
4378   [(set_attr "type" "fistp")
4379    (set_attr "mode" "HI")])
4380
4381 (define_insn "fix_trunchi_memory"
4382   [(set (match_operand:HI 0 "memory_operand" "=m")
4383         (fix:HI (match_operand 1 "register_operand" "f")))
4384    (use (match_operand:HI 2 "memory_operand" "m"))
4385    (use (match_operand:HI 3 "memory_operand" "m"))]
4386   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388   "* return output_fix_trunc (insn, operands);"
4389   [(set_attr "type" "fistp")
4390    (set_attr "mode" "HI")])
4391
4392 (define_split 
4393   [(set (match_operand:HI 0 "memory_operand" "")
4394         (fix:HI (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:HI 4 "memory_operand" ""))]
4398   "reload_completed"
4399   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4400               (use (match_dup 2))
4401               (use (match_dup 3))])]
4402   "")
4403
4404 (define_split 
4405   [(set (match_operand:HI 0 "register_operand" "")
4406         (fix:HI (match_operand 1 "register_operand" "")))
4407    (use (match_operand:HI 2 "memory_operand" ""))
4408    (use (match_operand:HI 3 "memory_operand" ""))
4409    (clobber (match_operand:HI 4 "memory_operand" ""))]
4410   "reload_completed"
4411   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4412               (use (match_dup 2))
4413               (use (match_dup 3))
4414               (clobber (match_dup 4))])
4415    (set (match_dup 0) (match_dup 4))]
4416   "")
4417
4418 ;; %% Not used yet.
4419 (define_insn "x86_fnstcw_1"
4420   [(set (match_operand:HI 0 "memory_operand" "=m")
4421         (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4422   "TARGET_80387"
4423   "fnstcw\t%0"
4424   [(set_attr "length" "2")
4425    (set_attr "mode" "HI")
4426    (set_attr "unit" "i387")
4427    (set_attr "ppro_uops" "few")])
4428
4429 (define_insn "x86_fldcw_1"
4430   [(set (reg:HI 18)
4431         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4432   "TARGET_80387"
4433   "fldcw\t%0"
4434   [(set_attr "length" "2")
4435    (set_attr "mode" "HI")
4436    (set_attr "unit" "i387")
4437    (set_attr "athlon_decode" "vector")
4438    (set_attr "ppro_uops" "few")])
4439 \f
4440 ;; Conversion between fixed point and floating point.
4441
4442 ;; Even though we only accept memory inputs, the backend _really_
4443 ;; wants to be able to do this between registers.
4444
4445 (define_expand "floathisf2"
4446   [(set (match_operand:SF 0 "register_operand" "")
4447         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4448   "TARGET_SSE || TARGET_80387"
4449 {
4450   if (TARGET_SSE && TARGET_SSE_MATH)
4451     {
4452       emit_insn (gen_floatsisf2 (operands[0],
4453                                  convert_to_mode (SImode, operands[1], 0)));
4454       DONE;
4455     }
4456 })
4457
4458 (define_insn "*floathisf2_1"
4459   [(set (match_operand:SF 0 "register_operand" "=f,f")
4460         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4461   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4462   "@
4463    fild%z1\t%1
4464    #"
4465   [(set_attr "type" "fmov,multi")
4466    (set_attr "mode" "SF")
4467    (set_attr "fp_int_src" "true")])
4468
4469 (define_expand "floatsisf2"
4470   [(set (match_operand:SF 0 "register_operand" "")
4471         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4472   "TARGET_SSE || TARGET_80387"
4473   "")
4474
4475 (define_insn "*floatsisf2_i387"
4476   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4477         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4478   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4479   "@
4480    fild%z1\t%1
4481    #
4482    cvtsi2ss\t{%1, %0|%0, %1}
4483    cvtsi2ss\t{%1, %0|%0, %1}"
4484   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4485    (set_attr "mode" "SF")
4486    (set_attr "athlon_decode" "*,*,vector,double")
4487    (set_attr "fp_int_src" "true")])
4488
4489 (define_insn "*floatsisf2_sse"
4490   [(set (match_operand:SF 0 "register_operand" "=x,x")
4491         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4492   "TARGET_SSE"
4493   "cvtsi2ss\t{%1, %0|%0, %1}"
4494   [(set_attr "type" "sseicvt")
4495    (set_attr "mode" "SF")
4496    (set_attr "athlon_decode" "vector,double")
4497    (set_attr "fp_int_src" "true")])
4498
4499 ; Avoid possible reformatting penalty on the destination by first
4500 ; zeroing it out
4501 (define_split
4502   [(set (match_operand:SF 0 "register_operand" "")
4503         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4504   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4505    && SSE_REG_P (operands[0])"
4506   [(const_int 0)]
4507 {
4508   rtx dest;
4509   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4510   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4511   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4512   DONE;
4513 })
4514
4515 (define_expand "floatdisf2"
4516   [(set (match_operand:SF 0 "register_operand" "")
4517         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4518   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4519   "")
4520
4521 (define_insn "*floatdisf2_i387_only"
4522   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4523         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4524   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4525   "@
4526    fild%z1\t%1
4527    #"
4528   [(set_attr "type" "fmov,multi")
4529    (set_attr "mode" "SF")
4530    (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatdisf2_i387"
4533   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4534         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4535   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4536   "@
4537    fild%z1\t%1
4538    #
4539    cvtsi2ss{q}\t{%1, %0|%0, %1}
4540    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4541   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4542    (set_attr "mode" "SF")
4543    (set_attr "athlon_decode" "*,*,vector,double")
4544    (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatdisf2_sse"
4547   [(set (match_operand:SF 0 "register_operand" "=x,x")
4548         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549   "TARGET_64BIT && TARGET_SSE"
4550   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "sseicvt")
4552    (set_attr "mode" "SF")
4553    (set_attr "athlon_decode" "vector,double")
4554    (set_attr "fp_int_src" "true")])
4555
4556 ; Avoid possible reformatting penalty on the destination by first
4557 ; zeroing it out
4558 (define_split
4559   [(set (match_operand:SF 0 "register_operand" "")
4560         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4561   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4562    && SSE_REG_P (operands[0])"
4563   [(const_int 0)]
4564 {
4565   rtx dest;
4566   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4568   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4569   DONE;
4570 })
4571
4572 (define_expand "floathidf2"
4573   [(set (match_operand:DF 0 "register_operand" "")
4574         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4575   "TARGET_SSE2 || TARGET_80387"
4576 {
4577   if (TARGET_SSE && TARGET_SSE_MATH)
4578     {
4579       emit_insn (gen_floatsidf2 (operands[0],
4580                                  convert_to_mode (SImode, operands[1], 0)));
4581       DONE;
4582     }
4583 })
4584
4585 (define_insn "*floathidf2_1"
4586   [(set (match_operand:DF 0 "register_operand" "=f,f")
4587         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4588   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4589   "@
4590    fild%z1\t%1
4591    #"
4592   [(set_attr "type" "fmov,multi")
4593    (set_attr "mode" "DF")
4594    (set_attr "fp_int_src" "true")])
4595
4596 (define_expand "floatsidf2"
4597   [(set (match_operand:DF 0 "register_operand" "")
4598         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4599   "TARGET_80387 || TARGET_SSE2"
4600   "")
4601
4602 (define_insn "*floatsidf2_i387"
4603   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4604         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4605   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4606   "@
4607    fild%z1\t%1
4608    #
4609    cvtsi2sd\t{%1, %0|%0, %1}
4610    cvtsi2sd\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4612    (set_attr "mode" "DF")
4613    (set_attr "athlon_decode" "*,*,double,direct")
4614    (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "*floatsidf2_sse"
4617   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4618         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4619   "TARGET_SSE2"
4620   "cvtsi2sd\t{%1, %0|%0, %1}"
4621   [(set_attr "type" "sseicvt")
4622    (set_attr "mode" "DF")
4623    (set_attr "athlon_decode" "double,direct")
4624    (set_attr "fp_int_src" "true")])
4625
4626 (define_expand "floatdidf2"
4627   [(set (match_operand:DF 0 "register_operand" "")
4628         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4629   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4630   "")
4631
4632 (define_insn "*floatdidf2_i387_only"
4633   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4634         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4635   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4636   "@
4637    fild%z1\t%1
4638    #"
4639   [(set_attr "type" "fmov,multi")
4640    (set_attr "mode" "DF")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "*floatdidf2_i387"
4644   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4645         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4646   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4647   "@
4648    fild%z1\t%1
4649    #
4650    cvtsi2sd{q}\t{%1, %0|%0, %1}
4651    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4652   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4653    (set_attr "mode" "DF")
4654    (set_attr "athlon_decode" "*,*,double,direct")
4655    (set_attr "fp_int_src" "true")])
4656
4657 (define_insn "*floatdidf2_sse"
4658   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660   "TARGET_SSE2"
4661   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662   [(set_attr "type" "sseicvt")
4663    (set_attr "mode" "DF")
4664    (set_attr "athlon_decode" "double,direct")
4665    (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "floathixf2"
4668   [(set (match_operand:XF 0 "register_operand" "=f,f")
4669         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4670   "TARGET_80387"
4671   "@
4672    fild%z1\t%1
4673    #"
4674   [(set_attr "type" "fmov,multi")
4675    (set_attr "mode" "XF")
4676    (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "floatsixf2"
4679   [(set (match_operand:XF 0 "register_operand" "=f,f")
4680         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4681   "TARGET_80387"
4682   "@
4683    fild%z1\t%1
4684    #"
4685   [(set_attr "type" "fmov,multi")
4686    (set_attr "mode" "XF")
4687    (set_attr "fp_int_src" "true")])
4688
4689 (define_insn "floatdixf2"
4690   [(set (match_operand:XF 0 "register_operand" "=f,f")
4691         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4692   "TARGET_80387"
4693   "@
4694    fild%z1\t%1
4695    #"
4696   [(set_attr "type" "fmov,multi")
4697    (set_attr "mode" "XF")
4698    (set_attr "fp_int_src" "true")])
4699
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702   [(set (match_operand 0 "fp_register_operand" "")
4703         (float (match_operand 1 "register_operand" "")))]
4704   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4705   [(const_int 0)]
4706 {
4707   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4708   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4709   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4710   ix86_free_from_memory (GET_MODE (operands[1]));
4711   DONE;
4712 })
4713
4714 (define_expand "floatunssisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:SI 1 "register_operand" ""))]
4717   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4718   "x86_emit_floatuns (operands); DONE;")
4719
4720 (define_expand "floatunsdisf2"
4721   [(use (match_operand:SF 0 "register_operand" ""))
4722    (use (match_operand:DI 1 "register_operand" ""))]
4723   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4724   "x86_emit_floatuns (operands); DONE;")
4725
4726 (define_expand "floatunsdidf2"
4727   [(use (match_operand:DF 0 "register_operand" ""))
4728    (use (match_operand:DI 1 "register_operand" ""))]
4729   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4730   "x86_emit_floatuns (operands); DONE;")
4731 \f
4732 ;; Add instructions
4733
4734 ;; %%% splits for addsidi3
4735 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4736 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4737 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4738
4739 (define_expand "adddi3"
4740   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4741         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4742                  (match_operand:DI 2 "x86_64_general_operand" "")))
4743    (clobber (reg:CC 17))]
4744   ""
4745   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4746
4747 (define_insn "*adddi3_1"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4750                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4751    (clobber (reg:CC 17))]
4752   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4753   "#")
4754
4755 (define_split
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4758                  (match_operand:DI 2 "general_operand" "")))
4759    (clobber (reg:CC 17))]
4760   "!TARGET_64BIT && reload_completed"
4761   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4762                                           UNSPEC_ADD_CARRY))
4763               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4764    (parallel [(set (match_dup 3)
4765                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4766                                      (match_dup 4))
4767                             (match_dup 5)))
4768               (clobber (reg:CC 17))])]
4769   "split_di (operands+0, 1, operands+0, operands+3);
4770    split_di (operands+1, 1, operands+1, operands+4);
4771    split_di (operands+2, 1, operands+2, operands+5);")
4772
4773 (define_insn "adddi3_carry_rex64"
4774   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4775           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4776                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4777                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4778    (clobber (reg:CC 17))]
4779   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4780   "adc{q}\t{%2, %0|%0, %2}"
4781   [(set_attr "type" "alu")
4782    (set_attr "pent_pair" "pu")
4783    (set_attr "mode" "DI")
4784    (set_attr "ppro_uops" "few")])
4785
4786 (define_insn "*adddi3_cc_rex64"
4787   [(set (reg:CC 17)
4788         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4789                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4790                    UNSPEC_ADD_CARRY))
4791    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4792         (plus:DI (match_dup 1) (match_dup 2)))]
4793   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794   "add{q}\t{%2, %0|%0, %2}"
4795   [(set_attr "type" "alu")
4796    (set_attr "mode" "DI")])
4797
4798 (define_insn "addqi3_carry"
4799   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4800           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4801                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4802                    (match_operand:QI 2 "general_operand" "qi,qm")))
4803    (clobber (reg:CC 17))]
4804   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4805   "adc{b}\t{%2, %0|%0, %2}"
4806   [(set_attr "type" "alu")
4807    (set_attr "pent_pair" "pu")
4808    (set_attr "mode" "QI")
4809    (set_attr "ppro_uops" "few")])
4810
4811 (define_insn "addhi3_carry"
4812   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4813           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4814                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4815                    (match_operand:HI 2 "general_operand" "ri,rm")))
4816    (clobber (reg:CC 17))]
4817   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4818   "adc{w}\t{%2, %0|%0, %2}"
4819   [(set_attr "type" "alu")
4820    (set_attr "pent_pair" "pu")
4821    (set_attr "mode" "HI")
4822    (set_attr "ppro_uops" "few")])
4823
4824 (define_insn "addsi3_carry"
4825   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4826           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4827                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4828                    (match_operand:SI 2 "general_operand" "ri,rm")))
4829    (clobber (reg:CC 17))]
4830   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4831   "adc{l}\t{%2, %0|%0, %2}"
4832   [(set_attr "type" "alu")
4833    (set_attr "pent_pair" "pu")
4834    (set_attr "mode" "SI")
4835    (set_attr "ppro_uops" "few")])
4836
4837 (define_insn "*addsi3_carry_zext"
4838   [(set (match_operand:DI 0 "register_operand" "=r")
4839           (zero_extend:DI 
4840             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4841                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4842                      (match_operand:SI 2 "general_operand" "rim"))))
4843    (clobber (reg:CC 17))]
4844   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4845   "adc{l}\t{%2, %k0|%k0, %2}"
4846   [(set_attr "type" "alu")
4847    (set_attr "pent_pair" "pu")
4848    (set_attr "mode" "SI")
4849    (set_attr "ppro_uops" "few")])
4850
4851 (define_insn "*addsi3_cc"
4852   [(set (reg:CC 17)
4853         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4854                     (match_operand:SI 2 "general_operand" "ri,rm")]
4855                    UNSPEC_ADD_CARRY))
4856    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4857         (plus:SI (match_dup 1) (match_dup 2)))]
4858   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4859   "add{l}\t{%2, %0|%0, %2}"
4860   [(set_attr "type" "alu")
4861    (set_attr "mode" "SI")])
4862
4863 (define_insn "addqi3_cc"
4864   [(set (reg:CC 17)
4865         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4866                     (match_operand:QI 2 "general_operand" "qi,qm")]
4867                    UNSPEC_ADD_CARRY))
4868    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4869         (plus:QI (match_dup 1) (match_dup 2)))]
4870   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4871   "add{b}\t{%2, %0|%0, %2}"
4872   [(set_attr "type" "alu")
4873    (set_attr "mode" "QI")])
4874
4875 (define_expand "addsi3"
4876   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4877                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4878                             (match_operand:SI 2 "general_operand" "")))
4879               (clobber (reg:CC 17))])]
4880   ""
4881   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4882
4883 (define_insn "*lea_1"
4884   [(set (match_operand:SI 0 "register_operand" "=r")
4885         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4886   "!TARGET_64BIT"
4887   "lea{l}\t{%a1, %0|%0, %a1}"
4888   [(set_attr "type" "lea")
4889    (set_attr "mode" "SI")])
4890
4891 (define_insn "*lea_1_rex64"
4892   [(set (match_operand:SI 0 "register_operand" "=r")
4893         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4894   "TARGET_64BIT"
4895   "lea{l}\t{%a1, %0|%0, %a1}"
4896   [(set_attr "type" "lea")
4897    (set_attr "mode" "SI")])
4898
4899 (define_insn "*lea_1_zext"
4900   [(set (match_operand:DI 0 "register_operand" "=r")
4901         (zero_extend:DI
4902          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4903   "TARGET_64BIT"
4904   "lea{l}\t{%a1, %k0|%k0, %a1}"
4905   [(set_attr "type" "lea")
4906    (set_attr "mode" "SI")])
4907
4908 (define_insn "*lea_2_rex64"
4909   [(set (match_operand:DI 0 "register_operand" "=r")
4910         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4911   "TARGET_64BIT"
4912   "lea{q}\t{%a1, %0|%0, %a1}"
4913   [(set_attr "type" "lea")
4914    (set_attr "mode" "DI")])
4915
4916 ;; The lea patterns for non-Pmodes needs to be matched by several
4917 ;; insns converted to real lea by splitters.
4918
4919 (define_insn_and_split "*lea_general_1"
4920   [(set (match_operand 0 "register_operand" "=r")
4921         (plus (plus (match_operand 1 "index_register_operand" "r")
4922                     (match_operand 2 "register_operand" "r"))
4923               (match_operand 3 "immediate_operand" "i")))]
4924   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4925     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4926    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4927    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4928    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4929    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4930        || GET_MODE (operands[3]) == VOIDmode)"
4931   "#"
4932   "&& reload_completed"
4933   [(const_int 0)]
4934 {
4935   rtx pat;
4936   operands[0] = gen_lowpart (SImode, operands[0]);
4937   operands[1] = gen_lowpart (Pmode, operands[1]);
4938   operands[2] = gen_lowpart (Pmode, operands[2]);
4939   operands[3] = gen_lowpart (Pmode, operands[3]);
4940   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4941                       operands[3]);
4942   if (Pmode != SImode)
4943     pat = gen_rtx_SUBREG (SImode, pat, 0);
4944   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4945   DONE;
4946 }
4947   [(set_attr "type" "lea")
4948    (set_attr "mode" "SI")])
4949
4950 (define_insn_and_split "*lea_general_1_zext"
4951   [(set (match_operand:DI 0 "register_operand" "=r")
4952         (zero_extend:DI
4953           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
4954                             (match_operand:SI 2 "register_operand" "r"))
4955                    (match_operand:SI 3 "immediate_operand" "i"))))]
4956   "TARGET_64BIT"
4957   "#"
4958   "&& reload_completed"
4959   [(set (match_dup 0)
4960         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4961                                                      (match_dup 2))
4962                                             (match_dup 3)) 0)))]
4963 {
4964   operands[1] = gen_lowpart (Pmode, operands[1]);
4965   operands[2] = gen_lowpart (Pmode, operands[2]);
4966   operands[3] = gen_lowpart (Pmode, operands[3]);
4967 }
4968   [(set_attr "type" "lea")
4969    (set_attr "mode" "SI")])
4970
4971 (define_insn_and_split "*lea_general_2"
4972   [(set (match_operand 0 "register_operand" "=r")
4973         (plus (mult (match_operand 1 "index_register_operand" "r")
4974                     (match_operand 2 "const248_operand" "i"))
4975               (match_operand 3 "nonmemory_operand" "ri")))]
4976   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4977     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4978    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4979    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4980    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981        || GET_MODE (operands[3]) == VOIDmode)"
4982   "#"
4983   "&& reload_completed"
4984   [(const_int 0)]
4985 {
4986   rtx pat;
4987   operands[0] = gen_lowpart (SImode, operands[0]);
4988   operands[1] = gen_lowpart (Pmode, operands[1]);
4989   operands[3] = gen_lowpart (Pmode, operands[3]);
4990   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4991                       operands[3]);
4992   if (Pmode != SImode)
4993     pat = gen_rtx_SUBREG (SImode, pat, 0);
4994   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4995   DONE;
4996 }
4997   [(set_attr "type" "lea")
4998    (set_attr "mode" "SI")])
4999
5000 (define_insn_and_split "*lea_general_2_zext"
5001   [(set (match_operand:DI 0 "register_operand" "=r")
5002         (zero_extend:DI
5003           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5004                             (match_operand:SI 2 "const248_operand" "n"))
5005                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5006   "TARGET_64BIT"
5007   "#"
5008   "&& reload_completed"
5009   [(set (match_dup 0)
5010         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5011                                                      (match_dup 2))
5012                                             (match_dup 3)) 0)))]
5013 {
5014   operands[1] = gen_lowpart (Pmode, operands[1]);
5015   operands[3] = gen_lowpart (Pmode, operands[3]);
5016 }
5017   [(set_attr "type" "lea")
5018    (set_attr "mode" "SI")])
5019
5020 (define_insn_and_split "*lea_general_3"
5021   [(set (match_operand 0 "register_operand" "=r")
5022         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5023                           (match_operand 2 "const248_operand" "i"))
5024                     (match_operand 3 "register_operand" "r"))
5025               (match_operand 4 "immediate_operand" "i")))]
5026   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5027     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5028    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5029    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5030    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5031   "#"
5032   "&& reload_completed"
5033   [(const_int 0)]
5034 {
5035   rtx pat;
5036   operands[0] = gen_lowpart (SImode, operands[0]);
5037   operands[1] = gen_lowpart (Pmode, operands[1]);
5038   operands[3] = gen_lowpart (Pmode, operands[3]);
5039   operands[4] = gen_lowpart (Pmode, operands[4]);
5040   pat = gen_rtx_PLUS (Pmode,
5041                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5042                                                          operands[2]),
5043                                     operands[3]),
5044                       operands[4]);
5045   if (Pmode != SImode)
5046     pat = gen_rtx_SUBREG (SImode, pat, 0);
5047   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5048   DONE;
5049 }
5050   [(set_attr "type" "lea")
5051    (set_attr "mode" "SI")])
5052
5053 (define_insn_and_split "*lea_general_3_zext"
5054   [(set (match_operand:DI 0 "register_operand" "=r")
5055         (zero_extend:DI
5056           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5057                                      (match_operand:SI 2 "const248_operand" "n"))
5058                             (match_operand:SI 3 "register_operand" "r"))
5059                    (match_operand:SI 4 "immediate_operand" "i"))))]
5060   "TARGET_64BIT"
5061   "#"
5062   "&& reload_completed"
5063   [(set (match_dup 0)
5064         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5065                                                               (match_dup 2))
5066                                                      (match_dup 3))
5067                                             (match_dup 4)) 0)))]
5068 {
5069   operands[1] = gen_lowpart (Pmode, operands[1]);
5070   operands[3] = gen_lowpart (Pmode, operands[3]);
5071   operands[4] = gen_lowpart (Pmode, operands[4]);
5072 }
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn "*adddi_1_rex64"
5077   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5078         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5079                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5080    (clobber (reg:CC 17))]
5081   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5082 {
5083   switch (get_attr_type (insn))
5084     {
5085     case TYPE_LEA:
5086       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5087       return "lea{q}\t{%a2, %0|%0, %a2}";
5088
5089     case TYPE_INCDEC:
5090       if (! rtx_equal_p (operands[0], operands[1]))
5091         abort ();
5092       if (operands[2] == const1_rtx)
5093         return "inc{q}\t%0";
5094       else if (operands[2] == constm1_rtx)
5095         return "dec{q}\t%0";
5096       else
5097         abort ();
5098
5099     default:
5100       if (! rtx_equal_p (operands[0], operands[1]))
5101         abort ();
5102
5103       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5104          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5105       if (GET_CODE (operands[2]) == CONST_INT
5106           /* Avoid overflows.  */
5107           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5108           && (INTVAL (operands[2]) == 128
5109               || (INTVAL (operands[2]) < 0
5110                   && INTVAL (operands[2]) != -128)))
5111         {
5112           operands[2] = GEN_INT (-INTVAL (operands[2]));
5113           return "sub{q}\t{%2, %0|%0, %2}";
5114         }
5115       return "add{q}\t{%2, %0|%0, %2}";
5116     }
5117 }
5118   [(set (attr "type")
5119      (cond [(eq_attr "alternative" "2")
5120               (const_string "lea")
5121             ; Current assemblers are broken and do not allow @GOTOFF in
5122             ; ought but a memory context.
5123             (match_operand:DI 2 "pic_symbolic_operand" "")
5124               (const_string "lea")
5125             (match_operand:DI 2 "incdec_operand" "")
5126               (const_string "incdec")
5127            ]
5128            (const_string "alu")))
5129    (set_attr "mode" "DI")])
5130
5131 ;; Convert lea to the lea pattern to avoid flags dependency.
5132 (define_split
5133   [(set (match_operand:DI 0 "register_operand" "")
5134         (plus:DI (match_operand:DI 1 "register_operand" "")
5135                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5136    (clobber (reg:CC 17))]
5137   "TARGET_64BIT && reload_completed
5138    && true_regnum (operands[0]) != true_regnum (operands[1])"
5139   [(set (match_dup 0)
5140         (plus:DI (match_dup 1)
5141                  (match_dup 2)))]
5142   "")
5143
5144 (define_insn "*adddi_2_rex64"
5145   [(set (reg 17)
5146         (compare
5147           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5148                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5149           (const_int 0)))                       
5150    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5151         (plus:DI (match_dup 1) (match_dup 2)))]
5152   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5153    && ix86_binary_operator_ok (PLUS, DImode, operands)
5154    /* Current assemblers are broken and do not allow @GOTOFF in
5155       ought but a memory context.  */
5156    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5157 {
5158   switch (get_attr_type (insn))
5159     {
5160     case TYPE_INCDEC:
5161       if (! rtx_equal_p (operands[0], operands[1]))
5162         abort ();
5163       if (operands[2] == const1_rtx)
5164         return "inc{q}\t%0";
5165       else if (operands[2] == constm1_rtx)
5166         return "dec{q}\t%0";
5167       else
5168         abort ();
5169
5170     default:
5171       if (! rtx_equal_p (operands[0], operands[1]))
5172         abort ();
5173       /* ???? We ought to handle there the 32bit case too
5174          - do we need new constraint?  */
5175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5177       if (GET_CODE (operands[2]) == CONST_INT
5178           /* Avoid overflows.  */
5179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180           && (INTVAL (operands[2]) == 128
5181               || (INTVAL (operands[2]) < 0
5182                   && INTVAL (operands[2]) != -128)))
5183         {
5184           operands[2] = GEN_INT (-INTVAL (operands[2]));
5185           return "sub{q}\t{%2, %0|%0, %2}";
5186         }
5187       return "add{q}\t{%2, %0|%0, %2}";
5188     }
5189 }
5190   [(set (attr "type")
5191      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192         (const_string "incdec")
5193         (const_string "alu")))
5194    (set_attr "mode" "DI")])
5195
5196 (define_insn "*adddi_3_rex64"
5197   [(set (reg 17)
5198         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5199                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5200    (clobber (match_scratch:DI 0 "=r"))]
5201   "TARGET_64BIT
5202    && ix86_match_ccmode (insn, CCZmode)
5203    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5204    /* Current assemblers are broken and do not allow @GOTOFF in
5205       ought but a memory context.  */
5206    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5207 {
5208   switch (get_attr_type (insn))
5209     {
5210     case TYPE_INCDEC:
5211       if (! rtx_equal_p (operands[0], operands[1]))
5212         abort ();
5213       if (operands[2] == const1_rtx)
5214         return "inc{q}\t%0";
5215       else if (operands[2] == constm1_rtx)
5216         return "dec{q}\t%0";
5217       else
5218         abort ();
5219
5220     default:
5221       if (! rtx_equal_p (operands[0], operands[1]))
5222         abort ();
5223       /* ???? We ought to handle there the 32bit case too
5224          - do we need new constraint?  */
5225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5227       if (GET_CODE (operands[2]) == CONST_INT
5228           /* Avoid overflows.  */
5229           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230           && (INTVAL (operands[2]) == 128
5231               || (INTVAL (operands[2]) < 0
5232                   && INTVAL (operands[2]) != -128)))
5233         {
5234           operands[2] = GEN_INT (-INTVAL (operands[2]));
5235           return "sub{q}\t{%2, %0|%0, %2}";
5236         }
5237       return "add{q}\t{%2, %0|%0, %2}";
5238     }
5239 }
5240   [(set (attr "type")
5241      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242         (const_string "incdec")
5243         (const_string "alu")))
5244    (set_attr "mode" "DI")])
5245
5246 ; For comparisons against 1, -1 and 128, we may generate better code
5247 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5248 ; is matched then.  We can't accept general immediate, because for
5249 ; case of overflows,  the result is messed up.
5250 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5251 ; when negated.
5252 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5253 ; only for comparisons not depending on it.
5254 (define_insn "*adddi_4_rex64"
5255   [(set (reg 17)
5256         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5257                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5258    (clobber (match_scratch:DI 0 "=rm"))]
5259   "TARGET_64BIT
5260    &&  ix86_match_ccmode (insn, CCGCmode)"
5261 {
5262   switch (get_attr_type (insn))
5263     {
5264     case TYPE_INCDEC:
5265       if (operands[2] == constm1_rtx)
5266         return "inc{q}\t%0";
5267       else if (operands[2] == const1_rtx)
5268         return "dec{q}\t%0";
5269       else
5270         abort();
5271
5272     default:
5273       if (! rtx_equal_p (operands[0], operands[1]))
5274         abort ();
5275       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5276          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5277       if ((INTVAL (operands[2]) == -128
5278            || (INTVAL (operands[2]) > 0
5279                && INTVAL (operands[2]) != 128))
5280           /* Avoid overflows.  */
5281           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5282         return "sub{q}\t{%2, %0|%0, %2}";
5283       operands[2] = GEN_INT (-INTVAL (operands[2]));
5284       return "add{q}\t{%2, %0|%0, %2}";
5285     }
5286 }
5287   [(set (attr "type")
5288      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5289         (const_string "incdec")
5290         (const_string "alu")))
5291    (set_attr "mode" "DI")])
5292
5293 (define_insn "*adddi_5_rex64"
5294   [(set (reg 17)
5295         (compare
5296           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5297                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5298           (const_int 0)))                       
5299    (clobber (match_scratch:DI 0 "=r"))]
5300   "TARGET_64BIT
5301    && ix86_match_ccmode (insn, CCGOCmode)
5302    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5303    /* Current assemblers are broken and do not allow @GOTOFF in
5304       ought but a memory context.  */
5305    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 {
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_INCDEC:
5310       if (! rtx_equal_p (operands[0], operands[1]))
5311         abort ();
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else if (operands[2] == constm1_rtx)
5315         return "dec{q}\t%0";
5316       else
5317         abort();
5318
5319     default:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
5322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5324       if (GET_CODE (operands[2]) == CONST_INT
5325           /* Avoid overflows.  */
5326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327           && (INTVAL (operands[2]) == 128
5328               || (INTVAL (operands[2]) < 0
5329                   && INTVAL (operands[2]) != -128)))
5330         {
5331           operands[2] = GEN_INT (-INTVAL (operands[2]));
5332           return "sub{q}\t{%2, %0|%0, %2}";
5333         }
5334       return "add{q}\t{%2, %0|%0, %2}";
5335     }
5336 }
5337   [(set (attr "type")
5338      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339         (const_string "incdec")
5340         (const_string "alu")))
5341    (set_attr "mode" "DI")])
5342
5343
5344 (define_insn "*addsi_1"
5345   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5348    (clobber (reg:CC 17))]
5349   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %0|%0, %a2}";
5356
5357     case TYPE_INCDEC:
5358       if (! rtx_equal_p (operands[0], operands[1]))
5359         abort ();
5360       if (operands[2] == const1_rtx)
5361         return "inc{l}\t%0";
5362       else if (operands[2] == constm1_rtx)
5363         return "dec{l}\t%0";
5364       else
5365         abort();
5366
5367     default:
5368       if (! rtx_equal_p (operands[0], operands[1]))
5369         abort ();
5370
5371       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5372          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5373       if (GET_CODE (operands[2]) == CONST_INT
5374           && (INTVAL (operands[2]) == 128
5375               || (INTVAL (operands[2]) < 0
5376                   && INTVAL (operands[2]) != -128)))
5377         {
5378           operands[2] = GEN_INT (-INTVAL (operands[2]));
5379           return "sub{l}\t{%2, %0|%0, %2}";
5380         }
5381       return "add{l}\t{%2, %0|%0, %2}";
5382     }
5383 }
5384   [(set (attr "type")
5385      (cond [(eq_attr "alternative" "2")
5386               (const_string "lea")
5387             ; Current assemblers are broken and do not allow @GOTOFF in
5388             ; ought but a memory context.
5389             (match_operand:SI 2 "pic_symbolic_operand" "")
5390               (const_string "lea")
5391             (match_operand:SI 2 "incdec_operand" "")
5392               (const_string "incdec")
5393            ]
5394            (const_string "alu")))
5395    (set_attr "mode" "SI")])
5396
5397 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 (define_split
5399   [(set (match_operand 0 "register_operand" "")
5400         (plus (match_operand 1 "register_operand" "")
5401               (match_operand 2 "nonmemory_operand" "")))
5402    (clobber (reg:CC 17))]
5403   "reload_completed
5404    && true_regnum (operands[0]) != true_regnum (operands[1])"
5405   [(const_int 0)]
5406 {
5407   rtx pat;
5408   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5409      may confuse gen_lowpart.  */
5410   if (GET_MODE (operands[0]) != Pmode)
5411     {
5412       operands[1] = gen_lowpart (Pmode, operands[1]);
5413       operands[2] = gen_lowpart (Pmode, operands[2]);
5414     }
5415   operands[0] = gen_lowpart (SImode, operands[0]);
5416   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5417   if (Pmode != SImode)
5418     pat = gen_rtx_SUBREG (SImode, pat, 0);
5419   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420   DONE;
5421 })
5422
5423 ;; It may seem that nonimmediate operand is proper one for operand 1.
5424 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5425 ;; we take care in ix86_binary_operator_ok to not allow two memory
5426 ;; operands so proper swapping will be done in reload.  This allow
5427 ;; patterns constructed from addsi_1 to match.
5428 (define_insn "addsi_1_zext"
5429   [(set (match_operand:DI 0 "register_operand" "=r,r")
5430         (zero_extend:DI
5431           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5432                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5433    (clobber (reg:CC 17))]
5434   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435 {
5436   switch (get_attr_type (insn))
5437     {
5438     case TYPE_LEA:
5439       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5441
5442     case TYPE_INCDEC:
5443       if (operands[2] == const1_rtx)
5444         return "inc{l}\t%k0";
5445       else if (operands[2] == constm1_rtx)
5446         return "dec{l}\t%k0";
5447       else
5448         abort();
5449
5450     default:
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if (GET_CODE (operands[2]) == CONST_INT
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{l}\t{%2, %k0|%k0, %2}";
5460         }
5461       return "add{l}\t{%2, %k0|%k0, %2}";
5462     }
5463 }
5464   [(set (attr "type")
5465      (cond [(eq_attr "alternative" "1")
5466               (const_string "lea")
5467             ; Current assemblers are broken and do not allow @GOTOFF in
5468             ; ought but a memory context.
5469             (match_operand:SI 2 "pic_symbolic_operand" "")
5470               (const_string "lea")
5471             (match_operand:SI 2 "incdec_operand" "")
5472               (const_string "incdec")
5473            ]
5474            (const_string "alu")))
5475    (set_attr "mode" "SI")])
5476
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479   [(set (match_operand:DI 0 "register_operand" "")
5480         (zero_extend:DI
5481           (plus:SI (match_operand:SI 1 "register_operand" "")
5482                    (match_operand:SI 2 "nonmemory_operand" ""))))
5483    (clobber (reg:CC 17))]
5484   "TARGET_64BIT && reload_completed
5485    && true_regnum (operands[0]) != true_regnum (operands[1])"
5486   [(set (match_dup 0)
5487         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5488 {
5489   operands[1] = gen_lowpart (Pmode, operands[1]);
5490   operands[2] = gen_lowpart (Pmode, operands[2]);
5491 })
5492
5493 (define_insn "*addsi_2"
5494   [(set (reg 17)
5495         (compare
5496           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5498           (const_int 0)))                       
5499    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:SI (match_dup 1) (match_dup 2)))]
5501   "ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, SImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       if (! rtx_equal_p (operands[0], operands[1]))
5511         abort ();
5512       if (operands[2] == const1_rtx)
5513         return "inc{l}\t%0";
5514       else if (operands[2] == constm1_rtx)
5515         return "dec{l}\t%0";
5516       else
5517         abort();
5518
5519     default:
5520       if (! rtx_equal_p (operands[0], operands[1]))
5521         abort ();
5522       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5524       if (GET_CODE (operands[2]) == CONST_INT
5525           && (INTVAL (operands[2]) == 128
5526               || (INTVAL (operands[2]) < 0
5527                   && INTVAL (operands[2]) != -128)))
5528         {
5529           operands[2] = GEN_INT (-INTVAL (operands[2]));
5530           return "sub{l}\t{%2, %0|%0, %2}";
5531         }
5532       return "add{l}\t{%2, %0|%0, %2}";
5533     }
5534 }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "SI")])
5540
5541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5542 (define_insn "*addsi_2_zext"
5543   [(set (reg 17)
5544         (compare
5545           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5546                    (match_operand:SI 2 "general_operand" "rmni"))
5547           (const_int 0)))                       
5548    (set (match_operand:DI 0 "register_operand" "=r")
5549         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5551    && ix86_binary_operator_ok (PLUS, SImode, operands)
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       if (operands[2] == const1_rtx)
5560         return "inc{l}\t%k0";
5561       else if (operands[2] == constm1_rtx)
5562         return "dec{l}\t%k0";
5563       else
5564         abort();
5565
5566     default:
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %k0|%k0, %2}";
5576         }
5577       return "add{l}\t{%2, %k0|%k0, %2}";
5578     }
5579 }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5585
5586 (define_insn "*addsi_3"
5587   [(set (reg 17)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (clobber (match_scratch:SI 0 "=r"))]
5591   "ix86_match_ccmode (insn, CCZmode)
5592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593    /* Current assemblers are broken and do not allow @GOTOFF in
5594       ought but a memory context.  */
5595    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 {
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_INCDEC:
5600       if (! rtx_equal_p (operands[0], operands[1]))
5601         abort ();
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%0";
5604       else if (operands[2] == constm1_rtx)
5605         return "dec{l}\t%0";
5606       else
5607         abort();
5608
5609     default:
5610       if (! rtx_equal_p (operands[0], operands[1]))
5611         abort ();
5612       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5614       if (GET_CODE (operands[2]) == CONST_INT
5615           && (INTVAL (operands[2]) == 128
5616               || (INTVAL (operands[2]) < 0
5617                   && INTVAL (operands[2]) != -128)))
5618         {
5619           operands[2] = GEN_INT (-INTVAL (operands[2]));
5620           return "sub{l}\t{%2, %0|%0, %2}";
5621         }
5622       return "add{l}\t{%2, %0|%0, %2}";
5623     }
5624 }
5625   [(set (attr "type")
5626      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627         (const_string "incdec")
5628         (const_string "alu")))
5629    (set_attr "mode" "SI")])
5630
5631 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5632 (define_insn "*addsi_3_zext"
5633   [(set (reg 17)
5634         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5635                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5636    (set (match_operand:DI 0 "register_operand" "=r")
5637         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5639    && ix86_binary_operator_ok (PLUS, SImode, operands)
5640    /* Current assemblers are broken and do not allow @GOTOFF in
5641       ought but a memory context.  */
5642    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643 {
5644   switch (get_attr_type (insn))
5645     {
5646     case TYPE_INCDEC:
5647       if (operands[2] == const1_rtx)
5648         return "inc{l}\t%k0";
5649       else if (operands[2] == constm1_rtx)
5650         return "dec{l}\t%k0";
5651       else
5652         abort();
5653
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5676 ; is matched then.  We can't accept general immediate, because for
5677 ; case of overflows,  the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683   [(set (reg 17)
5684         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685                  (match_operand:SI 2 "const_int_operand" "n")))
5686    (clobber (match_scratch:SI 0 "=rm"))]
5687   "ix86_match_ccmode (insn, CCGCmode)
5688    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5689 {
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == constm1_rtx)
5694         return "inc{l}\t%0";
5695       else if (operands[2] == const1_rtx)
5696         return "dec{l}\t%0";
5697       else
5698         abort();
5699
5700     default:
5701       if (! rtx_equal_p (operands[0], operands[1]))
5702         abort ();
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if ((INTVAL (operands[2]) == -128
5706            || (INTVAL (operands[2]) > 0
5707                && INTVAL (operands[2]) != 128)))
5708         return "sub{l}\t{%2, %0|%0, %2}";
5709       operands[2] = GEN_INT (-INTVAL (operands[2]));
5710       return "add{l}\t{%2, %0|%0, %2}";
5711     }
5712 }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715         (const_string "incdec")
5716         (const_string "alu")))
5717    (set_attr "mode" "SI")])
5718
5719 (define_insn "*addsi_5"
5720   [(set (reg 17)
5721         (compare
5722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723                    (match_operand:SI 2 "general_operand" "rmni"))
5724           (const_int 0)))                       
5725    (clobber (match_scratch:SI 0 "=r"))]
5726   "ix86_match_ccmode (insn, CCGOCmode)
5727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       if (! rtx_equal_p (operands[0], operands[1]))
5736         abort ();
5737       if (operands[2] == const1_rtx)
5738         return "inc{l}\t%0";
5739       else if (operands[2] == constm1_rtx)
5740         return "dec{l}\t%0";
5741       else
5742         abort();
5743
5744     default:
5745       if (! rtx_equal_p (operands[0], operands[1]))
5746         abort ();
5747       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5748          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5749       if (GET_CODE (operands[2]) == CONST_INT
5750           && (INTVAL (operands[2]) == 128
5751               || (INTVAL (operands[2]) < 0
5752                   && INTVAL (operands[2]) != -128)))
5753         {
5754           operands[2] = GEN_INT (-INTVAL (operands[2]));
5755           return "sub{l}\t{%2, %0|%0, %2}";
5756         }
5757       return "add{l}\t{%2, %0|%0, %2}";
5758     }
5759 }
5760   [(set (attr "type")
5761      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762         (const_string "incdec")
5763         (const_string "alu")))
5764    (set_attr "mode" "SI")])
5765
5766 (define_expand "addhi3"
5767   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5768                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5769                             (match_operand:HI 2 "general_operand" "")))
5770               (clobber (reg:CC 17))])]
5771   "TARGET_HIMODE_MATH"
5772   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773
5774 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5775 ;; type optimizations enabled by define-splits.  This is not important
5776 ;; for PII, and in fact harmful because of partial register stalls.
5777
5778 (define_insn "*addhi_1_lea"
5779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5780         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5781                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5782    (clobber (reg:CC 17))]
5783   "!TARGET_PARTIAL_REG_STALL
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_LEA:
5789       return "#";
5790     case TYPE_INCDEC:
5791       if (operands[2] == const1_rtx)
5792         return "inc{w}\t%0";
5793       else if (operands[2] == constm1_rtx)
5794         return "dec{w}\t%0";
5795       abort();
5796
5797     default:
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (GET_CODE (operands[2]) == CONST_INT
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{w}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{w}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (eq_attr "alternative" "2")
5813         (const_string "lea")
5814         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5815            (const_string "incdec")
5816            (const_string "alu"))))
5817    (set_attr "mode" "HI,HI,SI")])
5818
5819 (define_insn "*addhi_1"
5820   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5821         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5822                  (match_operand:HI 2 "general_operand" "ri,rm")))
5823    (clobber (reg:CC 17))]
5824   "TARGET_PARTIAL_REG_STALL
5825    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 {
5827   switch (get_attr_type (insn))
5828     {
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{w}\t%0";
5832       else if (operands[2] == constm1_rtx)
5833         return "dec{w}\t%0";
5834       abort();
5835
5836     default:
5837       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5839       if (GET_CODE (operands[2]) == CONST_INT
5840           && (INTVAL (operands[2]) == 128
5841               || (INTVAL (operands[2]) < 0
5842                   && INTVAL (operands[2]) != -128)))
5843         {
5844           operands[2] = GEN_INT (-INTVAL (operands[2]));
5845           return "sub{w}\t{%2, %0|%0, %2}";
5846         }
5847       return "add{w}\t{%2, %0|%0, %2}";
5848     }
5849 }
5850   [(set (attr "type")
5851      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852         (const_string "incdec")
5853         (const_string "alu")))
5854    (set_attr "mode" "HI")])
5855
5856 (define_insn "*addhi_2"
5857   [(set (reg 17)
5858         (compare
5859           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5860                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5861           (const_int 0)))                       
5862    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5863         (plus:HI (match_dup 1) (match_dup 2)))]
5864   "ix86_match_ccmode (insn, CCGOCmode)
5865    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5866 {
5867   switch (get_attr_type (insn))
5868     {
5869     case TYPE_INCDEC:
5870       if (operands[2] == const1_rtx)
5871         return "inc{w}\t%0";
5872       else if (operands[2] == constm1_rtx)
5873         return "dec{w}\t%0";
5874       abort();
5875
5876     default:
5877       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5878          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5879       if (GET_CODE (operands[2]) == CONST_INT
5880           && (INTVAL (operands[2]) == 128
5881               || (INTVAL (operands[2]) < 0
5882                   && INTVAL (operands[2]) != -128)))
5883         {
5884           operands[2] = GEN_INT (-INTVAL (operands[2]));
5885           return "sub{w}\t{%2, %0|%0, %2}";
5886         }
5887       return "add{w}\t{%2, %0|%0, %2}";
5888     }
5889 }
5890   [(set (attr "type")
5891      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5892         (const_string "incdec")
5893         (const_string "alu")))
5894    (set_attr "mode" "HI")])
5895
5896 (define_insn "*addhi_3"
5897   [(set (reg 17)
5898         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5899                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5900    (clobber (match_scratch:HI 0 "=r"))]
5901   "ix86_match_ccmode (insn, CCZmode)
5902    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5903 {
5904   switch (get_attr_type (insn))
5905     {
5906     case TYPE_INCDEC:
5907       if (operands[2] == const1_rtx)
5908         return "inc{w}\t%0";
5909       else if (operands[2] == constm1_rtx)
5910         return "dec{w}\t%0";
5911       abort();
5912
5913     default:
5914       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916       if (GET_CODE (operands[2]) == CONST_INT
5917           && (INTVAL (operands[2]) == 128
5918               || (INTVAL (operands[2]) < 0
5919                   && INTVAL (operands[2]) != -128)))
5920         {
5921           operands[2] = GEN_INT (-INTVAL (operands[2]));
5922           return "sub{w}\t{%2, %0|%0, %2}";
5923         }
5924       return "add{w}\t{%2, %0|%0, %2}";
5925     }
5926 }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set_attr "mode" "HI")])
5932
5933 ; See comments above addsi_3_imm for details.
5934 (define_insn "*addhi_4"
5935   [(set (reg 17)
5936         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5937                  (match_operand:HI 2 "const_int_operand" "n")))
5938    (clobber (match_scratch:HI 0 "=rm"))]
5939   "ix86_match_ccmode (insn, CCGCmode)
5940    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5941 {
5942   switch (get_attr_type (insn))
5943     {
5944     case TYPE_INCDEC:
5945       if (operands[2] == constm1_rtx)
5946         return "inc{w}\t%0";
5947       else if (operands[2] == const1_rtx)
5948         return "dec{w}\t%0";
5949       else
5950         abort();
5951
5952     default:
5953       if (! rtx_equal_p (operands[0], operands[1]))
5954         abort ();
5955       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957       if ((INTVAL (operands[2]) == -128
5958            || (INTVAL (operands[2]) > 0
5959                && INTVAL (operands[2]) != 128)))
5960         return "sub{w}\t{%2, %0|%0, %2}";
5961       operands[2] = GEN_INT (-INTVAL (operands[2]));
5962       return "add{w}\t{%2, %0|%0, %2}";
5963     }
5964 }
5965   [(set (attr "type")
5966      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967         (const_string "incdec")
5968         (const_string "alu")))
5969    (set_attr "mode" "SI")])
5970
5971
5972 (define_insn "*addhi_5"
5973   [(set (reg 17)
5974         (compare
5975           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5976                    (match_operand:HI 2 "general_operand" "rmni"))
5977           (const_int 0)))                       
5978    (clobber (match_scratch:HI 0 "=r"))]
5979   "ix86_match_ccmode (insn, CCGOCmode)
5980    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981 {
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == const1_rtx)
5986         return "inc{w}\t%0";
5987       else if (operands[2] == constm1_rtx)
5988         return "dec{w}\t%0";
5989       abort();
5990
5991     default:
5992       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5993          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5994       if (GET_CODE (operands[2]) == CONST_INT
5995           && (INTVAL (operands[2]) == 128
5996               || (INTVAL (operands[2]) < 0
5997                   && INTVAL (operands[2]) != -128)))
5998         {
5999           operands[2] = GEN_INT (-INTVAL (operands[2]));
6000           return "sub{w}\t{%2, %0|%0, %2}";
6001         }
6002       return "add{w}\t{%2, %0|%0, %2}";
6003     }
6004 }
6005   [(set (attr "type")
6006      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007         (const_string "incdec")
6008         (const_string "alu")))
6009    (set_attr "mode" "HI")])
6010
6011 (define_expand "addqi3"
6012   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6013                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6014                             (match_operand:QI 2 "general_operand" "")))
6015               (clobber (reg:CC 17))])]
6016   "TARGET_QIMODE_MATH"
6017   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6018
6019 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6020 (define_insn "*addqi_1_lea"
6021   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6022         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6023                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6024    (clobber (reg:CC 17))]
6025   "!TARGET_PARTIAL_REG_STALL
6026    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6027 {
6028   int widen = (which_alternative == 2);
6029   switch (get_attr_type (insn))
6030     {
6031     case TYPE_LEA:
6032       return "#";
6033     case TYPE_INCDEC:
6034       if (operands[2] == const1_rtx)
6035         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6036       else if (operands[2] == constm1_rtx)
6037         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6038       abort();
6039
6040     default:
6041       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6042          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6043       if (GET_CODE (operands[2]) == CONST_INT
6044           && (INTVAL (operands[2]) == 128
6045               || (INTVAL (operands[2]) < 0
6046                   && INTVAL (operands[2]) != -128)))
6047         {
6048           operands[2] = GEN_INT (-INTVAL (operands[2]));
6049           if (widen)
6050             return "sub{l}\t{%2, %k0|%k0, %2}";
6051           else
6052             return "sub{b}\t{%2, %0|%0, %2}";
6053         }
6054       if (widen)
6055         return "add{l}\t{%k2, %k0|%k0, %k2}";
6056       else
6057         return "add{b}\t{%2, %0|%0, %2}";
6058     }
6059 }
6060   [(set (attr "type")
6061      (if_then_else (eq_attr "alternative" "3")
6062         (const_string "lea")
6063         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6064            (const_string "incdec")
6065            (const_string "alu"))))
6066    (set_attr "mode" "QI,QI,SI,SI")])
6067
6068 (define_insn "*addqi_1"
6069   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6070         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6071                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6072    (clobber (reg:CC 17))]
6073   "TARGET_PARTIAL_REG_STALL
6074    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6075 {
6076   int widen = (which_alternative == 2);
6077   switch (get_attr_type (insn))
6078     {
6079     case TYPE_INCDEC:
6080       if (operands[2] == const1_rtx)
6081         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6082       else if (operands[2] == constm1_rtx)
6083         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6084       abort();
6085
6086     default:
6087       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6088          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6089       if (GET_CODE (operands[2]) == CONST_INT
6090           && (INTVAL (operands[2]) == 128
6091               || (INTVAL (operands[2]) < 0
6092                   && INTVAL (operands[2]) != -128)))
6093         {
6094           operands[2] = GEN_INT (-INTVAL (operands[2]));
6095           if (widen)
6096             return "sub{l}\t{%2, %k0|%k0, %2}";
6097           else
6098             return "sub{b}\t{%2, %0|%0, %2}";
6099         }
6100       if (widen)
6101         return "add{l}\t{%k2, %k0|%k0, %k2}";
6102       else
6103         return "add{b}\t{%2, %0|%0, %2}";
6104     }
6105 }
6106   [(set (attr "type")
6107      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108         (const_string "incdec")
6109         (const_string "alu")))
6110    (set_attr "mode" "QI,QI,SI")])
6111
6112 (define_insn "*addqi_1_slp"
6113   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6114         (plus:QI (match_dup 0)
6115                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6116    (clobber (reg:CC 17))]
6117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6118    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6119 {
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[1] == const1_rtx)
6124         return "inc{b}\t%0";
6125       else if (operands[1] == constm1_rtx)
6126         return "dec{b}\t%0";
6127       abort();
6128
6129     default:
6130       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6131       if (GET_CODE (operands[1]) == CONST_INT
6132           && INTVAL (operands[1]) < 0)
6133         {
6134           operands[2] = GEN_INT (-INTVAL (operands[2]));
6135           return "sub{b}\t{%1, %0|%0, %1}";
6136         }
6137       return "add{b}\t{%1, %0|%0, %1}";
6138     }
6139 }
6140   [(set (attr "type")
6141      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6142         (const_string "incdec")
6143         (const_string "alu1")))
6144    (set_attr "mode" "QI")])
6145
6146 (define_insn "*addqi_2"
6147   [(set (reg 17)
6148         (compare
6149           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6150                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6151           (const_int 0)))
6152    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6153         (plus:QI (match_dup 1) (match_dup 2)))]
6154   "ix86_match_ccmode (insn, CCGOCmode)
6155    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6156 {
6157   switch (get_attr_type (insn))
6158     {
6159     case TYPE_INCDEC:
6160       if (operands[2] == const1_rtx)
6161         return "inc{b}\t%0";
6162       else if (operands[2] == constm1_rtx
6163                || (GET_CODE (operands[2]) == CONST_INT
6164                    && INTVAL (operands[2]) == 255))
6165         return "dec{b}\t%0";
6166       abort();
6167
6168     default:
6169       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6170       if (GET_CODE (operands[2]) == CONST_INT
6171           && INTVAL (operands[2]) < 0)
6172         {
6173           operands[2] = GEN_INT (-INTVAL (operands[2]));
6174           return "sub{b}\t{%2, %0|%0, %2}";
6175         }
6176       return "add{b}\t{%2, %0|%0, %2}";
6177     }
6178 }
6179   [(set (attr "type")
6180      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6181         (const_string "incdec")
6182         (const_string "alu")))
6183    (set_attr "mode" "QI")])
6184
6185 (define_insn "*addqi_3"
6186   [(set (reg 17)
6187         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6188                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6189    (clobber (match_scratch:QI 0 "=q"))]
6190   "ix86_match_ccmode (insn, CCZmode)
6191    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{b}\t%0";
6198       else if (operands[2] == constm1_rtx
6199                || (GET_CODE (operands[2]) == CONST_INT
6200                    && INTVAL (operands[2]) == 255))
6201         return "dec{b}\t%0";
6202       abort();
6203
6204     default:
6205       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6206       if (GET_CODE (operands[2]) == CONST_INT
6207           && INTVAL (operands[2]) < 0)
6208         {
6209           operands[2] = GEN_INT (-INTVAL (operands[2]));
6210           return "sub{b}\t{%2, %0|%0, %2}";
6211         }
6212       return "add{b}\t{%2, %0|%0, %2}";
6213     }
6214 }
6215   [(set (attr "type")
6216      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6217         (const_string "incdec")
6218         (const_string "alu")))
6219    (set_attr "mode" "QI")])
6220
6221 ; See comments above addsi_3_imm for details.
6222 (define_insn "*addqi_4"
6223   [(set (reg 17)
6224         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6225                  (match_operand:QI 2 "const_int_operand" "n")))
6226    (clobber (match_scratch:QI 0 "=qm"))]
6227   "ix86_match_ccmode (insn, CCGCmode)
6228    && (INTVAL (operands[2]) & 0xff) != 0x80"
6229 {
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       if (operands[2] == constm1_rtx
6234           || (GET_CODE (operands[2]) == CONST_INT
6235               && INTVAL (operands[2]) == 255))
6236         return "inc{b}\t%0";
6237       else if (operands[2] == const1_rtx)
6238         return "dec{b}\t%0";
6239       else
6240         abort();
6241
6242     default:
6243       if (! rtx_equal_p (operands[0], operands[1]))
6244         abort ();
6245       if (INTVAL (operands[2]) < 0)
6246         {
6247           operands[2] = GEN_INT (-INTVAL (operands[2]));
6248           return "add{b}\t{%2, %0|%0, %2}";
6249         }
6250       return "sub{b}\t{%2, %0|%0, %2}";
6251     }
6252 }
6253   [(set (attr "type")
6254      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255         (const_string "incdec")
6256         (const_string "alu")))
6257    (set_attr "mode" "QI")])
6258
6259
6260 (define_insn "*addqi_5"
6261   [(set (reg 17)
6262         (compare
6263           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6264                    (match_operand:QI 2 "general_operand" "qmni"))
6265           (const_int 0)))
6266    (clobber (match_scratch:QI 0 "=q"))]
6267   "ix86_match_ccmode (insn, CCGOCmode)
6268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6269 {
6270   switch (get_attr_type (insn))
6271     {
6272     case TYPE_INCDEC:
6273       if (operands[2] == const1_rtx)
6274         return "inc{b}\t%0";
6275       else if (operands[2] == constm1_rtx
6276                || (GET_CODE (operands[2]) == CONST_INT
6277                    && INTVAL (operands[2]) == 255))
6278         return "dec{b}\t%0";
6279       abort();
6280
6281     default:
6282       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6283       if (GET_CODE (operands[2]) == CONST_INT
6284           && INTVAL (operands[2]) < 0)
6285         {
6286           operands[2] = GEN_INT (-INTVAL (operands[2]));
6287           return "sub{b}\t{%2, %0|%0, %2}";
6288         }
6289       return "add{b}\t{%2, %0|%0, %2}";
6290     }
6291 }
6292   [(set (attr "type")
6293      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294         (const_string "incdec")
6295         (const_string "alu")))
6296    (set_attr "mode" "QI")])
6297
6298
6299 (define_insn "addqi_ext_1"
6300   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6301                          (const_int 8)
6302                          (const_int 8))
6303         (plus:SI
6304           (zero_extract:SI
6305             (match_operand 1 "ext_register_operand" "0")
6306             (const_int 8)
6307             (const_int 8))
6308           (match_operand:QI 2 "general_operand" "Qmn")))
6309    (clobber (reg:CC 17))]
6310   "!TARGET_64BIT"
6311 {
6312   switch (get_attr_type (insn))
6313     {
6314     case TYPE_INCDEC:
6315       if (operands[2] == const1_rtx)
6316         return "inc{b}\t%h0";
6317       else if (operands[2] == constm1_rtx
6318                || (GET_CODE (operands[2]) == CONST_INT
6319                    && INTVAL (operands[2]) == 255))
6320         return "dec{b}\t%h0";
6321       abort();
6322
6323     default:
6324       return "add{b}\t{%2, %h0|%h0, %2}";
6325     }
6326 }
6327   [(set (attr "type")
6328      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6329         (const_string "incdec")
6330         (const_string "alu")))
6331    (set_attr "mode" "QI")])
6332
6333 (define_insn "*addqi_ext_1_rex64"
6334   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6335                          (const_int 8)
6336                          (const_int 8))
6337         (plus:SI
6338           (zero_extract:SI
6339             (match_operand 1 "ext_register_operand" "0")
6340             (const_int 8)
6341             (const_int 8))
6342           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6343    (clobber (reg:CC 17))]
6344   "TARGET_64BIT"
6345 {
6346   switch (get_attr_type (insn))
6347     {
6348     case TYPE_INCDEC:
6349       if (operands[2] == const1_rtx)
6350         return "inc{b}\t%h0";
6351       else if (operands[2] == constm1_rtx
6352                || (GET_CODE (operands[2]) == CONST_INT
6353                    && INTVAL (operands[2]) == 255))
6354         return "dec{b}\t%h0";
6355       abort();
6356
6357     default:
6358       return "add{b}\t{%2, %h0|%h0, %2}";
6359     }
6360 }
6361   [(set (attr "type")
6362      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6363         (const_string "incdec")
6364         (const_string "alu")))
6365    (set_attr "mode" "QI")])
6366
6367 (define_insn "*addqi_ext_2"
6368   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6369                          (const_int 8)
6370                          (const_int 8))
6371         (plus:SI
6372           (zero_extract:SI
6373             (match_operand 1 "ext_register_operand" "%0")
6374             (const_int 8)
6375             (const_int 8))
6376           (zero_extract:SI
6377             (match_operand 2 "ext_register_operand" "Q")
6378             (const_int 8)
6379             (const_int 8))))
6380    (clobber (reg:CC 17))]
6381   ""
6382   "add{b}\t{%h2, %h0|%h0, %h2}"
6383   [(set_attr "type" "alu")
6384    (set_attr "mode" "QI")])
6385
6386 ;; The patterns that match these are at the end of this file.
6387
6388 (define_expand "addxf3"
6389   [(set (match_operand:XF 0 "register_operand" "")
6390         (plus:XF (match_operand:XF 1 "register_operand" "")
6391                  (match_operand:XF 2 "register_operand" "")))]
6392   "TARGET_80387"
6393   "")
6394
6395 (define_expand "adddf3"
6396   [(set (match_operand:DF 0 "register_operand" "")
6397         (plus:DF (match_operand:DF 1 "register_operand" "")
6398                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6399   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6400   "")
6401
6402 (define_expand "addsf3"
6403   [(set (match_operand:SF 0 "register_operand" "")
6404         (plus:SF (match_operand:SF 1 "register_operand" "")
6405                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6406   "TARGET_80387 || TARGET_SSE_MATH"
6407   "")
6408 \f
6409 ;; Subtract instructions
6410
6411 ;; %%% splits for subsidi3
6412
6413 (define_expand "subdi3"
6414   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6415                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6416                              (match_operand:DI 2 "x86_64_general_operand" "")))
6417               (clobber (reg:CC 17))])]
6418   ""
6419   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6420
6421 (define_insn "*subdi3_1"
6422   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6423         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6424                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6425    (clobber (reg:CC 17))]
6426   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6427   "#")
6428
6429 (define_split
6430   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6431         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6432                   (match_operand:DI 2 "general_operand" "")))
6433    (clobber (reg:CC 17))]
6434   "!TARGET_64BIT && reload_completed"
6435   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6436               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6437    (parallel [(set (match_dup 3)
6438                    (minus:SI (match_dup 4)
6439                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6440                                       (match_dup 5))))
6441               (clobber (reg:CC 17))])]
6442   "split_di (operands+0, 1, operands+0, operands+3);
6443    split_di (operands+1, 1, operands+1, operands+4);
6444    split_di (operands+2, 1, operands+2, operands+5);")
6445
6446 (define_insn "subdi3_carry_rex64"
6447   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6448           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6449             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6450                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6451    (clobber (reg:CC 17))]
6452   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6453   "sbb{q}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "pent_pair" "pu")
6456    (set_attr "ppro_uops" "few")
6457    (set_attr "mode" "DI")])
6458
6459 (define_insn "*subdi_1_rex64"
6460   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6461         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6462                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6463    (clobber (reg:CC 17))]
6464   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6465   "sub{q}\t{%2, %0|%0, %2}"
6466   [(set_attr "type" "alu")
6467    (set_attr "mode" "DI")])
6468
6469 (define_insn "*subdi_2_rex64"
6470   [(set (reg 17)
6471         (compare
6472           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6473                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6474           (const_int 0)))
6475    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6476         (minus:DI (match_dup 1) (match_dup 2)))]
6477   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6478    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6479   "sub{q}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "mode" "DI")])
6482
6483 (define_insn "*subdi_3_rex63"
6484   [(set (reg 17)
6485         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6486                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6487    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6488         (minus:DI (match_dup 1) (match_dup 2)))]
6489   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6490    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6491   "sub{q}\t{%2, %0|%0, %2}"
6492   [(set_attr "type" "alu")
6493    (set_attr "mode" "DI")])
6494
6495 (define_insn "subqi3_carry"
6496   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6497           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6498             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6499                (match_operand:QI 2 "general_operand" "qi,qm"))))
6500    (clobber (reg:CC 17))]
6501   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6502   "sbb{b}\t{%2, %0|%0, %2}"
6503   [(set_attr "type" "alu")
6504    (set_attr "pent_pair" "pu")
6505    (set_attr "ppro_uops" "few")
6506    (set_attr "mode" "QI")])
6507
6508 (define_insn "subhi3_carry"
6509   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6510           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6511             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6512                (match_operand:HI 2 "general_operand" "ri,rm"))))
6513    (clobber (reg:CC 17))]
6514   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6515   "sbb{w}\t{%2, %0|%0, %2}"
6516   [(set_attr "type" "alu")
6517    (set_attr "pent_pair" "pu")
6518    (set_attr "ppro_uops" "few")
6519    (set_attr "mode" "HI")])
6520
6521 (define_insn "subsi3_carry"
6522   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6523           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6524             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6525                (match_operand:SI 2 "general_operand" "ri,rm"))))
6526    (clobber (reg:CC 17))]
6527   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6528   "sbb{l}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "pent_pair" "pu")
6531    (set_attr "ppro_uops" "few")
6532    (set_attr "mode" "SI")])
6533
6534 (define_insn "subsi3_carry_zext"
6535   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6536           (zero_extend:DI
6537             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6538               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6539                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6540    (clobber (reg:CC 17))]
6541   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6542   "sbb{l}\t{%2, %k0|%k0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "pent_pair" "pu")
6545    (set_attr "ppro_uops" "few")
6546    (set_attr "mode" "SI")])
6547
6548 (define_expand "subsi3"
6549   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6550                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6551                              (match_operand:SI 2 "general_operand" "")))
6552               (clobber (reg:CC 17))])]
6553   ""
6554   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6555
6556 (define_insn "*subsi_1"
6557   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6558         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6559                   (match_operand:SI 2 "general_operand" "ri,rm")))
6560    (clobber (reg:CC 17))]
6561   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6562   "sub{l}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "mode" "SI")])
6565
6566 (define_insn "*subsi_1_zext"
6567   [(set (match_operand:DI 0 "register_operand" "=r")
6568         (zero_extend:DI
6569           (minus:SI (match_operand:SI 1 "register_operand" "0")
6570                     (match_operand:SI 2 "general_operand" "rim"))))
6571    (clobber (reg:CC 17))]
6572   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573   "sub{l}\t{%2, %k0|%k0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "SI")])
6576
6577 (define_insn "*subsi_2"
6578   [(set (reg 17)
6579         (compare
6580           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6581                     (match_operand:SI 2 "general_operand" "ri,rm"))
6582           (const_int 0)))
6583    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584         (minus:SI (match_dup 1) (match_dup 2)))]
6585   "ix86_match_ccmode (insn, CCGOCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{l}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "SI")])
6590
6591 (define_insn "*subsi_2_zext"
6592   [(set (reg 17)
6593         (compare
6594           (minus:SI (match_operand:SI 1 "register_operand" "0")
6595                     (match_operand:SI 2 "general_operand" "rim"))
6596           (const_int 0)))
6597    (set (match_operand:DI 0 "register_operand" "=r")
6598         (zero_extend:DI
6599           (minus:SI (match_dup 1)
6600                     (match_dup 2))))]
6601   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6602    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6603   "sub{l}\t{%2, %k0|%k0, %2}"
6604   [(set_attr "type" "alu")
6605    (set_attr "mode" "SI")])
6606
6607 (define_insn "*subsi_3"
6608   [(set (reg 17)
6609         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6610                  (match_operand:SI 2 "general_operand" "ri,rm")))
6611    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:SI (match_dup 1) (match_dup 2)))]
6613   "ix86_match_ccmode (insn, CCmode)
6614    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6615   "sub{l}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "SI")])
6618
6619 (define_insn "*subsi_3_zext"
6620   [(set (reg 17)
6621         (compare (match_operand:SI 1 "register_operand" "0")
6622                  (match_operand:SI 2 "general_operand" "rim")))
6623    (set (match_operand:DI 0 "register_operand" "=r")
6624         (zero_extend:DI
6625           (minus:SI (match_dup 1)
6626                     (match_dup 2))))]
6627   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6628    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6629   "sub{q}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "mode" "DI")])
6632
6633 (define_expand "subhi3"
6634   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6635                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6636                              (match_operand:HI 2 "general_operand" "")))
6637               (clobber (reg:CC 17))])]
6638   "TARGET_HIMODE_MATH"
6639   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6640
6641 (define_insn "*subhi_1"
6642   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6644                   (match_operand:HI 2 "general_operand" "ri,rm")))
6645    (clobber (reg:CC 17))]
6646   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6647   "sub{w}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "HI")])
6650
6651 (define_insn "*subhi_2"
6652   [(set (reg 17)
6653         (compare
6654           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6655                     (match_operand:HI 2 "general_operand" "ri,rm"))
6656           (const_int 0)))
6657    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6658         (minus:HI (match_dup 1) (match_dup 2)))]
6659   "ix86_match_ccmode (insn, CCGOCmode)
6660    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6661   "sub{w}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "HI")])
6664
6665 (define_insn "*subhi_3"
6666   [(set (reg 17)
6667         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6668                  (match_operand:HI 2 "general_operand" "ri,rm")))
6669    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6670         (minus:HI (match_dup 1) (match_dup 2)))]
6671   "ix86_match_ccmode (insn, CCmode)
6672    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6673   "sub{w}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "HI")])
6676
6677 (define_expand "subqi3"
6678   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6679                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6680                              (match_operand:QI 2 "general_operand" "")))
6681               (clobber (reg:CC 17))])]
6682   "TARGET_QIMODE_MATH"
6683   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6684
6685 (define_insn "*subqi_1"
6686   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6689    (clobber (reg:CC 17))]
6690   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6691   "sub{b}\t{%2, %0|%0, %2}"
6692   [(set_attr "type" "alu")
6693    (set_attr "mode" "QI")])
6694
6695 (define_insn "*subqi_1_slp"
6696   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6697         (minus:QI (match_dup 0)
6698                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6699    (clobber (reg:CC 17))]
6700   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6702   "sub{b}\t{%1, %0|%0, %1}"
6703   [(set_attr "type" "alu1")
6704    (set_attr "mode" "QI")])
6705
6706 (define_insn "*subqi_2"
6707   [(set (reg 17)
6708         (compare
6709           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6710                     (match_operand:QI 2 "general_operand" "qi,qm"))
6711           (const_int 0)))
6712    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6713         (minus:HI (match_dup 1) (match_dup 2)))]
6714   "ix86_match_ccmode (insn, CCGOCmode)
6715    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6716   "sub{b}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "QI")])
6719
6720 (define_insn "*subqi_3"
6721   [(set (reg 17)
6722         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6723                  (match_operand:QI 2 "general_operand" "qi,qm")))
6724    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6725         (minus:HI (match_dup 1) (match_dup 2)))]
6726   "ix86_match_ccmode (insn, CCmode)
6727    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6728   "sub{b}\t{%2, %0|%0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "QI")])
6731
6732 ;; The patterns that match these are at the end of this file.
6733
6734 (define_expand "subxf3"
6735   [(set (match_operand:XF 0 "register_operand" "")
6736         (minus:XF (match_operand:XF 1 "register_operand" "")
6737                   (match_operand:XF 2 "register_operand" "")))]
6738   "TARGET_80387"
6739   "")
6740
6741 (define_expand "subdf3"
6742   [(set (match_operand:DF 0 "register_operand" "")
6743         (minus:DF (match_operand:DF 1 "register_operand" "")
6744                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6745   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6746   "")
6747
6748 (define_expand "subsf3"
6749   [(set (match_operand:SF 0 "register_operand" "")
6750         (minus:SF (match_operand:SF 1 "register_operand" "")
6751                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6752   "TARGET_80387 || TARGET_SSE_MATH"
6753   "")
6754 \f
6755 ;; Multiply instructions
6756
6757 (define_expand "muldi3"
6758   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6759                    (mult:DI (match_operand:DI 1 "register_operand" "")
6760                             (match_operand:DI 2 "x86_64_general_operand" "")))
6761               (clobber (reg:CC 17))])]
6762   "TARGET_64BIT"
6763   "")
6764
6765 (define_insn "*muldi3_1_rex64"
6766   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6767         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6768                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6769    (clobber (reg:CC 17))]
6770   "TARGET_64BIT
6771    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6772   "@
6773    imul{q}\t{%2, %1, %0|%0, %1, %2}
6774    imul{q}\t{%2, %1, %0|%0, %1, %2}
6775    imul{q}\t{%2, %0|%0, %2}"
6776   [(set_attr "type" "imul")
6777    (set_attr "prefix_0f" "0,0,1")
6778    (set (attr "athlon_decode")
6779         (cond [(eq_attr "cpu" "athlon")
6780                   (const_string "vector")
6781                (eq_attr "alternative" "1")
6782                   (const_string "vector")
6783                (and (eq_attr "alternative" "2")
6784                     (match_operand 1 "memory_operand" ""))
6785                   (const_string "vector")]
6786               (const_string "direct")))
6787    (set_attr "mode" "DI")])
6788
6789 (define_expand "mulsi3"
6790   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6791                    (mult:SI (match_operand:SI 1 "register_operand" "")
6792                             (match_operand:SI 2 "general_operand" "")))
6793               (clobber (reg:CC 17))])]
6794   ""
6795   "")
6796
6797 (define_insn "*mulsi3_1"
6798   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6799         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6800                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6801    (clobber (reg:CC 17))]
6802   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6803   "@
6804    imul{l}\t{%2, %1, %0|%0, %1, %2}
6805    imul{l}\t{%2, %1, %0|%0, %1, %2}
6806    imul{l}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "imul")
6808    (set_attr "prefix_0f" "0,0,1")
6809    (set (attr "athlon_decode")
6810         (cond [(eq_attr "cpu" "athlon")
6811                   (const_string "vector")
6812                (eq_attr "alternative" "1")
6813                   (const_string "vector")
6814                (and (eq_attr "alternative" "2")
6815                     (match_operand 1 "memory_operand" ""))
6816                   (const_string "vector")]
6817               (const_string "direct")))
6818    (set_attr "mode" "SI")])
6819
6820 (define_insn "*mulsi3_1_zext"
6821   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6822         (zero_extend:DI
6823           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6824                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6825    (clobber (reg:CC 17))]
6826   "TARGET_64BIT
6827    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6828   "@
6829    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6830    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6831    imul{l}\t{%2, %k0|%k0, %2}"
6832   [(set_attr "type" "imul")
6833    (set_attr "prefix_0f" "0,0,1")
6834    (set (attr "athlon_decode")
6835         (cond [(eq_attr "cpu" "athlon")
6836                   (const_string "vector")
6837                (eq_attr "alternative" "1")
6838                   (const_string "vector")
6839                (and (eq_attr "alternative" "2")
6840                     (match_operand 1 "memory_operand" ""))
6841                   (const_string "vector")]
6842               (const_string "direct")))
6843    (set_attr "mode" "SI")])
6844
6845 (define_expand "mulhi3"
6846   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6847                    (mult:HI (match_operand:HI 1 "register_operand" "")
6848                             (match_operand:HI 2 "general_operand" "")))
6849               (clobber (reg:CC 17))])]
6850   "TARGET_HIMODE_MATH"
6851   "")
6852
6853 (define_insn "*mulhi3_1"
6854   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6855         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6856                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6857    (clobber (reg:CC 17))]
6858   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6859   "@
6860    imul{w}\t{%2, %1, %0|%0, %1, %2}
6861    imul{w}\t{%2, %1, %0|%0, %1, %2}
6862    imul{w}\t{%2, %0|%0, %2}"
6863   [(set_attr "type" "imul")
6864    (set_attr "prefix_0f" "0,0,1")
6865    (set (attr "athlon_decode")
6866         (cond [(eq_attr "cpu" "athlon")
6867                   (const_string "vector")
6868                (eq_attr "alternative" "1,2")
6869                   (const_string "vector")]
6870               (const_string "direct")))
6871    (set_attr "mode" "HI")])
6872
6873 (define_expand "mulqi3"
6874   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6875                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6876                             (match_operand:QI 2 "register_operand" "")))
6877               (clobber (reg:CC 17))])]
6878   "TARGET_QIMODE_MATH"
6879   "")
6880
6881 (define_insn "*mulqi3_1"
6882   [(set (match_operand:QI 0 "register_operand" "=a")
6883         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6884                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6885    (clobber (reg:CC 17))]
6886   "TARGET_QIMODE_MATH
6887    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888   "mul{b}\t%2"
6889   [(set_attr "type" "imul")
6890    (set_attr "length_immediate" "0")
6891    (set (attr "athlon_decode")
6892      (if_then_else (eq_attr "cpu" "athlon")
6893         (const_string "vector")
6894         (const_string "direct")))
6895    (set_attr "mode" "QI")])
6896
6897 (define_expand "umulqihi3"
6898   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6899                    (mult:HI (zero_extend:HI
6900                               (match_operand:QI 1 "nonimmediate_operand" ""))
6901                             (zero_extend:HI
6902                               (match_operand:QI 2 "register_operand" ""))))
6903               (clobber (reg:CC 17))])]
6904   "TARGET_QIMODE_MATH"
6905   "")
6906
6907 (define_insn "*umulqihi3_1"
6908   [(set (match_operand:HI 0 "register_operand" "=a")
6909         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6910                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6911    (clobber (reg:CC 17))]
6912   "TARGET_QIMODE_MATH
6913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6914   "mul{b}\t%2"
6915   [(set_attr "type" "imul")
6916    (set_attr "length_immediate" "0")
6917    (set (attr "athlon_decode")
6918      (if_then_else (eq_attr "cpu" "athlon")
6919         (const_string "vector")
6920         (const_string "direct")))
6921    (set_attr "mode" "QI")])
6922
6923 (define_expand "mulqihi3"
6924   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6925                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6926                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6927               (clobber (reg:CC 17))])]
6928   "TARGET_QIMODE_MATH"
6929   "")
6930
6931 (define_insn "*mulqihi3_insn"
6932   [(set (match_operand:HI 0 "register_operand" "=a")
6933         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6934                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6935    (clobber (reg:CC 17))]
6936   "TARGET_QIMODE_MATH
6937    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6938   "imul{b}\t%2"
6939   [(set_attr "type" "imul")
6940    (set_attr "length_immediate" "0")
6941    (set (attr "athlon_decode")
6942      (if_then_else (eq_attr "cpu" "athlon")
6943         (const_string "vector")
6944         (const_string "direct")))
6945    (set_attr "mode" "QI")])
6946
6947 (define_expand "umulditi3"
6948   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6949                    (mult:TI (zero_extend:TI
6950                               (match_operand:DI 1 "nonimmediate_operand" ""))
6951                             (zero_extend:TI
6952                               (match_operand:DI 2 "register_operand" ""))))
6953               (clobber (reg:CC 17))])]
6954   "TARGET_64BIT"
6955   "")
6956
6957 (define_insn "*umulditi3_insn"
6958   [(set (match_operand:TI 0 "register_operand" "=A")
6959         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6960                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6961    (clobber (reg:CC 17))]
6962   "TARGET_64BIT
6963    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964   "mul{q}\t%2"
6965   [(set_attr "type" "imul")
6966    (set_attr "ppro_uops" "few")
6967    (set_attr "length_immediate" "0")
6968    (set (attr "athlon_decode")
6969      (if_then_else (eq_attr "cpu" "athlon")
6970         (const_string "vector")
6971         (const_string "double")))
6972    (set_attr "mode" "DI")])
6973
6974 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6975 (define_expand "umulsidi3"
6976   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6977                    (mult:DI (zero_extend:DI
6978                               (match_operand:SI 1 "nonimmediate_operand" ""))
6979                             (zero_extend:DI
6980                               (match_operand:SI 2 "register_operand" ""))))
6981               (clobber (reg:CC 17))])]
6982   "!TARGET_64BIT"
6983   "")
6984
6985 (define_insn "*umulsidi3_insn"
6986   [(set (match_operand:DI 0 "register_operand" "=A")
6987         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6988                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6989    (clobber (reg:CC 17))]
6990   "!TARGET_64BIT
6991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6992   "mul{l}\t%2"
6993   [(set_attr "type" "imul")
6994    (set_attr "ppro_uops" "few")
6995    (set_attr "length_immediate" "0")
6996    (set (attr "athlon_decode")
6997      (if_then_else (eq_attr "cpu" "athlon")
6998         (const_string "vector")
6999         (const_string "double")))
7000    (set_attr "mode" "SI")])
7001
7002 (define_expand "mulditi3"
7003   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7004                    (mult:TI (sign_extend:TI
7005                               (match_operand:DI 1 "nonimmediate_operand" ""))
7006                             (sign_extend:TI
7007                               (match_operand:DI 2 "register_operand" ""))))
7008               (clobber (reg:CC 17))])]
7009   "TARGET_64BIT"
7010   "")
7011
7012 (define_insn "*mulditi3_insn"
7013   [(set (match_operand:TI 0 "register_operand" "=A")
7014         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7015                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7016    (clobber (reg:CC 17))]
7017   "TARGET_64BIT
7018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7019   "imul{q}\t%2"
7020   [(set_attr "type" "imul")
7021    (set_attr "length_immediate" "0")
7022    (set (attr "athlon_decode")
7023      (if_then_else (eq_attr "cpu" "athlon")
7024         (const_string "vector")
7025         (const_string "double")))
7026    (set_attr "mode" "DI")])
7027
7028 (define_expand "mulsidi3"
7029   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7030                    (mult:DI (sign_extend:DI
7031                               (match_operand:SI 1 "nonimmediate_operand" ""))
7032                             (sign_extend:DI
7033                               (match_operand:SI 2 "register_operand" ""))))
7034               (clobber (reg:CC 17))])]
7035   "!TARGET_64BIT"
7036   "")
7037
7038 (define_insn "*mulsidi3_insn"
7039   [(set (match_operand:DI 0 "register_operand" "=A")
7040         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7041                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7042    (clobber (reg:CC 17))]
7043   "!TARGET_64BIT
7044    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7045   "imul{l}\t%2"
7046   [(set_attr "type" "imul")
7047    (set_attr "length_immediate" "0")
7048    (set (attr "athlon_decode")
7049      (if_then_else (eq_attr "cpu" "athlon")
7050         (const_string "vector")
7051         (const_string "double")))
7052    (set_attr "mode" "SI")])
7053
7054 (define_expand "umuldi3_highpart"
7055   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7056                    (truncate:DI
7057                      (lshiftrt:TI
7058                        (mult:TI (zero_extend:TI
7059                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7060                                 (zero_extend:TI
7061                                   (match_operand:DI 2 "register_operand" "")))
7062                        (const_int 64))))
7063               (clobber (match_scratch:DI 3 ""))
7064               (clobber (reg:CC 17))])]
7065   "TARGET_64BIT"
7066   "")
7067
7068 (define_insn "*umuldi3_highpart_rex64"
7069   [(set (match_operand:DI 0 "register_operand" "=d")
7070         (truncate:DI
7071           (lshiftrt:TI
7072             (mult:TI (zero_extend:TI
7073                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7074                      (zero_extend:TI
7075                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7076             (const_int 64))))
7077    (clobber (match_scratch:DI 3 "=1"))
7078    (clobber (reg:CC 17))]
7079   "TARGET_64BIT
7080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081   "mul{q}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "ppro_uops" "few")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "DI")])
7090
7091 (define_expand "umulsi3_highpart"
7092   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7093                    (truncate:SI
7094                      (lshiftrt:DI
7095                        (mult:DI (zero_extend:DI
7096                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7097                                 (zero_extend:DI
7098                                   (match_operand:SI 2 "register_operand" "")))
7099                        (const_int 32))))
7100               (clobber (match_scratch:SI 3 ""))
7101               (clobber (reg:CC 17))])]
7102   ""
7103   "")
7104
7105 (define_insn "*umulsi3_highpart_insn"
7106   [(set (match_operand:SI 0 "register_operand" "=d")
7107         (truncate:SI
7108           (lshiftrt:DI
7109             (mult:DI (zero_extend:DI
7110                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7111                      (zero_extend:DI
7112                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7113             (const_int 32))))
7114    (clobber (match_scratch:SI 3 "=1"))
7115    (clobber (reg:CC 17))]
7116   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7117   "mul{l}\t%2"
7118   [(set_attr "type" "imul")
7119    (set_attr "ppro_uops" "few")
7120    (set_attr "length_immediate" "0")
7121    (set (attr "athlon_decode")
7122      (if_then_else (eq_attr "cpu" "athlon")
7123         (const_string "vector")
7124         (const_string "double")))
7125    (set_attr "mode" "SI")])
7126
7127 (define_insn "*umulsi3_highpart_zext"
7128   [(set (match_operand:DI 0 "register_operand" "=d")
7129         (zero_extend:DI (truncate:SI
7130           (lshiftrt:DI
7131             (mult:DI (zero_extend:DI
7132                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7133                      (zero_extend:DI
7134                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7135             (const_int 32)))))
7136    (clobber (match_scratch:SI 3 "=1"))
7137    (clobber (reg:CC 17))]
7138   "TARGET_64BIT
7139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140   "mul{l}\t%2"
7141   [(set_attr "type" "imul")
7142    (set_attr "ppro_uops" "few")
7143    (set_attr "length_immediate" "0")
7144    (set (attr "athlon_decode")
7145      (if_then_else (eq_attr "cpu" "athlon")
7146         (const_string "vector")
7147         (const_string "double")))
7148    (set_attr "mode" "SI")])
7149
7150 (define_expand "smuldi3_highpart"
7151   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7152                    (truncate:DI
7153                      (lshiftrt:TI
7154                        (mult:TI (sign_extend:TI
7155                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7156                                 (sign_extend:TI
7157                                   (match_operand:DI 2 "register_operand" "")))
7158                        (const_int 64))))
7159               (clobber (match_scratch:DI 3 ""))
7160               (clobber (reg:CC 17))])]
7161   "TARGET_64BIT"
7162   "")
7163
7164 (define_insn "*smuldi3_highpart_rex64"
7165   [(set (match_operand:DI 0 "register_operand" "=d")
7166         (truncate:DI
7167           (lshiftrt:TI
7168             (mult:TI (sign_extend:TI
7169                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170                      (sign_extend:TI
7171                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172             (const_int 64))))
7173    (clobber (match_scratch:DI 3 "=1"))
7174    (clobber (reg:CC 17))]
7175   "TARGET_64BIT
7176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177   "imul{q}\t%2"
7178   [(set_attr "type" "imul")
7179    (set_attr "ppro_uops" "few")
7180    (set (attr "athlon_decode")
7181      (if_then_else (eq_attr "cpu" "athlon")
7182         (const_string "vector")
7183         (const_string "double")))
7184    (set_attr "mode" "DI")])
7185
7186 (define_expand "smulsi3_highpart"
7187   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7188                    (truncate:SI
7189                      (lshiftrt:DI
7190                        (mult:DI (sign_extend:DI
7191                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7192                                 (sign_extend:DI
7193                                   (match_operand:SI 2 "register_operand" "")))
7194                        (const_int 32))))
7195               (clobber (match_scratch:SI 3 ""))
7196               (clobber (reg:CC 17))])]
7197   ""
7198   "")
7199
7200 (define_insn "*smulsi3_highpart_insn"
7201   [(set (match_operand:SI 0 "register_operand" "=d")
7202         (truncate:SI
7203           (lshiftrt:DI
7204             (mult:DI (sign_extend:DI
7205                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7206                      (sign_extend:DI
7207                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7208             (const_int 32))))
7209    (clobber (match_scratch:SI 3 "=1"))
7210    (clobber (reg:CC 17))]
7211   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7212   "imul{l}\t%2"
7213   [(set_attr "type" "imul")
7214    (set_attr "ppro_uops" "few")
7215    (set (attr "athlon_decode")
7216      (if_then_else (eq_attr "cpu" "athlon")
7217         (const_string "vector")
7218         (const_string "double")))
7219    (set_attr "mode" "SI")])
7220
7221 (define_insn "*smulsi3_highpart_zext"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (zero_extend:DI (truncate:SI
7224           (lshiftrt:DI
7225             (mult:DI (sign_extend:DI
7226                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7227                      (sign_extend:DI
7228                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7229             (const_int 32)))))
7230    (clobber (match_scratch:SI 3 "=1"))
7231    (clobber (reg:CC 17))]
7232   "TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "imul{l}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "ppro_uops" "few")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "SI")])
7242
7243 ;; The patterns that match these are at the end of this file.
7244
7245 (define_expand "mulxf3"
7246   [(set (match_operand:XF 0 "register_operand" "")
7247         (mult:XF (match_operand:XF 1 "register_operand" "")
7248                  (match_operand:XF 2 "register_operand" "")))]
7249   "TARGET_80387"
7250   "")
7251
7252 (define_expand "muldf3"
7253   [(set (match_operand:DF 0 "register_operand" "")
7254         (mult:DF (match_operand:DF 1 "register_operand" "")
7255                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7256   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7257   "")
7258
7259 (define_expand "mulsf3"
7260   [(set (match_operand:SF 0 "register_operand" "")
7261         (mult:SF (match_operand:SF 1 "register_operand" "")
7262                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7263   "TARGET_80387 || TARGET_SSE_MATH"
7264   "")
7265 \f
7266 ;; Divide instructions
7267
7268 (define_insn "divqi3"
7269   [(set (match_operand:QI 0 "register_operand" "=a")
7270         (div:QI (match_operand:HI 1 "register_operand" "0")
7271                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7272    (clobber (reg:CC 17))]
7273   "TARGET_QIMODE_MATH"
7274   "idiv{b}\t%2"
7275   [(set_attr "type" "idiv")
7276    (set_attr "mode" "QI")
7277    (set_attr "ppro_uops" "few")])
7278
7279 (define_insn "udivqi3"
7280   [(set (match_operand:QI 0 "register_operand" "=a")
7281         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7282                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7283    (clobber (reg:CC 17))]
7284   "TARGET_QIMODE_MATH"
7285   "div{b}\t%2"
7286   [(set_attr "type" "idiv")
7287    (set_attr "mode" "QI")
7288    (set_attr "ppro_uops" "few")])
7289
7290 ;; The patterns that match these are at the end of this file.
7291
7292 (define_expand "divxf3"
7293   [(set (match_operand:XF 0 "register_operand" "")
7294         (div:XF (match_operand:XF 1 "register_operand" "")
7295                 (match_operand:XF 2 "register_operand" "")))]
7296   "TARGET_80387"
7297   "")
7298
7299 (define_expand "divdf3"
7300   [(set (match_operand:DF 0 "register_operand" "")
7301         (div:DF (match_operand:DF 1 "register_operand" "")
7302                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7303    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7304    "")
7305  
7306 (define_expand "divsf3"
7307   [(set (match_operand:SF 0 "register_operand" "")
7308         (div:SF (match_operand:SF 1 "register_operand" "")
7309                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7310   "TARGET_80387 || TARGET_SSE_MATH"
7311   "")
7312 \f
7313 ;; Remainder instructions.
7314
7315 (define_expand "divmoddi4"
7316   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7317                    (div:DI (match_operand:DI 1 "register_operand" "")
7318                            (match_operand:DI 2 "nonimmediate_operand" "")))
7319               (set (match_operand:DI 3 "register_operand" "")
7320                    (mod:DI (match_dup 1) (match_dup 2)))
7321               (clobber (reg:CC 17))])]
7322   "TARGET_64BIT"
7323   "")
7324
7325 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7326 ;; Penalize eax case slightly because it results in worse scheduling
7327 ;; of code.
7328 (define_insn "*divmoddi4_nocltd_rex64"
7329   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7330         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7331                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7332    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7333         (mod:DI (match_dup 2) (match_dup 3)))
7334    (clobber (reg:CC 17))]
7335   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7336   "#"
7337   [(set_attr "type" "multi")])
7338
7339 (define_insn "*divmoddi4_cltd_rex64"
7340   [(set (match_operand:DI 0 "register_operand" "=a")
7341         (div:DI (match_operand:DI 2 "register_operand" "a")
7342                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7343    (set (match_operand:DI 1 "register_operand" "=&d")
7344         (mod:DI (match_dup 2) (match_dup 3)))
7345    (clobber (reg:CC 17))]
7346   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7347   "#"
7348   [(set_attr "type" "multi")])
7349
7350 (define_insn "*divmoddi_noext_rex64"
7351   [(set (match_operand:DI 0 "register_operand" "=a")
7352         (div:DI (match_operand:DI 1 "register_operand" "0")
7353                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7354    (set (match_operand:DI 3 "register_operand" "=d")
7355         (mod:DI (match_dup 1) (match_dup 2)))
7356    (use (match_operand:DI 4 "register_operand" "3"))
7357    (clobber (reg:CC 17))]
7358   "TARGET_64BIT"
7359   "idiv{q}\t%2"
7360   [(set_attr "type" "idiv")
7361    (set_attr "mode" "DI")
7362    (set_attr "ppro_uops" "few")])
7363
7364 (define_split
7365   [(set (match_operand:DI 0 "register_operand" "")
7366         (div:DI (match_operand:DI 1 "register_operand" "")
7367                 (match_operand:DI 2 "nonimmediate_operand" "")))
7368    (set (match_operand:DI 3 "register_operand" "")
7369         (mod:DI (match_dup 1) (match_dup 2)))
7370    (clobber (reg:CC 17))]
7371   "TARGET_64BIT && reload_completed"
7372   [(parallel [(set (match_dup 3)
7373                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7374               (clobber (reg:CC 17))])
7375    (parallel [(set (match_dup 0)
7376                    (div:DI (reg:DI 0) (match_dup 2)))
7377               (set (match_dup 3)
7378                    (mod:DI (reg:DI 0) (match_dup 2)))
7379               (use (match_dup 3))
7380               (clobber (reg:CC 17))])]
7381 {
7382   /* Avoid use of cltd in favor of a mov+shift.  */
7383   if (!TARGET_USE_CLTD && !optimize_size)
7384     {
7385       if (true_regnum (operands[1]))
7386         emit_move_insn (operands[0], operands[1]);
7387       else
7388         emit_move_insn (operands[3], operands[1]);
7389       operands[4] = operands[3];
7390     }
7391   else
7392     {
7393       if (true_regnum (operands[1]))
7394         abort();
7395       operands[4] = operands[1];
7396     }
7397 })
7398
7399
7400 (define_expand "divmodsi4"
7401   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7402                    (div:SI (match_operand:SI 1 "register_operand" "")
7403                            (match_operand:SI 2 "nonimmediate_operand" "")))
7404               (set (match_operand:SI 3 "register_operand" "")
7405                    (mod:SI (match_dup 1) (match_dup 2)))
7406               (clobber (reg:CC 17))])]
7407   ""
7408   "")
7409
7410 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7411 ;; Penalize eax case slightly because it results in worse scheduling
7412 ;; of code.
7413 (define_insn "*divmodsi4_nocltd"
7414   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7415         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7416                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7417    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7418         (mod:SI (match_dup 2) (match_dup 3)))
7419    (clobber (reg:CC 17))]
7420   "!optimize_size && !TARGET_USE_CLTD"
7421   "#"
7422   [(set_attr "type" "multi")])
7423
7424 (define_insn "*divmodsi4_cltd"
7425   [(set (match_operand:SI 0 "register_operand" "=a")
7426         (div:SI (match_operand:SI 2 "register_operand" "a")
7427                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7428    (set (match_operand:SI 1 "register_operand" "=&d")
7429         (mod:SI (match_dup 2) (match_dup 3)))
7430    (clobber (reg:CC 17))]
7431   "optimize_size || TARGET_USE_CLTD"
7432   "#"
7433   [(set_attr "type" "multi")])
7434
7435 (define_insn "*divmodsi_noext"
7436   [(set (match_operand:SI 0 "register_operand" "=a")
7437         (div:SI (match_operand:SI 1 "register_operand" "0")
7438                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7439    (set (match_operand:SI 3 "register_operand" "=d")
7440         (mod:SI (match_dup 1) (match_dup 2)))
7441    (use (match_operand:SI 4 "register_operand" "3"))
7442    (clobber (reg:CC 17))]
7443   ""
7444   "idiv{l}\t%2"
7445   [(set_attr "type" "idiv")
7446    (set_attr "mode" "SI")
7447    (set_attr "ppro_uops" "few")])
7448
7449 (define_split
7450   [(set (match_operand:SI 0 "register_operand" "")
7451         (div:SI (match_operand:SI 1 "register_operand" "")
7452                 (match_operand:SI 2 "nonimmediate_operand" "")))
7453    (set (match_operand:SI 3 "register_operand" "")
7454         (mod:SI (match_dup 1) (match_dup 2)))
7455    (clobber (reg:CC 17))]
7456   "reload_completed"
7457   [(parallel [(set (match_dup 3)
7458                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7459               (clobber (reg:CC 17))])
7460    (parallel [(set (match_dup 0)
7461                    (div:SI (reg:SI 0) (match_dup 2)))
7462               (set (match_dup 3)
7463                    (mod:SI (reg:SI 0) (match_dup 2)))
7464               (use (match_dup 3))
7465               (clobber (reg:CC 17))])]
7466 {
7467   /* Avoid use of cltd in favor of a mov+shift.  */
7468   if (!TARGET_USE_CLTD && !optimize_size)
7469     {
7470       if (true_regnum (operands[1]))
7471         emit_move_insn (operands[0], operands[1]);
7472       else
7473         emit_move_insn (operands[3], operands[1]);
7474       operands[4] = operands[3];
7475     }
7476   else
7477     {
7478       if (true_regnum (operands[1]))
7479         abort();
7480       operands[4] = operands[1];
7481     }
7482 })
7483 ;; %%% Split me.
7484 (define_insn "divmodhi4"
7485   [(set (match_operand:HI 0 "register_operand" "=a")
7486         (div:HI (match_operand:HI 1 "register_operand" "0")
7487                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7488    (set (match_operand:HI 3 "register_operand" "=&d")
7489         (mod:HI (match_dup 1) (match_dup 2)))
7490    (clobber (reg:CC 17))]
7491   "TARGET_HIMODE_MATH"
7492   "cwtd\;idiv{w}\t%2"
7493   [(set_attr "type" "multi")
7494    (set_attr "length_immediate" "0")
7495    (set_attr "mode" "SI")])
7496
7497 (define_insn "udivmoddi4"
7498   [(set (match_operand:DI 0 "register_operand" "=a")
7499         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7500                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7501    (set (match_operand:DI 3 "register_operand" "=&d")
7502         (umod:DI (match_dup 1) (match_dup 2)))
7503    (clobber (reg:CC 17))]
7504   "TARGET_64BIT"
7505   "xor{q}\t%3, %3\;div{q}\t%2"
7506   [(set_attr "type" "multi")
7507    (set_attr "length_immediate" "0")
7508    (set_attr "mode" "DI")])
7509
7510 (define_insn "*udivmoddi4_noext"
7511   [(set (match_operand:DI 0 "register_operand" "=a")
7512         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7513                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514    (set (match_operand:DI 3 "register_operand" "=d")
7515         (umod:DI (match_dup 1) (match_dup 2)))
7516    (use (match_dup 3))
7517    (clobber (reg:CC 17))]
7518   "TARGET_64BIT"
7519   "div{q}\t%2"
7520   [(set_attr "type" "idiv")
7521    (set_attr "ppro_uops" "few")
7522    (set_attr "mode" "DI")])
7523
7524 (define_split
7525   [(set (match_operand:DI 0 "register_operand" "")
7526         (udiv:DI (match_operand:DI 1 "register_operand" "")
7527                  (match_operand:DI 2 "nonimmediate_operand" "")))
7528    (set (match_operand:DI 3 "register_operand" "")
7529         (umod:DI (match_dup 1) (match_dup 2)))
7530    (clobber (reg:CC 17))]
7531   "TARGET_64BIT && reload_completed"
7532   [(set (match_dup 3) (const_int 0))
7533    (parallel [(set (match_dup 0)
7534                    (udiv:DI (match_dup 1) (match_dup 2)))
7535               (set (match_dup 3)
7536                    (umod:DI (match_dup 1) (match_dup 2)))
7537               (use (match_dup 3))
7538               (clobber (reg:CC 17))])]
7539   "")
7540
7541 (define_insn "udivmodsi4"
7542   [(set (match_operand:SI 0 "register_operand" "=a")
7543         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7544                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7545    (set (match_operand:SI 3 "register_operand" "=&d")
7546         (umod:SI (match_dup 1) (match_dup 2)))
7547    (clobber (reg:CC 17))]
7548   ""
7549   "xor{l}\t%3, %3\;div{l}\t%2"
7550   [(set_attr "type" "multi")
7551    (set_attr "length_immediate" "0")
7552    (set_attr "mode" "SI")])
7553
7554 (define_insn "*udivmodsi4_noext"
7555   [(set (match_operand:SI 0 "register_operand" "=a")
7556         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7557                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7558    (set (match_operand:SI 3 "register_operand" "=d")
7559         (umod:SI (match_dup 1) (match_dup 2)))
7560    (use (match_dup 3))
7561    (clobber (reg:CC 17))]
7562   ""
7563   "div{l}\t%2"
7564   [(set_attr "type" "idiv")
7565    (set_attr "ppro_uops" "few")
7566    (set_attr "mode" "SI")])
7567
7568 (define_split
7569   [(set (match_operand:SI 0 "register_operand" "")
7570         (udiv:SI (match_operand:SI 1 "register_operand" "")
7571                  (match_operand:SI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:SI 3 "register_operand" "")
7573         (umod:SI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC 17))]
7575   "reload_completed"
7576   [(set (match_dup 3) (const_int 0))
7577    (parallel [(set (match_dup 0)
7578                    (udiv:SI (match_dup 1) (match_dup 2)))
7579               (set (match_dup 3)
7580                    (umod:SI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 3))
7582               (clobber (reg:CC 17))])]
7583   "")
7584
7585 (define_expand "udivmodhi4"
7586   [(set (match_dup 4) (const_int 0))
7587    (parallel [(set (match_operand:HI 0 "register_operand" "")
7588                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7589                             (match_operand:HI 2 "nonimmediate_operand" "")))
7590               (set (match_operand:HI 3 "register_operand" "")
7591                    (umod:HI (match_dup 1) (match_dup 2)))
7592               (use (match_dup 4))
7593               (clobber (reg:CC 17))])]
7594   "TARGET_HIMODE_MATH"
7595   "operands[4] = gen_reg_rtx (HImode);")
7596
7597 (define_insn "*udivmodhi_noext"
7598   [(set (match_operand:HI 0 "register_operand" "=a")
7599         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7600                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7601    (set (match_operand:HI 3 "register_operand" "=d")
7602         (umod:HI (match_dup 1) (match_dup 2)))
7603    (use (match_operand:HI 4 "register_operand" "3"))
7604    (clobber (reg:CC 17))]
7605   ""
7606   "div{w}\t%2"
7607   [(set_attr "type" "idiv")
7608    (set_attr "mode" "HI")
7609    (set_attr "ppro_uops" "few")])
7610
7611 ;; We can not use div/idiv for double division, because it causes
7612 ;; "division by zero" on the overflow and that's not what we expect
7613 ;; from truncate.  Because true (non truncating) double division is
7614 ;; never generated, we can't create this insn anyway.
7615 ;
7616 ;(define_insn ""
7617 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7618 ;       (truncate:SI
7619 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7620 ;                  (zero_extend:DI
7621 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7622 ;   (set (match_operand:SI 3 "register_operand" "=d")
7623 ;       (truncate:SI
7624 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7625 ;   (clobber (reg:CC 17))]
7626 ;  ""
7627 ;  "div{l}\t{%2, %0|%0, %2}"
7628 ;  [(set_attr "type" "idiv")
7629 ;   (set_attr "ppro_uops" "few")])
7630 \f
7631 ;;- Logical AND instructions
7632
7633 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7634 ;; Note that this excludes ah.
7635
7636 (define_insn "*testdi_1_rex64"
7637   [(set (reg 17)
7638         (compare
7639           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7640                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7641           (const_int 0)))]
7642   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7643    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7644   "@
7645    test{l}\t{%k1, %k0|%k0, %k1} 
7646    test{l}\t{%k1, %k0|%k0, %k1} 
7647    test{q}\t{%1, %0|%0, %1} 
7648    test{q}\t{%1, %0|%0, %1} 
7649    test{q}\t{%1, %0|%0, %1}"
7650   [(set_attr "type" "test")
7651    (set_attr "modrm" "0,1,0,1,1")
7652    (set_attr "mode" "SI,SI,DI,DI,DI")
7653    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7654
7655 (define_insn "testsi_1"
7656   [(set (reg 17)
7657         (compare
7658           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7659                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7660           (const_int 0)))]
7661   "ix86_match_ccmode (insn, CCNOmode)
7662    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7663   "test{l}\t{%1, %0|%0, %1}"
7664   [(set_attr "type" "test")
7665    (set_attr "modrm" "0,1,1")
7666    (set_attr "mode" "SI")
7667    (set_attr "pent_pair" "uv,np,uv")])
7668
7669 (define_expand "testsi_ccno_1"
7670   [(set (reg:CCNO 17)
7671         (compare:CCNO
7672           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7673                   (match_operand:SI 1 "nonmemory_operand" ""))
7674           (const_int 0)))]
7675   ""
7676   "")
7677
7678 (define_insn "*testhi_1"
7679   [(set (reg 17)
7680         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7681                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7682                  (const_int 0)))]
7683   "ix86_match_ccmode (insn, CCNOmode)
7684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685   "test{w}\t{%1, %0|%0, %1}"
7686   [(set_attr "type" "test")
7687    (set_attr "modrm" "0,1,1")
7688    (set_attr "mode" "HI")
7689    (set_attr "pent_pair" "uv,np,uv")])
7690
7691 (define_expand "testqi_ccz_1"
7692   [(set (reg:CCZ 17)
7693         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7694                              (match_operand:QI 1 "nonmemory_operand" ""))
7695                  (const_int 0)))]
7696   ""
7697   "")
7698
7699 (define_insn "*testqi_1"
7700   [(set (reg 17)
7701         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7702                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7703                  (const_int 0)))]
7704   "ix86_match_ccmode (insn, CCNOmode)
7705    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7706 {
7707   if (which_alternative == 3)
7708     {
7709       if (GET_CODE (operands[1]) == CONST_INT
7710           && (INTVAL (operands[1]) & 0xffffff00))
7711         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7712       return "test{l}\t{%1, %k0|%k0, %1}";
7713     }
7714   return "test{b}\t{%1, %0|%0, %1}";
7715 }
7716   [(set_attr "type" "test")
7717    (set_attr "modrm" "0,1,1,1")
7718    (set_attr "mode" "QI,QI,QI,SI")
7719    (set_attr "pent_pair" "uv,np,uv,np")])
7720
7721 (define_expand "testqi_ext_ccno_0"
7722   [(set (reg:CCNO 17)
7723         (compare:CCNO
7724           (and:SI
7725             (zero_extract:SI
7726               (match_operand 0 "ext_register_operand" "")
7727               (const_int 8)
7728               (const_int 8))
7729             (match_operand 1 "const_int_operand" ""))
7730           (const_int 0)))]
7731   ""
7732   "")
7733
7734 (define_insn "*testqi_ext_0"
7735   [(set (reg 17)
7736         (compare
7737           (and:SI
7738             (zero_extract:SI
7739               (match_operand 0 "ext_register_operand" "Q")
7740               (const_int 8)
7741               (const_int 8))
7742             (match_operand 1 "const_int_operand" "n"))
7743           (const_int 0)))]
7744   "ix86_match_ccmode (insn, CCNOmode)"
7745   "test{b}\t{%1, %h0|%h0, %1}"
7746   [(set_attr "type" "test")
7747    (set_attr "mode" "QI")
7748    (set_attr "length_immediate" "1")
7749    (set_attr "pent_pair" "np")])
7750
7751 (define_insn "*testqi_ext_1"
7752   [(set (reg 17)
7753         (compare
7754           (and:SI
7755             (zero_extract:SI
7756               (match_operand 0 "ext_register_operand" "Q")
7757               (const_int 8)
7758               (const_int 8))
7759             (zero_extend:SI
7760               (match_operand:QI 1 "general_operand" "Qm")))
7761           (const_int 0)))]
7762   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7763    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7764   "test{b}\t{%1, %h0|%h0, %1}"
7765   [(set_attr "type" "test")
7766    (set_attr "mode" "QI")])
7767
7768 (define_insn "*testqi_ext_1_rex64"
7769   [(set (reg 17)
7770         (compare
7771           (and:SI
7772             (zero_extract:SI
7773               (match_operand 0 "ext_register_operand" "Q")
7774               (const_int 8)
7775               (const_int 8))
7776             (zero_extend:SI
7777               (match_operand:QI 1 "register_operand" "Q")))
7778           (const_int 0)))]
7779   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7780   "test{b}\t{%1, %h0|%h0, %1}"
7781   [(set_attr "type" "test")
7782    (set_attr "mode" "QI")])
7783
7784 (define_insn "*testqi_ext_2"
7785   [(set (reg 17)
7786         (compare
7787           (and:SI
7788             (zero_extract:SI
7789               (match_operand 0 "ext_register_operand" "Q")
7790               (const_int 8)
7791               (const_int 8))
7792             (zero_extract:SI
7793               (match_operand 1 "ext_register_operand" "Q")
7794               (const_int 8)
7795               (const_int 8)))
7796           (const_int 0)))]
7797   "ix86_match_ccmode (insn, CCNOmode)"
7798   "test{b}\t{%h1, %h0|%h0, %h1}"
7799   [(set_attr "type" "test")
7800    (set_attr "mode" "QI")])
7801
7802 ;; Combine likes to form bit extractions for some tests.  Humor it.
7803 (define_insn "*testqi_ext_3"
7804   [(set (reg 17)
7805         (compare (zero_extract:SI
7806                    (match_operand 0 "nonimmediate_operand" "rm")
7807                    (match_operand:SI 1 "const_int_operand" "")
7808                    (match_operand:SI 2 "const_int_operand" ""))
7809                  (const_int 0)))]
7810   "ix86_match_ccmode (insn, CCNOmode)
7811    && (GET_MODE (operands[0]) == SImode
7812        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7813        || GET_MODE (operands[0]) == HImode
7814        || GET_MODE (operands[0]) == QImode)"
7815   "#")
7816
7817 (define_insn "*testqi_ext_3_rex64"
7818   [(set (reg 17)
7819         (compare (zero_extract:DI
7820                    (match_operand 0 "nonimmediate_operand" "rm")
7821                    (match_operand:DI 1 "const_int_operand" "")
7822                    (match_operand:DI 2 "const_int_operand" ""))
7823                  (const_int 0)))]
7824   "TARGET_64BIT
7825    && ix86_match_ccmode (insn, CCNOmode)
7826    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7827    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7828    /* Ensure that resulting mask is zero or sign extended operand.  */
7829    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7830        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7831            && INTVAL (operands[1]) > 32))
7832    && (GET_MODE (operands[0]) == SImode
7833        || GET_MODE (operands[0]) == DImode
7834        || GET_MODE (operands[0]) == HImode
7835        || GET_MODE (operands[0]) == QImode)"
7836   "#")
7837
7838 (define_split
7839   [(set (reg 17)
7840         (compare (zero_extract
7841                    (match_operand 0 "nonimmediate_operand" "")
7842                    (match_operand 1 "const_int_operand" "")
7843                    (match_operand 2 "const_int_operand" ""))
7844                  (const_int 0)))]
7845   "ix86_match_ccmode (insn, CCNOmode)"
7846   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7847 {
7848   HOST_WIDE_INT len = INTVAL (operands[1]);
7849   HOST_WIDE_INT pos = INTVAL (operands[2]);
7850   HOST_WIDE_INT mask;
7851   enum machine_mode mode, submode;
7852
7853   mode = GET_MODE (operands[0]);
7854   if (GET_CODE (operands[0]) == MEM)
7855     {
7856       /* ??? Combine likes to put non-volatile mem extractions in QImode
7857          no matter the size of the test.  So find a mode that works.  */
7858       if (! MEM_VOLATILE_P (operands[0]))
7859         {
7860           mode = smallest_mode_for_size (pos + len, MODE_INT);
7861           operands[0] = adjust_address (operands[0], mode, 0);
7862         }
7863     }
7864   else if (GET_CODE (operands[0]) == SUBREG
7865            && (submode = GET_MODE (SUBREG_REG (operands[0])),
7866                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7867            && pos + len <= GET_MODE_BITSIZE (submode))
7868     {
7869       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7870       mode = submode;
7871       operands[0] = SUBREG_REG (operands[0]);
7872     }
7873   else if (mode == HImode && pos + len <= 8)
7874     {
7875       /* Small HImode tests can be converted to QImode.  */
7876       mode = QImode;
7877       operands[0] = gen_lowpart (QImode, operands[0]);
7878     }
7879
7880   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7881   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7882
7883   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
7884 })
7885
7886 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7887 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7888 ;; this is relatively important trick.
7889 ;; Do the conversion only post-reload to avoid limiting of the register class
7890 ;; to QI regs.
7891 (define_split
7892   [(set (reg 17)
7893         (compare
7894           (and (match_operand 0 "register_operand" "")
7895                (match_operand 1 "const_int_operand" ""))
7896           (const_int 0)))]
7897    "reload_completed
7898     && QI_REG_P (operands[0])
7899     && ((ix86_match_ccmode (insn, CCZmode)
7900          && !(INTVAL (operands[1]) & ~(255 << 8)))
7901         || (ix86_match_ccmode (insn, CCNOmode)
7902             && !(INTVAL (operands[1]) & ~(127 << 8))))
7903     && GET_MODE (operands[0]) != QImode"
7904   [(set (reg:CCNO 17)
7905         (compare:CCNO
7906           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7907                   (match_dup 1))
7908           (const_int 0)))]
7909   "operands[0] = gen_lowpart (SImode, operands[0]);
7910    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7911
7912 (define_split
7913   [(set (reg 17)
7914         (compare
7915           (and (match_operand 0 "nonimmediate_operand" "")
7916                (match_operand 1 "const_int_operand" ""))
7917           (const_int 0)))]
7918    "reload_completed
7919     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
7920     && ((ix86_match_ccmode (insn, CCZmode)
7921          && !(INTVAL (operands[1]) & ~255))
7922         || (ix86_match_ccmode (insn, CCNOmode)
7923             && !(INTVAL (operands[1]) & ~127)))
7924     && GET_MODE (operands[0]) != QImode"
7925   [(set (reg:CCNO 17)
7926         (compare:CCNO
7927           (and:QI (match_dup 0)
7928                   (match_dup 1))
7929           (const_int 0)))]
7930   "operands[0] = gen_lowpart (QImode, operands[0]);
7931    operands[1] = gen_lowpart (QImode, operands[1]);")
7932
7933
7934 ;; %%% This used to optimize known byte-wide and operations to memory,
7935 ;; and sometimes to QImode registers.  If this is considered useful,
7936 ;; it should be done with splitters.
7937
7938 (define_expand "anddi3"
7939   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7940         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7941                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7942    (clobber (reg:CC 17))]
7943   "TARGET_64BIT"
7944   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7945
7946 (define_insn "*anddi_1_rex64"
7947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7948         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7949                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7950    (clobber (reg:CC 17))]
7951   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7952 {
7953   switch (get_attr_type (insn))
7954     {
7955     case TYPE_IMOVX:
7956       {
7957         enum machine_mode mode;
7958
7959         if (GET_CODE (operands[2]) != CONST_INT)
7960           abort ();
7961         if (INTVAL (operands[2]) == 0xff)
7962           mode = QImode;
7963         else if (INTVAL (operands[2]) == 0xffff)
7964           mode = HImode;
7965         else
7966           abort ();
7967         
7968         operands[1] = gen_lowpart (mode, operands[1]);
7969         if (mode == QImode)
7970           return "movz{bq|x}\t{%1,%0|%0, %1}";
7971         else
7972           return "movz{wq|x}\t{%1,%0|%0, %1}";
7973       }
7974
7975     default:
7976       if (! rtx_equal_p (operands[0], operands[1]))
7977         abort ();
7978       if (get_attr_mode (insn) == MODE_SI)
7979         return "and{l}\t{%k2, %k0|%k0, %k2}";
7980       else
7981         return "and{q}\t{%2, %0|%0, %2}";
7982     }
7983 }
7984   [(set_attr "type" "alu,alu,alu,imovx")
7985    (set_attr "length_immediate" "*,*,*,0")
7986    (set_attr "mode" "SI,DI,DI,DI")])
7987
7988 (define_insn "*anddi_2"
7989   [(set (reg 17)
7990         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7991                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7992                  (const_int 0)))
7993    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7994         (and:DI (match_dup 1) (match_dup 2)))]
7995   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7996    && ix86_binary_operator_ok (AND, DImode, operands)"
7997   "@
7998    and{l}\t{%k2, %k0|%k0, %k2} 
7999    and{q}\t{%2, %0|%0, %2} 
8000    and{q}\t{%2, %0|%0, %2}"
8001   [(set_attr "type" "alu")
8002    (set_attr "mode" "SI,DI,DI")])
8003
8004 (define_expand "andsi3"
8005   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8006         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8007                 (match_operand:SI 2 "general_operand" "")))
8008    (clobber (reg:CC 17))]
8009   ""
8010   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8011
8012 (define_insn "*andsi_1"
8013   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8014         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8015                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8016    (clobber (reg:CC 17))]
8017   "ix86_binary_operator_ok (AND, SImode, operands)"
8018 {
8019   switch (get_attr_type (insn))
8020     {
8021     case TYPE_IMOVX:
8022       {
8023         enum machine_mode mode;
8024
8025         if (GET_CODE (operands[2]) != CONST_INT)
8026           abort ();
8027         if (INTVAL (operands[2]) == 0xff)
8028           mode = QImode;
8029         else if (INTVAL (operands[2]) == 0xffff)
8030           mode = HImode;
8031         else
8032           abort ();
8033         
8034         operands[1] = gen_lowpart (mode, operands[1]);
8035         if (mode == QImode)
8036           return "movz{bl|x}\t{%1,%0|%0, %1}";
8037         else
8038           return "movz{wl|x}\t{%1,%0|%0, %1}";
8039       }
8040
8041     default:
8042       if (! rtx_equal_p (operands[0], operands[1]))
8043         abort ();
8044       return "and{l}\t{%2, %0|%0, %2}";
8045     }
8046 }
8047   [(set_attr "type" "alu,alu,imovx")
8048    (set_attr "length_immediate" "*,*,0")
8049    (set_attr "mode" "SI")])
8050
8051 (define_split
8052   [(set (match_operand 0 "register_operand" "")
8053         (and (match_dup 0)
8054              (const_int -65536)))
8055    (clobber (reg:CC 17))]
8056   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8057   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8058   "operands[1] = gen_lowpart (HImode, operands[0]);")
8059
8060 (define_split
8061   [(set (match_operand 0 "ext_register_operand" "")
8062         (and (match_dup 0)
8063              (const_int -256)))
8064    (clobber (reg:CC 17))]
8065   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8066   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8067   "operands[1] = gen_lowpart (QImode, operands[0]);")
8068
8069 (define_split
8070   [(set (match_operand 0 "ext_register_operand" "")
8071         (and (match_dup 0)
8072              (const_int -65281)))
8073    (clobber (reg:CC 17))]
8074   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8075   [(parallel [(set (zero_extract:SI (match_dup 0)
8076                                     (const_int 8)
8077                                     (const_int 8))
8078                    (xor:SI 
8079                      (zero_extract:SI (match_dup 0)
8080                                       (const_int 8)
8081                                       (const_int 8))
8082                      (zero_extract:SI (match_dup 0)
8083                                       (const_int 8)
8084                                       (const_int 8))))
8085               (clobber (reg:CC 17))])]
8086   "operands[0] = gen_lowpart (SImode, operands[0]);")
8087
8088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8089 (define_insn "*andsi_1_zext"
8090   [(set (match_operand:DI 0 "register_operand" "=r")
8091         (zero_extend:DI
8092           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8093                   (match_operand:SI 2 "general_operand" "rim"))))
8094    (clobber (reg:CC 17))]
8095   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8096   "and{l}\t{%2, %k0|%k0, %2}"
8097   [(set_attr "type" "alu")
8098    (set_attr "mode" "SI")])
8099
8100 (define_insn "*andsi_2"
8101   [(set (reg 17)
8102         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8103                          (match_operand:SI 2 "general_operand" "rim,ri"))
8104                  (const_int 0)))
8105    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8106         (and:SI (match_dup 1) (match_dup 2)))]
8107   "ix86_match_ccmode (insn, CCNOmode)
8108    && ix86_binary_operator_ok (AND, SImode, operands)"
8109   "and{l}\t{%2, %0|%0, %2}"
8110   [(set_attr "type" "alu")
8111    (set_attr "mode" "SI")])
8112
8113 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8114 (define_insn "*andsi_2_zext"
8115   [(set (reg 17)
8116         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8117                          (match_operand:SI 2 "general_operand" "rim"))
8118                  (const_int 0)))
8119    (set (match_operand:DI 0 "register_operand" "=r")
8120         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8121   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8122    && ix86_binary_operator_ok (AND, SImode, operands)"
8123   "and{l}\t{%2, %k0|%k0, %2}"
8124   [(set_attr "type" "alu")
8125    (set_attr "mode" "SI")])
8126
8127 (define_expand "andhi3"
8128   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8129         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8130                 (match_operand:HI 2 "general_operand" "")))
8131    (clobber (reg:CC 17))]
8132   "TARGET_HIMODE_MATH"
8133   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8134
8135 (define_insn "*andhi_1"
8136   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8137         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8138                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8139    (clobber (reg:CC 17))]
8140   "ix86_binary_operator_ok (AND, HImode, operands)"
8141 {
8142   switch (get_attr_type (insn))
8143     {
8144     case TYPE_IMOVX:
8145       if (GET_CODE (operands[2]) != CONST_INT)
8146         abort ();
8147       if (INTVAL (operands[2]) == 0xff)
8148         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8149       abort ();
8150
8151     default:
8152       if (! rtx_equal_p (operands[0], operands[1]))
8153         abort ();
8154
8155       return "and{w}\t{%2, %0|%0, %2}";
8156     }
8157 }
8158   [(set_attr "type" "alu,alu,imovx")
8159    (set_attr "length_immediate" "*,*,0")
8160    (set_attr "mode" "HI,HI,SI")])
8161
8162 (define_insn "*andhi_2"
8163   [(set (reg 17)
8164         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8165                          (match_operand:HI 2 "general_operand" "rim,ri"))
8166                  (const_int 0)))
8167    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8168         (and:HI (match_dup 1) (match_dup 2)))]
8169   "ix86_match_ccmode (insn, CCNOmode)
8170    && ix86_binary_operator_ok (AND, HImode, operands)"
8171   "and{w}\t{%2, %0|%0, %2}"
8172   [(set_attr "type" "alu")
8173    (set_attr "mode" "HI")])
8174
8175 (define_expand "andqi3"
8176   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8177         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8178                 (match_operand:QI 2 "general_operand" "")))
8179    (clobber (reg:CC 17))]
8180   "TARGET_QIMODE_MATH"
8181   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8182
8183 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8184 (define_insn "*andqi_1"
8185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8186         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8187                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8188    (clobber (reg:CC 17))]
8189   "ix86_binary_operator_ok (AND, QImode, operands)"
8190   "@
8191    and{b}\t{%2, %0|%0, %2}
8192    and{b}\t{%2, %0|%0, %2}
8193    and{l}\t{%k2, %k0|%k0, %k2}"
8194   [(set_attr "type" "alu")
8195    (set_attr "mode" "QI,QI,SI")])
8196
8197 (define_insn "*andqi_1_slp"
8198   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8199         (and:QI (match_dup 0)
8200                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8201    (clobber (reg:CC 17))]
8202   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8203    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8204   "and{b}\t{%1, %0|%0, %1}"
8205   [(set_attr "type" "alu1")
8206    (set_attr "mode" "QI")])
8207
8208 (define_insn "*andqi_2"
8209   [(set (reg 17)
8210         (compare (and:QI
8211                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8212                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8213                  (const_int 0)))
8214    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8215         (and:QI (match_dup 1) (match_dup 2)))]
8216   "ix86_match_ccmode (insn, CCNOmode)
8217    && ix86_binary_operator_ok (AND, QImode, operands)"
8218 {
8219   if (which_alternative == 2)
8220     {
8221       if (GET_CODE (operands[2]) == CONST_INT
8222           && (INTVAL (operands[2]) & 0xffffff00))
8223         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8224       return "and{l}\t{%2, %k0|%k0, %2}";
8225     }
8226   return "and{b}\t{%2, %0|%0, %2}";
8227 }
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "QI,QI,SI")])
8230
8231 (define_insn "*andqi_2_slp"
8232   [(set (reg 17)
8233         (compare (and:QI
8234                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8235                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8236                  (const_int 0)))
8237    (set (strict_low_part (match_dup 0))
8238         (and:QI (match_dup 0) (match_dup 1)))]
8239   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8240    && ix86_match_ccmode (insn, CCNOmode)
8241    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8242   "and{b}\t{%1, %0|%0, %1}"
8243   [(set_attr "type" "alu1")
8244    (set_attr "mode" "QI")])
8245
8246 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8247 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8248 ;; for a QImode operand, which of course failed.
8249
8250 (define_insn "andqi_ext_0"
8251   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252                          (const_int 8)
8253                          (const_int 8))
8254         (and:SI 
8255           (zero_extract:SI
8256             (match_operand 1 "ext_register_operand" "0")
8257             (const_int 8)
8258             (const_int 8))
8259           (match_operand 2 "const_int_operand" "n")))
8260    (clobber (reg:CC 17))]
8261   ""
8262   "and{b}\t{%2, %h0|%h0, %2}"
8263   [(set_attr "type" "alu")
8264    (set_attr "length_immediate" "1")
8265    (set_attr "mode" "QI")])
8266
8267 ;; Generated by peephole translating test to and.  This shows up
8268 ;; often in fp comparisons.
8269
8270 (define_insn "*andqi_ext_0_cc"
8271   [(set (reg 17)
8272         (compare
8273           (and:SI
8274             (zero_extract:SI
8275               (match_operand 1 "ext_register_operand" "0")
8276               (const_int 8)
8277               (const_int 8))
8278             (match_operand 2 "const_int_operand" "n"))
8279           (const_int 0)))
8280    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8281                          (const_int 8)
8282                          (const_int 8))
8283         (and:SI 
8284           (zero_extract:SI
8285             (match_dup 1)
8286             (const_int 8)
8287             (const_int 8))
8288           (match_dup 2)))]
8289   "ix86_match_ccmode (insn, CCNOmode)"
8290   "and{b}\t{%2, %h0|%h0, %2}"
8291   [(set_attr "type" "alu")
8292    (set_attr "length_immediate" "1")
8293    (set_attr "mode" "QI")])
8294
8295 (define_insn "*andqi_ext_1"
8296   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8297                          (const_int 8)
8298                          (const_int 8))
8299         (and:SI 
8300           (zero_extract:SI
8301             (match_operand 1 "ext_register_operand" "0")
8302             (const_int 8)
8303             (const_int 8))
8304           (zero_extend:SI
8305             (match_operand:QI 2 "general_operand" "Qm"))))
8306    (clobber (reg:CC 17))]
8307   "!TARGET_64BIT"
8308   "and{b}\t{%2, %h0|%h0, %2}"
8309   [(set_attr "type" "alu")
8310    (set_attr "length_immediate" "0")
8311    (set_attr "mode" "QI")])
8312
8313 (define_insn "*andqi_ext_1_rex64"
8314   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8315                          (const_int 8)
8316                          (const_int 8))
8317         (and:SI 
8318           (zero_extract:SI
8319             (match_operand 1 "ext_register_operand" "0")
8320             (const_int 8)
8321             (const_int 8))
8322           (zero_extend:SI
8323             (match_operand 2 "ext_register_operand" "Q"))))
8324    (clobber (reg:CC 17))]
8325   "TARGET_64BIT"
8326   "and{b}\t{%2, %h0|%h0, %2}"
8327   [(set_attr "type" "alu")
8328    (set_attr "length_immediate" "0")
8329    (set_attr "mode" "QI")])
8330
8331 (define_insn "*andqi_ext_2"
8332   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333                          (const_int 8)
8334                          (const_int 8))
8335         (and:SI
8336           (zero_extract:SI
8337             (match_operand 1 "ext_register_operand" "%0")
8338             (const_int 8)
8339             (const_int 8))
8340           (zero_extract:SI
8341             (match_operand 2 "ext_register_operand" "Q")
8342             (const_int 8)
8343             (const_int 8))))
8344    (clobber (reg:CC 17))]
8345   ""
8346   "and{b}\t{%h2, %h0|%h0, %h2}"
8347   [(set_attr "type" "alu")
8348    (set_attr "length_immediate" "0")
8349    (set_attr "mode" "QI")])
8350
8351 ;; Convert wide AND instructions with immediate operand to shorter QImode
8352 ;; equivalents when possible.
8353 ;; Don't do the splitting with memory operands, since it introduces risk
8354 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8355 ;; for size, but that can (should?) be handled by generic code instead.
8356 (define_split
8357   [(set (match_operand 0 "register_operand" "")
8358         (and (match_operand 1 "register_operand" "")
8359              (match_operand 2 "const_int_operand" "")))
8360    (clobber (reg:CC 17))]
8361    "reload_completed
8362     && QI_REG_P (operands[0])
8363     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8364     && !(~INTVAL (operands[2]) & ~(255 << 8))
8365     && GET_MODE (operands[0]) != QImode"
8366   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8367                    (and:SI (zero_extract:SI (match_dup 1)
8368                                             (const_int 8) (const_int 8))
8369                            (match_dup 2)))
8370               (clobber (reg:CC 17))])]
8371   "operands[0] = gen_lowpart (SImode, operands[0]);
8372    operands[1] = gen_lowpart (SImode, operands[1]);
8373    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8374
8375 ;; Since AND can be encoded with sign extended immediate, this is only
8376 ;; profitable when 7th bit is not set.
8377 (define_split
8378   [(set (match_operand 0 "register_operand" "")
8379         (and (match_operand 1 "general_operand" "")
8380              (match_operand 2 "const_int_operand" "")))
8381    (clobber (reg:CC 17))]
8382    "reload_completed
8383     && ANY_QI_REG_P (operands[0])
8384     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8385     && !(~INTVAL (operands[2]) & ~255)
8386     && !(INTVAL (operands[2]) & 128)
8387     && GET_MODE (operands[0]) != QImode"
8388   [(parallel [(set (strict_low_part (match_dup 0))
8389                    (and:QI (match_dup 1)
8390                            (match_dup 2)))
8391               (clobber (reg:CC 17))])]
8392   "operands[0] = gen_lowpart (QImode, operands[0]);
8393    operands[1] = gen_lowpart (QImode, operands[1]);
8394    operands[2] = gen_lowpart (QImode, operands[2]);")
8395 \f
8396 ;; Logical inclusive OR instructions
8397
8398 ;; %%% This used to optimize known byte-wide and operations to memory.
8399 ;; If this is considered useful, it should be done with splitters.
8400
8401 (define_expand "iordi3"
8402   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8403         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8404                 (match_operand:DI 2 "x86_64_general_operand" "")))
8405    (clobber (reg:CC 17))]
8406   "TARGET_64BIT"
8407   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8408
8409 (define_insn "*iordi_1_rex64"
8410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8411         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8412                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8413    (clobber (reg:CC 17))]
8414   "TARGET_64BIT
8415    && ix86_binary_operator_ok (IOR, DImode, operands)"
8416   "or{q}\t{%2, %0|%0, %2}"
8417   [(set_attr "type" "alu")
8418    (set_attr "mode" "DI")])
8419
8420 (define_insn "*iordi_2_rex64"
8421   [(set (reg 17)
8422         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8423                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8424                  (const_int 0)))
8425    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8426         (ior:DI (match_dup 1) (match_dup 2)))]
8427   "TARGET_64BIT
8428    && ix86_match_ccmode (insn, CCNOmode)
8429    && ix86_binary_operator_ok (IOR, DImode, operands)"
8430   "or{q}\t{%2, %0|%0, %2}"
8431   [(set_attr "type" "alu")
8432    (set_attr "mode" "DI")])
8433
8434 (define_insn "*iordi_3_rex64"
8435   [(set (reg 17)
8436         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8437                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8438                  (const_int 0)))
8439    (clobber (match_scratch:DI 0 "=r"))]
8440   "TARGET_64BIT
8441    && ix86_match_ccmode (insn, CCNOmode)
8442    && ix86_binary_operator_ok (IOR, DImode, operands)"
8443   "or{q}\t{%2, %0|%0, %2}"
8444   [(set_attr "type" "alu")
8445    (set_attr "mode" "DI")])
8446
8447
8448 (define_expand "iorsi3"
8449   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8450         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8451                 (match_operand:SI 2 "general_operand" "")))
8452    (clobber (reg:CC 17))]
8453   ""
8454   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8455
8456 (define_insn "*iorsi_1"
8457   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8458         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8459                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8460    (clobber (reg:CC 17))]
8461   "ix86_binary_operator_ok (IOR, SImode, operands)"
8462   "or{l}\t{%2, %0|%0, %2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "mode" "SI")])
8465
8466 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8467 (define_insn "*iorsi_1_zext"
8468   [(set (match_operand:DI 0 "register_operand" "=rm")
8469         (zero_extend:DI
8470           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8471                   (match_operand:SI 2 "general_operand" "rim"))))
8472    (clobber (reg:CC 17))]
8473   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8474   "or{l}\t{%2, %k0|%k0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "mode" "SI")])
8477
8478 (define_insn "*iorsi_1_zext_imm"
8479   [(set (match_operand:DI 0 "register_operand" "=rm")
8480         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8481                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8482    (clobber (reg:CC 17))]
8483   "TARGET_64BIT"
8484   "or{l}\t{%2, %k0|%k0, %2}"
8485   [(set_attr "type" "alu")
8486    (set_attr "mode" "SI")])
8487
8488 (define_insn "*iorsi_2"
8489   [(set (reg 17)
8490         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8491                          (match_operand:SI 2 "general_operand" "rim,ri"))
8492                  (const_int 0)))
8493    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8494         (ior:SI (match_dup 1) (match_dup 2)))]
8495   "ix86_match_ccmode (insn, CCNOmode)
8496    && ix86_binary_operator_ok (IOR, SImode, operands)"
8497   "or{l}\t{%2, %0|%0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "mode" "SI")])
8500
8501 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8502 ;; ??? Special case for immediate operand is missing - it is tricky.
8503 (define_insn "*iorsi_2_zext"
8504   [(set (reg 17)
8505         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8506                          (match_operand:SI 2 "general_operand" "rim"))
8507                  (const_int 0)))
8508    (set (match_operand:DI 0 "register_operand" "=r")
8509         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8510   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8511    && ix86_binary_operator_ok (IOR, SImode, operands)"
8512   "or{l}\t{%2, %k0|%k0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "SI")])
8515
8516 (define_insn "*iorsi_2_zext_imm"
8517   [(set (reg 17)
8518         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8519                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8520                  (const_int 0)))
8521    (set (match_operand:DI 0 "register_operand" "=r")
8522         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8523   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8524    && ix86_binary_operator_ok (IOR, SImode, operands)"
8525   "or{l}\t{%2, %k0|%k0, %2}"
8526   [(set_attr "type" "alu")
8527    (set_attr "mode" "SI")])
8528
8529 (define_insn "*iorsi_3"
8530   [(set (reg 17)
8531         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8532                          (match_operand:SI 2 "general_operand" "rim"))
8533                  (const_int 0)))
8534    (clobber (match_scratch:SI 0 "=r"))]
8535   "ix86_match_ccmode (insn, CCNOmode)
8536    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8537   "or{l}\t{%2, %0|%0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "SI")])
8540
8541 (define_expand "iorhi3"
8542   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8543         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8544                 (match_operand:HI 2 "general_operand" "")))
8545    (clobber (reg:CC 17))]
8546   "TARGET_HIMODE_MATH"
8547   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8548
8549 (define_insn "*iorhi_1"
8550   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8551         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8552                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8553    (clobber (reg:CC 17))]
8554   "ix86_binary_operator_ok (IOR, HImode, operands)"
8555   "or{w}\t{%2, %0|%0, %2}"
8556   [(set_attr "type" "alu")
8557    (set_attr "mode" "HI")])
8558
8559 (define_insn "*iorhi_2"
8560   [(set (reg 17)
8561         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8562                          (match_operand:HI 2 "general_operand" "rim,ri"))
8563                  (const_int 0)))
8564    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8565         (ior:HI (match_dup 1) (match_dup 2)))]
8566   "ix86_match_ccmode (insn, CCNOmode)
8567    && ix86_binary_operator_ok (IOR, HImode, operands)"
8568   "or{w}\t{%2, %0|%0, %2}"
8569   [(set_attr "type" "alu")
8570    (set_attr "mode" "HI")])
8571
8572 (define_insn "*iorhi_3"
8573   [(set (reg 17)
8574         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:HI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (clobber (match_scratch:HI 0 "=r"))]
8578   "ix86_match_ccmode (insn, CCNOmode)
8579    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8580   "or{w}\t{%2, %0|%0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "mode" "HI")])
8583
8584 (define_expand "iorqi3"
8585   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8586         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8587                 (match_operand:QI 2 "general_operand" "")))
8588    (clobber (reg:CC 17))]
8589   "TARGET_QIMODE_MATH"
8590   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8591
8592 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8593 (define_insn "*iorqi_1"
8594   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8595         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8596                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8597    (clobber (reg:CC 17))]
8598   "ix86_binary_operator_ok (IOR, QImode, operands)"
8599   "@
8600    or{b}\t{%2, %0|%0, %2}
8601    or{b}\t{%2, %0|%0, %2}
8602    or{l}\t{%k2, %k0|%k0, %k2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "QI,QI,SI")])
8605
8606 (define_insn "*iorqi_1_slp"
8607   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8608         (ior:QI (match_dup 0)
8609                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8610    (clobber (reg:CC 17))]
8611   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8612    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8613   "or{b}\t{%1, %0|%0, %1}"
8614   [(set_attr "type" "alu1")
8615    (set_attr "mode" "QI")])
8616
8617 (define_insn "*iorqi_2"
8618   [(set (reg 17)
8619         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8620                          (match_operand:QI 2 "general_operand" "qim,qi"))
8621                  (const_int 0)))
8622    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8623         (ior:QI (match_dup 1) (match_dup 2)))]
8624   "ix86_match_ccmode (insn, CCNOmode)
8625    && ix86_binary_operator_ok (IOR, QImode, operands)"
8626   "or{b}\t{%2, %0|%0, %2}"
8627   [(set_attr "type" "alu")
8628    (set_attr "mode" "QI")])
8629
8630 (define_insn "*iorqi_2_slp"
8631   [(set (reg 17)
8632         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8633                          (match_operand:QI 1 "general_operand" "qim,qi"))
8634                  (const_int 0)))
8635    (set (strict_low_part (match_dup 0))
8636         (ior:QI (match_dup 0) (match_dup 1)))]
8637   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8638    && ix86_match_ccmode (insn, CCNOmode)
8639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8640   "or{b}\t{%1, %0|%0, %1}"
8641   [(set_attr "type" "alu1")
8642    (set_attr "mode" "QI")])
8643
8644 (define_insn "*iorqi_3"
8645   [(set (reg 17)
8646         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8647                          (match_operand:QI 2 "general_operand" "qim"))
8648                  (const_int 0)))
8649    (clobber (match_scratch:QI 0 "=q"))]
8650   "ix86_match_ccmode (insn, CCNOmode)
8651    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8652   "or{b}\t{%2, %0|%0, %2}"
8653   [(set_attr "type" "alu")
8654    (set_attr "mode" "QI")])
8655
8656 (define_insn "iorqi_ext_0"
8657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8658                          (const_int 8)
8659                          (const_int 8))
8660         (ior:SI 
8661           (zero_extract:SI
8662             (match_operand 1 "ext_register_operand" "0")
8663             (const_int 8)
8664             (const_int 8))
8665           (match_operand 2 "const_int_operand" "n")))
8666    (clobber (reg:CC 17))]
8667   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8668   "or{b}\t{%2, %h0|%h0, %2}"
8669   [(set_attr "type" "alu")
8670    (set_attr "length_immediate" "1")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "*iorqi_ext_1"
8674   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8675                          (const_int 8)
8676                          (const_int 8))
8677         (ior:SI 
8678           (zero_extract:SI
8679             (match_operand 1 "ext_register_operand" "0")
8680             (const_int 8)
8681             (const_int 8))
8682           (zero_extend:SI
8683             (match_operand:QI 2 "general_operand" "Qm"))))
8684    (clobber (reg:CC 17))]
8685   "!TARGET_64BIT
8686    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8687   "or{b}\t{%2, %h0|%h0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "length_immediate" "0")
8690    (set_attr "mode" "QI")])
8691
8692 (define_insn "*iorqi_ext_1_rex64"
8693   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8694                          (const_int 8)
8695                          (const_int 8))
8696         (ior:SI 
8697           (zero_extract:SI
8698             (match_operand 1 "ext_register_operand" "0")
8699             (const_int 8)
8700             (const_int 8))
8701           (zero_extend:SI
8702             (match_operand 2 "ext_register_operand" "Q"))))
8703    (clobber (reg:CC 17))]
8704   "TARGET_64BIT
8705    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8706   "or{b}\t{%2, %h0|%h0, %2}"
8707   [(set_attr "type" "alu")
8708    (set_attr "length_immediate" "0")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*iorqi_ext_2"
8712   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713                          (const_int 8)
8714                          (const_int 8))
8715         (ior:SI 
8716           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8717                            (const_int 8)
8718                            (const_int 8))
8719           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8720                            (const_int 8)
8721                            (const_int 8))))
8722    (clobber (reg:CC 17))]
8723   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8724   "ior{b}\t{%h2, %h0|%h0, %h2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "length_immediate" "0")
8727    (set_attr "mode" "QI")])
8728
8729 (define_split
8730   [(set (match_operand 0 "register_operand" "")
8731         (ior (match_operand 1 "register_operand" "")
8732              (match_operand 2 "const_int_operand" "")))
8733    (clobber (reg:CC 17))]
8734    "reload_completed
8735     && QI_REG_P (operands[0])
8736     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8737     && !(INTVAL (operands[2]) & ~(255 << 8))
8738     && GET_MODE (operands[0]) != QImode"
8739   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740                    (ior:SI (zero_extract:SI (match_dup 1)
8741                                             (const_int 8) (const_int 8))
8742                            (match_dup 2)))
8743               (clobber (reg:CC 17))])]
8744   "operands[0] = gen_lowpart (SImode, operands[0]);
8745    operands[1] = gen_lowpart (SImode, operands[1]);
8746    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8747
8748 ;; Since OR can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is set.
8750 (define_split
8751   [(set (match_operand 0 "register_operand" "")
8752         (ior (match_operand 1 "general_operand" "")
8753              (match_operand 2 "const_int_operand" "")))
8754    (clobber (reg:CC 17))]
8755    "reload_completed
8756     && ANY_QI_REG_P (operands[0])
8757     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8758     && !(INTVAL (operands[2]) & ~255)
8759     && (INTVAL (operands[2]) & 128)
8760     && GET_MODE (operands[0]) != QImode"
8761   [(parallel [(set (strict_low_part (match_dup 0))
8762                    (ior:QI (match_dup 1)
8763                            (match_dup 2)))
8764               (clobber (reg:CC 17))])]
8765   "operands[0] = gen_lowpart (QImode, operands[0]);
8766    operands[1] = gen_lowpart (QImode, operands[1]);
8767    operands[2] = gen_lowpart (QImode, operands[2]);")
8768 \f
8769 ;; Logical XOR instructions
8770
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8773
8774 (define_expand "xordi3"
8775   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8776         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8777                 (match_operand:DI 2 "x86_64_general_operand" "")))
8778    (clobber (reg:CC 17))]
8779   "TARGET_64BIT"
8780   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8781
8782 (define_insn "*xordi_1_rex64"
8783   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8784         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8785                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8786    (clobber (reg:CC 17))]
8787   "TARGET_64BIT
8788    && ix86_binary_operator_ok (XOR, DImode, operands)"
8789   "@
8790    xor{q}\t{%2, %0|%0, %2} 
8791    xor{q}\t{%2, %0|%0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "mode" "DI,DI")])
8794
8795 (define_insn "*xordi_2_rex64"
8796   [(set (reg 17)
8797         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8798                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8799                  (const_int 0)))
8800    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8801         (xor:DI (match_dup 1) (match_dup 2)))]
8802   "TARGET_64BIT
8803    && ix86_match_ccmode (insn, CCNOmode)
8804    && ix86_binary_operator_ok (XOR, DImode, operands)"
8805   "@
8806    xor{q}\t{%2, %0|%0, %2} 
8807    xor{q}\t{%2, %0|%0, %2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "DI,DI")])
8810
8811 (define_insn "*xordi_3_rex64"
8812   [(set (reg 17)
8813         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8814                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8815                  (const_int 0)))
8816    (clobber (match_scratch:DI 0 "=r"))]
8817   "TARGET_64BIT
8818    && ix86_match_ccmode (insn, CCNOmode)
8819    && ix86_binary_operator_ok (XOR, DImode, operands)"
8820   "xor{q}\t{%2, %0|%0, %2}"
8821   [(set_attr "type" "alu")
8822    (set_attr "mode" "DI")])
8823
8824 (define_expand "xorsi3"
8825   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8826         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8827                 (match_operand:SI 2 "general_operand" "")))
8828    (clobber (reg:CC 17))]
8829   ""
8830   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8831
8832 (define_insn "*xorsi_1"
8833   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8834         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8835                 (match_operand:SI 2 "general_operand" "ri,rm")))
8836    (clobber (reg:CC 17))]
8837   "ix86_binary_operator_ok (XOR, SImode, operands)"
8838   "xor{l}\t{%2, %0|%0, %2}"
8839   [(set_attr "type" "alu")
8840    (set_attr "mode" "SI")])
8841
8842 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8843 ;; Add speccase for immediates
8844 (define_insn "*xorsi_1_zext"
8845   [(set (match_operand:DI 0 "register_operand" "=r")
8846         (zero_extend:DI
8847           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8848                   (match_operand:SI 2 "general_operand" "rim"))))
8849    (clobber (reg:CC 17))]
8850   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8851   "xor{l}\t{%2, %k0|%k0, %2}"
8852   [(set_attr "type" "alu")
8853    (set_attr "mode" "SI")])
8854
8855 (define_insn "*xorsi_1_zext_imm"
8856   [(set (match_operand:DI 0 "register_operand" "=r")
8857         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8858                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8859    (clobber (reg:CC 17))]
8860   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8861   "xor{l}\t{%2, %k0|%k0, %2}"
8862   [(set_attr "type" "alu")
8863    (set_attr "mode" "SI")])
8864
8865 (define_insn "*xorsi_2"
8866   [(set (reg 17)
8867         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8868                          (match_operand:SI 2 "general_operand" "rim,ri"))
8869                  (const_int 0)))
8870    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8871         (xor:SI (match_dup 1) (match_dup 2)))]
8872   "ix86_match_ccmode (insn, CCNOmode)
8873    && ix86_binary_operator_ok (XOR, SImode, operands)"
8874   "xor{l}\t{%2, %0|%0, %2}"
8875   [(set_attr "type" "alu")
8876    (set_attr "mode" "SI")])
8877
8878 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8879 ;; ??? Special case for immediate operand is missing - it is tricky.
8880 (define_insn "*xorsi_2_zext"
8881   [(set (reg 17)
8882         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8883                          (match_operand:SI 2 "general_operand" "rim"))
8884                  (const_int 0)))
8885    (set (match_operand:DI 0 "register_operand" "=r")
8886         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8887   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8888    && ix86_binary_operator_ok (XOR, SImode, operands)"
8889   "xor{l}\t{%2, %k0|%k0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "SI")])
8892
8893 (define_insn "*xorsi_2_zext_imm"
8894   [(set (reg 17)
8895         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8896                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8897                  (const_int 0)))
8898    (set (match_operand:DI 0 "register_operand" "=r")
8899         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8900   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8901    && ix86_binary_operator_ok (XOR, SImode, operands)"
8902   "xor{l}\t{%2, %k0|%k0, %2}"
8903   [(set_attr "type" "alu")
8904    (set_attr "mode" "SI")])
8905
8906 (define_insn "*xorsi_3"
8907   [(set (reg 17)
8908         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8909                          (match_operand:SI 2 "general_operand" "rim"))
8910                  (const_int 0)))
8911    (clobber (match_scratch:SI 0 "=r"))]
8912   "ix86_match_ccmode (insn, CCNOmode)
8913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8914   "xor{l}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "SI")])
8917
8918 (define_expand "xorhi3"
8919   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8920         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8921                 (match_operand:HI 2 "general_operand" "")))
8922    (clobber (reg:CC 17))]
8923   "TARGET_HIMODE_MATH"
8924   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8925
8926 (define_insn "*xorhi_1"
8927   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8928         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8929                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8930    (clobber (reg:CC 17))]
8931   "ix86_binary_operator_ok (XOR, HImode, operands)"
8932   "xor{w}\t{%2, %0|%0, %2}"
8933   [(set_attr "type" "alu")
8934    (set_attr "mode" "HI")])
8935
8936 (define_insn "*xorhi_2"
8937   [(set (reg 17)
8938         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8939                          (match_operand:HI 2 "general_operand" "rim,ri"))
8940                  (const_int 0)))
8941    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8942         (xor:HI (match_dup 1) (match_dup 2)))]
8943   "ix86_match_ccmode (insn, CCNOmode)
8944    && ix86_binary_operator_ok (XOR, HImode, operands)"
8945   "xor{w}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "HI")])
8948
8949 (define_insn "*xorhi_3"
8950   [(set (reg 17)
8951         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8952                          (match_operand:HI 2 "general_operand" "rim"))
8953                  (const_int 0)))
8954    (clobber (match_scratch:HI 0 "=r"))]
8955   "ix86_match_ccmode (insn, CCNOmode)
8956    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8957   "xor{w}\t{%2, %0|%0, %2}"
8958   [(set_attr "type" "alu")
8959    (set_attr "mode" "HI")])
8960
8961 (define_expand "xorqi3"
8962   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8963         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8964                 (match_operand:QI 2 "general_operand" "")))
8965    (clobber (reg:CC 17))]
8966   "TARGET_QIMODE_MATH"
8967   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8968
8969 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8970 (define_insn "*xorqi_1"
8971   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8972         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8973                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8974    (clobber (reg:CC 17))]
8975   "ix86_binary_operator_ok (XOR, QImode, operands)"
8976   "@
8977    xor{b}\t{%2, %0|%0, %2}
8978    xor{b}\t{%2, %0|%0, %2}
8979    xor{l}\t{%k2, %k0|%k0, %k2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "QI,QI,SI")])
8982
8983 (define_insn "*xorqi_1_slp"
8984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8985         (xor:QI (match_dup 0)
8986                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8987    (clobber (reg:CC 17))]
8988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8989    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8990   "xor{b}\t{%1, %0|%0, %1}"
8991   [(set_attr "type" "alu1")
8992    (set_attr "mode" "QI")])
8993
8994 (define_insn "xorqi_ext_0"
8995   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8996                          (const_int 8)
8997                          (const_int 8))
8998         (xor:SI 
8999           (zero_extract:SI
9000             (match_operand 1 "ext_register_operand" "0")
9001             (const_int 8)
9002             (const_int 8))
9003           (match_operand 2 "const_int_operand" "n")))
9004    (clobber (reg:CC 17))]
9005   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9006   "xor{b}\t{%2, %h0|%h0, %2}"
9007   [(set_attr "type" "alu")
9008    (set_attr "length_immediate" "1")
9009    (set_attr "mode" "QI")])
9010
9011 (define_insn "*xorqi_ext_1"
9012   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9013                          (const_int 8)
9014                          (const_int 8))
9015         (xor:SI 
9016           (zero_extract:SI
9017             (match_operand 1 "ext_register_operand" "0")
9018             (const_int 8)
9019             (const_int 8))
9020           (zero_extend:SI
9021             (match_operand:QI 2 "general_operand" "Qm"))))
9022    (clobber (reg:CC 17))]
9023   "!TARGET_64BIT
9024    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9025   "xor{b}\t{%2, %h0|%h0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "length_immediate" "0")
9028    (set_attr "mode" "QI")])
9029
9030 (define_insn "*xorqi_ext_1_rex64"
9031   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9032                          (const_int 8)
9033                          (const_int 8))
9034         (xor:SI 
9035           (zero_extract:SI
9036             (match_operand 1 "ext_register_operand" "0")
9037             (const_int 8)
9038             (const_int 8))
9039           (zero_extend:SI
9040             (match_operand 2 "ext_register_operand" "Q"))))
9041    (clobber (reg:CC 17))]
9042   "TARGET_64BIT
9043    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9044   "xor{b}\t{%2, %h0|%h0, %2}"
9045   [(set_attr "type" "alu")
9046    (set_attr "length_immediate" "0")
9047    (set_attr "mode" "QI")])
9048
9049 (define_insn "*xorqi_ext_2"
9050   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9051                          (const_int 8)
9052                          (const_int 8))
9053         (xor:SI 
9054           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9055                            (const_int 8)
9056                            (const_int 8))
9057           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9058                            (const_int 8)
9059                            (const_int 8))))
9060    (clobber (reg:CC 17))]
9061   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9062   "xor{b}\t{%h2, %h0|%h0, %h2}"
9063   [(set_attr "type" "alu")
9064    (set_attr "length_immediate" "0")
9065    (set_attr "mode" "QI")])
9066
9067 (define_insn "*xorqi_cc_1"
9068   [(set (reg 17)
9069         (compare
9070           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9071                   (match_operand:QI 2 "general_operand" "qim,qi"))
9072           (const_int 0)))
9073    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9074         (xor:QI (match_dup 1) (match_dup 2)))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && ix86_binary_operator_ok (XOR, QImode, operands)"
9077   "xor{b}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "QI")])
9080
9081 (define_insn "*xorqi_2_slp"
9082   [(set (reg 17)
9083         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9084                          (match_operand:QI 1 "general_operand" "qim,qi"))
9085                  (const_int 0)))
9086    (set (strict_low_part (match_dup 0))
9087         (xor:QI (match_dup 0) (match_dup 1)))]
9088   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9089    && ix86_match_ccmode (insn, CCNOmode)
9090    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9091   "xor{b}\t{%1, %0|%0, %1}"
9092   [(set_attr "type" "alu1")
9093    (set_attr "mode" "QI")])
9094
9095 (define_insn "*xorqi_cc_2"
9096   [(set (reg 17)
9097         (compare
9098           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9099                   (match_operand:QI 2 "general_operand" "qim"))
9100           (const_int 0)))
9101    (clobber (match_scratch:QI 0 "=q"))]
9102   "ix86_match_ccmode (insn, CCNOmode)
9103    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9104   "xor{b}\t{%2, %0|%0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "mode" "QI")])
9107
9108 (define_insn "*xorqi_cc_ext_1"
9109   [(set (reg 17)
9110         (compare
9111           (xor:SI
9112             (zero_extract:SI
9113               (match_operand 1 "ext_register_operand" "0")
9114               (const_int 8)
9115               (const_int 8))
9116             (match_operand:QI 2 "general_operand" "qmn"))
9117           (const_int 0)))
9118    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9119                          (const_int 8)
9120                          (const_int 8))
9121         (xor:SI 
9122           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9123           (match_dup 2)))]
9124   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9125   "xor{b}\t{%2, %h0|%h0, %2}"
9126   [(set_attr "type" "alu")
9127    (set_attr "mode" "QI")])
9128
9129 (define_insn "*xorqi_cc_ext_1_rex64"
9130   [(set (reg 17)
9131         (compare
9132           (xor:SI
9133             (zero_extract:SI
9134               (match_operand 1 "ext_register_operand" "0")
9135               (const_int 8)
9136               (const_int 8))
9137             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9138           (const_int 0)))
9139    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140                          (const_int 8)
9141                          (const_int 8))
9142         (xor:SI 
9143           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9144           (match_dup 2)))]
9145   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9146   "xor{b}\t{%2, %h0|%h0, %2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "mode" "QI")])
9149
9150 (define_expand "xorqi_cc_ext_1"
9151   [(parallel [
9152      (set (reg:CCNO 17)
9153           (compare:CCNO
9154             (xor:SI
9155               (zero_extract:SI
9156                 (match_operand 1 "ext_register_operand" "")
9157                 (const_int 8)
9158                 (const_int 8))
9159               (match_operand:QI 2 "general_operand" ""))
9160             (const_int 0)))
9161      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9162                            (const_int 8)
9163                            (const_int 8))
9164           (xor:SI 
9165             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9166             (match_dup 2)))])]
9167   ""
9168   "")
9169
9170 (define_split
9171   [(set (match_operand 0 "register_operand" "")
9172         (xor (match_operand 1 "register_operand" "")
9173              (match_operand 2 "const_int_operand" "")))
9174    (clobber (reg:CC 17))]
9175    "reload_completed
9176     && QI_REG_P (operands[0])
9177     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9178     && !(INTVAL (operands[2]) & ~(255 << 8))
9179     && GET_MODE (operands[0]) != QImode"
9180   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9181                    (xor:SI (zero_extract:SI (match_dup 1)
9182                                             (const_int 8) (const_int 8))
9183                            (match_dup 2)))
9184               (clobber (reg:CC 17))])]
9185   "operands[0] = gen_lowpart (SImode, operands[0]);
9186    operands[1] = gen_lowpart (SImode, operands[1]);
9187    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9188
9189 ;; Since XOR can be encoded with sign extended immediate, this is only
9190 ;; profitable when 7th bit is set.
9191 (define_split
9192   [(set (match_operand 0 "register_operand" "")
9193         (xor (match_operand 1 "general_operand" "")
9194              (match_operand 2 "const_int_operand" "")))
9195    (clobber (reg:CC 17))]
9196    "reload_completed
9197     && ANY_QI_REG_P (operands[0])
9198     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9199     && !(INTVAL (operands[2]) & ~255)
9200     && (INTVAL (operands[2]) & 128)
9201     && GET_MODE (operands[0]) != QImode"
9202   [(parallel [(set (strict_low_part (match_dup 0))
9203                    (xor:QI (match_dup 1)
9204                            (match_dup 2)))
9205               (clobber (reg:CC 17))])]
9206   "operands[0] = gen_lowpart (QImode, operands[0]);
9207    operands[1] = gen_lowpart (QImode, operands[1]);
9208    operands[2] = gen_lowpart (QImode, operands[2]);")
9209 \f
9210 ;; Negation instructions
9211
9212 (define_expand "negdi2"
9213   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9214                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9215               (clobber (reg:CC 17))])]
9216   ""
9217   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9218
9219 (define_insn "*negdi2_1"
9220   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9221         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9222    (clobber (reg:CC 17))]
9223   "!TARGET_64BIT
9224    && ix86_unary_operator_ok (NEG, DImode, operands)"
9225   "#")
9226
9227 (define_split
9228   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229         (neg:DI (match_operand:DI 1 "general_operand" "")))
9230    (clobber (reg:CC 17))]
9231   "!TARGET_64BIT && reload_completed"
9232   [(parallel
9233     [(set (reg:CCZ 17)
9234           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9235      (set (match_dup 0) (neg:SI (match_dup 2)))])
9236    (parallel
9237     [(set (match_dup 1)
9238           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9239                             (match_dup 3))
9240                    (const_int 0)))
9241      (clobber (reg:CC 17))])
9242    (parallel
9243     [(set (match_dup 1)
9244           (neg:SI (match_dup 1)))
9245      (clobber (reg:CC 17))])]
9246   "split_di (operands+1, 1, operands+2, operands+3);
9247    split_di (operands+0, 1, operands+0, operands+1);")
9248
9249 (define_insn "*negdi2_1_rex64"
9250   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9251         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9252    (clobber (reg:CC 17))]
9253   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9254   "neg{q}\t%0"
9255   [(set_attr "type" "negnot")
9256    (set_attr "mode" "DI")])
9257
9258 ;; The problem with neg is that it does not perform (compare x 0),
9259 ;; it really performs (compare 0 x), which leaves us with the zero
9260 ;; flag being the only useful item.
9261
9262 (define_insn "*negdi2_cmpz_rex64"
9263   [(set (reg:CCZ 17)
9264         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9265                      (const_int 0)))
9266    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9267         (neg:DI (match_dup 1)))]
9268   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9269   "neg{q}\t%0"
9270   [(set_attr "type" "negnot")
9271    (set_attr "mode" "DI")])
9272
9273
9274 (define_expand "negsi2"
9275   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9276                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9277               (clobber (reg:CC 17))])]
9278   ""
9279   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9280
9281 (define_insn "*negsi2_1"
9282   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9283         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9284    (clobber (reg:CC 17))]
9285   "ix86_unary_operator_ok (NEG, SImode, operands)"
9286   "neg{l}\t%0"
9287   [(set_attr "type" "negnot")
9288    (set_attr "mode" "SI")])
9289
9290 ;; Combine is quite creative about this pattern.
9291 (define_insn "*negsi2_1_zext"
9292   [(set (match_operand:DI 0 "register_operand" "=r")
9293         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9294                                         (const_int 32)))
9295                      (const_int 32)))
9296    (clobber (reg:CC 17))]
9297   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9298   "neg{l}\t%k0"
9299   [(set_attr "type" "negnot")
9300    (set_attr "mode" "SI")])
9301
9302 ;; The problem with neg is that it does not perform (compare x 0),
9303 ;; it really performs (compare 0 x), which leaves us with the zero
9304 ;; flag being the only useful item.
9305
9306 (define_insn "*negsi2_cmpz"
9307   [(set (reg:CCZ 17)
9308         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9309                      (const_int 0)))
9310    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9311         (neg:SI (match_dup 1)))]
9312   "ix86_unary_operator_ok (NEG, SImode, operands)"
9313   "neg{l}\t%0"
9314   [(set_attr "type" "negnot")
9315    (set_attr "mode" "SI")])
9316
9317 (define_insn "*negsi2_cmpz_zext"
9318   [(set (reg:CCZ 17)
9319         (compare:CCZ (lshiftrt:DI
9320                        (neg:DI (ashift:DI
9321                                  (match_operand:DI 1 "register_operand" "0")
9322                                  (const_int 32)))
9323                        (const_int 32))
9324                      (const_int 0)))
9325    (set (match_operand:DI 0 "register_operand" "=r")
9326         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9327                                         (const_int 32)))
9328                      (const_int 32)))]
9329   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9330   "neg{l}\t%k0"
9331   [(set_attr "type" "negnot")
9332    (set_attr "mode" "SI")])
9333
9334 (define_expand "neghi2"
9335   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9336                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9337               (clobber (reg:CC 17))])]
9338   "TARGET_HIMODE_MATH"
9339   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9340
9341 (define_insn "*neghi2_1"
9342   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9343         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9344    (clobber (reg:CC 17))]
9345   "ix86_unary_operator_ok (NEG, HImode, operands)"
9346   "neg{w}\t%0"
9347   [(set_attr "type" "negnot")
9348    (set_attr "mode" "HI")])
9349
9350 (define_insn "*neghi2_cmpz"
9351   [(set (reg:CCZ 17)
9352         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9353                      (const_int 0)))
9354    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9355         (neg:HI (match_dup 1)))]
9356   "ix86_unary_operator_ok (NEG, HImode, operands)"
9357   "neg{w}\t%0"
9358   [(set_attr "type" "negnot")
9359    (set_attr "mode" "HI")])
9360
9361 (define_expand "negqi2"
9362   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9363                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9364               (clobber (reg:CC 17))])]
9365   "TARGET_QIMODE_MATH"
9366   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9367
9368 (define_insn "*negqi2_1"
9369   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9370         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9371    (clobber (reg:CC 17))]
9372   "ix86_unary_operator_ok (NEG, QImode, operands)"
9373   "neg{b}\t%0"
9374   [(set_attr "type" "negnot")
9375    (set_attr "mode" "QI")])
9376
9377 (define_insn "*negqi2_cmpz"
9378   [(set (reg:CCZ 17)
9379         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9380                      (const_int 0)))
9381    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9382         (neg:QI (match_dup 1)))]
9383   "ix86_unary_operator_ok (NEG, QImode, operands)"
9384   "neg{b}\t%0"
9385   [(set_attr "type" "negnot")
9386    (set_attr "mode" "QI")])
9387
9388 ;; Changing of sign for FP values is doable using integer unit too.
9389
9390 (define_expand "negsf2"
9391   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9392                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9393               (clobber (reg:CC 17))])]
9394   "TARGET_80387"
9395   "if (TARGET_SSE)
9396      {
9397        /* In case operand is in memory,  we will not use SSE.  */
9398        if (memory_operand (operands[0], VOIDmode)
9399            && rtx_equal_p (operands[0], operands[1]))
9400          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9401        else
9402         {
9403           /* Using SSE is tricky, since we need bitwise negation of -0
9404              in register.  */
9405           rtx reg = gen_reg_rtx (SFmode);
9406           rtx dest = operands[0];
9407           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9408
9409           operands[1] = force_reg (SFmode, operands[1]);
9410           operands[0] = force_reg (SFmode, operands[0]);
9411           reg = force_reg (V4SFmode,
9412                            gen_rtx_CONST_VECTOR (V4SFmode,
9413                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9414                                         CONST0_RTX (SFmode),
9415                                         CONST0_RTX (SFmode))));
9416           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9417           if (dest != operands[0])
9418             emit_move_insn (dest, operands[0]);
9419         }
9420        DONE;
9421      }
9422    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9423
9424 (define_insn "negsf2_memory"
9425   [(set (match_operand:SF 0 "memory_operand" "=m")
9426         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9427    (clobber (reg:CC 17))]
9428   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9429   "#")
9430
9431 (define_insn "negsf2_ifs"
9432   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9433         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9434    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9435    (clobber (reg:CC 17))]
9436   "TARGET_SSE
9437    && (reload_in_progress || reload_completed
9438        || (register_operand (operands[0], VOIDmode)
9439            && register_operand (operands[1], VOIDmode)))"
9440   "#")
9441
9442 (define_split
9443   [(set (match_operand:SF 0 "memory_operand" "")
9444         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9445    (use (match_operand:SF 2 "" ""))
9446    (clobber (reg:CC 17))]
9447   ""
9448   [(parallel [(set (match_dup 0)
9449                    (neg:SF (match_dup 1)))
9450               (clobber (reg:CC 17))])])
9451
9452 (define_split
9453   [(set (match_operand:SF 0 "register_operand" "")
9454         (neg:SF (match_operand:SF 1 "register_operand" "")))
9455    (use (match_operand:V4SF 2 "" ""))
9456    (clobber (reg:CC 17))]
9457   "reload_completed && !SSE_REG_P (operands[0])"
9458   [(parallel [(set (match_dup 0)
9459                    (neg:SF (match_dup 1)))
9460               (clobber (reg:CC 17))])])
9461
9462 (define_split
9463   [(set (match_operand:SF 0 "register_operand" "")
9464         (neg:SF (match_operand:SF 1 "register_operand" "")))
9465    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9466    (clobber (reg:CC 17))]
9467   "reload_completed && SSE_REG_P (operands[0])"
9468   [(set (subreg:TI (match_dup 0) 0)
9469         (xor:TI (match_dup 1)
9470                 (match_dup 2)))]
9471 {
9472   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9473   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9474   if (operands_match_p (operands[0], operands[2]))
9475     {
9476       rtx tmp;
9477       tmp = operands[1];
9478       operands[1] = operands[2];
9479       operands[2] = tmp;
9480     }
9481 })
9482
9483
9484 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9485 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9486 ;; to itself.
9487 (define_insn "*negsf2_if"
9488   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9489         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9490    (clobber (reg:CC 17))]
9491   "TARGET_80387 && !TARGET_SSE
9492    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9493   "#")
9494
9495 (define_split
9496   [(set (match_operand:SF 0 "fp_register_operand" "")
9497         (neg:SF (match_operand:SF 1 "register_operand" "")))
9498    (clobber (reg:CC 17))]
9499   "TARGET_80387 && reload_completed"
9500   [(set (match_dup 0)
9501         (neg:SF (match_dup 1)))]
9502   "")
9503
9504 (define_split
9505   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9506         (neg:SF (match_operand:SF 1 "register_operand" "")))
9507    (clobber (reg:CC 17))]
9508   "TARGET_80387 && reload_completed"
9509   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9510               (clobber (reg:CC 17))])]
9511   "operands[1] = gen_int_mode (0x80000000, SImode);
9512    operands[0] = gen_lowpart (SImode, operands[0]);")
9513
9514 (define_split
9515   [(set (match_operand 0 "memory_operand" "")
9516         (neg (match_operand 1 "memory_operand" "")))
9517    (clobber (reg:CC 17))]
9518   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9519   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9520               (clobber (reg:CC 17))])]
9521 {
9522   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9523
9524   if (GET_MODE (operands[1]) == XFmode)
9525     size = 10;
9526   operands[0] = adjust_address (operands[0], QImode, size - 1);
9527   operands[1] = gen_int_mode (0x80, QImode);
9528 })
9529
9530 (define_expand "negdf2"
9531   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9532                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9533               (clobber (reg:CC 17))])]
9534   "TARGET_80387"
9535   "if (TARGET_SSE2)
9536      {
9537        /* In case operand is in memory,  we will not use SSE.  */
9538        if (memory_operand (operands[0], VOIDmode)
9539            && rtx_equal_p (operands[0], operands[1]))
9540          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9541        else
9542         {
9543           /* Using SSE is tricky, since we need bitwise negation of -0
9544              in register.  */
9545           rtx reg;
9546 #if HOST_BITS_PER_WIDE_INT >= 64
9547           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9548 #else
9549           rtx imm = immed_double_const (0, 0x80000000, DImode);
9550 #endif
9551           rtx dest = operands[0];
9552
9553           operands[1] = force_reg (DFmode, operands[1]);
9554           operands[0] = force_reg (DFmode, operands[0]);
9555           imm = gen_lowpart (DFmode, imm);
9556           reg = force_reg (V2DFmode,
9557                            gen_rtx_CONST_VECTOR (V2DFmode,
9558                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9559           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9560           if (dest != operands[0])
9561             emit_move_insn (dest, operands[0]);
9562         }
9563        DONE;
9564      }
9565    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9566
9567 (define_insn "negdf2_memory"
9568   [(set (match_operand:DF 0 "memory_operand" "=m")
9569         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9570    (clobber (reg:CC 17))]
9571   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9572   "#")
9573
9574 (define_insn "negdf2_ifs"
9575   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9576         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9577    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9578    (clobber (reg:CC 17))]
9579   "!TARGET_64BIT && TARGET_SSE2
9580    && (reload_in_progress || reload_completed
9581        || (register_operand (operands[0], VOIDmode)
9582            && register_operand (operands[1], VOIDmode)))"
9583   "#")
9584
9585 (define_insn "*negdf2_ifs_rex64"
9586   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9587         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9588    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9589    (clobber (reg:CC 17))]
9590   "TARGET_64BIT && TARGET_SSE2
9591    && (reload_in_progress || reload_completed
9592        || (register_operand (operands[0], VOIDmode)
9593            && register_operand (operands[1], VOIDmode)))"
9594   "#")
9595
9596 (define_split
9597   [(set (match_operand:DF 0 "memory_operand" "")
9598         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9599    (use (match_operand:V2DF 2 "" ""))
9600    (clobber (reg:CC 17))]
9601   ""
9602   [(parallel [(set (match_dup 0)
9603                    (neg:DF (match_dup 1)))
9604               (clobber (reg:CC 17))])])
9605
9606 (define_split
9607   [(set (match_operand:DF 0 "register_operand" "")
9608         (neg:DF (match_operand:DF 1 "register_operand" "")))
9609    (use (match_operand:V2DF 2 "" ""))
9610    (clobber (reg:CC 17))]
9611   "reload_completed && !SSE_REG_P (operands[0])
9612    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9613   [(parallel [(set (match_dup 0)
9614                    (neg:DF (match_dup 1)))
9615               (clobber (reg:CC 17))])])
9616
9617 (define_split
9618   [(set (match_operand:DF 0 "register_operand" "")
9619         (neg:DF (match_operand:DF 1 "register_operand" "")))
9620    (use (match_operand:V2DF 2 "" ""))
9621    (clobber (reg:CC 17))]
9622   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9623   [(parallel [(set (match_dup 0)
9624                    (xor:DI (match_dup 1) (match_dup 2)))
9625               (clobber (reg:CC 17))])]
9626    "operands[0] = gen_lowpart (DImode, operands[0]);
9627     operands[1] = gen_lowpart (DImode, operands[1]);
9628     operands[2] = gen_lowpart (DImode, operands[2]);")
9629
9630 (define_split
9631   [(set (match_operand:DF 0 "register_operand" "")
9632         (neg:DF (match_operand:DF 1 "register_operand" "")))
9633    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9634    (clobber (reg:CC 17))]
9635   "reload_completed && SSE_REG_P (operands[0])"
9636   [(set (subreg:TI (match_dup 0) 0)
9637         (xor:TI (match_dup 1)
9638                 (match_dup 2)))]
9639 {
9640   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9641   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9642   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9643   /* Avoid possible reformatting on the operands.  */
9644   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9645     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9646   if (operands_match_p (operands[0], operands[2]))
9647     {
9648       rtx tmp;
9649       tmp = operands[1];
9650       operands[1] = operands[2];
9651       operands[2] = tmp;
9652     }
9653 })
9654
9655 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9656 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9657 ;; to itself.
9658 (define_insn "*negdf2_if"
9659   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9660         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9661    (clobber (reg:CC 17))]
9662   "!TARGET_64BIT && TARGET_80387
9663    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9664   "#")
9665
9666 ;; FIXME: We should to allow integer registers here.  Problem is that
9667 ;; we need another scratch register to get constant from.
9668 ;; Forcing constant to mem if no register available in peep2 should be
9669 ;; safe even for PIC mode, because of RIP relative addressing.
9670 (define_insn "*negdf2_if_rex64"
9671   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9672         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9673    (clobber (reg:CC 17))]
9674   "TARGET_64BIT && TARGET_80387
9675    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9676   "#")
9677
9678 (define_split
9679   [(set (match_operand:DF 0 "fp_register_operand" "")
9680         (neg:DF (match_operand:DF 1 "register_operand" "")))
9681    (clobber (reg:CC 17))]
9682   "TARGET_80387 && reload_completed"
9683   [(set (match_dup 0)
9684         (neg:DF (match_dup 1)))]
9685   "")
9686
9687 (define_split
9688   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9689         (neg:DF (match_operand:DF 1 "register_operand" "")))
9690    (clobber (reg:CC 17))]
9691   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9692   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9693               (clobber (reg:CC 17))])]
9694   "operands[4] = gen_int_mode (0x80000000, SImode);
9695    split_di (operands+0, 1, operands+2, operands+3);")
9696
9697 (define_expand "negxf2"
9698   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9699                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9700               (clobber (reg:CC 17))])]
9701   "TARGET_80387"
9702   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9703
9704 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9705 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9706 ;; to itself.
9707 (define_insn "*negxf2_if"
9708   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9709         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9710    (clobber (reg:CC 17))]
9711   "TARGET_80387
9712    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9713   "#")
9714
9715 (define_split
9716   [(set (match_operand:XF 0 "fp_register_operand" "")
9717         (neg:XF (match_operand:XF 1 "register_operand" "")))
9718    (clobber (reg:CC 17))]
9719   "TARGET_80387 && reload_completed"
9720   [(set (match_dup 0)
9721         (neg:XF (match_dup 1)))]
9722   "")
9723
9724 (define_split
9725   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9726         (neg:XF (match_operand:XF 1 "register_operand" "")))
9727    (clobber (reg:CC 17))]
9728   "TARGET_80387 && reload_completed"
9729   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9730               (clobber (reg:CC 17))])]
9731   "operands[1] = GEN_INT (0x8000);
9732    operands[0] = gen_rtx_REG (SImode,
9733                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9734
9735 ;; Conditionalize these after reload. If they matches before reload, we 
9736 ;; lose the clobber and ability to use integer instructions.
9737
9738 (define_insn "*negsf2_1"
9739   [(set (match_operand:SF 0 "register_operand" "=f")
9740         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9741   "TARGET_80387 && reload_completed"
9742   "fchs"
9743   [(set_attr "type" "fsgn")
9744    (set_attr "mode" "SF")
9745    (set_attr "ppro_uops" "few")])
9746
9747 (define_insn "*negdf2_1"
9748   [(set (match_operand:DF 0 "register_operand" "=f")
9749         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9750   "TARGET_80387 && reload_completed"
9751   "fchs"
9752   [(set_attr "type" "fsgn")
9753    (set_attr "mode" "DF")
9754    (set_attr "ppro_uops" "few")])
9755
9756 (define_insn "*negextendsfdf2"
9757   [(set (match_operand:DF 0 "register_operand" "=f")
9758         (neg:DF (float_extend:DF
9759                   (match_operand:SF 1 "register_operand" "0"))))]
9760   "TARGET_80387"
9761   "fchs"
9762   [(set_attr "type" "fsgn")
9763    (set_attr "mode" "DF")
9764    (set_attr "ppro_uops" "few")])
9765
9766 (define_insn "*negxf2_1"
9767   [(set (match_operand:XF 0 "register_operand" "=f")
9768         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9769   "TARGET_80387 && reload_completed"
9770   "fchs"
9771   [(set_attr "type" "fsgn")
9772    (set_attr "mode" "XF")
9773    (set_attr "ppro_uops" "few")])
9774
9775 (define_insn "*negextenddfxf2"
9776   [(set (match_operand:XF 0 "register_operand" "=f")
9777         (neg:XF (float_extend:XF
9778                   (match_operand:DF 1 "register_operand" "0"))))]
9779   "TARGET_80387"
9780   "fchs"
9781   [(set_attr "type" "fsgn")
9782    (set_attr "mode" "XF")
9783    (set_attr "ppro_uops" "few")])
9784
9785 (define_insn "*negextendsfxf2"
9786   [(set (match_operand:XF 0 "register_operand" "=f")
9787         (neg:XF (float_extend:XF
9788                   (match_operand:SF 1 "register_operand" "0"))))]
9789   "TARGET_80387"
9790   "fchs"
9791   [(set_attr "type" "fsgn")
9792    (set_attr "mode" "XF")
9793    (set_attr "ppro_uops" "few")])
9794 \f
9795 ;; Absolute value instructions
9796
9797 (define_expand "abssf2"
9798   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9799                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9800               (clobber (reg:CC 17))])]
9801   "TARGET_80387"
9802   "if (TARGET_SSE)
9803      {
9804        /* In case operand is in memory,  we will not use SSE.  */
9805        if (memory_operand (operands[0], VOIDmode)
9806            && rtx_equal_p (operands[0], operands[1]))
9807          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9808        else
9809         {
9810           /* Using SSE is tricky, since we need bitwise negation of -0
9811              in register.  */
9812           rtx reg = gen_reg_rtx (V4SFmode);
9813           rtx dest = operands[0];
9814           rtx imm;
9815
9816           operands[1] = force_reg (SFmode, operands[1]);
9817           operands[0] = force_reg (SFmode, operands[0]);
9818           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9819           reg = force_reg (V4SFmode,
9820                            gen_rtx_CONST_VECTOR (V4SFmode,
9821                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9822                                       CONST0_RTX (SFmode),
9823                                       CONST0_RTX (SFmode))));
9824           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9825           if (dest != operands[0])
9826             emit_move_insn (dest, operands[0]);
9827         }
9828        DONE;
9829      }
9830    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9831
9832 (define_insn "abssf2_memory"
9833   [(set (match_operand:SF 0 "memory_operand" "=m")
9834         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9835    (clobber (reg:CC 17))]
9836   "ix86_unary_operator_ok (ABS, SFmode, operands)"
9837   "#")
9838
9839 (define_insn "abssf2_ifs"
9840   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9841         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9842    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9843    (clobber (reg:CC 17))]
9844   "TARGET_SSE
9845    && (reload_in_progress || reload_completed
9846        || (register_operand (operands[0], VOIDmode)
9847             && register_operand (operands[1], VOIDmode)))"
9848   "#")
9849
9850 (define_split
9851   [(set (match_operand:SF 0 "memory_operand" "")
9852         (abs:SF (match_operand:SF 1 "memory_operand" "")))
9853    (use (match_operand:V4SF 2 "" ""))
9854    (clobber (reg:CC 17))]
9855   ""
9856   [(parallel [(set (match_dup 0)
9857                    (abs:SF (match_dup 1)))
9858               (clobber (reg:CC 17))])])
9859
9860 (define_split
9861   [(set (match_operand:SF 0 "register_operand" "")
9862         (abs:SF (match_operand:SF 1 "register_operand" "")))
9863    (use (match_operand:V4SF 2 "" ""))
9864    (clobber (reg:CC 17))]
9865   "reload_completed && !SSE_REG_P (operands[0])"
9866   [(parallel [(set (match_dup 0)
9867                    (abs:SF (match_dup 1)))
9868               (clobber (reg:CC 17))])])
9869
9870 (define_split
9871   [(set (match_operand:SF 0 "register_operand" "")
9872         (abs:SF (match_operand:SF 1 "register_operand" "")))
9873    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9874    (clobber (reg:CC 17))]
9875   "reload_completed && SSE_REG_P (operands[0])"
9876   [(set (subreg:TI (match_dup 0) 0)
9877         (and:TI (match_dup 1)
9878                 (match_dup 2)))]
9879 {
9880   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9881   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9882   if (operands_match_p (operands[0], operands[2]))
9883     {
9884       rtx tmp;
9885       tmp = operands[1];
9886       operands[1] = operands[2];
9887       operands[2] = tmp;
9888     }
9889 })
9890
9891 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9892 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9893 ;; to itself.
9894 (define_insn "*abssf2_if"
9895   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9896         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9897    (clobber (reg:CC 17))]
9898   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9899   "#")
9900
9901 (define_split
9902   [(set (match_operand:SF 0 "fp_register_operand" "")
9903         (abs:SF (match_operand:SF 1 "register_operand" "")))
9904    (clobber (reg:CC 17))]
9905   "TARGET_80387 && reload_completed"
9906   [(set (match_dup 0)
9907         (abs:SF (match_dup 1)))]
9908   "")
9909
9910 (define_split
9911   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9912         (abs:SF (match_operand:SF 1 "register_operand" "")))
9913    (clobber (reg:CC 17))]
9914   "TARGET_80387 && reload_completed"
9915   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9916               (clobber (reg:CC 17))])]
9917   "operands[1] = gen_int_mode (~0x80000000, SImode);
9918    operands[0] = gen_lowpart (SImode, operands[0]);")
9919
9920 (define_split
9921   [(set (match_operand 0 "memory_operand" "")
9922         (abs (match_operand 1 "memory_operand" "")))
9923    (clobber (reg:CC 17))]
9924   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9925   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9926               (clobber (reg:CC 17))])]
9927 {
9928   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9929
9930   if (GET_MODE (operands[1]) == XFmode)
9931     size = 10;
9932   operands[0] = adjust_address (operands[0], QImode, size - 1);
9933   operands[1] = gen_int_mode (~0x80, QImode);
9934 })
9935
9936 (define_expand "absdf2"
9937   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9938                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9939               (clobber (reg:CC 17))])]
9940   "TARGET_80387"
9941   "if (TARGET_SSE2)
9942      {
9943        /* In case operand is in memory,  we will not use SSE.  */
9944        if (memory_operand (operands[0], VOIDmode)
9945            && rtx_equal_p (operands[0], operands[1]))
9946          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9947        else
9948         {
9949           /* Using SSE is tricky, since we need bitwise negation of -0
9950              in register.  */
9951           rtx reg = gen_reg_rtx (V2DFmode);
9952 #if HOST_BITS_PER_WIDE_INT >= 64
9953           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
9954 #else
9955           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
9956 #endif
9957           rtx dest = operands[0];
9958
9959           operands[1] = force_reg (DFmode, operands[1]);
9960           operands[0] = force_reg (DFmode, operands[0]);
9961
9962           /* Produce LONG_DOUBLE with the proper immediate argument.  */
9963           imm = gen_lowpart (DFmode, imm);
9964           reg = force_reg (V2DFmode,
9965                            gen_rtx_CONST_VECTOR (V2DFmode,
9966                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9967           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9968           if (dest != operands[0])
9969             emit_move_insn (dest, operands[0]);
9970         }
9971        DONE;
9972      }
9973    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9974
9975 (define_insn "absdf2_memory"
9976   [(set (match_operand:DF 0 "memory_operand" "=m")
9977         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9978    (clobber (reg:CC 17))]
9979   "ix86_unary_operator_ok (ABS, DFmode, operands)"
9980   "#")
9981
9982 (define_insn "absdf2_ifs"
9983   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
9984         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9985    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9986    (clobber (reg:CC 17))]
9987   "!TARGET_64BIT && TARGET_SSE2
9988    && (reload_in_progress || reload_completed
9989        || (register_operand (operands[0], VOIDmode)
9990            && register_operand (operands[1], VOIDmode)))"
9991   "#")
9992
9993 (define_insn "*absdf2_ifs_rex64"
9994   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
9995         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9996    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9997    (clobber (reg:CC 17))]
9998   "TARGET_64BIT && TARGET_SSE2
9999    && (reload_in_progress || reload_completed
10000        || (register_operand (operands[0], VOIDmode)
10001            && register_operand (operands[1], VOIDmode)))"
10002   "#")
10003
10004 (define_split
10005   [(set (match_operand:DF 0 "memory_operand" "")
10006         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10007    (use (match_operand:V2DF 2 "" ""))
10008    (clobber (reg:CC 17))]
10009   ""
10010   [(parallel [(set (match_dup 0)
10011                    (abs:DF (match_dup 1)))
10012               (clobber (reg:CC 17))])])
10013
10014 (define_split
10015   [(set (match_operand:DF 0 "register_operand" "")
10016         (abs:DF (match_operand:DF 1 "register_operand" "")))
10017    (use (match_operand:V2DF 2 "" ""))
10018    (clobber (reg:CC 17))]
10019   "reload_completed && !SSE_REG_P (operands[0])"
10020   [(parallel [(set (match_dup 0)
10021                    (abs:DF (match_dup 1)))
10022               (clobber (reg:CC 17))])])
10023
10024 (define_split
10025   [(set (match_operand:DF 0 "register_operand" "")
10026         (abs:DF (match_operand:DF 1 "register_operand" "")))
10027    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10028    (clobber (reg:CC 17))]
10029   "reload_completed && SSE_REG_P (operands[0])"
10030   [(set (subreg:TI (match_dup 0) 0)
10031         (and:TI (match_dup 1)
10032                 (match_dup 2)))]
10033 {
10034   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10035   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10036   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10037   /* Avoid possible reformatting on the operands.  */
10038   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10039     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10040   if (operands_match_p (operands[0], operands[2]))
10041     {
10042       rtx tmp;
10043       tmp = operands[1];
10044       operands[1] = operands[2];
10045       operands[2] = tmp;
10046     }
10047 })
10048
10049
10050 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10051 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10052 ;; to itself.
10053 (define_insn "*absdf2_if"
10054   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10055         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10056    (clobber (reg:CC 17))]
10057   "!TARGET_64BIT && TARGET_80387
10058    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10059   "#")
10060
10061 ;; FIXME: We should to allow integer registers here.  Problem is that
10062 ;; we need another scratch register to get constant from.
10063 ;; Forcing constant to mem if no register available in peep2 should be
10064 ;; safe even for PIC mode, because of RIP relative addressing.
10065 (define_insn "*absdf2_if_rex64"
10066   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10067         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10068    (clobber (reg:CC 17))]
10069   "TARGET_64BIT && TARGET_80387
10070    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10071   "#")
10072
10073 (define_split
10074   [(set (match_operand:DF 0 "fp_register_operand" "")
10075         (abs:DF (match_operand:DF 1 "register_operand" "")))
10076    (clobber (reg:CC 17))]
10077   "TARGET_80387 && reload_completed"
10078   [(set (match_dup 0)
10079         (abs:DF (match_dup 1)))]
10080   "")
10081
10082 (define_split
10083   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10084         (abs:DF (match_operand:DF 1 "register_operand" "")))
10085    (clobber (reg:CC 17))]
10086   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10087   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10088               (clobber (reg:CC 17))])]
10089   "operands[4] = gen_int_mode (~0x80000000, SImode);
10090    split_di (operands+0, 1, operands+2, operands+3);")
10091
10092 (define_expand "absxf2"
10093   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10094                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10095               (clobber (reg:CC 17))])]
10096   "TARGET_80387"
10097   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10098
10099 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10100 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10101 ;; to itself.
10102 (define_insn "*absxf2_if"
10103   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10104         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10105    (clobber (reg:CC 17))]
10106   "TARGET_80387
10107    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10108   "#")
10109
10110 (define_split
10111   [(set (match_operand:XF 0 "fp_register_operand" "")
10112         (abs:XF (match_operand:XF 1 "register_operand" "")))
10113    (clobber (reg:CC 17))]
10114   "TARGET_80387 && reload_completed"
10115   [(set (match_dup 0)
10116         (abs:XF (match_dup 1)))]
10117   "")
10118
10119 (define_split
10120   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10121         (abs:XF (match_operand:XF 1 "register_operand" "")))
10122    (clobber (reg:CC 17))]
10123   "TARGET_80387 && reload_completed"
10124   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10125               (clobber (reg:CC 17))])]
10126   "operands[1] = GEN_INT (~0x8000);
10127    operands[0] = gen_rtx_REG (SImode,
10128                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10129
10130 (define_insn "*abssf2_1"
10131   [(set (match_operand:SF 0 "register_operand" "=f")
10132         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10133   "TARGET_80387 && reload_completed"
10134   "fabs"
10135   [(set_attr "type" "fsgn")
10136    (set_attr "mode" "SF")])
10137
10138 (define_insn "*absdf2_1"
10139   [(set (match_operand:DF 0 "register_operand" "=f")
10140         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10141   "TARGET_80387 && reload_completed"
10142   "fabs"
10143   [(set_attr "type" "fsgn")
10144    (set_attr "mode" "DF")])
10145
10146 (define_insn "*absextendsfdf2"
10147   [(set (match_operand:DF 0 "register_operand" "=f")
10148         (abs:DF (float_extend:DF
10149                   (match_operand:SF 1 "register_operand" "0"))))]
10150   "TARGET_80387"
10151   "fabs"
10152   [(set_attr "type" "fsgn")
10153    (set_attr "mode" "DF")])
10154
10155 (define_insn "*absxf2_1"
10156   [(set (match_operand:XF 0 "register_operand" "=f")
10157         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10158   "TARGET_80387 && reload_completed"
10159   "fabs"
10160   [(set_attr "type" "fsgn")
10161    (set_attr "mode" "DF")])
10162
10163 (define_insn "*absextenddfxf2"
10164   [(set (match_operand:XF 0 "register_operand" "=f")
10165         (abs:XF (float_extend:XF
10166           (match_operand:DF 1 "register_operand" "0"))))]
10167   "TARGET_80387"
10168   "fabs"
10169   [(set_attr "type" "fsgn")
10170    (set_attr "mode" "XF")])
10171
10172 (define_insn "*absextendsfxf2"
10173   [(set (match_operand:XF 0 "register_operand" "=f")
10174         (abs:XF (float_extend:XF
10175           (match_operand:SF 1 "register_operand" "0"))))]
10176   "TARGET_80387"
10177   "fabs"
10178   [(set_attr "type" "fsgn")
10179    (set_attr "mode" "XF")])
10180 \f
10181 ;; One complement instructions
10182
10183 (define_expand "one_cmpldi2"
10184   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10185         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10186   "TARGET_64BIT"
10187   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10188
10189 (define_insn "*one_cmpldi2_1_rex64"
10190   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10191         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10192   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10193   "not{q}\t%0"
10194   [(set_attr "type" "negnot")
10195    (set_attr "mode" "DI")])
10196
10197 (define_insn "*one_cmpldi2_2_rex64"
10198   [(set (reg 17)
10199         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10200                  (const_int 0)))
10201    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10202         (not:DI (match_dup 1)))]
10203   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10204    && ix86_unary_operator_ok (NOT, DImode, operands)"
10205   "#"
10206   [(set_attr "type" "alu1")
10207    (set_attr "mode" "DI")])
10208
10209 (define_split
10210   [(set (reg 17)
10211         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10212                  (const_int 0)))
10213    (set (match_operand:DI 0 "nonimmediate_operand" "")
10214         (not:DI (match_dup 1)))]
10215   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10216   [(parallel [(set (reg:CCNO 17)
10217                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10218                                  (const_int 0)))
10219               (set (match_dup 0)
10220                    (xor:DI (match_dup 1) (const_int -1)))])]
10221   "")
10222
10223 (define_expand "one_cmplsi2"
10224   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10225         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10226   ""
10227   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10228
10229 (define_insn "*one_cmplsi2_1"
10230   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10231         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10232   "ix86_unary_operator_ok (NOT, SImode, operands)"
10233   "not{l}\t%0"
10234   [(set_attr "type" "negnot")
10235    (set_attr "mode" "SI")])
10236
10237 ;; ??? Currently never generated - xor is used instead.
10238 (define_insn "*one_cmplsi2_1_zext"
10239   [(set (match_operand:DI 0 "register_operand" "=r")
10240         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10241   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10242   "not{l}\t%k0"
10243   [(set_attr "type" "negnot")
10244    (set_attr "mode" "SI")])
10245
10246 (define_insn "*one_cmplsi2_2"
10247   [(set (reg 17)
10248         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10249                  (const_int 0)))
10250    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10251         (not:SI (match_dup 1)))]
10252   "ix86_match_ccmode (insn, CCNOmode)
10253    && ix86_unary_operator_ok (NOT, SImode, operands)"
10254   "#"
10255   [(set_attr "type" "alu1")
10256    (set_attr "mode" "SI")])
10257
10258 (define_split
10259   [(set (reg 17)
10260         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10261                  (const_int 0)))
10262    (set (match_operand:SI 0 "nonimmediate_operand" "")
10263         (not:SI (match_dup 1)))]
10264   "ix86_match_ccmode (insn, CCNOmode)"
10265   [(parallel [(set (reg:CCNO 17)
10266                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10267                                  (const_int 0)))
10268               (set (match_dup 0)
10269                    (xor:SI (match_dup 1) (const_int -1)))])]
10270   "")
10271
10272 ;; ??? Currently never generated - xor is used instead.
10273 (define_insn "*one_cmplsi2_2_zext"
10274   [(set (reg 17)
10275         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10276                  (const_int 0)))
10277    (set (match_operand:DI 0 "register_operand" "=r")
10278         (zero_extend:DI (not:SI (match_dup 1))))]
10279   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10280    && ix86_unary_operator_ok (NOT, SImode, operands)"
10281   "#"
10282   [(set_attr "type" "alu1")
10283    (set_attr "mode" "SI")])
10284
10285 (define_split
10286   [(set (reg 17)
10287         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10288                  (const_int 0)))
10289    (set (match_operand:DI 0 "register_operand" "")
10290         (zero_extend:DI (not:SI (match_dup 1))))]
10291   "ix86_match_ccmode (insn, CCNOmode)"
10292   [(parallel [(set (reg:CCNO 17)
10293                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10294                                  (const_int 0)))
10295               (set (match_dup 0)
10296                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10297   "")
10298
10299 (define_expand "one_cmplhi2"
10300   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10301         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10302   "TARGET_HIMODE_MATH"
10303   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10304
10305 (define_insn "*one_cmplhi2_1"
10306   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10307         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10308   "ix86_unary_operator_ok (NOT, HImode, operands)"
10309   "not{w}\t%0"
10310   [(set_attr "type" "negnot")
10311    (set_attr "mode" "HI")])
10312
10313 (define_insn "*one_cmplhi2_2"
10314   [(set (reg 17)
10315         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10316                  (const_int 0)))
10317    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10318         (not:HI (match_dup 1)))]
10319   "ix86_match_ccmode (insn, CCNOmode)
10320    && ix86_unary_operator_ok (NEG, HImode, operands)"
10321   "#"
10322   [(set_attr "type" "alu1")
10323    (set_attr "mode" "HI")])
10324
10325 (define_split
10326   [(set (reg 17)
10327         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10328                  (const_int 0)))
10329    (set (match_operand:HI 0 "nonimmediate_operand" "")
10330         (not:HI (match_dup 1)))]
10331   "ix86_match_ccmode (insn, CCNOmode)"
10332   [(parallel [(set (reg:CCNO 17)
10333                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10334                                  (const_int 0)))
10335               (set (match_dup 0)
10336                    (xor:HI (match_dup 1) (const_int -1)))])]
10337   "")
10338
10339 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10340 (define_expand "one_cmplqi2"
10341   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10342         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10343   "TARGET_QIMODE_MATH"
10344   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10345
10346 (define_insn "*one_cmplqi2_1"
10347   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10348         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10349   "ix86_unary_operator_ok (NOT, QImode, operands)"
10350   "@
10351    not{b}\t%0
10352    not{l}\t%k0"
10353   [(set_attr "type" "negnot")
10354    (set_attr "mode" "QI,SI")])
10355
10356 (define_insn "*one_cmplqi2_2"
10357   [(set (reg 17)
10358         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10359                  (const_int 0)))
10360    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10361         (not:QI (match_dup 1)))]
10362   "ix86_match_ccmode (insn, CCNOmode)
10363    && ix86_unary_operator_ok (NOT, QImode, operands)"
10364   "#"
10365   [(set_attr "type" "alu1")
10366    (set_attr "mode" "QI")])
10367
10368 (define_split
10369   [(set (reg 17)
10370         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10371                  (const_int 0)))
10372    (set (match_operand:QI 0 "nonimmediate_operand" "")
10373         (not:QI (match_dup 1)))]
10374   "ix86_match_ccmode (insn, CCNOmode)"
10375   [(parallel [(set (reg:CCNO 17)
10376                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10377                                  (const_int 0)))
10378               (set (match_dup 0)
10379                    (xor:QI (match_dup 1) (const_int -1)))])]
10380   "")
10381 \f
10382 ;; Arithmetic shift instructions
10383
10384 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10385 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10386 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10387 ;; from the assembler input.
10388 ;;
10389 ;; This instruction shifts the target reg/mem as usual, but instead of
10390 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10391 ;; is a left shift double, bits are taken from the high order bits of
10392 ;; reg, else if the insn is a shift right double, bits are taken from the
10393 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10394 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10395 ;;
10396 ;; Since sh[lr]d does not change the `reg' operand, that is done
10397 ;; separately, making all shifts emit pairs of shift double and normal
10398 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10399 ;; support a 63 bit shift, each shift where the count is in a reg expands
10400 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10401 ;;
10402 ;; If the shift count is a constant, we need never emit more than one
10403 ;; shift pair, instead using moves and sign extension for counts greater
10404 ;; than 31.
10405
10406 (define_expand "ashldi3"
10407   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10408                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10409                               (match_operand:QI 2 "nonmemory_operand" "")))
10410               (clobber (reg:CC 17))])]
10411   ""
10412 {
10413   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10414     {
10415       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10416       DONE;
10417     }
10418   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10419   DONE;
10420 })
10421
10422 (define_insn "*ashldi3_1_rex64"
10423   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10424         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10425                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10426    (clobber (reg:CC 17))]
10427   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10428 {
10429   switch (get_attr_type (insn))
10430     {
10431     case TYPE_ALU:
10432       if (operands[2] != const1_rtx)
10433         abort ();
10434       if (!rtx_equal_p (operands[0], operands[1]))
10435         abort ();
10436       return "add{q}\t{%0, %0|%0, %0}";
10437
10438     case TYPE_LEA:
10439       if (GET_CODE (operands[2]) != CONST_INT
10440           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10441         abort ();
10442       operands[1] = gen_rtx_MULT (DImode, operands[1],
10443                                   GEN_INT (1 << INTVAL (operands[2])));
10444       return "lea{q}\t{%a1, %0|%0, %a1}";
10445
10446     default:
10447       if (REG_P (operands[2]))
10448         return "sal{q}\t{%b2, %0|%0, %b2}";
10449       else if (GET_CODE (operands[2]) == CONST_INT
10450                && INTVAL (operands[2]) == 1
10451                && (TARGET_SHIFT1 || optimize_size))
10452         return "sal{q}\t%0";
10453       else
10454         return "sal{q}\t{%2, %0|%0, %2}";
10455     }
10456 }
10457   [(set (attr "type")
10458      (cond [(eq_attr "alternative" "1")
10459               (const_string "lea")
10460             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10461                           (const_int 0))
10462                       (match_operand 0 "register_operand" ""))
10463                  (match_operand 2 "const1_operand" ""))
10464               (const_string "alu")
10465            ]
10466            (const_string "ishift")))
10467    (set_attr "mode" "DI")])
10468
10469 ;; Convert lea to the lea pattern to avoid flags dependency.
10470 (define_split
10471   [(set (match_operand:DI 0 "register_operand" "")
10472         (ashift:DI (match_operand:DI 1 "register_operand" "")
10473                    (match_operand:QI 2 "immediate_operand" "")))
10474    (clobber (reg:CC 17))]
10475   "TARGET_64BIT && reload_completed
10476    && true_regnum (operands[0]) != true_regnum (operands[1])"
10477   [(set (match_dup 0)
10478         (mult:DI (match_dup 1)
10479                  (match_dup 2)))]
10480   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10481
10482 ;; This pattern can't accept a variable shift count, since shifts by
10483 ;; zero don't affect the flags.  We assume that shifts by constant
10484 ;; zero are optimized away.
10485 (define_insn "*ashldi3_cmp_rex64"
10486   [(set (reg 17)
10487         (compare
10488           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10489                      (match_operand:QI 2 "immediate_operand" "e"))
10490           (const_int 0)))
10491    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10492         (ashift:DI (match_dup 1) (match_dup 2)))]
10493   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10494    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10495 {
10496   switch (get_attr_type (insn))
10497     {
10498     case TYPE_ALU:
10499       if (operands[2] != const1_rtx)
10500         abort ();
10501       return "add{q}\t{%0, %0|%0, %0}";
10502
10503     default:
10504       if (REG_P (operands[2]))
10505         return "sal{q}\t{%b2, %0|%0, %b2}";
10506       else if (GET_CODE (operands[2]) == CONST_INT
10507                && INTVAL (operands[2]) == 1
10508                && (TARGET_SHIFT1 || optimize_size))
10509         return "sal{q}\t%0";
10510       else
10511         return "sal{q}\t{%2, %0|%0, %2}";
10512     }
10513 }
10514   [(set (attr "type")
10515      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10516                           (const_int 0))
10517                       (match_operand 0 "register_operand" ""))
10518                  (match_operand 2 "const1_operand" ""))
10519               (const_string "alu")
10520            ]
10521            (const_string "ishift")))
10522    (set_attr "mode" "DI")])
10523
10524 (define_insn "ashldi3_1"
10525   [(set (match_operand:DI 0 "register_operand" "=r")
10526         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10527                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10528    (clobber (match_scratch:SI 3 "=&r"))
10529    (clobber (reg:CC 17))]
10530   "!TARGET_64BIT && TARGET_CMOVE"
10531   "#"
10532   [(set_attr "type" "multi")])
10533
10534 (define_insn "*ashldi3_2"
10535   [(set (match_operand:DI 0 "register_operand" "=r")
10536         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10537                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10538    (clobber (reg:CC 17))]
10539   "!TARGET_64BIT"
10540   "#"
10541   [(set_attr "type" "multi")])
10542
10543 (define_split
10544   [(set (match_operand:DI 0 "register_operand" "")
10545         (ashift:DI (match_operand:DI 1 "register_operand" "")
10546                    (match_operand:QI 2 "nonmemory_operand" "")))
10547    (clobber (match_scratch:SI 3 ""))
10548    (clobber (reg:CC 17))]
10549   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10550   [(const_int 0)]
10551   "ix86_split_ashldi (operands, operands[3]); DONE;")
10552
10553 (define_split
10554   [(set (match_operand:DI 0 "register_operand" "")
10555         (ashift:DI (match_operand:DI 1 "register_operand" "")
10556                    (match_operand:QI 2 "nonmemory_operand" "")))
10557    (clobber (reg:CC 17))]
10558   "!TARGET_64BIT && reload_completed"
10559   [(const_int 0)]
10560   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10561
10562 (define_insn "x86_shld_1"
10563   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10564         (ior:SI (ashift:SI (match_dup 0)
10565                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10566                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10567                   (minus:QI (const_int 32) (match_dup 2)))))
10568    (clobber (reg:CC 17))]
10569   ""
10570   "@
10571    shld{l}\t{%2, %1, %0|%0, %1, %2}
10572    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10573   [(set_attr "type" "ishift")
10574    (set_attr "prefix_0f" "1")
10575    (set_attr "mode" "SI")
10576    (set_attr "pent_pair" "np")
10577    (set_attr "athlon_decode" "vector")
10578    (set_attr "ppro_uops" "few")])
10579
10580 (define_expand "x86_shift_adj_1"
10581   [(set (reg:CCZ 17)
10582         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10583                              (const_int 32))
10584                      (const_int 0)))
10585    (set (match_operand:SI 0 "register_operand" "")
10586         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10587                          (match_operand:SI 1 "register_operand" "")
10588                          (match_dup 0)))
10589    (set (match_dup 1)
10590         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10591                          (match_operand:SI 3 "register_operand" "r")
10592                          (match_dup 1)))]
10593   "TARGET_CMOVE"
10594   "")
10595
10596 (define_expand "x86_shift_adj_2"
10597   [(use (match_operand:SI 0 "register_operand" ""))
10598    (use (match_operand:SI 1 "register_operand" ""))
10599    (use (match_operand:QI 2 "register_operand" ""))]
10600   ""
10601 {
10602   rtx label = gen_label_rtx ();
10603   rtx tmp;
10604
10605   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10606
10607   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10608   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10609   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10610                               gen_rtx_LABEL_REF (VOIDmode, label),
10611                               pc_rtx);
10612   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10613   JUMP_LABEL (tmp) = label;
10614
10615   emit_move_insn (operands[0], operands[1]);
10616   emit_move_insn (operands[1], const0_rtx);
10617
10618   emit_label (label);
10619   LABEL_NUSES (label) = 1;
10620
10621   DONE;
10622 })
10623
10624 (define_expand "ashlsi3"
10625   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10626         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10627                    (match_operand:QI 2 "nonmemory_operand" "")))
10628    (clobber (reg:CC 17))]
10629   ""
10630   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10631
10632 (define_insn "*ashlsi3_1"
10633   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10634         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10635                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10636    (clobber (reg:CC 17))]
10637   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10638 {
10639   switch (get_attr_type (insn))
10640     {
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       if (!rtx_equal_p (operands[0], operands[1]))
10645         abort ();
10646       return "add{l}\t{%0, %0|%0, %0}";
10647
10648     case TYPE_LEA:
10649       return "#";
10650
10651     default:
10652       if (REG_P (operands[2]))
10653         return "sal{l}\t{%b2, %0|%0, %b2}";
10654       else if (GET_CODE (operands[2]) == CONST_INT
10655                && INTVAL (operands[2]) == 1
10656                && (TARGET_SHIFT1 || optimize_size))
10657         return "sal{l}\t%0";
10658       else
10659         return "sal{l}\t{%2, %0|%0, %2}";
10660     }
10661 }
10662   [(set (attr "type")
10663      (cond [(eq_attr "alternative" "1")
10664               (const_string "lea")
10665             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666                           (const_int 0))
10667                       (match_operand 0 "register_operand" ""))
10668                  (match_operand 2 "const1_operand" ""))
10669               (const_string "alu")
10670            ]
10671            (const_string "ishift")))
10672    (set_attr "mode" "SI")])
10673
10674 ;; Convert lea to the lea pattern to avoid flags dependency.
10675 (define_split
10676   [(set (match_operand 0 "register_operand" "")
10677         (ashift (match_operand 1 "index_register_operand" "")
10678                 (match_operand:QI 2 "const_int_operand" "")))
10679    (clobber (reg:CC 17))]
10680   "reload_completed
10681    && true_regnum (operands[0]) != true_regnum (operands[1])"
10682   [(const_int 0)]
10683 {
10684   rtx pat;
10685   operands[0] = gen_lowpart (SImode, operands[0]);
10686   operands[1] = gen_lowpart (Pmode, operands[1]);
10687   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10689   if (Pmode != SImode)
10690     pat = gen_rtx_SUBREG (SImode, pat, 0);
10691   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10692   DONE;
10693 })
10694
10695 ;; Rare case of shifting RSP is handled by generating move and shift
10696 (define_split
10697   [(set (match_operand 0 "register_operand" "")
10698         (ashift (match_operand 1 "register_operand" "")
10699                 (match_operand:QI 2 "const_int_operand" "")))
10700    (clobber (reg:CC 17))]
10701   "reload_completed
10702    && true_regnum (operands[0]) != true_regnum (operands[1])"
10703   [(const_int 0)]
10704 {
10705   rtx pat, clob;
10706   emit_move_insn (operands[1], operands[0]);
10707   pat = gen_rtx_SET (VOIDmode, operands[0],
10708                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10709                                      operands[0], operands[2]));
10710   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10711   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10712   DONE;
10713 })
10714
10715 (define_insn "*ashlsi3_1_zext"
10716   [(set (match_operand:DI 0 "register_operand" "=r,r")
10717         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10718                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10719    (clobber (reg:CC 17))]
10720   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10721 {
10722   switch (get_attr_type (insn))
10723     {
10724     case TYPE_ALU:
10725       if (operands[2] != const1_rtx)
10726         abort ();
10727       return "add{l}\t{%k0, %k0|%k0, %k0}";
10728
10729     case TYPE_LEA:
10730       return "#";
10731
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735       else if (GET_CODE (operands[2]) == CONST_INT
10736                && INTVAL (operands[2]) == 1
10737                && (TARGET_SHIFT1 || optimize_size))
10738         return "sal{l}\t%k0";
10739       else
10740         return "sal{l}\t{%2, %k0|%k0, %2}";
10741     }
10742 }
10743   [(set (attr "type")
10744      (cond [(eq_attr "alternative" "1")
10745               (const_string "lea")
10746             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747                      (const_int 0))
10748                  (match_operand 2 "const1_operand" ""))
10749               (const_string "alu")
10750            ]
10751            (const_string "ishift")))
10752    (set_attr "mode" "SI")])
10753
10754 ;; Convert lea to the lea pattern to avoid flags dependency.
10755 (define_split
10756   [(set (match_operand:DI 0 "register_operand" "")
10757         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10758                                 (match_operand:QI 2 "const_int_operand" ""))))
10759    (clobber (reg:CC 17))]
10760   "TARGET_64BIT && reload_completed
10761    && true_regnum (operands[0]) != true_regnum (operands[1])"
10762   [(set (match_dup 0) (zero_extend:DI
10763                         (subreg:SI (mult:SI (match_dup 1)
10764                                             (match_dup 2)) 0)))]
10765 {
10766   operands[1] = gen_lowpart (Pmode, operands[1]);
10767   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10768 })
10769
10770 ;; This pattern can't accept a variable shift count, since shifts by
10771 ;; zero don't affect the flags.  We assume that shifts by constant
10772 ;; zero are optimized away.
10773 (define_insn "*ashlsi3_cmp"
10774   [(set (reg 17)
10775         (compare
10776           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10777                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10778           (const_int 0)))
10779    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10780         (ashift:SI (match_dup 1) (match_dup 2)))]
10781   "ix86_match_ccmode (insn, CCGOCmode)
10782    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10783 {
10784   switch (get_attr_type (insn))
10785     {
10786     case TYPE_ALU:
10787       if (operands[2] != const1_rtx)
10788         abort ();
10789       return "add{l}\t{%0, %0|%0, %0}";
10790
10791     default:
10792       if (REG_P (operands[2]))
10793         return "sal{l}\t{%b2, %0|%0, %b2}";
10794       else if (GET_CODE (operands[2]) == CONST_INT
10795                && INTVAL (operands[2]) == 1
10796                && (TARGET_SHIFT1 || optimize_size))
10797         return "sal{l}\t%0";
10798       else
10799         return "sal{l}\t{%2, %0|%0, %2}";
10800     }
10801 }
10802   [(set (attr "type")
10803      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10804                           (const_int 0))
10805                       (match_operand 0 "register_operand" ""))
10806                  (match_operand 2 "const1_operand" ""))
10807               (const_string "alu")
10808            ]
10809            (const_string "ishift")))
10810    (set_attr "mode" "SI")])
10811
10812 (define_insn "*ashlsi3_cmp_zext"
10813   [(set (reg 17)
10814         (compare
10815           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10816                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10817           (const_int 0)))
10818    (set (match_operand:DI 0 "register_operand" "=r")
10819         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10820   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10821    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10822 {
10823   switch (get_attr_type (insn))
10824     {
10825     case TYPE_ALU:
10826       if (operands[2] != const1_rtx)
10827         abort ();
10828       return "add{l}\t{%k0, %k0|%k0, %k0}";
10829
10830     default:
10831       if (REG_P (operands[2]))
10832         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10833       else if (GET_CODE (operands[2]) == CONST_INT
10834                && INTVAL (operands[2]) == 1
10835                && (TARGET_SHIFT1 || optimize_size))
10836         return "sal{l}\t%k0";
10837       else
10838         return "sal{l}\t{%2, %k0|%k0, %2}";
10839     }
10840 }
10841   [(set (attr "type")
10842      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10843                      (const_int 0))
10844                  (match_operand 2 "const1_operand" ""))
10845               (const_string "alu")
10846            ]
10847            (const_string "ishift")))
10848    (set_attr "mode" "SI")])
10849
10850 (define_expand "ashlhi3"
10851   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10852         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10853                    (match_operand:QI 2 "nonmemory_operand" "")))
10854    (clobber (reg:CC 17))]
10855   "TARGET_HIMODE_MATH"
10856   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10857
10858 (define_insn "*ashlhi3_1_lea"
10859   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10860         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10861                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10862    (clobber (reg:CC 17))]
10863   "!TARGET_PARTIAL_REG_STALL
10864    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10865 {
10866   switch (get_attr_type (insn))
10867     {
10868     case TYPE_LEA:
10869       return "#";
10870     case TYPE_ALU:
10871       if (operands[2] != const1_rtx)
10872         abort ();
10873       return "add{w}\t{%0, %0|%0, %0}";
10874
10875     default:
10876       if (REG_P (operands[2]))
10877         return "sal{w}\t{%b2, %0|%0, %b2}";
10878       else if (GET_CODE (operands[2]) == CONST_INT
10879                && INTVAL (operands[2]) == 1
10880                && (TARGET_SHIFT1 || optimize_size))
10881         return "sal{w}\t%0";
10882       else
10883         return "sal{w}\t{%2, %0|%0, %2}";
10884     }
10885 }
10886   [(set (attr "type")
10887      (cond [(eq_attr "alternative" "1")
10888               (const_string "lea")
10889             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890                           (const_int 0))
10891                       (match_operand 0 "register_operand" ""))
10892                  (match_operand 2 "const1_operand" ""))
10893               (const_string "alu")
10894            ]
10895            (const_string "ishift")))
10896    (set_attr "mode" "HI,SI")])
10897
10898 (define_insn "*ashlhi3_1"
10899   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10900         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10901                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10902    (clobber (reg:CC 17))]
10903   "TARGET_PARTIAL_REG_STALL
10904    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10905 {
10906   switch (get_attr_type (insn))
10907     {
10908     case TYPE_ALU:
10909       if (operands[2] != const1_rtx)
10910         abort ();
10911       return "add{w}\t{%0, %0|%0, %0}";
10912
10913     default:
10914       if (REG_P (operands[2]))
10915         return "sal{w}\t{%b2, %0|%0, %b2}";
10916       else if (GET_CODE (operands[2]) == CONST_INT
10917                && INTVAL (operands[2]) == 1
10918                && (TARGET_SHIFT1 || optimize_size))
10919         return "sal{w}\t%0";
10920       else
10921         return "sal{w}\t{%2, %0|%0, %2}";
10922     }
10923 }
10924   [(set (attr "type")
10925      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10926                           (const_int 0))
10927                       (match_operand 0 "register_operand" ""))
10928                  (match_operand 2 "const1_operand" ""))
10929               (const_string "alu")
10930            ]
10931            (const_string "ishift")))
10932    (set_attr "mode" "HI")])
10933
10934 ;; This pattern can't accept a variable shift count, since shifts by
10935 ;; zero don't affect the flags.  We assume that shifts by constant
10936 ;; zero are optimized away.
10937 (define_insn "*ashlhi3_cmp"
10938   [(set (reg 17)
10939         (compare
10940           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10941                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10942           (const_int 0)))
10943    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944         (ashift:HI (match_dup 1) (match_dup 2)))]
10945   "ix86_match_ccmode (insn, CCGOCmode)
10946    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10947 {
10948   switch (get_attr_type (insn))
10949     {
10950     case TYPE_ALU:
10951       if (operands[2] != const1_rtx)
10952         abort ();
10953       return "add{w}\t{%0, %0|%0, %0}";
10954
10955     default:
10956       if (REG_P (operands[2]))
10957         return "sal{w}\t{%b2, %0|%0, %b2}";
10958       else if (GET_CODE (operands[2]) == CONST_INT
10959                && INTVAL (operands[2]) == 1
10960                && (TARGET_SHIFT1 || optimize_size))
10961         return "sal{w}\t%0";
10962       else
10963         return "sal{w}\t{%2, %0|%0, %2}";
10964     }
10965 }
10966   [(set (attr "type")
10967      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968                           (const_int 0))
10969                       (match_operand 0 "register_operand" ""))
10970                  (match_operand 2 "const1_operand" ""))
10971               (const_string "alu")
10972            ]
10973            (const_string "ishift")))
10974    (set_attr "mode" "HI")])
10975
10976 (define_expand "ashlqi3"
10977   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10978         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10979                    (match_operand:QI 2 "nonmemory_operand" "")))
10980    (clobber (reg:CC 17))]
10981   "TARGET_QIMODE_MATH"
10982   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10983
10984 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10985
10986 (define_insn "*ashlqi3_1_lea"
10987   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10988         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10989                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10990    (clobber (reg:CC 17))]
10991   "!TARGET_PARTIAL_REG_STALL
10992    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10993 {
10994   switch (get_attr_type (insn))
10995     {
10996     case TYPE_LEA:
10997       return "#";
10998     case TYPE_ALU:
10999       if (operands[2] != const1_rtx)
11000         abort ();
11001       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11002         return "add{l}\t{%k0, %k0|%k0, %k0}";
11003       else
11004         return "add{b}\t{%0, %0|%0, %0}";
11005
11006     default:
11007       if (REG_P (operands[2]))
11008         {
11009           if (get_attr_mode (insn) == MODE_SI)
11010             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11011           else
11012             return "sal{b}\t{%b2, %0|%0, %b2}";
11013         }
11014       else if (GET_CODE (operands[2]) == CONST_INT
11015                && INTVAL (operands[2]) == 1
11016                && (TARGET_SHIFT1 || optimize_size))
11017         {
11018           if (get_attr_mode (insn) == MODE_SI)
11019             return "sal{l}\t%0";
11020           else
11021             return "sal{b}\t%0";
11022         }
11023       else
11024         {
11025           if (get_attr_mode (insn) == MODE_SI)
11026             return "sal{l}\t{%2, %k0|%k0, %2}";
11027           else
11028             return "sal{b}\t{%2, %0|%0, %2}";
11029         }
11030     }
11031 }
11032   [(set (attr "type")
11033      (cond [(eq_attr "alternative" "2")
11034               (const_string "lea")
11035             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11036                           (const_int 0))
11037                       (match_operand 0 "register_operand" ""))
11038                  (match_operand 2 "const1_operand" ""))
11039               (const_string "alu")
11040            ]
11041            (const_string "ishift")))
11042    (set_attr "mode" "QI,SI,SI")])
11043
11044 (define_insn "*ashlqi3_1"
11045   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11046         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11047                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11048    (clobber (reg:CC 17))]
11049   "TARGET_PARTIAL_REG_STALL
11050    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11051 {
11052   switch (get_attr_type (insn))
11053     {
11054     case TYPE_ALU:
11055       if (operands[2] != const1_rtx)
11056         abort ();
11057       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11058         return "add{l}\t{%k0, %k0|%k0, %k0}";
11059       else
11060         return "add{b}\t{%0, %0|%0, %0}";
11061
11062     default:
11063       if (REG_P (operands[2]))
11064         {
11065           if (get_attr_mode (insn) == MODE_SI)
11066             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11067           else
11068             return "sal{b}\t{%b2, %0|%0, %b2}";
11069         }
11070       else if (GET_CODE (operands[2]) == CONST_INT
11071                && INTVAL (operands[2]) == 1
11072                && (TARGET_SHIFT1 || optimize_size))
11073         {
11074           if (get_attr_mode (insn) == MODE_SI)
11075             return "sal{l}\t%0";
11076           else
11077             return "sal{b}\t%0";
11078         }
11079       else
11080         {
11081           if (get_attr_mode (insn) == MODE_SI)
11082             return "sal{l}\t{%2, %k0|%k0, %2}";
11083           else
11084             return "sal{b}\t{%2, %0|%0, %2}";
11085         }
11086     }
11087 }
11088   [(set (attr "type")
11089      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090                           (const_int 0))
11091                       (match_operand 0 "register_operand" ""))
11092                  (match_operand 2 "const1_operand" ""))
11093               (const_string "alu")
11094            ]
11095            (const_string "ishift")))
11096    (set_attr "mode" "QI,SI")])
11097
11098 ;; This pattern can't accept a variable shift count, since shifts by
11099 ;; zero don't affect the flags.  We assume that shifts by constant
11100 ;; zero are optimized away.
11101 (define_insn "*ashlqi3_cmp"
11102   [(set (reg 17)
11103         (compare
11104           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11105                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11106           (const_int 0)))
11107    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11108         (ashift:QI (match_dup 1) (match_dup 2)))]
11109   "ix86_match_ccmode (insn, CCGOCmode)
11110    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11111 {
11112   switch (get_attr_type (insn))
11113     {
11114     case TYPE_ALU:
11115       if (operands[2] != const1_rtx)
11116         abort ();
11117       return "add{b}\t{%0, %0|%0, %0}";
11118
11119     default:
11120       if (REG_P (operands[2]))
11121         return "sal{b}\t{%b2, %0|%0, %b2}";
11122       else if (GET_CODE (operands[2]) == CONST_INT
11123                && INTVAL (operands[2]) == 1
11124                && (TARGET_SHIFT1 || optimize_size))
11125         return "sal{b}\t%0";
11126       else
11127         return "sal{b}\t{%2, %0|%0, %2}";
11128     }
11129 }
11130   [(set (attr "type")
11131      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132                           (const_int 0))
11133                       (match_operand 0 "register_operand" ""))
11134                  (match_operand 2 "const1_operand" ""))
11135               (const_string "alu")
11136            ]
11137            (const_string "ishift")))
11138    (set_attr "mode" "QI")])
11139
11140 ;; See comment above `ashldi3' about how this works.
11141
11142 (define_expand "ashrdi3"
11143   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11144                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11145                                 (match_operand:QI 2 "nonmemory_operand" "")))
11146               (clobber (reg:CC 17))])]
11147   ""
11148 {
11149   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11150     {
11151       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11152       DONE;
11153     }
11154   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11155   DONE;
11156 })
11157
11158 (define_insn "ashrdi3_63_rex64"
11159   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11160         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11161                      (match_operand:DI 2 "const_int_operand" "i,i")))
11162    (clobber (reg:CC 17))]
11163   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11164    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11165   "@
11166    {cqto|cqo}
11167    sar{q}\t{%2, %0|%0, %2}"
11168   [(set_attr "type" "imovx,ishift")
11169    (set_attr "prefix_0f" "0,*")
11170    (set_attr "length_immediate" "0,*")
11171    (set_attr "modrm" "0,1")
11172    (set_attr "mode" "DI")])
11173
11174 (define_insn "*ashrdi3_1_one_bit_rex64"
11175   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11176         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11177                      (match_operand:QI 2 "const_int_1_operand" "")))
11178    (clobber (reg:CC 17))]
11179   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11180    && (TARGET_SHIFT1 || optimize_size)"
11181   "sar{q}\t%0"
11182   [(set_attr "type" "ishift")
11183    (set (attr "length") 
11184      (if_then_else (match_operand:DI 0 "register_operand" "") 
11185         (const_string "2")
11186         (const_string "*")))])
11187
11188 (define_insn "*ashrdi3_1_rex64"
11189   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11190         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11191                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11192    (clobber (reg:CC 17))]
11193   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11194   "@
11195    sar{q}\t{%2, %0|%0, %2}
11196    sar{q}\t{%b2, %0|%0, %b2}"
11197   [(set_attr "type" "ishift")
11198    (set_attr "mode" "DI")])
11199
11200 ;; This pattern can't accept a variable shift count, since shifts by
11201 ;; zero don't affect the flags.  We assume that shifts by constant
11202 ;; zero are optimized away.
11203 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11204   [(set (reg 17)
11205         (compare
11206           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11207                        (match_operand:QI 2 "const_int_1_operand" ""))
11208           (const_int 0)))
11209    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11210         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11211   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11212    && (TARGET_SHIFT1 || optimize_size)
11213    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11214   "sar{q}\t%0"
11215   [(set_attr "type" "ishift")
11216    (set (attr "length") 
11217      (if_then_else (match_operand:DI 0 "register_operand" "") 
11218         (const_string "2")
11219         (const_string "*")))])
11220
11221 ;; This pattern can't accept a variable shift count, since shifts by
11222 ;; zero don't affect the flags.  We assume that shifts by constant
11223 ;; zero are optimized away.
11224 (define_insn "*ashrdi3_cmp_rex64"
11225   [(set (reg 17)
11226         (compare
11227           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11228                        (match_operand:QI 2 "const_int_operand" "n"))
11229           (const_int 0)))
11230    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11231         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11232   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11234   "sar{q}\t{%2, %0|%0, %2}"
11235   [(set_attr "type" "ishift")
11236    (set_attr "mode" "DI")])
11237
11238
11239 (define_insn "ashrdi3_1"
11240   [(set (match_operand:DI 0 "register_operand" "=r")
11241         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11242                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11243    (clobber (match_scratch:SI 3 "=&r"))
11244    (clobber (reg:CC 17))]
11245   "!TARGET_64BIT && TARGET_CMOVE"
11246   "#"
11247   [(set_attr "type" "multi")])
11248
11249 (define_insn "*ashrdi3_2"
11250   [(set (match_operand:DI 0 "register_operand" "=r")
11251         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11252                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11253    (clobber (reg:CC 17))]
11254   "!TARGET_64BIT"
11255   "#"
11256   [(set_attr "type" "multi")])
11257
11258 (define_split
11259   [(set (match_operand:DI 0 "register_operand" "")
11260         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11261                      (match_operand:QI 2 "nonmemory_operand" "")))
11262    (clobber (match_scratch:SI 3 ""))
11263    (clobber (reg:CC 17))]
11264   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11265   [(const_int 0)]
11266   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11267
11268 (define_split
11269   [(set (match_operand:DI 0 "register_operand" "")
11270         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11271                      (match_operand:QI 2 "nonmemory_operand" "")))
11272    (clobber (reg:CC 17))]
11273   "!TARGET_64BIT && reload_completed"
11274   [(const_int 0)]
11275   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11276
11277 (define_insn "x86_shrd_1"
11278   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11279         (ior:SI (ashiftrt:SI (match_dup 0)
11280                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11281                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11282                   (minus:QI (const_int 32) (match_dup 2)))))
11283    (clobber (reg:CC 17))]
11284   ""
11285   "@
11286    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11287    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11288   [(set_attr "type" "ishift")
11289    (set_attr "prefix_0f" "1")
11290    (set_attr "pent_pair" "np")
11291    (set_attr "ppro_uops" "few")
11292    (set_attr "mode" "SI")])
11293
11294 (define_expand "x86_shift_adj_3"
11295   [(use (match_operand:SI 0 "register_operand" ""))
11296    (use (match_operand:SI 1 "register_operand" ""))
11297    (use (match_operand:QI 2 "register_operand" ""))]
11298   ""
11299 {
11300   rtx label = gen_label_rtx ();
11301   rtx tmp;
11302
11303   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11304
11305   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11306   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11307   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11308                               gen_rtx_LABEL_REF (VOIDmode, label),
11309                               pc_rtx);
11310   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11311   JUMP_LABEL (tmp) = label;
11312
11313   emit_move_insn (operands[0], operands[1]);
11314   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11315
11316   emit_label (label);
11317   LABEL_NUSES (label) = 1;
11318
11319   DONE;
11320 })
11321
11322 (define_insn "ashrsi3_31"
11323   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11324         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11325                      (match_operand:SI 2 "const_int_operand" "i,i")))
11326    (clobber (reg:CC 17))]
11327   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11328    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329   "@
11330    {cltd|cdq}
11331    sar{l}\t{%2, %0|%0, %2}"
11332   [(set_attr "type" "imovx,ishift")
11333    (set_attr "prefix_0f" "0,*")
11334    (set_attr "length_immediate" "0,*")
11335    (set_attr "modrm" "0,1")
11336    (set_attr "mode" "SI")])
11337
11338 (define_insn "*ashrsi3_31_zext"
11339   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11340         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11341                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11342    (clobber (reg:CC 17))]
11343   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11344    && INTVAL (operands[2]) == 31
11345    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11346   "@
11347    {cltd|cdq}
11348    sar{l}\t{%2, %k0|%k0, %2}"
11349   [(set_attr "type" "imovx,ishift")
11350    (set_attr "prefix_0f" "0,*")
11351    (set_attr "length_immediate" "0,*")
11352    (set_attr "modrm" "0,1")
11353    (set_attr "mode" "SI")])
11354
11355 (define_expand "ashrsi3"
11356   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11357         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11358                      (match_operand:QI 2 "nonmemory_operand" "")))
11359    (clobber (reg:CC 17))]
11360   ""
11361   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11362
11363 (define_insn "*ashrsi3_1_one_bit"
11364   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11365         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11366                      (match_operand:QI 2 "const_int_1_operand" "")))
11367    (clobber (reg:CC 17))]
11368   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11369    && (TARGET_SHIFT1 || optimize_size)"
11370   "sar{l}\t%0"
11371   [(set_attr "type" "ishift")
11372    (set (attr "length") 
11373      (if_then_else (match_operand:SI 0 "register_operand" "") 
11374         (const_string "2")
11375         (const_string "*")))])
11376
11377 (define_insn "*ashrsi3_1_one_bit_zext"
11378   [(set (match_operand:DI 0 "register_operand" "=r")
11379         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11380                                      (match_operand:QI 2 "const_int_1_operand" ""))))
11381    (clobber (reg:CC 17))]
11382   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11383    && (TARGET_SHIFT1 || optimize_size)"
11384   "sar{l}\t%k0"
11385   [(set_attr "type" "ishift")
11386    (set_attr "length" "2")])
11387
11388 (define_insn "*ashrsi3_1"
11389   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11390         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11391                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11392    (clobber (reg:CC 17))]
11393   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11394   "@
11395    sar{l}\t{%2, %0|%0, %2}
11396    sar{l}\t{%b2, %0|%0, %b2}"
11397   [(set_attr "type" "ishift")
11398    (set_attr "mode" "SI")])
11399
11400 (define_insn "*ashrsi3_1_zext"
11401   [(set (match_operand:DI 0 "register_operand" "=r,r")
11402         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11403                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11404    (clobber (reg:CC 17))]
11405   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11406   "@
11407    sar{l}\t{%2, %k0|%k0, %2}
11408    sar{l}\t{%b2, %k0|%k0, %b2}"
11409   [(set_attr "type" "ishift")
11410    (set_attr "mode" "SI")])
11411
11412 ;; This pattern can't accept a variable shift count, since shifts by
11413 ;; zero don't affect the flags.  We assume that shifts by constant
11414 ;; zero are optimized away.
11415 (define_insn "*ashrsi3_one_bit_cmp"
11416   [(set (reg 17)
11417         (compare
11418           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11419                        (match_operand:QI 2 "const_int_1_operand" ""))
11420           (const_int 0)))
11421    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11422         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11423   "ix86_match_ccmode (insn, CCGOCmode)
11424    && (TARGET_SHIFT1 || optimize_size)
11425    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11426   "sar{l}\t%0"
11427   [(set_attr "type" "ishift")
11428    (set (attr "length") 
11429      (if_then_else (match_operand:SI 0 "register_operand" "") 
11430         (const_string "2")
11431         (const_string "*")))])
11432
11433 (define_insn "*ashrsi3_one_bit_cmp_zext"
11434   [(set (reg 17)
11435         (compare
11436           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11437                        (match_operand:QI 2 "const_int_1_operand" ""))
11438           (const_int 0)))
11439    (set (match_operand:DI 0 "register_operand" "=r")
11440         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11441   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11442    && (TARGET_SHIFT1 || optimize_size)
11443    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11444   "sar{l}\t%k0"
11445   [(set_attr "type" "ishift")
11446    (set_attr "length" "2")])
11447
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags.  We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*ashrsi3_cmp"
11452   [(set (reg 17)
11453         (compare
11454           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11455                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11456           (const_int 0)))
11457    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11458         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11459   "ix86_match_ccmode (insn, CCGOCmode)
11460    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11461   "sar{l}\t{%2, %0|%0, %2}"
11462   [(set_attr "type" "ishift")
11463    (set_attr "mode" "SI")])
11464
11465 (define_insn "*ashrsi3_cmp_zext"
11466   [(set (reg 17)
11467         (compare
11468           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11469                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11470           (const_int 0)))
11471    (set (match_operand:DI 0 "register_operand" "=r")
11472         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11473   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11474    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11475   "sar{l}\t{%2, %k0|%k0, %2}"
11476   [(set_attr "type" "ishift")
11477    (set_attr "mode" "SI")])
11478
11479 (define_expand "ashrhi3"
11480   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11481         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11482                      (match_operand:QI 2 "nonmemory_operand" "")))
11483    (clobber (reg:CC 17))]
11484   "TARGET_HIMODE_MATH"
11485   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11486
11487 (define_insn "*ashrhi3_1_one_bit"
11488   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11489         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11490                      (match_operand:QI 2 "const_int_1_operand" "")))
11491    (clobber (reg:CC 17))]
11492   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11493    && (TARGET_SHIFT1 || optimize_size)"
11494   "sar{w}\t%0"
11495   [(set_attr "type" "ishift")
11496    (set (attr "length") 
11497      (if_then_else (match_operand 0 "register_operand" "") 
11498         (const_string "2")
11499         (const_string "*")))])
11500
11501 (define_insn "*ashrhi3_1"
11502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11503         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11504                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11505    (clobber (reg:CC 17))]
11506   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11507   "@
11508    sar{w}\t{%2, %0|%0, %2}
11509    sar{w}\t{%b2, %0|%0, %b2}"
11510   [(set_attr "type" "ishift")
11511    (set_attr "mode" "HI")])
11512
11513 ;; This pattern can't accept a variable shift count, since shifts by
11514 ;; zero don't affect the flags.  We assume that shifts by constant
11515 ;; zero are optimized away.
11516 (define_insn "*ashrhi3_one_bit_cmp"
11517   [(set (reg 17)
11518         (compare
11519           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11520                        (match_operand:QI 2 "const_int_1_operand" ""))
11521           (const_int 0)))
11522    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11523         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11524   "ix86_match_ccmode (insn, CCGOCmode)
11525    && (TARGET_SHIFT1 || optimize_size)
11526    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11527   "sar{w}\t%0"
11528   [(set_attr "type" "ishift")
11529    (set (attr "length") 
11530      (if_then_else (match_operand 0 "register_operand" "") 
11531         (const_string "2")
11532         (const_string "*")))])
11533
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags.  We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*ashrhi3_cmp"
11538   [(set (reg 17)
11539         (compare
11540           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11542           (const_int 0)))
11543    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11545   "ix86_match_ccmode (insn, CCGOCmode)
11546    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11547   "sar{w}\t{%2, %0|%0, %2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "HI")])
11550
11551 (define_expand "ashrqi3"
11552   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11553         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11554                      (match_operand:QI 2 "nonmemory_operand" "")))
11555    (clobber (reg:CC 17))]
11556   "TARGET_QIMODE_MATH"
11557   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11558
11559 (define_insn "*ashrqi3_1_one_bit"
11560   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11561         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11562                      (match_operand:QI 2 "const_int_1_operand" "")))
11563    (clobber (reg:CC 17))]
11564   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11565    && (TARGET_SHIFT1 || optimize_size)"
11566   "sar{b}\t%0"
11567   [(set_attr "type" "ishift")
11568    (set (attr "length") 
11569      (if_then_else (match_operand 0 "register_operand" "") 
11570         (const_string "2")
11571         (const_string "*")))])
11572
11573 (define_insn "*ashrqi3_1_one_bit_slp"
11574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11575         (ashiftrt:QI (match_dup 0)
11576                      (match_operand:QI 1 "const_int_1_operand" "")))
11577    (clobber (reg:CC 17))]
11578   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11579    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11580    && (TARGET_SHIFT1 || optimize_size)"
11581   "sar{b}\t%0"
11582   [(set_attr "type" "ishift1")
11583    (set (attr "length") 
11584      (if_then_else (match_operand 0 "register_operand" "") 
11585         (const_string "2")
11586         (const_string "*")))])
11587
11588 (define_insn "*ashrqi3_1"
11589   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11590         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11591                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11592    (clobber (reg:CC 17))]
11593   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11594   "@
11595    sar{b}\t{%2, %0|%0, %2}
11596    sar{b}\t{%b2, %0|%0, %b2}"
11597   [(set_attr "type" "ishift")
11598    (set_attr "mode" "QI")])
11599
11600 (define_insn "*ashrqi3_1_slp"
11601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11602         (ashiftrt:QI (match_dup 0)
11603                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11604    (clobber (reg:CC 17))]
11605   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11606    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11607   "@
11608    sar{b}\t{%1, %0|%0, %1}
11609    sar{b}\t{%b1, %0|%0, %b1}"
11610   [(set_attr "type" "ishift1")
11611    (set_attr "mode" "QI")])
11612
11613 ;; This pattern can't accept a variable shift count, since shifts by
11614 ;; zero don't affect the flags.  We assume that shifts by constant
11615 ;; zero are optimized away.
11616 (define_insn "*ashrqi3_one_bit_cmp"
11617   [(set (reg 17)
11618         (compare
11619           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11620                        (match_operand:QI 2 "const_int_1_operand" "I"))
11621           (const_int 0)))
11622    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11623         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11624   "ix86_match_ccmode (insn, CCGOCmode)
11625    && (TARGET_SHIFT1 || optimize_size)
11626    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11627   "sar{b}\t%0"
11628   [(set_attr "type" "ishift")
11629    (set (attr "length") 
11630      (if_then_else (match_operand 0 "register_operand" "") 
11631         (const_string "2")
11632         (const_string "*")))])
11633
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags.  We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrqi3_cmp"
11638   [(set (reg 17)
11639         (compare
11640           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11641                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11642           (const_int 0)))
11643    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11644         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11645   "ix86_match_ccmode (insn, CCGOCmode)
11646    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11647   "sar{b}\t{%2, %0|%0, %2}"
11648   [(set_attr "type" "ishift")
11649    (set_attr "mode" "QI")])
11650 \f
11651 ;; Logical shift instructions
11652
11653 ;; See comment above `ashldi3' about how this works.
11654
11655 (define_expand "lshrdi3"
11656   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11657                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11658                                 (match_operand:QI 2 "nonmemory_operand" "")))
11659               (clobber (reg:CC 17))])]
11660   ""
11661 {
11662   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11663     {
11664       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11665       DONE;
11666     }
11667   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11668   DONE;
11669 })
11670
11671 (define_insn "*lshrdi3_1_one_bit_rex64"
11672   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11673         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11674                      (match_operand:QI 2 "const_int_1_operand" "")))
11675    (clobber (reg:CC 17))]
11676   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11677    && (TARGET_SHIFT1 || optimize_size)"
11678   "shr{q}\t%0"
11679   [(set_attr "type" "ishift")
11680    (set (attr "length") 
11681      (if_then_else (match_operand:DI 0 "register_operand" "") 
11682         (const_string "2")
11683         (const_string "*")))])
11684
11685 (define_insn "*lshrdi3_1_rex64"
11686   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11687         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11688                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11689    (clobber (reg:CC 17))]
11690   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11691   "@
11692    shr{q}\t{%2, %0|%0, %2}
11693    shr{q}\t{%b2, %0|%0, %b2}"
11694   [(set_attr "type" "ishift")
11695    (set_attr "mode" "DI")])
11696
11697 ;; This pattern can't accept a variable shift count, since shifts by
11698 ;; zero don't affect the flags.  We assume that shifts by constant
11699 ;; zero are optimized away.
11700 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11701   [(set (reg 17)
11702         (compare
11703           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11704                        (match_operand:QI 2 "const_int_1_operand" ""))
11705           (const_int 0)))
11706    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11707         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11708   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11709    && (TARGET_SHIFT1 || optimize_size)
11710    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11711   "shr{q}\t%0"
11712   [(set_attr "type" "ishift")
11713    (set (attr "length") 
11714      (if_then_else (match_operand:DI 0 "register_operand" "") 
11715         (const_string "2")
11716         (const_string "*")))])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*lshrdi3_cmp_rex64"
11722   [(set (reg 17)
11723         (compare
11724           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const_int_operand" "e"))
11726           (const_int 0)))
11727    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11728         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11729   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11730    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11731   "shr{q}\t{%2, %0|%0, %2}"
11732   [(set_attr "type" "ishift")
11733    (set_attr "mode" "DI")])
11734
11735 (define_insn "lshrdi3_1"
11736   [(set (match_operand:DI 0 "register_operand" "=r")
11737         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11738                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11739    (clobber (match_scratch:SI 3 "=&r"))
11740    (clobber (reg:CC 17))]
11741   "!TARGET_64BIT && TARGET_CMOVE"
11742   "#"
11743   [(set_attr "type" "multi")])
11744
11745 (define_insn "*lshrdi3_2"
11746   [(set (match_operand:DI 0 "register_operand" "=r")
11747         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11748                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11749    (clobber (reg:CC 17))]
11750   "!TARGET_64BIT"
11751   "#"
11752   [(set_attr "type" "multi")])
11753
11754 (define_split 
11755   [(set (match_operand:DI 0 "register_operand" "")
11756         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11757                      (match_operand:QI 2 "nonmemory_operand" "")))
11758    (clobber (match_scratch:SI 3 ""))
11759    (clobber (reg:CC 17))]
11760   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11761   [(const_int 0)]
11762   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11763
11764 (define_split 
11765   [(set (match_operand:DI 0 "register_operand" "")
11766         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11767                      (match_operand:QI 2 "nonmemory_operand" "")))
11768    (clobber (reg:CC 17))]
11769   "!TARGET_64BIT && reload_completed"
11770   [(const_int 0)]
11771   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11772
11773 (define_expand "lshrsi3"
11774   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11775         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11776                      (match_operand:QI 2 "nonmemory_operand" "")))
11777    (clobber (reg:CC 17))]
11778   ""
11779   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11780
11781 (define_insn "*lshrsi3_1_one_bit"
11782   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784                      (match_operand:QI 2 "const_int_1_operand" "")))
11785    (clobber (reg:CC 17))]
11786   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11787    && (TARGET_SHIFT1 || optimize_size)"
11788   "shr{l}\t%0"
11789   [(set_attr "type" "ishift")
11790    (set (attr "length") 
11791      (if_then_else (match_operand:SI 0 "register_operand" "") 
11792         (const_string "2")
11793         (const_string "*")))])
11794
11795 (define_insn "*lshrsi3_1_one_bit_zext"
11796   [(set (match_operand:DI 0 "register_operand" "=r")
11797         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11798                      (match_operand:QI 2 "const_int_1_operand" "")))
11799    (clobber (reg:CC 17))]
11800   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11801    && (TARGET_SHIFT1 || optimize_size)"
11802   "shr{l}\t%k0"
11803   [(set_attr "type" "ishift")
11804    (set_attr "length" "2")])
11805
11806 (define_insn "*lshrsi3_1"
11807   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11808         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11809                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11810    (clobber (reg:CC 17))]
11811   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11812   "@
11813    shr{l}\t{%2, %0|%0, %2}
11814    shr{l}\t{%b2, %0|%0, %b2}"
11815   [(set_attr "type" "ishift")
11816    (set_attr "mode" "SI")])
11817
11818 (define_insn "*lshrsi3_1_zext"
11819   [(set (match_operand:DI 0 "register_operand" "=r,r")
11820         (zero_extend:DI
11821           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11822                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11823    (clobber (reg:CC 17))]
11824   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11825   "@
11826    shr{l}\t{%2, %k0|%k0, %2}
11827    shr{l}\t{%b2, %k0|%k0, %b2}"
11828   [(set_attr "type" "ishift")
11829    (set_attr "mode" "SI")])
11830
11831 ;; This pattern can't accept a variable shift count, since shifts by
11832 ;; zero don't affect the flags.  We assume that shifts by constant
11833 ;; zero are optimized away.
11834 (define_insn "*lshrsi3_one_bit_cmp"
11835   [(set (reg 17)
11836         (compare
11837           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11838                        (match_operand:QI 2 "const_int_1_operand" ""))
11839           (const_int 0)))
11840    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11841         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11842   "ix86_match_ccmode (insn, CCGOCmode)
11843    && (TARGET_SHIFT1 || optimize_size)
11844    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11845   "shr{l}\t%0"
11846   [(set_attr "type" "ishift")
11847    (set (attr "length") 
11848      (if_then_else (match_operand:SI 0 "register_operand" "") 
11849         (const_string "2")
11850         (const_string "*")))])
11851
11852 (define_insn "*lshrsi3_cmp_one_bit_zext"
11853   [(set (reg 17)
11854         (compare
11855           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11856                        (match_operand:QI 2 "const_int_1_operand" ""))
11857           (const_int 0)))
11858    (set (match_operand:DI 0 "register_operand" "=r")
11859         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11860   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11861    && (TARGET_SHIFT1 || optimize_size)
11862    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11863   "shr{l}\t%k0"
11864   [(set_attr "type" "ishift")
11865    (set_attr "length" "2")])
11866
11867 ;; This pattern can't accept a variable shift count, since shifts by
11868 ;; zero don't affect the flags.  We assume that shifts by constant
11869 ;; zero are optimized away.
11870 (define_insn "*lshrsi3_cmp"
11871   [(set (reg 17)
11872         (compare
11873           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11875           (const_int 0)))
11876    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11877         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11878   "ix86_match_ccmode (insn, CCGOCmode)
11879    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11880   "shr{l}\t{%2, %0|%0, %2}"
11881   [(set_attr "type" "ishift")
11882    (set_attr "mode" "SI")])
11883
11884 (define_insn "*lshrsi3_cmp_zext"
11885   [(set (reg 17)
11886         (compare
11887           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11888                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11889           (const_int 0)))
11890    (set (match_operand:DI 0 "register_operand" "=r")
11891         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11892   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11893    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894   "shr{l}\t{%2, %k0|%k0, %2}"
11895   [(set_attr "type" "ishift")
11896    (set_attr "mode" "SI")])
11897
11898 (define_expand "lshrhi3"
11899   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11900         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11901                      (match_operand:QI 2 "nonmemory_operand" "")))
11902    (clobber (reg:CC 17))]
11903   "TARGET_HIMODE_MATH"
11904   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11905
11906 (define_insn "*lshrhi3_1_one_bit"
11907   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11908         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11909                      (match_operand:QI 2 "const_int_1_operand" "")))
11910    (clobber (reg:CC 17))]
11911   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11912    && (TARGET_SHIFT1 || optimize_size)"
11913   "shr{w}\t%0"
11914   [(set_attr "type" "ishift")
11915    (set (attr "length") 
11916      (if_then_else (match_operand 0 "register_operand" "") 
11917         (const_string "2")
11918         (const_string "*")))])
11919
11920 (define_insn "*lshrhi3_1"
11921   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11922         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11923                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924    (clobber (reg:CC 17))]
11925   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11926   "@
11927    shr{w}\t{%2, %0|%0, %2}
11928    shr{w}\t{%b2, %0|%0, %b2}"
11929   [(set_attr "type" "ishift")
11930    (set_attr "mode" "HI")])
11931
11932 ;; This pattern can't accept a variable shift count, since shifts by
11933 ;; zero don't affect the flags.  We assume that shifts by constant
11934 ;; zero are optimized away.
11935 (define_insn "*lshrhi3_one_bit_cmp"
11936   [(set (reg 17)
11937         (compare
11938           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11939                        (match_operand:QI 2 "const_int_1_operand" ""))
11940           (const_int 0)))
11941    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11942         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11943   "ix86_match_ccmode (insn, CCGOCmode)
11944    && (TARGET_SHIFT1 || optimize_size)
11945    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11946   "shr{w}\t%0"
11947   [(set_attr "type" "ishift")
11948    (set (attr "length") 
11949      (if_then_else (match_operand:SI 0 "register_operand" "") 
11950         (const_string "2")
11951         (const_string "*")))])
11952
11953 ;; This pattern can't accept a variable shift count, since shifts by
11954 ;; zero don't affect the flags.  We assume that shifts by constant
11955 ;; zero are optimized away.
11956 (define_insn "*lshrhi3_cmp"
11957   [(set (reg 17)
11958         (compare
11959           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11960                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11961           (const_int 0)))
11962    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11963         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11964   "ix86_match_ccmode (insn, CCGOCmode)
11965    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11966   "shr{w}\t{%2, %0|%0, %2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "mode" "HI")])
11969
11970 (define_expand "lshrqi3"
11971   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11972         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11973                      (match_operand:QI 2 "nonmemory_operand" "")))
11974    (clobber (reg:CC 17))]
11975   "TARGET_QIMODE_MATH"
11976   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11977
11978 (define_insn "*lshrqi3_1_one_bit"
11979   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11980         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11981                      (match_operand:QI 2 "const_int_1_operand" "")))
11982    (clobber (reg:CC 17))]
11983   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11984    && (TARGET_SHIFT1 || optimize_size)"
11985   "shr{b}\t%0"
11986   [(set_attr "type" "ishift")
11987    (set (attr "length") 
11988      (if_then_else (match_operand 0 "register_operand" "") 
11989         (const_string "2")
11990         (const_string "*")))])
11991
11992 (define_insn "*lshrqi3_1_one_bit_slp"
11993   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11994         (lshiftrt:QI (match_dup 0)
11995                      (match_operand:QI 1 "const_int_1_operand" "")))
11996    (clobber (reg:CC 17))]
11997   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11998    && (TARGET_SHIFT1 || optimize_size)"
11999   "shr{b}\t%0"
12000   [(set_attr "type" "ishift1")
12001    (set (attr "length") 
12002      (if_then_else (match_operand 0 "register_operand" "") 
12003         (const_string "2")
12004         (const_string "*")))])
12005
12006 (define_insn "*lshrqi3_1"
12007   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12008         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12009                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12010    (clobber (reg:CC 17))]
12011   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12012   "@
12013    shr{b}\t{%2, %0|%0, %2}
12014    shr{b}\t{%b2, %0|%0, %b2}"
12015   [(set_attr "type" "ishift")
12016    (set_attr "mode" "QI")])
12017
12018 (define_insn "*lshrqi3_1_slp"
12019   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12020         (lshiftrt:QI (match_dup 0)
12021                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12022    (clobber (reg:CC 17))]
12023   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12024    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12025   "@
12026    shr{b}\t{%1, %0|%0, %1}
12027    shr{b}\t{%b1, %0|%0, %b1}"
12028   [(set_attr "type" "ishift1")
12029    (set_attr "mode" "QI")])
12030
12031 ;; This pattern can't accept a variable shift count, since shifts by
12032 ;; zero don't affect the flags.  We assume that shifts by constant
12033 ;; zero are optimized away.
12034 (define_insn "*lshrqi2_one_bit_cmp"
12035   [(set (reg 17)
12036         (compare
12037           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038                        (match_operand:QI 2 "const_int_1_operand" ""))
12039           (const_int 0)))
12040    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12041         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12042   "ix86_match_ccmode (insn, CCGOCmode)
12043    && (TARGET_SHIFT1 || optimize_size)
12044    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12045   "shr{b}\t%0"
12046   [(set_attr "type" "ishift")
12047    (set (attr "length") 
12048      (if_then_else (match_operand:SI 0 "register_operand" "") 
12049         (const_string "2")
12050         (const_string "*")))])
12051
12052 ;; This pattern can't accept a variable shift count, since shifts by
12053 ;; zero don't affect the flags.  We assume that shifts by constant
12054 ;; zero are optimized away.
12055 (define_insn "*lshrqi2_cmp"
12056   [(set (reg 17)
12057         (compare
12058           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12059                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12060           (const_int 0)))
12061    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12062         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12063   "ix86_match_ccmode (insn, CCGOCmode)
12064    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12065   "shr{b}\t{%2, %0|%0, %2}"
12066   [(set_attr "type" "ishift")
12067    (set_attr "mode" "QI")])
12068 \f
12069 ;; Rotate instructions
12070
12071 (define_expand "rotldi3"
12072   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12073         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12074                    (match_operand:QI 2 "nonmemory_operand" "")))
12075    (clobber (reg:CC 17))]
12076   "TARGET_64BIT"
12077   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12078
12079 (define_insn "*rotlsi3_1_one_bit_rex64"
12080   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12081         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12082                    (match_operand:QI 2 "const_int_1_operand" "")))
12083    (clobber (reg:CC 17))]
12084   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12085    && (TARGET_SHIFT1 || optimize_size)"
12086   "rol{q}\t%0"
12087   [(set_attr "type" "rotate")
12088    (set (attr "length") 
12089      (if_then_else (match_operand:DI 0 "register_operand" "") 
12090         (const_string "2")
12091         (const_string "*")))])
12092
12093 (define_insn "*rotldi3_1_rex64"
12094   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12095         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12096                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12097    (clobber (reg:CC 17))]
12098   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12099   "@
12100    rol{q}\t{%2, %0|%0, %2}
12101    rol{q}\t{%b2, %0|%0, %b2}"
12102   [(set_attr "type" "rotate")
12103    (set_attr "mode" "DI")])
12104
12105 (define_expand "rotlsi3"
12106   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12107         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12108                    (match_operand:QI 2 "nonmemory_operand" "")))
12109    (clobber (reg:CC 17))]
12110   ""
12111   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12112
12113 (define_insn "*rotlsi3_1_one_bit"
12114   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12115         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12116                    (match_operand:QI 2 "const_int_1_operand" "")))
12117    (clobber (reg:CC 17))]
12118   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12119    && (TARGET_SHIFT1 || optimize_size)"
12120   "rol{l}\t%0"
12121   [(set_attr "type" "rotate")
12122    (set (attr "length") 
12123      (if_then_else (match_operand:SI 0 "register_operand" "") 
12124         (const_string "2")
12125         (const_string "*")))])
12126
12127 (define_insn "*rotlsi3_1_one_bit_zext"
12128   [(set (match_operand:DI 0 "register_operand" "=r")
12129         (zero_extend:DI
12130           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12131                      (match_operand:QI 2 "const_int_1_operand" ""))))
12132    (clobber (reg:CC 17))]
12133   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12134    && (TARGET_SHIFT1 || optimize_size)"
12135   "rol{l}\t%k0"
12136   [(set_attr "type" "rotate")
12137    (set_attr "length" "2")])
12138
12139 (define_insn "*rotlsi3_1"
12140   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12141         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12142                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12143    (clobber (reg:CC 17))]
12144   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12145   "@
12146    rol{l}\t{%2, %0|%0, %2}
12147    rol{l}\t{%b2, %0|%0, %b2}"
12148   [(set_attr "type" "rotate")
12149    (set_attr "mode" "SI")])
12150
12151 (define_insn "*rotlsi3_1_zext"
12152   [(set (match_operand:DI 0 "register_operand" "=r,r")
12153         (zero_extend:DI
12154           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12155                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12156    (clobber (reg:CC 17))]
12157   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158   "@
12159    rol{l}\t{%2, %k0|%k0, %2}
12160    rol{l}\t{%b2, %k0|%k0, %b2}"
12161   [(set_attr "type" "rotate")
12162    (set_attr "mode" "SI")])
12163
12164 (define_expand "rotlhi3"
12165   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12166         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12167                    (match_operand:QI 2 "nonmemory_operand" "")))
12168    (clobber (reg:CC 17))]
12169   "TARGET_HIMODE_MATH"
12170   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12171
12172 (define_insn "*rotlhi3_1_one_bit"
12173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12174         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12175                    (match_operand:QI 2 "const_int_1_operand" "")))
12176    (clobber (reg:CC 17))]
12177   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12178    && (TARGET_SHIFT1 || optimize_size)"
12179   "rol{w}\t%0"
12180   [(set_attr "type" "rotate")
12181    (set (attr "length") 
12182      (if_then_else (match_operand 0 "register_operand" "") 
12183         (const_string "2")
12184         (const_string "*")))])
12185
12186 (define_insn "*rotlhi3_1"
12187   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12188         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12189                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190    (clobber (reg:CC 17))]
12191   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12192   "@
12193    rol{w}\t{%2, %0|%0, %2}
12194    rol{w}\t{%b2, %0|%0, %b2}"
12195   [(set_attr "type" "rotate")
12196    (set_attr "mode" "HI")])
12197
12198 (define_expand "rotlqi3"
12199   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12200         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12201                    (match_operand:QI 2 "nonmemory_operand" "")))
12202    (clobber (reg:CC 17))]
12203   "TARGET_QIMODE_MATH"
12204   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12205
12206 (define_insn "*rotlqi3_1_one_bit_slp"
12207   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12208         (rotate:QI (match_dup 0)
12209                    (match_operand:QI 1 "const_int_1_operand" "")))
12210    (clobber (reg:CC 17))]
12211   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12212    && (TARGET_SHIFT1 || optimize_size)"
12213   "rol{b}\t%0"
12214   [(set_attr "type" "rotate1")
12215    (set (attr "length") 
12216      (if_then_else (match_operand 0 "register_operand" "") 
12217         (const_string "2")
12218         (const_string "*")))])
12219
12220 (define_insn "*rotlqi3_1_one_bit"
12221   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12223                    (match_operand:QI 2 "const_int_1_operand" "")))
12224    (clobber (reg:CC 17))]
12225   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12226    && (TARGET_SHIFT1 || optimize_size)"
12227   "rol{b}\t%0"
12228   [(set_attr "type" "rotate")
12229    (set (attr "length") 
12230      (if_then_else (match_operand 0 "register_operand" "") 
12231         (const_string "2")
12232         (const_string "*")))])
12233
12234 (define_insn "*rotlqi3_1_slp"
12235   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12236         (rotate:QI (match_dup 0)
12237                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12238    (clobber (reg:CC 17))]
12239   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12240    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12241   "@
12242    rol{b}\t{%1, %0|%0, %1}
12243    rol{b}\t{%b1, %0|%0, %b1}"
12244   [(set_attr "type" "rotate1")
12245    (set_attr "mode" "QI")])
12246
12247 (define_insn "*rotlqi3_1"
12248   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12249         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12250                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12251    (clobber (reg:CC 17))]
12252   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12253   "@
12254    rol{b}\t{%2, %0|%0, %2}
12255    rol{b}\t{%b2, %0|%0, %b2}"
12256   [(set_attr "type" "rotate")
12257    (set_attr "mode" "QI")])
12258
12259 (define_expand "rotrdi3"
12260   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12261         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12262                      (match_operand:QI 2 "nonmemory_operand" "")))
12263    (clobber (reg:CC 17))]
12264   "TARGET_64BIT"
12265   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12266
12267 (define_insn "*rotrdi3_1_one_bit_rex64"
12268   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12269         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12270                      (match_operand:QI 2 "const_int_1_operand" "")))
12271    (clobber (reg:CC 17))]
12272   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12273    && (TARGET_SHIFT1 || optimize_size)"
12274   "ror{q}\t%0"
12275   [(set_attr "type" "rotate")
12276    (set (attr "length") 
12277      (if_then_else (match_operand:DI 0 "register_operand" "") 
12278         (const_string "2")
12279         (const_string "*")))])
12280
12281 (define_insn "*rotrdi3_1_rex64"
12282   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12283         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12284                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12285    (clobber (reg:CC 17))]
12286   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12287   "@
12288    ror{q}\t{%2, %0|%0, %2}
12289    ror{q}\t{%b2, %0|%0, %b2}"
12290   [(set_attr "type" "rotate")
12291    (set_attr "mode" "DI")])
12292
12293 (define_expand "rotrsi3"
12294   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12295         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12296                      (match_operand:QI 2 "nonmemory_operand" "")))
12297    (clobber (reg:CC 17))]
12298   ""
12299   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12300
12301 (define_insn "*rotrsi3_1_one_bit"
12302   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12303         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12304                      (match_operand:QI 2 "const_int_1_operand" "")))
12305    (clobber (reg:CC 17))]
12306   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12307    && (TARGET_SHIFT1 || optimize_size)"
12308   "ror{l}\t%0"
12309   [(set_attr "type" "rotate")
12310    (set (attr "length") 
12311      (if_then_else (match_operand:SI 0 "register_operand" "") 
12312         (const_string "2")
12313         (const_string "*")))])
12314
12315 (define_insn "*rotrsi3_1_one_bit_zext"
12316   [(set (match_operand:DI 0 "register_operand" "=r")
12317         (zero_extend:DI
12318           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12319                        (match_operand:QI 2 "const_int_1_operand" ""))))
12320    (clobber (reg:CC 17))]
12321   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "ror{l}\t%k0"
12324   [(set_attr "type" "rotate")
12325    (set (attr "length") 
12326      (if_then_else (match_operand:SI 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*rotrsi3_1"
12331   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12332         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334    (clobber (reg:CC 17))]
12335   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12336   "@
12337    ror{l}\t{%2, %0|%0, %2}
12338    ror{l}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "rotate")
12340    (set_attr "mode" "SI")])
12341
12342 (define_insn "*rotrsi3_1_zext"
12343   [(set (match_operand:DI 0 "register_operand" "=r,r")
12344         (zero_extend:DI
12345           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12346                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12347    (clobber (reg:CC 17))]
12348   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12349   "@
12350    ror{l}\t{%2, %k0|%k0, %2}
12351    ror{l}\t{%b2, %k0|%k0, %b2}"
12352   [(set_attr "type" "rotate")
12353    (set_attr "mode" "SI")])
12354
12355 (define_expand "rotrhi3"
12356   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12357         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12358                      (match_operand:QI 2 "nonmemory_operand" "")))
12359    (clobber (reg:CC 17))]
12360   "TARGET_HIMODE_MATH"
12361   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12362
12363 (define_insn "*rotrhi3_one_bit"
12364   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12365         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12366                      (match_operand:QI 2 "const_int_1_operand" "")))
12367    (clobber (reg:CC 17))]
12368   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12369    && (TARGET_SHIFT1 || optimize_size)"
12370   "ror{w}\t%0"
12371   [(set_attr "type" "rotate")
12372    (set (attr "length") 
12373      (if_then_else (match_operand 0 "register_operand" "") 
12374         (const_string "2")
12375         (const_string "*")))])
12376
12377 (define_insn "*rotrhi3"
12378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12379         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12380                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12381    (clobber (reg:CC 17))]
12382   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12383   "@
12384    ror{w}\t{%2, %0|%0, %2}
12385    ror{w}\t{%b2, %0|%0, %b2}"
12386   [(set_attr "type" "rotate")
12387    (set_attr "mode" "HI")])
12388
12389 (define_expand "rotrqi3"
12390   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12391         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12392                      (match_operand:QI 2 "nonmemory_operand" "")))
12393    (clobber (reg:CC 17))]
12394   "TARGET_QIMODE_MATH"
12395   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12396
12397 (define_insn "*rotrqi3_1_one_bit"
12398   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12399         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12400                      (match_operand:QI 2 "const_int_1_operand" "")))
12401    (clobber (reg:CC 17))]
12402   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12403    && (TARGET_SHIFT1 || optimize_size)"
12404   "ror{b}\t%0"
12405   [(set_attr "type" "rotate")
12406    (set (attr "length") 
12407      (if_then_else (match_operand 0 "register_operand" "") 
12408         (const_string "2")
12409         (const_string "*")))])
12410
12411 (define_insn "*rotrqi3_1_one_bit_slp"
12412   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12413         (rotatert:QI (match_dup 0)
12414                      (match_operand:QI 1 "const_int_1_operand" "")))
12415    (clobber (reg:CC 17))]
12416   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{b}\t%0"
12419   [(set_attr "type" "rotate1")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12424
12425 (define_insn "*rotrqi3_1"
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12427         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12428                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12429    (clobber (reg:CC 17))]
12430   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12431   "@
12432    ror{b}\t{%2, %0|%0, %2}
12433    ror{b}\t{%b2, %0|%0, %b2}"
12434   [(set_attr "type" "rotate")
12435    (set_attr "mode" "QI")])
12436
12437 (define_insn "*rotrqi3_1_slp"
12438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12439         (rotatert:QI (match_dup 0)
12440                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12441    (clobber (reg:CC 17))]
12442   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12443    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12444   "@
12445    ror{b}\t{%1, %0|%0, %1}
12446    ror{b}\t{%b1, %0|%0, %b1}"
12447   [(set_attr "type" "rotate1")
12448    (set_attr "mode" "QI")])
12449 \f
12450 ;; Bit set / bit test instructions
12451
12452 (define_expand "extv"
12453   [(set (match_operand:SI 0 "register_operand" "")
12454         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12455                          (match_operand:SI 2 "immediate_operand" "")
12456                          (match_operand:SI 3 "immediate_operand" "")))]
12457   ""
12458 {
12459   /* Handle extractions from %ah et al.  */
12460   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12461     FAIL;
12462
12463   /* From mips.md: extract_bit_field doesn't verify that our source
12464      matches the predicate, so check it again here.  */
12465   if (! register_operand (operands[1], VOIDmode))
12466     FAIL;
12467 })
12468
12469 (define_expand "extzv"
12470   [(set (match_operand:SI 0 "register_operand" "")
12471         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12472                          (match_operand:SI 2 "immediate_operand" "")
12473                          (match_operand:SI 3 "immediate_operand" "")))]
12474   ""
12475 {
12476   /* Handle extractions from %ah et al.  */
12477   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12478     FAIL;
12479
12480   /* From mips.md: extract_bit_field doesn't verify that our source
12481      matches the predicate, so check it again here.  */
12482   if (! register_operand (operands[1], VOIDmode))
12483     FAIL;
12484 })
12485
12486 (define_expand "insv"
12487   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12488                          (match_operand:SI 1 "immediate_operand" "")
12489                          (match_operand:SI 2 "immediate_operand" ""))
12490         (match_operand:SI 3 "register_operand" ""))]
12491   ""
12492 {
12493   /* Handle extractions from %ah et al.  */
12494   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12495     FAIL;
12496
12497   /* From mips.md: insert_bit_field doesn't verify that our source
12498      matches the predicate, so check it again here.  */
12499   if (! register_operand (operands[0], VOIDmode))
12500     FAIL;
12501 })
12502
12503 ;; %%% bts, btr, btc, bt.
12504 \f
12505 ;; Store-flag instructions.
12506
12507 ;; For all sCOND expanders, also expand the compare or test insn that
12508 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12509
12510 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12511 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12512 ;; way, which can later delete the movzx if only QImode is needed.
12513
12514 (define_expand "seq"
12515   [(set (match_operand:QI 0 "register_operand" "")
12516         (eq:QI (reg:CC 17) (const_int 0)))]
12517   ""
12518   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12519
12520 (define_expand "sne"
12521   [(set (match_operand:QI 0 "register_operand" "")
12522         (ne:QI (reg:CC 17) (const_int 0)))]
12523   ""
12524   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12525
12526 (define_expand "sgt"
12527   [(set (match_operand:QI 0 "register_operand" "")
12528         (gt:QI (reg:CC 17) (const_int 0)))]
12529   ""
12530   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12531
12532 (define_expand "sgtu"
12533   [(set (match_operand:QI 0 "register_operand" "")
12534         (gtu:QI (reg:CC 17) (const_int 0)))]
12535   ""
12536   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12537
12538 (define_expand "slt"
12539   [(set (match_operand:QI 0 "register_operand" "")
12540         (lt:QI (reg:CC 17) (const_int 0)))]
12541   ""
12542   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12543
12544 (define_expand "sltu"
12545   [(set (match_operand:QI 0 "register_operand" "")
12546         (ltu:QI (reg:CC 17) (const_int 0)))]
12547   ""
12548   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12549
12550 (define_expand "sge"
12551   [(set (match_operand:QI 0 "register_operand" "")
12552         (ge:QI (reg:CC 17) (const_int 0)))]
12553   ""
12554   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12555
12556 (define_expand "sgeu"
12557   [(set (match_operand:QI 0 "register_operand" "")
12558         (geu:QI (reg:CC 17) (const_int 0)))]
12559   ""
12560   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12561
12562 (define_expand "sle"
12563   [(set (match_operand:QI 0 "register_operand" "")
12564         (le:QI (reg:CC 17) (const_int 0)))]
12565   ""
12566   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12567
12568 (define_expand "sleu"
12569   [(set (match_operand:QI 0 "register_operand" "")
12570         (leu:QI (reg:CC 17) (const_int 0)))]
12571   ""
12572   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12573
12574 (define_expand "sunordered"
12575   [(set (match_operand:QI 0 "register_operand" "")
12576         (unordered:QI (reg:CC 17) (const_int 0)))]
12577   "TARGET_80387 || TARGET_SSE"
12578   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12579
12580 (define_expand "sordered"
12581   [(set (match_operand:QI 0 "register_operand" "")
12582         (ordered:QI (reg:CC 17) (const_int 0)))]
12583   "TARGET_80387"
12584   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12585
12586 (define_expand "suneq"
12587   [(set (match_operand:QI 0 "register_operand" "")
12588         (uneq:QI (reg:CC 17) (const_int 0)))]
12589   "TARGET_80387 || TARGET_SSE"
12590   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12591
12592 (define_expand "sunge"
12593   [(set (match_operand:QI 0 "register_operand" "")
12594         (unge:QI (reg:CC 17) (const_int 0)))]
12595   "TARGET_80387 || TARGET_SSE"
12596   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12597
12598 (define_expand "sungt"
12599   [(set (match_operand:QI 0 "register_operand" "")
12600         (ungt:QI (reg:CC 17) (const_int 0)))]
12601   "TARGET_80387 || TARGET_SSE"
12602   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12603
12604 (define_expand "sunle"
12605   [(set (match_operand:QI 0 "register_operand" "")
12606         (unle:QI (reg:CC 17) (const_int 0)))]
12607   "TARGET_80387 || TARGET_SSE"
12608   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12609
12610 (define_expand "sunlt"
12611   [(set (match_operand:QI 0 "register_operand" "")
12612         (unlt:QI (reg:CC 17) (const_int 0)))]
12613   "TARGET_80387 || TARGET_SSE"
12614   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12615
12616 (define_expand "sltgt"
12617   [(set (match_operand:QI 0 "register_operand" "")
12618         (ltgt:QI (reg:CC 17) (const_int 0)))]
12619   "TARGET_80387 || TARGET_SSE"
12620   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12621
12622 (define_insn "*setcc_1"
12623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12624         (match_operator:QI 1 "ix86_comparison_operator"
12625           [(reg 17) (const_int 0)]))]
12626   ""
12627   "set%C1\t%0"
12628   [(set_attr "type" "setcc")
12629    (set_attr "mode" "QI")])
12630
12631 (define_insn "setcc_2"
12632   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12633         (match_operator:QI 1 "ix86_comparison_operator"
12634           [(reg 17) (const_int 0)]))]
12635   ""
12636   "set%C1\t%0"
12637   [(set_attr "type" "setcc")
12638    (set_attr "mode" "QI")])
12639
12640 ;; In general it is not safe to assume too much about CCmode registers,
12641 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12642 ;; conditions this is safe on x86, so help combine not create
12643 ;;
12644 ;;      seta    %al
12645 ;;      testb   %al, %al
12646 ;;      sete    %al
12647
12648 (define_split 
12649   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12650         (ne:QI (match_operator 1 "ix86_comparison_operator"
12651                  [(reg 17) (const_int 0)])
12652             (const_int 0)))]
12653   ""
12654   [(set (match_dup 0) (match_dup 1))]
12655 {
12656   PUT_MODE (operands[1], QImode);
12657 })
12658
12659 (define_split 
12660   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12661         (ne:QI (match_operator 1 "ix86_comparison_operator"
12662                  [(reg 17) (const_int 0)])
12663             (const_int 0)))]
12664   ""
12665   [(set (match_dup 0) (match_dup 1))]
12666 {
12667   PUT_MODE (operands[1], QImode);
12668 })
12669
12670 (define_split 
12671   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12672         (eq:QI (match_operator 1 "ix86_comparison_operator"
12673                  [(reg 17) (const_int 0)])
12674             (const_int 0)))]
12675   ""
12676   [(set (match_dup 0) (match_dup 1))]
12677 {
12678   rtx new_op1 = copy_rtx (operands[1]);
12679   operands[1] = new_op1;
12680   PUT_MODE (new_op1, QImode);
12681   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12682                                         GET_MODE (XEXP (new_op1, 0))));
12683
12684   /* Make sure that (a) the CCmode we have for the flags is strong
12685      enough for the reversed compare or (b) we have a valid FP compare.  */
12686   if (! ix86_comparison_operator (new_op1, VOIDmode))
12687     FAIL;
12688 })
12689
12690 (define_split 
12691   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12692         (eq:QI (match_operator 1 "ix86_comparison_operator"
12693                  [(reg 17) (const_int 0)])
12694             (const_int 0)))]
12695   ""
12696   [(set (match_dup 0) (match_dup 1))]
12697 {
12698   rtx new_op1 = copy_rtx (operands[1]);
12699   operands[1] = new_op1;
12700   PUT_MODE (new_op1, QImode);
12701   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12702                                         GET_MODE (XEXP (new_op1, 0))));
12703
12704   /* Make sure that (a) the CCmode we have for the flags is strong
12705      enough for the reversed compare or (b) we have a valid FP compare.  */
12706   if (! ix86_comparison_operator (new_op1, VOIDmode))
12707     FAIL;
12708 })
12709
12710 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12711 ;; subsequent logical operations are used to imitate conditional moves.
12712 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12713 ;; it directly.  Further holding this value in pseudo register might bring
12714 ;; problem in implicit normalization in spill code.
12715 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12716 ;; instructions after reload by splitting the conditional move patterns.
12717
12718 (define_insn "*sse_setccsf"
12719   [(set (match_operand:SF 0 "register_operand" "=x")
12720         (match_operator:SF 1 "sse_comparison_operator"
12721           [(match_operand:SF 2 "register_operand" "0")
12722            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12723   "TARGET_SSE && reload_completed"
12724   "cmp%D1ss\t{%3, %0|%0, %3}"
12725   [(set_attr "type" "ssecmp")
12726    (set_attr "mode" "SF")])
12727
12728 (define_insn "*sse_setccdf"
12729   [(set (match_operand:DF 0 "register_operand" "=Y")
12730         (match_operator:DF 1 "sse_comparison_operator"
12731           [(match_operand:DF 2 "register_operand" "0")
12732            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12733   "TARGET_SSE2 && reload_completed"
12734   "cmp%D1sd\t{%3, %0|%0, %3}"
12735   [(set_attr "type" "ssecmp")
12736    (set_attr "mode" "DF")])
12737 \f
12738 ;; Basic conditional jump instructions.
12739 ;; We ignore the overflow flag for signed branch instructions.
12740
12741 ;; For all bCOND expanders, also expand the compare or test insn that
12742 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12743
12744 (define_expand "beq"
12745   [(set (pc)
12746         (if_then_else (match_dup 1)
12747                       (label_ref (match_operand 0 "" ""))
12748                       (pc)))]
12749   ""
12750   "ix86_expand_branch (EQ, operands[0]); DONE;")
12751
12752 (define_expand "bne"
12753   [(set (pc)
12754         (if_then_else (match_dup 1)
12755                       (label_ref (match_operand 0 "" ""))
12756                       (pc)))]
12757   ""
12758   "ix86_expand_branch (NE, operands[0]); DONE;")
12759
12760 (define_expand "bgt"
12761   [(set (pc)
12762         (if_then_else (match_dup 1)
12763                       (label_ref (match_operand 0 "" ""))
12764                       (pc)))]
12765   ""
12766   "ix86_expand_branch (GT, operands[0]); DONE;")
12767
12768 (define_expand "bgtu"
12769   [(set (pc)
12770         (if_then_else (match_dup 1)
12771                       (label_ref (match_operand 0 "" ""))
12772                       (pc)))]
12773   ""
12774   "ix86_expand_branch (GTU, operands[0]); DONE;")
12775
12776 (define_expand "blt"
12777   [(set (pc)
12778         (if_then_else (match_dup 1)
12779                       (label_ref (match_operand 0 "" ""))
12780                       (pc)))]
12781   ""
12782   "ix86_expand_branch (LT, operands[0]); DONE;")
12783
12784 (define_expand "bltu"
12785   [(set (pc)
12786         (if_then_else (match_dup 1)
12787                       (label_ref (match_operand 0 "" ""))
12788                       (pc)))]
12789   ""
12790   "ix86_expand_branch (LTU, operands[0]); DONE;")
12791
12792 (define_expand "bge"
12793   [(set (pc)
12794         (if_then_else (match_dup 1)
12795                       (label_ref (match_operand 0 "" ""))
12796                       (pc)))]
12797   ""
12798   "ix86_expand_branch (GE, operands[0]); DONE;")
12799
12800 (define_expand "bgeu"
12801   [(set (pc)
12802         (if_then_else (match_dup 1)
12803                       (label_ref (match_operand 0 "" ""))
12804                       (pc)))]
12805   ""
12806   "ix86_expand_branch (GEU, operands[0]); DONE;")
12807
12808 (define_expand "ble"
12809   [(set (pc)
12810         (if_then_else (match_dup 1)
12811                       (label_ref (match_operand 0 "" ""))
12812                       (pc)))]
12813   ""
12814   "ix86_expand_branch (LE, operands[0]); DONE;")
12815
12816 (define_expand "bleu"
12817   [(set (pc)
12818         (if_then_else (match_dup 1)
12819                       (label_ref (match_operand 0 "" ""))
12820                       (pc)))]
12821   ""
12822   "ix86_expand_branch (LEU, operands[0]); DONE;")
12823
12824 (define_expand "bunordered"
12825   [(set (pc)
12826         (if_then_else (match_dup 1)
12827                       (label_ref (match_operand 0 "" ""))
12828                       (pc)))]
12829   "TARGET_80387 || TARGET_SSE"
12830   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12831
12832 (define_expand "bordered"
12833   [(set (pc)
12834         (if_then_else (match_dup 1)
12835                       (label_ref (match_operand 0 "" ""))
12836                       (pc)))]
12837   "TARGET_80387 || TARGET_SSE"
12838   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12839
12840 (define_expand "buneq"
12841   [(set (pc)
12842         (if_then_else (match_dup 1)
12843                       (label_ref (match_operand 0 "" ""))
12844                       (pc)))]
12845   "TARGET_80387 || TARGET_SSE"
12846   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12847
12848 (define_expand "bunge"
12849   [(set (pc)
12850         (if_then_else (match_dup 1)
12851                       (label_ref (match_operand 0 "" ""))
12852                       (pc)))]
12853   "TARGET_80387 || TARGET_SSE"
12854   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12855
12856 (define_expand "bungt"
12857   [(set (pc)
12858         (if_then_else (match_dup 1)
12859                       (label_ref (match_operand 0 "" ""))
12860                       (pc)))]
12861   "TARGET_80387 || TARGET_SSE"
12862   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12863
12864 (define_expand "bunle"
12865   [(set (pc)
12866         (if_then_else (match_dup 1)
12867                       (label_ref (match_operand 0 "" ""))
12868                       (pc)))]
12869   "TARGET_80387 || TARGET_SSE"
12870   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12871
12872 (define_expand "bunlt"
12873   [(set (pc)
12874         (if_then_else (match_dup 1)
12875                       (label_ref (match_operand 0 "" ""))
12876                       (pc)))]
12877   "TARGET_80387 || TARGET_SSE"
12878   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12879
12880 (define_expand "bltgt"
12881   [(set (pc)
12882         (if_then_else (match_dup 1)
12883                       (label_ref (match_operand 0 "" ""))
12884                       (pc)))]
12885   "TARGET_80387 || TARGET_SSE"
12886   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12887
12888 (define_insn "*jcc_1"
12889   [(set (pc)
12890         (if_then_else (match_operator 1 "ix86_comparison_operator"
12891                                       [(reg 17) (const_int 0)])
12892                       (label_ref (match_operand 0 "" ""))
12893                       (pc)))]
12894   ""
12895   "%+j%C1\t%l0"
12896   [(set_attr "type" "ibr")
12897    (set_attr "modrm" "0")
12898    (set (attr "length")
12899            (if_then_else (and (ge (minus (match_dup 0) (pc))
12900                                   (const_int -126))
12901                               (lt (minus (match_dup 0) (pc))
12902                                   (const_int 128)))
12903              (const_int 2)
12904              (const_int 6)))])
12905
12906 (define_insn "*jcc_2"
12907   [(set (pc)
12908         (if_then_else (match_operator 1 "ix86_comparison_operator"
12909                                       [(reg 17) (const_int 0)])
12910                       (pc)
12911                       (label_ref (match_operand 0 "" ""))))]
12912   ""
12913   "%+j%c1\t%l0"
12914   [(set_attr "type" "ibr")
12915    (set_attr "modrm" "0")
12916    (set (attr "length")
12917            (if_then_else (and (ge (minus (match_dup 0) (pc))
12918                                   (const_int -126))
12919                               (lt (minus (match_dup 0) (pc))
12920                                   (const_int 128)))
12921              (const_int 2)
12922              (const_int 6)))])
12923
12924 ;; In general it is not safe to assume too much about CCmode registers,
12925 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12926 ;; conditions this is safe on x86, so help combine not create
12927 ;;
12928 ;;      seta    %al
12929 ;;      testb   %al, %al
12930 ;;      je      Lfoo
12931
12932 (define_split 
12933   [(set (pc)
12934         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12935                                       [(reg 17) (const_int 0)])
12936                           (const_int 0))
12937                       (label_ref (match_operand 1 "" ""))
12938                       (pc)))]
12939   ""
12940   [(set (pc)
12941         (if_then_else (match_dup 0)
12942                       (label_ref (match_dup 1))
12943                       (pc)))]
12944 {
12945   PUT_MODE (operands[0], VOIDmode);
12946 })
12947   
12948 (define_split 
12949   [(set (pc)
12950         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12951                                       [(reg 17) (const_int 0)])
12952                           (const_int 0))
12953                       (label_ref (match_operand 1 "" ""))
12954                       (pc)))]
12955   ""
12956   [(set (pc)
12957         (if_then_else (match_dup 0)
12958                       (label_ref (match_dup 1))
12959                       (pc)))]
12960 {
12961   rtx new_op0 = copy_rtx (operands[0]);
12962   operands[0] = new_op0;
12963   PUT_MODE (new_op0, VOIDmode);
12964   PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12965                                         GET_MODE (XEXP (new_op0, 0))));
12966
12967   /* Make sure that (a) the CCmode we have for the flags is strong
12968      enough for the reversed compare or (b) we have a valid FP compare.  */
12969   if (! ix86_comparison_operator (new_op0, VOIDmode))
12970     FAIL;
12971 })
12972
12973 ;; Define combination compare-and-branch fp compare instructions to use
12974 ;; during early optimization.  Splitting the operation apart early makes
12975 ;; for bad code when we want to reverse the operation.
12976
12977 (define_insn "*fp_jcc_1"
12978   [(set (pc)
12979         (if_then_else (match_operator 0 "comparison_operator"
12980                         [(match_operand 1 "register_operand" "f")
12981                          (match_operand 2 "register_operand" "f")])
12982           (label_ref (match_operand 3 "" ""))
12983           (pc)))
12984    (clobber (reg:CCFP 18))
12985    (clobber (reg:CCFP 17))]
12986   "TARGET_CMOVE && TARGET_80387
12987    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12988    && FLOAT_MODE_P (GET_MODE (operands[1]))
12989    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12990    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12991   "#")
12992
12993 (define_insn "*fp_jcc_1_sse"
12994   [(set (pc)
12995         (if_then_else (match_operator 0 "comparison_operator"
12996                         [(match_operand 1 "register_operand" "f#x,x#f")
12997                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12998           (label_ref (match_operand 3 "" ""))
12999           (pc)))
13000    (clobber (reg:CCFP 18))
13001    (clobber (reg:CCFP 17))]
13002   "TARGET_80387
13003    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13004    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13006   "#")
13007
13008 (define_insn "*fp_jcc_1_sse_only"
13009   [(set (pc)
13010         (if_then_else (match_operator 0 "comparison_operator"
13011                         [(match_operand 1 "register_operand" "x")
13012                          (match_operand 2 "nonimmediate_operand" "xm")])
13013           (label_ref (match_operand 3 "" ""))
13014           (pc)))
13015    (clobber (reg:CCFP 18))
13016    (clobber (reg:CCFP 17))]
13017   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13018    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13019    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13020   "#")
13021
13022 (define_insn "*fp_jcc_2"
13023   [(set (pc)
13024         (if_then_else (match_operator 0 "comparison_operator"
13025                         [(match_operand 1 "register_operand" "f")
13026                          (match_operand 2 "register_operand" "f")])
13027           (pc)
13028           (label_ref (match_operand 3 "" ""))))
13029    (clobber (reg:CCFP 18))
13030    (clobber (reg:CCFP 17))]
13031   "TARGET_CMOVE && TARGET_80387
13032    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13033    && FLOAT_MODE_P (GET_MODE (operands[1]))
13034    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13035    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13036   "#")
13037
13038 (define_insn "*fp_jcc_2_sse"
13039   [(set (pc)
13040         (if_then_else (match_operator 0 "comparison_operator"
13041                         [(match_operand 1 "register_operand" "f#x,x#f")
13042                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13043           (pc)
13044           (label_ref (match_operand 3 "" ""))))
13045    (clobber (reg:CCFP 18))
13046    (clobber (reg:CCFP 17))]
13047   "TARGET_80387
13048    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13049    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13050    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13051   "#")
13052
13053 (define_insn "*fp_jcc_2_sse_only"
13054   [(set (pc)
13055         (if_then_else (match_operator 0 "comparison_operator"
13056                         [(match_operand 1 "register_operand" "x")
13057                          (match_operand 2 "nonimmediate_operand" "xm")])
13058           (pc)
13059           (label_ref (match_operand 3 "" ""))))
13060    (clobber (reg:CCFP 18))
13061    (clobber (reg:CCFP 17))]
13062   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13063    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13064    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13065   "#")
13066
13067 (define_insn "*fp_jcc_3"
13068   [(set (pc)
13069         (if_then_else (match_operator 0 "comparison_operator"
13070                         [(match_operand 1 "register_operand" "f")
13071                          (match_operand 2 "nonimmediate_operand" "fm")])
13072           (label_ref (match_operand 3 "" ""))
13073           (pc)))
13074    (clobber (reg:CCFP 18))
13075    (clobber (reg:CCFP 17))
13076    (clobber (match_scratch:HI 4 "=a"))]
13077   "TARGET_80387
13078    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13079    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13080    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13081    && SELECT_CC_MODE (GET_CODE (operands[0]),
13082                       operands[1], operands[2]) == CCFPmode
13083    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13084   "#")
13085
13086 (define_insn "*fp_jcc_4"
13087   [(set (pc)
13088         (if_then_else (match_operator 0 "comparison_operator"
13089                         [(match_operand 1 "register_operand" "f")
13090                          (match_operand 2 "nonimmediate_operand" "fm")])
13091           (pc)
13092           (label_ref (match_operand 3 "" ""))))
13093    (clobber (reg:CCFP 18))
13094    (clobber (reg:CCFP 17))
13095    (clobber (match_scratch:HI 4 "=a"))]
13096   "TARGET_80387
13097    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13098    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13099    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13100    && SELECT_CC_MODE (GET_CODE (operands[0]),
13101                       operands[1], operands[2]) == CCFPmode
13102    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13103   "#")
13104
13105 (define_insn "*fp_jcc_5"
13106   [(set (pc)
13107         (if_then_else (match_operator 0 "comparison_operator"
13108                         [(match_operand 1 "register_operand" "f")
13109                          (match_operand 2 "register_operand" "f")])
13110           (label_ref (match_operand 3 "" ""))
13111           (pc)))
13112    (clobber (reg:CCFP 18))
13113    (clobber (reg:CCFP 17))
13114    (clobber (match_scratch:HI 4 "=a"))]
13115   "TARGET_80387
13116    && FLOAT_MODE_P (GET_MODE (operands[1]))
13117    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13118    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13119   "#")
13120
13121 (define_insn "*fp_jcc_6"
13122   [(set (pc)
13123         (if_then_else (match_operator 0 "comparison_operator"
13124                         [(match_operand 1 "register_operand" "f")
13125                          (match_operand 2 "register_operand" "f")])
13126           (pc)
13127           (label_ref (match_operand 3 "" ""))))
13128    (clobber (reg:CCFP 18))
13129    (clobber (reg:CCFP 17))
13130    (clobber (match_scratch:HI 4 "=a"))]
13131   "TARGET_80387
13132    && FLOAT_MODE_P (GET_MODE (operands[1]))
13133    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13134    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13135   "#")
13136
13137 (define_split
13138   [(set (pc)
13139         (if_then_else (match_operator 0 "comparison_operator"
13140                         [(match_operand 1 "register_operand" "")
13141                          (match_operand 2 "nonimmediate_operand" "")])
13142           (match_operand 3 "" "")
13143           (match_operand 4 "" "")))
13144    (clobber (reg:CCFP 18))
13145    (clobber (reg:CCFP 17))]
13146   "reload_completed"
13147   [(const_int 0)]
13148 {
13149   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13150                         operands[3], operands[4], NULL_RTX);
13151   DONE;
13152 })
13153
13154 (define_split
13155   [(set (pc)
13156         (if_then_else (match_operator 0 "comparison_operator"
13157                         [(match_operand 1 "register_operand" "")
13158                          (match_operand 2 "nonimmediate_operand" "")])
13159           (match_operand 3 "" "")
13160           (match_operand 4 "" "")))
13161    (clobber (reg:CCFP 18))
13162    (clobber (reg:CCFP 17))
13163    (clobber (match_scratch:HI 5 "=a"))]
13164   "reload_completed"
13165   [(set (pc)
13166         (if_then_else (match_dup 6)
13167           (match_dup 3)
13168           (match_dup 4)))]
13169 {
13170   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13171                         operands[3], operands[4], operands[5]);
13172   DONE;
13173 })
13174 \f
13175 ;; Unconditional and other jump instructions
13176
13177 (define_insn "jump"
13178   [(set (pc)
13179         (label_ref (match_operand 0 "" "")))]
13180   ""
13181   "jmp\t%l0"
13182   [(set_attr "type" "ibr")
13183    (set (attr "length")
13184            (if_then_else (and (ge (minus (match_dup 0) (pc))
13185                                   (const_int -126))
13186                               (lt (minus (match_dup 0) (pc))
13187                                   (const_int 128)))
13188              (const_int 2)
13189              (const_int 5)))
13190    (set_attr "modrm" "0")])
13191
13192 (define_expand "indirect_jump"
13193   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13194   ""
13195   "")
13196
13197 (define_insn "*indirect_jump"
13198   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13199   "!TARGET_64BIT"
13200   "jmp\t%A0"
13201   [(set_attr "type" "ibr")
13202    (set_attr "length_immediate" "0")])
13203
13204 (define_insn "*indirect_jump_rtx64"
13205   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13206   "TARGET_64BIT"
13207   "jmp\t%A0"
13208   [(set_attr "type" "ibr")
13209    (set_attr "length_immediate" "0")])
13210
13211 (define_expand "tablejump"
13212   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13213               (use (label_ref (match_operand 1 "" "")))])]
13214   ""
13215 {
13216   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13217      relative.  Convert the relative address to an absolute address.  */
13218   if (flag_pic)
13219     {
13220       rtx op0, op1;
13221       enum rtx_code code;
13222
13223       if (TARGET_64BIT)
13224         {
13225           code = PLUS;
13226           op0 = operands[0];
13227           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13228         }
13229       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13230         {
13231           code = PLUS;
13232           op0 = operands[0];
13233           op1 = pic_offset_table_rtx;
13234         }
13235       else
13236         {
13237           code = MINUS;
13238           op0 = pic_offset_table_rtx;
13239           op1 = operands[0];
13240         }
13241
13242       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13243                                          OPTAB_DIRECT);
13244     }
13245 })
13246
13247 (define_insn "*tablejump_1"
13248   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13249    (use (label_ref (match_operand 1 "" "")))]
13250   "!TARGET_64BIT"
13251   "jmp\t%A0"
13252   [(set_attr "type" "ibr")
13253    (set_attr "length_immediate" "0")])
13254
13255 (define_insn "*tablejump_1_rtx64"
13256   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13257    (use (label_ref (match_operand 1 "" "")))]
13258   "TARGET_64BIT"
13259   "jmp\t%A0"
13260   [(set_attr "type" "ibr")
13261    (set_attr "length_immediate" "0")])
13262 \f
13263 ;; Loop instruction
13264 ;;
13265 ;; This is all complicated by the fact that since this is a jump insn
13266 ;; we must handle our own reloads.
13267
13268 (define_expand "doloop_end"
13269   [(use (match_operand 0 "" ""))        ; loop pseudo
13270    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13271    (use (match_operand 2 "" ""))        ; max iterations
13272    (use (match_operand 3 "" ""))        ; loop level 
13273    (use (match_operand 4 "" ""))]       ; label
13274   "!TARGET_64BIT && TARGET_USE_LOOP"
13275   "                                 
13276 {
13277   /* Only use cloop on innermost loops.  */
13278   if (INTVAL (operands[3]) > 1)
13279     FAIL;
13280   if (GET_MODE (operands[0]) != SImode)
13281     FAIL;
13282   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13283                                            operands[0]));
13284   DONE;
13285 }")
13286
13287 (define_insn "doloop_end_internal"
13288   [(set (pc)
13289         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13290                           (const_int 1))
13291                       (label_ref (match_operand 0 "" ""))
13292                       (pc)))
13293    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13294         (plus:SI (match_dup 1)
13295                  (const_int -1)))
13296    (clobber (match_scratch:SI 3 "=X,X,r"))
13297    (clobber (reg:CC 17))]
13298   "!TARGET_64BIT && TARGET_USE_LOOP"
13299 {
13300   if (which_alternative != 0)
13301     return "#";
13302   if (get_attr_length (insn) == 2)
13303     return "%+loop\t%l0";
13304   else
13305     return "dec{l}\t%1\;%+jne\t%l0";
13306 }
13307   [(set_attr "ppro_uops" "many")
13308    (set (attr "length")
13309         (if_then_else (and (eq_attr "alternative" "0")
13310                            (and (ge (minus (match_dup 0) (pc))
13311                                     (const_int -126))
13312                                 (lt (minus (match_dup 0) (pc))
13313                                     (const_int 128))))
13314                       (const_int 2)
13315                       (const_int 16)))
13316    ;; We don't know the type before shorten branches.  Optimistically expect
13317    ;; the loop instruction to match.
13318    (set (attr "type") (const_string "ibr"))])
13319
13320 (define_split
13321   [(set (pc)
13322         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13323                           (const_int 1))
13324                       (match_operand 0 "" "")
13325                       (pc)))
13326    (set (match_dup 1)
13327         (plus:SI (match_dup 1)
13328                  (const_int -1)))
13329    (clobber (match_scratch:SI 2 ""))
13330    (clobber (reg:CC 17))]
13331   "!TARGET_64BIT && TARGET_USE_LOOP
13332    && reload_completed
13333    && REGNO (operands[1]) != 2"
13334   [(parallel [(set (reg:CCZ 17)
13335                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13336                                  (const_int 0)))
13337               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13338    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13339                            (match_dup 0)
13340                            (pc)))]
13341   "")
13342   
13343 (define_split
13344   [(set (pc)
13345         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13346                           (const_int 1))
13347                       (match_operand 0 "" "")
13348                       (pc)))
13349    (set (match_operand:SI 2 "nonimmediate_operand" "")
13350         (plus:SI (match_dup 1)
13351                  (const_int -1)))
13352    (clobber (match_scratch:SI 3 ""))
13353    (clobber (reg:CC 17))]
13354   "!TARGET_64BIT && TARGET_USE_LOOP
13355    && reload_completed
13356    && (! REG_P (operands[2])
13357        || ! rtx_equal_p (operands[1], operands[2]))"
13358   [(set (match_dup 3) (match_dup 1))
13359    (parallel [(set (reg:CCZ 17)
13360                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13361                                 (const_int 0)))
13362               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13363    (set (match_dup 2) (match_dup 3))
13364    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13365                            (match_dup 0)
13366                            (pc)))]
13367   "")
13368
13369 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13370
13371 (define_peephole2
13372   [(set (reg 17) (match_operand 0 "" ""))
13373    (set (match_operand:QI 1 "register_operand" "")
13374         (match_operator:QI 2 "ix86_comparison_operator"
13375           [(reg 17) (const_int 0)]))
13376    (set (match_operand 3 "q_regs_operand" "")
13377         (zero_extend (match_dup 1)))]
13378   "(peep2_reg_dead_p (3, operands[1])
13379     || operands_match_p (operands[1], operands[3]))
13380    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13381   [(set (match_dup 4) (match_dup 0))
13382    (set (strict_low_part (match_dup 5))
13383         (match_dup 2))]
13384 {
13385   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13386   operands[5] = gen_lowpart (QImode, operands[3]);
13387   ix86_expand_clear (operands[3]);
13388 })
13389
13390 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13391
13392 (define_peephole2
13393   [(set (reg 17) (match_operand 0 "" ""))
13394    (set (match_operand:QI 1 "register_operand" "")
13395         (match_operator:QI 2 "ix86_comparison_operator"
13396           [(reg 17) (const_int 0)]))
13397    (parallel [(set (match_operand 3 "q_regs_operand" "")
13398                    (zero_extend (match_dup 1)))
13399               (clobber (reg:CC 17))])]
13400   "(peep2_reg_dead_p (3, operands[1])
13401     || operands_match_p (operands[1], operands[3]))
13402    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13403   [(set (match_dup 4) (match_dup 0))
13404    (set (strict_low_part (match_dup 5))
13405         (match_dup 2))]
13406 {
13407   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13408   operands[5] = gen_lowpart (QImode, operands[3]);
13409   ix86_expand_clear (operands[3]);
13410 })
13411 \f
13412 ;; Call instructions.
13413
13414 ;; The predicates normally associated with named expanders are not properly
13415 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13416 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13417
13418 ;; Call subroutine returning no value.
13419
13420 (define_expand "call_pop"
13421   [(parallel [(call (match_operand:QI 0 "" "")
13422                     (match_operand:SI 1 "" ""))
13423               (set (reg:SI 7)
13424                    (plus:SI (reg:SI 7)
13425                             (match_operand:SI 3 "" "")))])]
13426   "!TARGET_64BIT"
13427 {
13428   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13429   DONE;
13430 })
13431
13432 (define_insn "*call_pop_0"
13433   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13434          (match_operand:SI 1 "" ""))
13435    (set (reg:SI 7) (plus:SI (reg:SI 7)
13436                             (match_operand:SI 2 "immediate_operand" "")))]
13437   "!TARGET_64BIT"
13438 {
13439   if (SIBLING_CALL_P (insn))
13440     return "jmp\t%P0";
13441   else
13442     return "call\t%P0";
13443 }
13444   [(set_attr "type" "call")])
13445   
13446 (define_insn "*call_pop_1"
13447   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13448          (match_operand:SI 1 "" ""))
13449    (set (reg:SI 7) (plus:SI (reg:SI 7)
13450                             (match_operand:SI 2 "immediate_operand" "i")))]
13451   "!TARGET_64BIT"
13452 {
13453   if (constant_call_address_operand (operands[0], Pmode))
13454     {
13455       if (SIBLING_CALL_P (insn))
13456         return "jmp\t%P0";
13457       else
13458         return "call\t%P0";
13459     }
13460   if (SIBLING_CALL_P (insn))
13461     return "jmp\t%A0";
13462   else
13463     return "call\t%A0";
13464 }
13465   [(set_attr "type" "call")])
13466
13467 (define_expand "call"
13468   [(call (match_operand:QI 0 "" "")
13469          (match_operand 1 "" ""))
13470    (use (match_operand 2 "" ""))]
13471   ""
13472 {
13473   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13474   DONE;
13475 })
13476
13477 (define_expand "sibcall"
13478   [(call (match_operand:QI 0 "" "")
13479          (match_operand 1 "" ""))
13480    (use (match_operand 2 "" ""))]
13481   ""
13482 {
13483   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13484   DONE;
13485 })
13486
13487 (define_insn "*call_0"
13488   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13489          (match_operand 1 "" ""))]
13490   ""
13491 {
13492   if (SIBLING_CALL_P (insn))
13493     return "jmp\t%P0";
13494   else
13495     return "call\t%P0";
13496 }
13497   [(set_attr "type" "call")])
13498
13499 (define_insn "*call_1"
13500   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13501          (match_operand 1 "" ""))]
13502   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13503 {
13504   if (constant_call_address_operand (operands[0], QImode))
13505     return "call\t%P0";
13506   return "call\t%A0";
13507 }
13508   [(set_attr "type" "call")])
13509
13510 (define_insn "*sibcall_1"
13511   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13512          (match_operand 1 "" ""))]
13513   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13514 {
13515   if (constant_call_address_operand (operands[0], QImode))
13516     return "jmp\t%P0";
13517   return "jmp\t%A0";
13518 }
13519   [(set_attr "type" "call")])
13520
13521 (define_insn "*call_1_rex64"
13522   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13523          (match_operand 1 "" ""))]
13524   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13525 {
13526   if (constant_call_address_operand (operands[0], QImode))
13527     return "call\t%P0";
13528   return "call\t%A0";
13529 }
13530   [(set_attr "type" "call")])
13531
13532 (define_insn "*sibcall_1_rex64"
13533   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13534          (match_operand 1 "" ""))]
13535   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13536   "jmp\t%P0"
13537   [(set_attr "type" "call")])
13538
13539 (define_insn "*sibcall_1_rex64_v"
13540   [(call (mem:QI (reg:DI 40))
13541          (match_operand 0 "" ""))]
13542   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13543   "jmp\t*%%r11"
13544   [(set_attr "type" "call")])
13545
13546
13547 ;; Call subroutine, returning value in operand 0
13548
13549 (define_expand "call_value_pop"
13550   [(parallel [(set (match_operand 0 "" "")
13551                    (call (match_operand:QI 1 "" "")
13552                          (match_operand:SI 2 "" "")))
13553               (set (reg:SI 7)
13554                    (plus:SI (reg:SI 7)
13555                             (match_operand:SI 4 "" "")))])]
13556   "!TARGET_64BIT"
13557 {
13558   ix86_expand_call (operands[0], operands[1], operands[2],
13559                     operands[3], operands[4], 0);
13560   DONE;
13561 })
13562
13563 (define_expand "call_value"
13564   [(set (match_operand 0 "" "")
13565         (call (match_operand:QI 1 "" "")
13566               (match_operand:SI 2 "" "")))
13567    (use (match_operand:SI 3 "" ""))]
13568   ;; Operand 2 not used on the i386.
13569   ""
13570 {
13571   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13572   DONE;
13573 })
13574
13575 (define_expand "sibcall_value"
13576   [(set (match_operand 0 "" "")
13577         (call (match_operand:QI 1 "" "")
13578               (match_operand:SI 2 "" "")))
13579    (use (match_operand:SI 3 "" ""))]
13580   ;; Operand 2 not used on the i386.
13581   ""
13582 {
13583   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13584   DONE;
13585 })
13586
13587 ;; Call subroutine returning any type.
13588
13589 (define_expand "untyped_call"
13590   [(parallel [(call (match_operand 0 "" "")
13591                     (const_int 0))
13592               (match_operand 1 "" "")
13593               (match_operand 2 "" "")])]
13594   ""
13595 {
13596   int i;
13597
13598   /* In order to give reg-stack an easier job in validating two
13599      coprocessor registers as containing a possible return value,
13600      simply pretend the untyped call returns a complex long double
13601      value.  */
13602
13603   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13604                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13605                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13606                     NULL, 0);
13607
13608   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13609     {
13610       rtx set = XVECEXP (operands[2], 0, i);
13611       emit_move_insn (SET_DEST (set), SET_SRC (set));
13612     }
13613
13614   /* The optimizer does not know that the call sets the function value
13615      registers we stored in the result block.  We avoid problems by
13616      claiming that all hard registers are used and clobbered at this
13617      point.  */
13618   emit_insn (gen_blockage (const0_rtx));
13619
13620   DONE;
13621 })
13622 \f
13623 ;; Prologue and epilogue instructions
13624
13625 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13626 ;; all of memory.  This blocks insns from being moved across this point.
13627
13628 (define_insn "blockage"
13629   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13630   ""
13631   ""
13632   [(set_attr "length" "0")])
13633
13634 ;; Insn emitted into the body of a function to return from a function.
13635 ;; This is only done if the function's epilogue is known to be simple.
13636 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13637
13638 (define_expand "return"
13639   [(return)]
13640   "ix86_can_use_return_insn_p ()"
13641 {
13642   if (current_function_pops_args)
13643     {
13644       rtx popc = GEN_INT (current_function_pops_args);
13645       emit_jump_insn (gen_return_pop_internal (popc));
13646       DONE;
13647     }
13648 })
13649
13650 (define_insn "return_internal"
13651   [(return)]
13652   "reload_completed"
13653   "ret"
13654   [(set_attr "length" "1")
13655    (set_attr "length_immediate" "0")
13656    (set_attr "modrm" "0")])
13657
13658 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13659 ;; instruction Athlon and K8 have.
13660
13661 (define_insn "return_internal_long"
13662   [(return)
13663    (unspec [(const_int 0)] UNSPEC_REP)]
13664   "reload_completed"
13665   "rep {;} ret"
13666   [(set_attr "length" "1")
13667    (set_attr "length_immediate" "0")
13668    (set_attr "prefix_rep" "1")
13669    (set_attr "modrm" "0")])
13670
13671 (define_insn "return_pop_internal"
13672   [(return)
13673    (use (match_operand:SI 0 "const_int_operand" ""))]
13674   "reload_completed"
13675   "ret\t%0"
13676   [(set_attr "length" "3")
13677    (set_attr "length_immediate" "2")
13678    (set_attr "modrm" "0")])
13679
13680 (define_insn "return_indirect_internal"
13681   [(return)
13682    (use (match_operand:SI 0 "register_operand" "r"))]
13683   "reload_completed"
13684   "jmp\t%A0"
13685   [(set_attr "type" "ibr")
13686    (set_attr "length_immediate" "0")])
13687
13688 (define_insn "nop"
13689   [(const_int 0)]
13690   ""
13691   "nop"
13692   [(set_attr "length" "1")
13693    (set_attr "length_immediate" "0")
13694    (set_attr "modrm" "0")
13695    (set_attr "ppro_uops" "one")])
13696
13697 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13698 ;; branch prediction penalty for the third jump in a 16-byte
13699 ;; block on K8.
13700
13701 (define_insn "align"
13702   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13703   ""
13704 {
13705 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13706   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13707 #else
13708   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13709      The align insn is used to avoid 3 jump instructions in the row to improve
13710      branch prediction and the benefits hardly outweight the cost of extra 8
13711      nops on the average inserted by full alignment pseudo operation.  */
13712 #endif
13713   return "";
13714 }
13715   [(set_attr "length" "16")])
13716
13717 (define_expand "prologue"
13718   [(const_int 1)]
13719   ""
13720   "ix86_expand_prologue (); DONE;")
13721
13722 (define_insn "set_got"
13723   [(set (match_operand:SI 0 "register_operand" "=r")
13724         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13725    (clobber (reg:CC 17))]
13726   "!TARGET_64BIT"
13727   { return output_set_got (operands[0]); }
13728   [(set_attr "type" "multi")
13729    (set_attr "length" "12")])
13730
13731 (define_expand "epilogue"
13732   [(const_int 1)]
13733   ""
13734   "ix86_expand_epilogue (1); DONE;")
13735
13736 (define_expand "sibcall_epilogue"
13737   [(const_int 1)]
13738   ""
13739   "ix86_expand_epilogue (0); DONE;")
13740
13741 (define_expand "eh_return"
13742   [(use (match_operand 0 "register_operand" ""))]
13743   ""
13744 {
13745   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13746
13747   /* Tricky bit: we write the address of the handler to which we will
13748      be returning into someone else's stack frame, one word below the
13749      stack address we wish to restore.  */
13750   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13751   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13752   tmp = gen_rtx_MEM (Pmode, tmp);
13753   emit_move_insn (tmp, ra);
13754
13755   if (Pmode == SImode)
13756     emit_insn (gen_eh_return_si (sa));
13757   else
13758     emit_insn (gen_eh_return_di (sa));
13759   emit_barrier ();
13760   DONE;
13761 })
13762
13763 (define_insn_and_split "eh_return_si"
13764   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13765                     UNSPECV_EH_RETURN)]
13766   "!TARGET_64BIT"
13767   "#"
13768   "reload_completed"
13769   [(const_int 1)]
13770   "ix86_expand_epilogue (2); DONE;")
13771
13772 (define_insn_and_split "eh_return_di"
13773   [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13774                     UNSPECV_EH_RETURN)]
13775   "TARGET_64BIT"
13776   "#"
13777   "reload_completed"
13778   [(const_int 1)]
13779   "ix86_expand_epilogue (2); DONE;")
13780
13781 (define_insn "leave"
13782   [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13783    (set (reg:SI 6) (mem:SI (reg:SI 6)))
13784    (clobber (mem:BLK (scratch)))]
13785   "!TARGET_64BIT"
13786   "leave"
13787   [(set_attr "type" "leave")])
13788
13789 (define_insn "leave_rex64"
13790   [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13791    (set (reg:DI 6) (mem:DI (reg:DI 6)))
13792    (clobber (mem:BLK (scratch)))]
13793   "TARGET_64BIT"
13794   "leave"
13795   [(set_attr "type" "leave")])
13796 \f
13797 (define_expand "ffssi2"
13798   [(parallel
13799      [(set (match_operand:SI 0 "register_operand" "") 
13800            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13801       (clobber (match_scratch:SI 2 ""))
13802       (clobber (reg:CC 17))])]
13803   ""
13804   "")
13805
13806 (define_insn_and_split "*ffs_cmove"
13807   [(set (match_operand:SI 0 "register_operand" "=r") 
13808         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13809    (clobber (match_scratch:SI 2 "=&r"))
13810    (clobber (reg:CC 17))]
13811   "TARGET_CMOVE"
13812   "#"
13813   "&& reload_completed"
13814   [(set (match_dup 2) (const_int -1))
13815    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13816               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13817    (set (match_dup 0) (if_then_else:SI
13818                         (eq (reg:CCZ 17) (const_int 0))
13819                         (match_dup 2)
13820                         (match_dup 0)))
13821    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13822               (clobber (reg:CC 17))])]
13823   "")
13824
13825 (define_insn_and_split "*ffs_no_cmove"
13826   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13827         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13828    (clobber (match_scratch:SI 2 "=&q"))
13829    (clobber (reg:CC 17))]
13830   ""
13831   "#"
13832   "reload_completed"
13833   [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13834               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13835    (set (strict_low_part (match_dup 3))
13836         (eq:QI (reg:CCZ 17) (const_int 0)))
13837    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13838               (clobber (reg:CC 17))])
13839    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13840               (clobber (reg:CC 17))])
13841    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13842               (clobber (reg:CC 17))])]
13843 {
13844   operands[3] = gen_lowpart (QImode, operands[2]);
13845   ix86_expand_clear (operands[2]);
13846 })
13847
13848 (define_insn "*ffssi_1"
13849   [(set (reg:CCZ 17)
13850         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13851                      (const_int 0)))
13852    (set (match_operand:SI 0 "register_operand" "=r")
13853         (ctz:SI (match_dup 1)))]
13854   ""
13855   "bsf{l}\t{%1, %0|%0, %1}"
13856   [(set_attr "prefix_0f" "1")
13857    (set_attr "ppro_uops" "few")])
13858
13859 (define_insn "ctzsi2"
13860   [(set (match_operand:SI 0 "register_operand" "=r")
13861         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13862    (clobber (reg:CC 17))]
13863   ""
13864   "bsf{l}\t{%1, %0|%0, %1}"
13865   [(set_attr "prefix_0f" "1")
13866    (set_attr "ppro_uops" "few")])
13867
13868 (define_expand "clzsi2"
13869   [(parallel
13870      [(set (match_operand:SI 0 "register_operand" "")
13871            (minus:SI (const_int 31)
13872                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13873       (clobber (reg:CC 17))])
13874    (parallel
13875      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13876       (clobber (reg:CC 17))])]
13877   ""
13878   "")
13879
13880 (define_insn "*bsr"
13881   [(set (match_operand:SI 0 "register_operand" "=r")
13882         (minus:SI (const_int 31)
13883                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13884    (clobber (reg:CC 17))]
13885   ""
13886   "bsr{l}\t{%1, %0|%0, %1}"
13887   [(set_attr "prefix_0f" "1")
13888    (set_attr "ppro_uops" "few")])
13889 \f
13890 ;; Thread-local storage patterns for ELF.
13891 ;;
13892 ;; Note that these code sequences must appear exactly as shown
13893 ;; in order to allow linker relaxation.
13894
13895 (define_insn "*tls_global_dynamic_32_gnu"
13896   [(set (match_operand:SI 0 "register_operand" "=a")
13897         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13898                     (match_operand:SI 2 "tls_symbolic_operand" "")
13899                     (match_operand:SI 3 "call_insn_operand" "")]
13900                     UNSPEC_TLS_GD))
13901    (clobber (match_scratch:SI 4 "=d"))
13902    (clobber (match_scratch:SI 5 "=c"))
13903    (clobber (reg:CC 17))]
13904   "!TARGET_64BIT && TARGET_GNU_TLS"
13905   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13906   [(set_attr "type" "multi")
13907    (set_attr "length" "12")])
13908
13909 (define_insn "*tls_global_dynamic_32_sun"
13910   [(set (match_operand:SI 0 "register_operand" "=a")
13911         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13912                     (match_operand:SI 2 "tls_symbolic_operand" "")
13913                     (match_operand:SI 3 "call_insn_operand" "")]
13914                     UNSPEC_TLS_GD))
13915    (clobber (match_scratch:SI 4 "=d"))
13916    (clobber (match_scratch:SI 5 "=c"))
13917    (clobber (reg:CC 17))]
13918   "!TARGET_64BIT && TARGET_SUN_TLS"
13919   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13920         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13921   [(set_attr "type" "multi")
13922    (set_attr "length" "14")])
13923
13924 (define_expand "tls_global_dynamic_32"
13925   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13926                    (unspec:SI
13927                     [(match_dup 2)
13928                      (match_operand:SI 1 "tls_symbolic_operand" "")
13929                      (match_dup 3)]
13930                     UNSPEC_TLS_GD))
13931               (clobber (match_scratch:SI 4 ""))
13932               (clobber (match_scratch:SI 5 ""))
13933               (clobber (reg:CC 17))])]
13934   ""
13935 {
13936   if (flag_pic)
13937     operands[2] = pic_offset_table_rtx;
13938   else
13939     {
13940       operands[2] = gen_reg_rtx (Pmode);
13941       emit_insn (gen_set_got (operands[2]));
13942     }
13943   operands[3] = ix86_tls_get_addr ();
13944 })
13945
13946 (define_insn "*tls_global_dynamic_64"
13947   [(set (match_operand:DI 0 "register_operand" "=a")
13948         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13949                       (match_operand:DI 3 "" "")))
13950    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13951               UNSPEC_TLS_GD)]
13952   "TARGET_64BIT"
13953   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13954   [(set_attr "type" "multi")
13955    (set_attr "length" "16")])
13956
13957 (define_expand "tls_global_dynamic_64"
13958   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13959                    (call (mem:QI (match_dup 2)) (const_int 0)))
13960               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13961                          UNSPEC_TLS_GD)])]
13962   ""
13963 {
13964   operands[2] = ix86_tls_get_addr ();
13965 })
13966
13967 (define_insn "*tls_local_dynamic_base_32_gnu"
13968   [(set (match_operand:SI 0 "register_operand" "=a")
13969         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13970                     (match_operand:SI 2 "call_insn_operand" "")]
13971                    UNSPEC_TLS_LD_BASE))
13972    (clobber (match_scratch:SI 3 "=d"))
13973    (clobber (match_scratch:SI 4 "=c"))
13974    (clobber (reg:CC 17))]
13975   "!TARGET_64BIT && TARGET_GNU_TLS"
13976   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13977   [(set_attr "type" "multi")
13978    (set_attr "length" "11")])
13979
13980 (define_insn "*tls_local_dynamic_base_32_sun"
13981   [(set (match_operand:SI 0 "register_operand" "=a")
13982         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13983                     (match_operand:SI 2 "call_insn_operand" "")]
13984                    UNSPEC_TLS_LD_BASE))
13985    (clobber (match_scratch:SI 3 "=d"))
13986    (clobber (match_scratch:SI 4 "=c"))
13987    (clobber (reg:CC 17))]
13988   "!TARGET_64BIT && TARGET_SUN_TLS"
13989   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13990         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13991   [(set_attr "type" "multi")
13992    (set_attr "length" "13")])
13993
13994 (define_expand "tls_local_dynamic_base_32"
13995   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13996                    (unspec:SI [(match_dup 1) (match_dup 2)]
13997                               UNSPEC_TLS_LD_BASE))
13998               (clobber (match_scratch:SI 3 ""))
13999               (clobber (match_scratch:SI 4 ""))
14000               (clobber (reg:CC 17))])]
14001   ""
14002 {
14003   if (flag_pic)
14004     operands[1] = pic_offset_table_rtx;
14005   else
14006     {
14007       operands[1] = gen_reg_rtx (Pmode);
14008       emit_insn (gen_set_got (operands[1]));
14009     }
14010   operands[2] = ix86_tls_get_addr ();
14011 })
14012
14013 (define_insn "*tls_local_dynamic_base_64"
14014   [(set (match_operand:DI 0 "register_operand" "=a")
14015         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14016                       (match_operand:DI 2 "" "")))
14017    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14018   "TARGET_64BIT"
14019   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14020   [(set_attr "type" "multi")
14021    (set_attr "length" "12")])
14022
14023 (define_expand "tls_local_dynamic_base_64"
14024   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14025                    (call (mem:QI (match_dup 1)) (const_int 0)))
14026               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14027   ""
14028 {
14029   operands[1] = ix86_tls_get_addr ();
14030 })
14031
14032 ;; Local dynamic of a single variable is a lose.  Show combine how
14033 ;; to convert that back to global dynamic.
14034
14035 (define_insn_and_split "*tls_local_dynamic_32_once"
14036   [(set (match_operand:SI 0 "register_operand" "=a")
14037         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14038                              (match_operand:SI 2 "call_insn_operand" "")]
14039                             UNSPEC_TLS_LD_BASE)
14040                  (const:SI (unspec:SI
14041                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14042                             UNSPEC_DTPOFF))))
14043    (clobber (match_scratch:SI 4 "=d"))
14044    (clobber (match_scratch:SI 5 "=c"))
14045    (clobber (reg:CC 17))]
14046   ""
14047   "#"
14048   ""
14049   [(parallel [(set (match_dup 0)
14050                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14051                               UNSPEC_TLS_GD))
14052               (clobber (match_dup 4))
14053               (clobber (match_dup 5))
14054               (clobber (reg:CC 17))])]
14055   "")
14056
14057 ;; Load and add the thread base pointer from %gs:0.
14058
14059 (define_insn "*load_tp_si"
14060   [(set (match_operand:SI 0 "register_operand" "=r")
14061         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14062   "!TARGET_64BIT"
14063   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14064   [(set_attr "type" "imov")
14065    (set_attr "modrm" "0")
14066    (set_attr "length" "7")
14067    (set_attr "memory" "load")
14068    (set_attr "imm_disp" "false")])
14069
14070 (define_insn "*add_tp_si"
14071   [(set (match_operand:SI 0 "register_operand" "=r")
14072         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14073                  (match_operand:SI 1 "register_operand" "0")))
14074    (clobber (reg:CC 17))]
14075   "!TARGET_64BIT"
14076   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14077   [(set_attr "type" "alu")
14078    (set_attr "modrm" "0")
14079    (set_attr "length" "7")
14080    (set_attr "memory" "load")
14081    (set_attr "imm_disp" "false")])
14082
14083 (define_insn "*load_tp_di"
14084   [(set (match_operand:DI 0 "register_operand" "=r")
14085         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14086   "TARGET_64BIT"
14087   "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14088   [(set_attr "type" "imov")
14089    (set_attr "modrm" "0")
14090    (set_attr "length" "7")
14091    (set_attr "memory" "load")
14092    (set_attr "imm_disp" "false")])
14093
14094 (define_insn "*add_tp_di"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14097                  (match_operand:DI 1 "register_operand" "0")))
14098    (clobber (reg:CC 17))]
14099   "TARGET_64BIT"
14100   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14101   [(set_attr "type" "alu")
14102    (set_attr "modrm" "0")
14103    (set_attr "length" "7")
14104    (set_attr "memory" "load")
14105    (set_attr "imm_disp" "false")])
14106 \f
14107 ;; These patterns match the binary 387 instructions for addM3, subM3,
14108 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14109 ;; SFmode.  The first is the normal insn, the second the same insn but
14110 ;; with one operand a conversion, and the third the same insn but with
14111 ;; the other operand a conversion.  The conversion may be SFmode or
14112 ;; SImode if the target mode DFmode, but only SImode if the target mode
14113 ;; is SFmode.
14114
14115 ;; Gcc is slightly more smart about handling normal two address instructions
14116 ;; so use special patterns for add and mull.
14117 (define_insn "*fop_sf_comm_nosse"
14118   [(set (match_operand:SF 0 "register_operand" "=f")
14119         (match_operator:SF 3 "binary_fp_operator"
14120                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14121                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14122   "TARGET_80387 && !TARGET_SSE_MATH
14123    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14124    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14125   "* return output_387_binary_op (insn, operands);"
14126   [(set (attr "type") 
14127         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14128            (const_string "fmul")
14129            (const_string "fop")))
14130    (set_attr "mode" "SF")])
14131
14132 (define_insn "*fop_sf_comm"
14133   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14134         (match_operator:SF 3 "binary_fp_operator"
14135                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14136                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14137   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14138    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14140   "* return output_387_binary_op (insn, operands);"
14141   [(set (attr "type") 
14142         (if_then_else (eq_attr "alternative" "1")
14143            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14144               (const_string "ssemul")
14145               (const_string "sseadd"))
14146            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14147               (const_string "fmul")
14148               (const_string "fop"))))
14149    (set_attr "mode" "SF")])
14150
14151 (define_insn "*fop_sf_comm_sse"
14152   [(set (match_operand:SF 0 "register_operand" "=x")
14153         (match_operator:SF 3 "binary_fp_operator"
14154                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14155                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14156   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14157    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14158   "* return output_387_binary_op (insn, operands);"
14159   [(set (attr "type") 
14160         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14161            (const_string "ssemul")
14162            (const_string "sseadd")))
14163    (set_attr "mode" "SF")])
14164
14165 (define_insn "*fop_df_comm_nosse"
14166   [(set (match_operand:DF 0 "register_operand" "=f")
14167         (match_operator:DF 3 "binary_fp_operator"
14168                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14169                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14170   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14171    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14173   "* return output_387_binary_op (insn, operands);"
14174   [(set (attr "type") 
14175         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14176            (const_string "fmul")
14177            (const_string "fop")))
14178    (set_attr "mode" "DF")])
14179
14180 (define_insn "*fop_df_comm"
14181   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14182         (match_operator:DF 3 "binary_fp_operator"
14183                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14184                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14185   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14186    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14187    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14188   "* return output_387_binary_op (insn, operands);"
14189   [(set (attr "type") 
14190         (if_then_else (eq_attr "alternative" "1")
14191            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14192               (const_string "ssemul")
14193               (const_string "sseadd"))
14194            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14195               (const_string "fmul")
14196               (const_string "fop"))))
14197    (set_attr "mode" "DF")])
14198
14199 (define_insn "*fop_df_comm_sse"
14200   [(set (match_operand:DF 0 "register_operand" "=Y")
14201         (match_operator:DF 3 "binary_fp_operator"
14202                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14203                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14204   "TARGET_SSE2 && TARGET_SSE_MATH
14205    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14207   "* return output_387_binary_op (insn, operands);"
14208   [(set (attr "type") 
14209         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14210            (const_string "ssemul")
14211            (const_string "sseadd")))
14212    (set_attr "mode" "DF")])
14213
14214 (define_insn "*fop_xf_comm"
14215   [(set (match_operand:XF 0 "register_operand" "=f")
14216         (match_operator:XF 3 "binary_fp_operator"
14217                         [(match_operand:XF 1 "register_operand" "%0")
14218                          (match_operand:XF 2 "register_operand" "f")]))]
14219   "TARGET_80387
14220    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14221   "* return output_387_binary_op (insn, operands);"
14222   [(set (attr "type") 
14223         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14224            (const_string "fmul")
14225            (const_string "fop")))
14226    (set_attr "mode" "XF")])
14227
14228 (define_insn "*fop_sf_1_nosse"
14229   [(set (match_operand:SF 0 "register_operand" "=f,f")
14230         (match_operator:SF 3 "binary_fp_operator"
14231                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14232                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14233   "TARGET_80387 && !TARGET_SSE_MATH
14234    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14236   "* return output_387_binary_op (insn, operands);"
14237   [(set (attr "type") 
14238         (cond [(match_operand:SF 3 "mult_operator" "") 
14239                  (const_string "fmul")
14240                (match_operand:SF 3 "div_operator" "") 
14241                  (const_string "fdiv")
14242               ]
14243               (const_string "fop")))
14244    (set_attr "mode" "SF")])
14245
14246 (define_insn "*fop_sf_1"
14247   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14248         (match_operator:SF 3 "binary_fp_operator"
14249                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14250                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14251   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14252    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14253    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14254   "* return output_387_binary_op (insn, operands);"
14255   [(set (attr "type") 
14256         (cond [(and (eq_attr "alternative" "2")
14257                     (match_operand:SF 3 "mult_operator" ""))
14258                  (const_string "ssemul")
14259                (and (eq_attr "alternative" "2")
14260                     (match_operand:SF 3 "div_operator" ""))
14261                  (const_string "ssediv")
14262                (eq_attr "alternative" "2")
14263                  (const_string "sseadd")
14264                (match_operand:SF 3 "mult_operator" "") 
14265                  (const_string "fmul")
14266                (match_operand:SF 3 "div_operator" "") 
14267                  (const_string "fdiv")
14268               ]
14269               (const_string "fop")))
14270    (set_attr "mode" "SF")])
14271
14272 (define_insn "*fop_sf_1_sse"
14273   [(set (match_operand:SF 0 "register_operand" "=x")
14274         (match_operator:SF 3 "binary_fp_operator"
14275                         [(match_operand:SF 1 "register_operand" "0")
14276                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14277   "TARGET_SSE_MATH
14278    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14279   "* return output_387_binary_op (insn, operands);"
14280   [(set (attr "type") 
14281         (cond [(match_operand:SF 3 "mult_operator" "")
14282                  (const_string "ssemul")
14283                (match_operand:SF 3 "div_operator" "")
14284                  (const_string "ssediv")
14285               ]
14286               (const_string "sseadd")))
14287    (set_attr "mode" "SF")])
14288
14289 ;; ??? Add SSE splitters for these!
14290 (define_insn "*fop_sf_2"
14291   [(set (match_operand:SF 0 "register_operand" "=f,f")
14292         (match_operator:SF 3 "binary_fp_operator"
14293           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14294            (match_operand:SF 2 "register_operand" "0,0")]))]
14295   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14296   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14297   [(set (attr "type") 
14298         (cond [(match_operand:SF 3 "mult_operator" "") 
14299                  (const_string "fmul")
14300                (match_operand:SF 3 "div_operator" "") 
14301                  (const_string "fdiv")
14302               ]
14303               (const_string "fop")))
14304    (set_attr "fp_int_src" "true")
14305    (set_attr "ppro_uops" "many")
14306    (set_attr "mode" "SI")])
14307
14308 (define_insn "*fop_sf_3"
14309   [(set (match_operand:SF 0 "register_operand" "=f,f")
14310         (match_operator:SF 3 "binary_fp_operator"
14311           [(match_operand:SF 1 "register_operand" "0,0")
14312            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14313   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14314   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14315   [(set (attr "type") 
14316         (cond [(match_operand:SF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:SF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "fp_int_src" "true")
14323    (set_attr "ppro_uops" "many")
14324    (set_attr "mode" "SI")])
14325
14326 (define_insn "*fop_df_1_nosse"
14327   [(set (match_operand:DF 0 "register_operand" "=f,f")
14328         (match_operator:DF 3 "binary_fp_operator"
14329                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14330                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14331   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14332    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14333    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14334   "* return output_387_binary_op (insn, operands);"
14335   [(set (attr "type") 
14336         (cond [(match_operand:DF 3 "mult_operator" "") 
14337                  (const_string "fmul")
14338                (match_operand:DF 3 "div_operator" "")
14339                  (const_string "fdiv")
14340               ]
14341               (const_string "fop")))
14342    (set_attr "mode" "DF")])
14343
14344
14345 (define_insn "*fop_df_1"
14346   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14347         (match_operator:DF 3 "binary_fp_operator"
14348                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14349                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14350   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
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         (cond [(and (eq_attr "alternative" "2")
14356                     (match_operand:SF 3 "mult_operator" ""))
14357                  (const_string "ssemul")
14358                (and (eq_attr "alternative" "2")
14359                     (match_operand:SF 3 "div_operator" ""))
14360                  (const_string "ssediv")
14361                (eq_attr "alternative" "2")
14362                  (const_string "sseadd")
14363                (match_operand:DF 3 "mult_operator" "") 
14364                  (const_string "fmul")
14365                (match_operand:DF 3 "div_operator" "") 
14366                  (const_string "fdiv")
14367               ]
14368               (const_string "fop")))
14369    (set_attr "mode" "DF")])
14370
14371 (define_insn "*fop_df_1_sse"
14372   [(set (match_operand:DF 0 "register_operand" "=Y")
14373         (match_operator:DF 3 "binary_fp_operator"
14374                         [(match_operand:DF 1 "register_operand" "0")
14375                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14376   "TARGET_SSE2 && TARGET_SSE_MATH
14377    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14378   "* return output_387_binary_op (insn, operands);"
14379   [(set_attr "mode" "DF")
14380    (set (attr "type") 
14381         (cond [(match_operand:SF 3 "mult_operator" "")
14382                  (const_string "ssemul")
14383                (match_operand:SF 3 "div_operator" "")
14384                  (const_string "ssediv")
14385               ]
14386               (const_string "sseadd")))])
14387
14388 ;; ??? Add SSE splitters for these!
14389 (define_insn "*fop_df_2"
14390   [(set (match_operand:DF 0 "register_operand" "=f,f")
14391         (match_operator:DF 3 "binary_fp_operator"
14392            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14393             (match_operand:DF 2 "register_operand" "0,0")]))]
14394   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14395   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14396   [(set (attr "type") 
14397         (cond [(match_operand:DF 3 "mult_operator" "") 
14398                  (const_string "fmul")
14399                (match_operand:DF 3 "div_operator" "") 
14400                  (const_string "fdiv")
14401               ]
14402               (const_string "fop")))
14403    (set_attr "fp_int_src" "true")
14404    (set_attr "ppro_uops" "many")
14405    (set_attr "mode" "SI")])
14406
14407 (define_insn "*fop_df_3"
14408   [(set (match_operand:DF 0 "register_operand" "=f,f")
14409         (match_operator:DF 3 "binary_fp_operator"
14410            [(match_operand:DF 1 "register_operand" "0,0")
14411             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14412   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14413   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (cond [(match_operand:DF 3 "mult_operator" "") 
14416                  (const_string "fmul")
14417                (match_operand:DF 3 "div_operator" "") 
14418                  (const_string "fdiv")
14419               ]
14420               (const_string "fop")))
14421    (set_attr "fp_int_src" "true")
14422    (set_attr "ppro_uops" "many")
14423    (set_attr "mode" "SI")])
14424
14425 (define_insn "*fop_df_4"
14426   [(set (match_operand:DF 0 "register_operand" "=f,f")
14427         (match_operator:DF 3 "binary_fp_operator"
14428            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14429             (match_operand:DF 2 "register_operand" "0,f")]))]
14430   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (cond [(match_operand:DF 3 "mult_operator" "") 
14435                  (const_string "fmul")
14436                (match_operand:DF 3 "div_operator" "") 
14437                  (const_string "fdiv")
14438               ]
14439               (const_string "fop")))
14440    (set_attr "mode" "SF")])
14441
14442 (define_insn "*fop_df_5"
14443   [(set (match_operand:DF 0 "register_operand" "=f,f")
14444         (match_operator:DF 3 "binary_fp_operator"
14445           [(match_operand:DF 1 "register_operand" "0,f")
14446            (float_extend:DF
14447             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14448   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14449   "* return output_387_binary_op (insn, operands);"
14450   [(set (attr "type") 
14451         (cond [(match_operand:DF 3 "mult_operator" "") 
14452                  (const_string "fmul")
14453                (match_operand:DF 3 "div_operator" "") 
14454                  (const_string "fdiv")
14455               ]
14456               (const_string "fop")))
14457    (set_attr "mode" "SF")])
14458
14459 (define_insn "*fop_df_6"
14460   [(set (match_operand:DF 0 "register_operand" "=f,f")
14461         (match_operator:DF 3 "binary_fp_operator"
14462           [(float_extend:DF
14463             (match_operand:SF 1 "register_operand" "0,f"))
14464            (float_extend:DF
14465             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14466   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (cond [(match_operand:DF 3 "mult_operator" "") 
14470                  (const_string "fmul")
14471                (match_operand:DF 3 "div_operator" "") 
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "mode" "SF")])
14476
14477 (define_insn "*fop_xf_1"
14478   [(set (match_operand:XF 0 "register_operand" "=f,f")
14479         (match_operator:XF 3 "binary_fp_operator"
14480                         [(match_operand:XF 1 "register_operand" "0,f")
14481                          (match_operand:XF 2 "register_operand" "f,0")]))]
14482   "TARGET_80387
14483    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14484   "* return output_387_binary_op (insn, operands);"
14485   [(set (attr "type") 
14486         (cond [(match_operand:XF 3 "mult_operator" "") 
14487                  (const_string "fmul")
14488                (match_operand:XF 3 "div_operator" "") 
14489                  (const_string "fdiv")
14490               ]
14491               (const_string "fop")))
14492    (set_attr "mode" "XF")])
14493
14494 (define_insn "*fop_xf_2"
14495   [(set (match_operand:XF 0 "register_operand" "=f,f")
14496         (match_operator:XF 3 "binary_fp_operator"
14497            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14498             (match_operand:XF 2 "register_operand" "0,0")]))]
14499   "TARGET_80387 && TARGET_USE_FIOP"
14500   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14501   [(set (attr "type") 
14502         (cond [(match_operand:XF 3 "mult_operator" "") 
14503                  (const_string "fmul")
14504                (match_operand:XF 3 "div_operator" "") 
14505                  (const_string "fdiv")
14506               ]
14507               (const_string "fop")))
14508    (set_attr "fp_int_src" "true")
14509    (set_attr "mode" "SI")
14510    (set_attr "ppro_uops" "many")])
14511
14512 (define_insn "*fop_xf_3"
14513   [(set (match_operand:XF 0 "register_operand" "=f,f")
14514         (match_operator:XF 3 "binary_fp_operator"
14515           [(match_operand:XF 1 "register_operand" "0,0")
14516            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14517   "TARGET_80387 && TARGET_USE_FIOP"
14518   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519   [(set (attr "type") 
14520         (cond [(match_operand:XF 3 "mult_operator" "") 
14521                  (const_string "fmul")
14522                (match_operand:XF 3 "div_operator" "") 
14523                  (const_string "fdiv")
14524               ]
14525               (const_string "fop")))
14526    (set_attr "fp_int_src" "true")
14527    (set_attr "mode" "SI")
14528    (set_attr "ppro_uops" "many")])
14529
14530 (define_insn "*fop_xf_4"
14531   [(set (match_operand:XF 0 "register_operand" "=f,f")
14532         (match_operator:XF 3 "binary_fp_operator"
14533            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14534             (match_operand:XF 2 "register_operand" "0,f")]))]
14535   "TARGET_80387"
14536   "* return output_387_binary_op (insn, operands);"
14537   [(set (attr "type") 
14538         (cond [(match_operand:XF 3 "mult_operator" "") 
14539                  (const_string "fmul")
14540                (match_operand:XF 3 "div_operator" "") 
14541                  (const_string "fdiv")
14542               ]
14543               (const_string "fop")))
14544    (set_attr "mode" "SF")])
14545
14546 (define_insn "*fop_xf_5"
14547   [(set (match_operand:XF 0 "register_operand" "=f,f")
14548         (match_operator:XF 3 "binary_fp_operator"
14549           [(match_operand:XF 1 "register_operand" "0,f")
14550            (float_extend:XF
14551             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14552   "TARGET_80387"
14553   "* return output_387_binary_op (insn, operands);"
14554   [(set (attr "type") 
14555         (cond [(match_operand:XF 3 "mult_operator" "") 
14556                  (const_string "fmul")
14557                (match_operand:XF 3 "div_operator" "") 
14558                  (const_string "fdiv")
14559               ]
14560               (const_string "fop")))
14561    (set_attr "mode" "SF")])
14562
14563 (define_insn "*fop_xf_6"
14564   [(set (match_operand:XF 0 "register_operand" "=f,f")
14565         (match_operator:XF 3 "binary_fp_operator"
14566           [(float_extend:XF
14567             (match_operand 1 "register_operand" "0,f"))
14568            (float_extend:XF
14569             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14570   "TARGET_80387"
14571   "* return output_387_binary_op (insn, operands);"
14572   [(set (attr "type") 
14573         (cond [(match_operand:XF 3 "mult_operator" "") 
14574                  (const_string "fmul")
14575                (match_operand:XF 3 "div_operator" "") 
14576                  (const_string "fdiv")
14577               ]
14578               (const_string "fop")))
14579    (set_attr "mode" "SF")])
14580
14581 (define_split
14582   [(set (match_operand 0 "register_operand" "")
14583         (match_operator 3 "binary_fp_operator"
14584            [(float (match_operand:SI 1 "register_operand" ""))
14585             (match_operand 2 "register_operand" "")]))]
14586   "TARGET_80387 && reload_completed
14587    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14588   [(const_int 0)]
14589
14590   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14591   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14592   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14593                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14594                                           GET_MODE (operands[3]),
14595                                           operands[4],
14596                                           operands[2])));
14597   ix86_free_from_memory (GET_MODE (operands[1]));
14598   DONE;
14599 })
14600
14601 (define_split
14602   [(set (match_operand 0 "register_operand" "")
14603         (match_operator 3 "binary_fp_operator"
14604            [(match_operand 1 "register_operand" "")
14605             (float (match_operand:SI 2 "register_operand" ""))]))]
14606   "TARGET_80387 && reload_completed
14607    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14608   [(const_int 0)]
14609 {
14610   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14611   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14612   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14613                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14614                                           GET_MODE (operands[3]),
14615                                           operands[1],
14616                                           operands[4])));
14617   ix86_free_from_memory (GET_MODE (operands[2]));
14618   DONE;
14619 })
14620 \f
14621 ;; FPU special functions.
14622
14623 (define_expand "sqrtsf2"
14624   [(set (match_operand:SF 0 "register_operand" "")
14625         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14626   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14627 {
14628   if (!TARGET_SSE_MATH)
14629     operands[1] = force_reg (SFmode, operands[1]);
14630 })
14631
14632 (define_insn "sqrtsf2_1"
14633   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14634         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14635   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14636    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14637   "@
14638    fsqrt
14639    sqrtss\t{%1, %0|%0, %1}"
14640   [(set_attr "type" "fpspc,sse")
14641    (set_attr "mode" "SF,SF")
14642    (set_attr "athlon_decode" "direct,*")])
14643
14644 (define_insn "sqrtsf2_1_sse_only"
14645   [(set (match_operand:SF 0 "register_operand" "=x")
14646         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14647   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14648   "sqrtss\t{%1, %0|%0, %1}"
14649   [(set_attr "type" "sse")
14650    (set_attr "mode" "SF")
14651    (set_attr "athlon_decode" "*")])
14652
14653 (define_insn "sqrtsf2_i387"
14654   [(set (match_operand:SF 0 "register_operand" "=f")
14655         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14656   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14657    && !TARGET_SSE_MATH"
14658   "fsqrt"
14659   [(set_attr "type" "fpspc")
14660    (set_attr "mode" "SF")
14661    (set_attr "athlon_decode" "direct")])
14662
14663 (define_expand "sqrtdf2"
14664   [(set (match_operand:DF 0 "register_operand" "")
14665         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14666   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14667    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14668 {
14669   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14670     operands[1] = force_reg (DFmode, operands[1]);
14671 })
14672
14673 (define_insn "sqrtdf2_1"
14674   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14675         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14676   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14677    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14678   "@
14679    fsqrt
14680    sqrtsd\t{%1, %0|%0, %1}"
14681   [(set_attr "type" "fpspc,sse")
14682    (set_attr "mode" "DF,DF")
14683    (set_attr "athlon_decode" "direct,*")])
14684
14685 (define_insn "sqrtdf2_1_sse_only"
14686   [(set (match_operand:DF 0 "register_operand" "=Y")
14687         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14688   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14689   "sqrtsd\t{%1, %0|%0, %1}"
14690   [(set_attr "type" "sse")
14691    (set_attr "mode" "DF")
14692    (set_attr "athlon_decode" "*")])
14693
14694 (define_insn "sqrtdf2_i387"
14695   [(set (match_operand:DF 0 "register_operand" "=f")
14696         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14697   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14698    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14699   "fsqrt"
14700   [(set_attr "type" "fpspc")
14701    (set_attr "mode" "DF")
14702    (set_attr "athlon_decode" "direct")])
14703
14704 (define_insn "*sqrtextendsfdf2"
14705   [(set (match_operand:DF 0 "register_operand" "=f")
14706         (sqrt:DF (float_extend:DF
14707                   (match_operand:SF 1 "register_operand" "0"))))]
14708   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14709    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14710   "fsqrt"
14711   [(set_attr "type" "fpspc")
14712    (set_attr "mode" "DF")
14713    (set_attr "athlon_decode" "direct")])
14714
14715 (define_insn "sqrtxf2"
14716   [(set (match_operand:XF 0 "register_operand" "=f")
14717         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14718   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14719    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14720   "fsqrt"
14721   [(set_attr "type" "fpspc")
14722    (set_attr "mode" "XF")
14723    (set_attr "athlon_decode" "direct")])
14724
14725 (define_insn "*sqrtextenddfxf2"
14726   [(set (match_operand:XF 0 "register_operand" "=f")
14727         (sqrt:XF (float_extend:XF
14728                   (match_operand:DF 1 "register_operand" "0"))))]
14729   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14730   "fsqrt"
14731   [(set_attr "type" "fpspc")
14732    (set_attr "mode" "XF")
14733    (set_attr "athlon_decode" "direct")])
14734
14735 (define_insn "*sqrtextendsfxf2"
14736   [(set (match_operand:XF 0 "register_operand" "=f")
14737         (sqrt:XF (float_extend:XF
14738                   (match_operand:SF 1 "register_operand" "0"))))]
14739   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14740   "fsqrt"
14741   [(set_attr "type" "fpspc")
14742    (set_attr "mode" "XF")
14743    (set_attr "athlon_decode" "direct")])
14744
14745 (define_insn "sindf2"
14746   [(set (match_operand:DF 0 "register_operand" "=f")
14747         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14748   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14749    && flag_unsafe_math_optimizations"
14750   "fsin"
14751   [(set_attr "type" "fpspc")
14752    (set_attr "mode" "DF")])
14753
14754 (define_insn "sinsf2"
14755   [(set (match_operand:SF 0 "register_operand" "=f")
14756         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14757   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14758    && flag_unsafe_math_optimizations"
14759   "fsin"
14760   [(set_attr "type" "fpspc")
14761    (set_attr "mode" "SF")])
14762
14763 (define_insn "*sinextendsfdf2"
14764   [(set (match_operand:DF 0 "register_operand" "=f")
14765         (unspec:DF [(float_extend:DF
14766                      (match_operand:SF 1 "register_operand" "0"))]
14767                    UNSPEC_SIN))]
14768   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14769    && flag_unsafe_math_optimizations"
14770   "fsin"
14771   [(set_attr "type" "fpspc")
14772    (set_attr "mode" "DF")])
14773
14774 (define_insn "sinxf2"
14775   [(set (match_operand:XF 0 "register_operand" "=f")
14776         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14777   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14778    && flag_unsafe_math_optimizations"
14779   "fsin"
14780   [(set_attr "type" "fpspc")
14781    (set_attr "mode" "XF")])
14782
14783 (define_insn "cosdf2"
14784   [(set (match_operand:DF 0 "register_operand" "=f")
14785         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14786   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14787    && flag_unsafe_math_optimizations"
14788   "fcos"
14789   [(set_attr "type" "fpspc")
14790    (set_attr "mode" "DF")])
14791
14792 (define_insn "cossf2"
14793   [(set (match_operand:SF 0 "register_operand" "=f")
14794         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14795   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14796    && flag_unsafe_math_optimizations"
14797   "fcos"
14798   [(set_attr "type" "fpspc")
14799    (set_attr "mode" "SF")])
14800
14801 (define_insn "*cosextendsfdf2"
14802   [(set (match_operand:DF 0 "register_operand" "=f")
14803         (unspec:DF [(float_extend:DF
14804                      (match_operand:SF 1 "register_operand" "0"))]
14805                    UNSPEC_COS))]
14806   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14807    && flag_unsafe_math_optimizations"
14808   "fcos"
14809   [(set_attr "type" "fpspc")
14810    (set_attr "mode" "DF")])
14811
14812 (define_insn "cosxf2"
14813   [(set (match_operand:XF 0 "register_operand" "=f")
14814         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14815   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14816    && flag_unsafe_math_optimizations"
14817   "fcos"
14818   [(set_attr "type" "fpspc")
14819    (set_attr "mode" "XF")])
14820
14821 (define_insn "atan2df3_1"
14822   [(set (match_operand:DF 0 "register_operand" "=f")
14823         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14824                     (match_operand:DF 1 "register_operand" "u")]
14825                    UNSPEC_FPATAN))
14826    (clobber (match_scratch:DF 3 "=1"))]
14827   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14828    && flag_unsafe_math_optimizations"
14829   "fpatan"
14830   [(set_attr "type" "fpspc")
14831    (set_attr "mode" "DF")])
14832
14833 (define_expand "atan2df3"
14834   [(use (match_operand:DF 0 "register_operand" "=f"))
14835    (use (match_operand:DF 2 "register_operand" "0"))
14836    (use (match_operand:DF 1 "register_operand" "u"))]
14837   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14838    && flag_unsafe_math_optimizations"
14839 {
14840   rtx copy = gen_reg_rtx (DFmode);
14841   emit_move_insn (copy, operands[1]);
14842   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
14843   DONE;
14844 })
14845
14846 (define_insn "atan2sf3_1"
14847   [(set (match_operand:SF 0 "register_operand" "=f")
14848         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
14849                     (match_operand:SF 1 "register_operand" "u")]
14850                    UNSPEC_FPATAN))
14851    (clobber (match_scratch:SF 3 "=1"))]
14852   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14853    && flag_unsafe_math_optimizations"
14854   "fpatan"
14855   [(set_attr "type" "fpspc")
14856    (set_attr "mode" "SF")])
14857
14858 (define_expand "atan2sf3"
14859   [(use (match_operand:SF 0 "register_operand" "=f"))
14860    (use (match_operand:SF 2 "register_operand" "0"))
14861    (use (match_operand:SF 1 "register_operand" "u"))]
14862   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14863    && flag_unsafe_math_optimizations"
14864 {
14865   rtx copy = gen_reg_rtx (SFmode);
14866   emit_move_insn (copy, operands[1]);
14867   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
14868   DONE;
14869 })
14870
14871 (define_insn "atan2xf3_1"
14872   [(set (match_operand:XF 0 "register_operand" "=f")
14873         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14874                     (match_operand:XF 1 "register_operand" "u")]
14875                    UNSPEC_FPATAN))
14876    (clobber (match_scratch:XF 3 "=1"))]
14877   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14878    && flag_unsafe_math_optimizations"
14879   "fpatan"
14880   [(set_attr "type" "fpspc")
14881    (set_attr "mode" "XF")])
14882
14883 (define_expand "atan2xf3"
14884   [(use (match_operand:XF 0 "register_operand" "=f"))
14885    (use (match_operand:XF 2 "register_operand" "0"))
14886    (use (match_operand:XF 1 "register_operand" "u"))]
14887   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14888    && flag_unsafe_math_optimizations"
14889 {
14890   rtx copy = gen_reg_rtx (XFmode);
14891   emit_move_insn (copy, operands[1]);
14892   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
14893   DONE;
14894 })
14895
14896 (define_insn "*fyl2x_sfxf3"
14897   [(set (match_operand:SF 0 "register_operand" "=f")
14898          (unspec:SF [(match_operand:SF 2 "register_operand" "0")
14899                      (match_operand:XF 1 "register_operand" "u")]
14900                     UNSPEC_FYL2X))
14901    (clobber (match_scratch:SF 3 "=1"))]
14902   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14903    && flag_unsafe_math_optimizations"
14904   "fyl2x"
14905   [(set_attr "type" "fpspc")
14906    (set_attr "mode" "SF")])
14907
14908 (define_insn "*fyl2x_dfxf3"
14909   [(set (match_operand:DF 0 "register_operand" "=f")
14910          (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14911                      (match_operand:XF 1 "register_operand" "u")]
14912                     UNSPEC_FYL2X))
14913    (clobber (match_scratch:DF 3 "=1"))]
14914   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14915    && flag_unsafe_math_optimizations"
14916   "fyl2x"
14917   [(set_attr "type" "fpspc")
14918    (set_attr "mode" "DF")])
14919
14920 (define_insn "*fyl2x_xf3"
14921   [(set (match_operand:XF 0 "register_operand" "=f")
14922         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14923                     (match_operand:XF 1 "register_operand" "u")]
14924                    UNSPEC_FYL2X))
14925    (clobber (match_scratch:XF 3 "=1"))]
14926   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14927    && flag_unsafe_math_optimizations"
14928   "fyl2x"
14929   [(set_attr "type" "fpspc")
14930    (set_attr "mode" "XF")])
14931
14932 (define_expand "logsf2"
14933   [(parallel [(set (match_operand:SF 0 "register_operand" "")
14934                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
14935                                (match_dup 2)] UNSPEC_FYL2X))
14936               (clobber (match_scratch:SF 3 ""))])]
14937   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14938    && flag_unsafe_math_optimizations"
14939 {
14940   rtx temp;
14941
14942   operands[2] = gen_reg_rtx (XFmode);
14943   temp = standard_80387_constant_rtx (4); /* fldln2 */
14944   emit_move_insn (operands[2], temp);
14945 })
14946
14947 (define_expand "logdf2"
14948   [(parallel [(set (match_operand:DF 0 "register_operand" "")
14949                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
14950                                (match_dup 2)] UNSPEC_FYL2X))
14951               (clobber (match_scratch:DF 3 ""))])]
14952   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14953    && flag_unsafe_math_optimizations"
14954 {
14955   rtx temp;
14956
14957   operands[2] = gen_reg_rtx (XFmode);
14958   temp = standard_80387_constant_rtx (4); /* fldln2 */
14959   emit_move_insn (operands[2], temp);
14960 })
14961
14962 (define_expand "logxf2"
14963   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14964                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14965                                (match_dup 2)] UNSPEC_FYL2X))
14966               (clobber (match_scratch:XF 3 ""))])]
14967   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14968    && flag_unsafe_math_optimizations"
14969 {
14970   rtx temp;
14971
14972   operands[2] = gen_reg_rtx (XFmode);
14973   temp = standard_80387_constant_rtx (4); /* fldln2 */
14974   emit_move_insn (operands[2], temp);
14975 })
14976
14977 (define_insn "*fscale_sfxf3"
14978   [(set (match_operand:SF 0 "register_operand" "=f")
14979          (unspec:SF [(match_operand:XF 2 "register_operand" "0")
14980                      (match_operand:XF 1 "register_operand" "u")]
14981                     UNSPEC_FSCALE))
14982    (clobber (match_scratch:SF 3 "=1"))]
14983   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14984    && flag_unsafe_math_optimizations"
14985   "fscale\;fstp\t%y1"
14986   [(set_attr "type" "fpspc")
14987    (set_attr "mode" "SF")])
14988
14989 (define_insn "*fscale_dfxf3"
14990   [(set (match_operand:DF 0 "register_operand" "=f")
14991          (unspec:DF [(match_operand:XF 2 "register_operand" "0")
14992                      (match_operand:XF 1 "register_operand" "u")]
14993                     UNSPEC_FSCALE))
14994    (clobber (match_scratch:DF 3 "=1"))]
14995   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14996    && flag_unsafe_math_optimizations"
14997   "fscale\;fstp\t%y1"
14998   [(set_attr "type" "fpspc")
14999    (set_attr "mode" "DF")])
15000
15001 (define_insn "*fscale_xf3"
15002   [(set (match_operand:XF 0 "register_operand" "=f")
15003         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15004                     (match_operand:XF 1 "register_operand" "u")]
15005                    UNSPEC_FSCALE))
15006    (clobber (match_scratch:XF 3 "=1"))]
15007   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15008    && flag_unsafe_math_optimizations"
15009   "fscale\;fstp\t%y1"
15010   [(set_attr "type" "fpspc")
15011    (set_attr "mode" "XF")])
15012
15013 (define_insn "*frndintxf2"
15014   [(set (match_operand:XF 0 "register_operand" "=f")
15015         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15016          UNSPEC_FRNDINT))]
15017   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15018    && flag_unsafe_math_optimizations"
15019   "frndint"
15020   [(set_attr "type" "fpspc")
15021    (set_attr "mode" "XF")])
15022
15023 (define_insn "*f2xm1xf2"
15024   [(set (match_operand:XF 0 "register_operand" "=f")
15025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15026          UNSPEC_F2XM1))]
15027   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15028    && flag_unsafe_math_optimizations"
15029   "f2xm1"
15030   [(set_attr "type" "fpspc")
15031    (set_attr "mode" "XF")])
15032
15033 (define_expand "expsf2"
15034   [(set (match_dup 2)
15035         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15036    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15037    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15038    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15039    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15040    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15041    (parallel [(set (match_operand:SF 0 "register_operand" "")
15042                    (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15043               (clobber (match_scratch:SF 5 ""))])]
15044   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15045    && flag_unsafe_math_optimizations"
15046 {
15047   rtx temp;
15048   int i;
15049
15050   for (i=2; i<10; i++)
15051     operands[i] = gen_reg_rtx (XFmode);
15052   temp = standard_80387_constant_rtx (5); /* fldl2e */
15053   emit_move_insn (operands[3], temp);
15054   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15055 })
15056
15057 (define_expand "expdf2"
15058   [(set (match_dup 2)
15059         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15060    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15061    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15062    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15063    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15064    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15065    (parallel [(set (match_operand:DF 0 "register_operand" "")
15066                    (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15067               (clobber (match_scratch:DF 5 ""))])]
15068   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15069    && flag_unsafe_math_optimizations"
15070 {
15071   rtx temp;
15072   int i;
15073
15074   for (i=2; i<10; i++)
15075     operands[i] = gen_reg_rtx (XFmode);
15076   temp = standard_80387_constant_rtx (5); /* fldl2e */
15077   emit_move_insn (operands[3], temp);
15078   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15079 })
15080
15081 (define_expand "expxf2"
15082   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15083                                (match_dup 2)))
15084    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15085    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15086    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15087    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15088    (parallel [(set (match_operand:XF 0 "register_operand" "")
15089                    (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15090               (clobber (match_scratch:XF 5 ""))])]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15093 {
15094   rtx temp;
15095   int i;
15096
15097   for (i=2; i<9; i++)
15098     operands[i] = gen_reg_rtx (XFmode);
15099   temp = standard_80387_constant_rtx (5); /* fldl2e */
15100   emit_move_insn (operands[2], temp);
15101   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15102 })
15103
15104 (define_expand "atansf2"
15105   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15106                    (unspec:SF [(match_dup 2)
15107                                (match_operand:SF 1 "register_operand" "")]
15108                     UNSPEC_FPATAN))
15109               (clobber (match_scratch:SF 3 ""))])]
15110   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15111    && flag_unsafe_math_optimizations"
15112 {
15113   operands[2] = gen_reg_rtx (SFmode);
15114   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15115 })
15116
15117 (define_expand "atandf2"
15118   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15119                    (unspec:DF [(match_dup 2)
15120                                (match_operand:DF 1 "register_operand" "")]
15121                     UNSPEC_FPATAN))
15122               (clobber (match_scratch:DF 3 ""))])]
15123   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15124    && flag_unsafe_math_optimizations"
15125 {
15126   operands[2] = gen_reg_rtx (DFmode);
15127   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15128 })
15129
15130 (define_expand "atanxf2"
15131   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15132                    (unspec:XF [(match_dup 2)
15133                                (match_operand:XF 1 "register_operand" "")]
15134                     UNSPEC_FPATAN))
15135               (clobber (match_scratch:XF 3 ""))])]
15136   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137    && flag_unsafe_math_optimizations"
15138 {
15139   operands[2] = gen_reg_rtx (XFmode);
15140   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15141 })
15142 \f
15143 ;; Block operation instructions
15144
15145 (define_insn "cld"
15146  [(set (reg:SI 19) (const_int 0))]
15147  ""
15148  "cld"
15149   [(set_attr "type" "cld")])
15150
15151 (define_expand "movstrsi"
15152   [(use (match_operand:BLK 0 "memory_operand" ""))
15153    (use (match_operand:BLK 1 "memory_operand" ""))
15154    (use (match_operand:SI 2 "nonmemory_operand" ""))
15155    (use (match_operand:SI 3 "const_int_operand" ""))]
15156   "! optimize_size"
15157 {
15158  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15159    DONE;
15160  else
15161    FAIL;
15162 })
15163
15164 (define_expand "movstrdi"
15165   [(use (match_operand:BLK 0 "memory_operand" ""))
15166    (use (match_operand:BLK 1 "memory_operand" ""))
15167    (use (match_operand:DI 2 "nonmemory_operand" ""))
15168    (use (match_operand:DI 3 "const_int_operand" ""))]
15169   "TARGET_64BIT"
15170 {
15171  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15172    DONE;
15173  else
15174    FAIL;
15175 })
15176
15177 ;; Most CPUs don't like single string operations
15178 ;; Handle this case here to simplify previous expander.
15179
15180 (define_expand "strmovdi_rex64"
15181   [(set (match_dup 2)
15182         (mem:DI (match_operand:DI 1 "register_operand" "")))
15183    (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15184         (match_dup 2))
15185    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15186               (clobber (reg:CC 17))])
15187    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15188               (clobber (reg:CC 17))])]
15189   "TARGET_64BIT"
15190 {
15191   if (TARGET_SINGLE_STRINGOP || optimize_size)
15192     {
15193       emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15194                                      operands[1]));
15195       DONE;
15196     }
15197   else 
15198     operands[2] = gen_reg_rtx (DImode);
15199 })
15200
15201
15202 (define_expand "strmovsi"
15203   [(set (match_dup 2)
15204         (mem:SI (match_operand:SI 1 "register_operand" "")))
15205    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15206         (match_dup 2))
15207    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15208               (clobber (reg:CC 17))])
15209    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15210               (clobber (reg:CC 17))])]
15211   ""
15212 {
15213   if (TARGET_64BIT)
15214     {
15215       emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15216       DONE;
15217     }
15218   if (TARGET_SINGLE_STRINGOP || optimize_size)
15219     {
15220       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15221                                 operands[1]));
15222       DONE;
15223     }
15224   else 
15225     operands[2] = gen_reg_rtx (SImode);
15226 })
15227
15228 (define_expand "strmovsi_rex64"
15229   [(set (match_dup 2)
15230         (mem:SI (match_operand:DI 1 "register_operand" "")))
15231    (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15232         (match_dup 2))
15233    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15234               (clobber (reg:CC 17))])
15235    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15236               (clobber (reg:CC 17))])]
15237   "TARGET_64BIT"
15238 {
15239   if (TARGET_SINGLE_STRINGOP || optimize_size)
15240     {
15241       emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15242                                      operands[1]));
15243       DONE;
15244     }
15245   else 
15246     operands[2] = gen_reg_rtx (SImode);
15247 })
15248
15249 (define_expand "strmovhi"
15250   [(set (match_dup 2)
15251         (mem:HI (match_operand:SI 1 "register_operand" "")))
15252    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15253         (match_dup 2))
15254    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15255               (clobber (reg:CC 17))])
15256    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15257               (clobber (reg:CC 17))])]
15258   ""
15259 {
15260   if (TARGET_64BIT)
15261     {
15262       emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15263       DONE;
15264     }
15265   if (TARGET_SINGLE_STRINGOP || optimize_size)
15266     {
15267       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15268                                 operands[1]));
15269       DONE;
15270     }
15271   else 
15272     operands[2] = gen_reg_rtx (HImode);
15273 })
15274
15275 (define_expand "strmovhi_rex64"
15276   [(set (match_dup 2)
15277         (mem:HI (match_operand:DI 1 "register_operand" "")))
15278    (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15279         (match_dup 2))
15280    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15281               (clobber (reg:CC 17))])
15282    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15283               (clobber (reg:CC 17))])]
15284   "TARGET_64BIT"
15285 {
15286   if (TARGET_SINGLE_STRINGOP || optimize_size)
15287     {
15288       emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15289                                      operands[1]));
15290       DONE;
15291     }
15292   else 
15293     operands[2] = gen_reg_rtx (HImode);
15294 })
15295
15296 (define_expand "strmovqi"
15297   [(set (match_dup 2)
15298         (mem:QI (match_operand:SI 1 "register_operand" "")))
15299    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15300         (match_dup 2))
15301    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15302               (clobber (reg:CC 17))])
15303    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15304               (clobber (reg:CC 17))])]
15305   ""
15306 {
15307   if (TARGET_64BIT)
15308     {
15309       emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15310       DONE;
15311     }
15312   if (TARGET_SINGLE_STRINGOP || optimize_size)
15313     {
15314       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15315                                 operands[1]));
15316       DONE;
15317     }
15318   else 
15319     operands[2] = gen_reg_rtx (QImode);
15320 })
15321
15322 (define_expand "strmovqi_rex64"
15323   [(set (match_dup 2)
15324         (mem:QI (match_operand:DI 1 "register_operand" "")))
15325    (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15326         (match_dup 2))
15327    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15328               (clobber (reg:CC 17))])
15329    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15330               (clobber (reg:CC 17))])]
15331   "TARGET_64BIT"
15332 {
15333   if (TARGET_SINGLE_STRINGOP || optimize_size)
15334     {
15335       emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15336                                      operands[1]));
15337       DONE;
15338     }
15339   else 
15340     operands[2] = gen_reg_rtx (QImode);
15341 })
15342
15343 (define_insn "strmovdi_rex_1"
15344   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15345         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15346    (set (match_operand:DI 0 "register_operand" "=D")
15347         (plus:DI (match_dup 2)
15348                  (const_int 8)))
15349    (set (match_operand:DI 1 "register_operand" "=S")
15350         (plus:DI (match_dup 3)
15351                  (const_int 8)))
15352    (use (reg:SI 19))]
15353   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15354   "movsq"
15355   [(set_attr "type" "str")
15356    (set_attr "mode" "DI")
15357    (set_attr "memory" "both")])
15358
15359 (define_insn "strmovsi_1"
15360   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15361         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15362    (set (match_operand:SI 0 "register_operand" "=D")
15363         (plus:SI (match_dup 2)
15364                  (const_int 4)))
15365    (set (match_operand:SI 1 "register_operand" "=S")
15366         (plus:SI (match_dup 3)
15367                  (const_int 4)))
15368    (use (reg:SI 19))]
15369   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15370   "{movsl|movsd}"
15371   [(set_attr "type" "str")
15372    (set_attr "mode" "SI")
15373    (set_attr "memory" "both")])
15374
15375 (define_insn "strmovsi_rex_1"
15376   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15377         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15378    (set (match_operand:DI 0 "register_operand" "=D")
15379         (plus:DI (match_dup 2)
15380                  (const_int 4)))
15381    (set (match_operand:DI 1 "register_operand" "=S")
15382         (plus:DI (match_dup 3)
15383                  (const_int 4)))
15384    (use (reg:SI 19))]
15385   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15386   "{movsl|movsd}"
15387   [(set_attr "type" "str")
15388    (set_attr "mode" "SI")
15389    (set_attr "memory" "both")])
15390
15391 (define_insn "strmovhi_1"
15392   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15393         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15394    (set (match_operand:SI 0 "register_operand" "=D")
15395         (plus:SI (match_dup 2)
15396                  (const_int 2)))
15397    (set (match_operand:SI 1 "register_operand" "=S")
15398         (plus:SI (match_dup 3)
15399                  (const_int 2)))
15400    (use (reg:SI 19))]
15401   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15402   "movsw"
15403   [(set_attr "type" "str")
15404    (set_attr "memory" "both")
15405    (set_attr "mode" "HI")])
15406
15407 (define_insn "strmovhi_rex_1"
15408   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15409         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15410    (set (match_operand:DI 0 "register_operand" "=D")
15411         (plus:DI (match_dup 2)
15412                  (const_int 2)))
15413    (set (match_operand:DI 1 "register_operand" "=S")
15414         (plus:DI (match_dup 3)
15415                  (const_int 2)))
15416    (use (reg:SI 19))]
15417   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15418   "movsw"
15419   [(set_attr "type" "str")
15420    (set_attr "memory" "both")
15421    (set_attr "mode" "HI")])
15422
15423 (define_insn "strmovqi_1"
15424   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15425         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15426    (set (match_operand:SI 0 "register_operand" "=D")
15427         (plus:SI (match_dup 2)
15428                  (const_int 1)))
15429    (set (match_operand:SI 1 "register_operand" "=S")
15430         (plus:SI (match_dup 3)
15431                  (const_int 1)))
15432    (use (reg:SI 19))]
15433   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15434   "movsb"
15435   [(set_attr "type" "str")
15436    (set_attr "memory" "both")
15437    (set_attr "mode" "QI")])
15438
15439 (define_insn "strmovqi_rex_1"
15440   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15441         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15442    (set (match_operand:DI 0 "register_operand" "=D")
15443         (plus:DI (match_dup 2)
15444                  (const_int 1)))
15445    (set (match_operand:DI 1 "register_operand" "=S")
15446         (plus:DI (match_dup 3)
15447                  (const_int 1)))
15448    (use (reg:SI 19))]
15449   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15450   "movsb"
15451   [(set_attr "type" "str")
15452    (set_attr "memory" "both")
15453    (set_attr "mode" "QI")])
15454
15455 (define_insn "rep_movdi_rex64"
15456   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15457    (set (match_operand:DI 0 "register_operand" "=D") 
15458         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15459                             (const_int 3))
15460                  (match_operand:DI 3 "register_operand" "0")))
15461    (set (match_operand:DI 1 "register_operand" "=S") 
15462         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15463                  (match_operand:DI 4 "register_operand" "1")))
15464    (set (mem:BLK (match_dup 3))
15465         (mem:BLK (match_dup 4)))
15466    (use (match_dup 5))
15467    (use (reg:SI 19))]
15468   "TARGET_64BIT"
15469   "{rep\;movsq|rep movsq}"
15470   [(set_attr "type" "str")
15471    (set_attr "prefix_rep" "1")
15472    (set_attr "memory" "both")
15473    (set_attr "mode" "DI")])
15474
15475 (define_insn "rep_movsi"
15476   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15477    (set (match_operand:SI 0 "register_operand" "=D") 
15478         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15479                             (const_int 2))
15480                  (match_operand:SI 3 "register_operand" "0")))
15481    (set (match_operand:SI 1 "register_operand" "=S") 
15482         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15483                  (match_operand:SI 4 "register_operand" "1")))
15484    (set (mem:BLK (match_dup 3))
15485         (mem:BLK (match_dup 4)))
15486    (use (match_dup 5))
15487    (use (reg:SI 19))]
15488   "!TARGET_64BIT"
15489   "{rep\;movsl|rep movsd}"
15490   [(set_attr "type" "str")
15491    (set_attr "prefix_rep" "1")
15492    (set_attr "memory" "both")
15493    (set_attr "mode" "SI")])
15494
15495 (define_insn "rep_movsi_rex64"
15496   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15497    (set (match_operand:DI 0 "register_operand" "=D") 
15498         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15499                             (const_int 2))
15500                  (match_operand:DI 3 "register_operand" "0")))
15501    (set (match_operand:DI 1 "register_operand" "=S") 
15502         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15503                  (match_operand:DI 4 "register_operand" "1")))
15504    (set (mem:BLK (match_dup 3))
15505         (mem:BLK (match_dup 4)))
15506    (use (match_dup 5))
15507    (use (reg:SI 19))]
15508   "TARGET_64BIT"
15509   "{rep\;movsl|rep movsd}"
15510   [(set_attr "type" "str")
15511    (set_attr "prefix_rep" "1")
15512    (set_attr "memory" "both")
15513    (set_attr "mode" "SI")])
15514
15515 (define_insn "rep_movqi"
15516   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15517    (set (match_operand:SI 0 "register_operand" "=D") 
15518         (plus:SI (match_operand:SI 3 "register_operand" "0")
15519                  (match_operand:SI 5 "register_operand" "2")))
15520    (set (match_operand:SI 1 "register_operand" "=S") 
15521         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15522    (set (mem:BLK (match_dup 3))
15523         (mem:BLK (match_dup 4)))
15524    (use (match_dup 5))
15525    (use (reg:SI 19))]
15526   "!TARGET_64BIT"
15527   "{rep\;movsb|rep movsb}"
15528   [(set_attr "type" "str")
15529    (set_attr "prefix_rep" "1")
15530    (set_attr "memory" "both")
15531    (set_attr "mode" "SI")])
15532
15533 (define_insn "rep_movqi_rex64"
15534   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15535    (set (match_operand:DI 0 "register_operand" "=D") 
15536         (plus:DI (match_operand:DI 3 "register_operand" "0")
15537                  (match_operand:DI 5 "register_operand" "2")))
15538    (set (match_operand:DI 1 "register_operand" "=S") 
15539         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15540    (set (mem:BLK (match_dup 3))
15541         (mem:BLK (match_dup 4)))
15542    (use (match_dup 5))
15543    (use (reg:SI 19))]
15544   "TARGET_64BIT"
15545   "{rep\;movsb|rep movsb}"
15546   [(set_attr "type" "str")
15547    (set_attr "prefix_rep" "1")
15548    (set_attr "memory" "both")
15549    (set_attr "mode" "SI")])
15550
15551 (define_expand "clrstrsi"
15552    [(use (match_operand:BLK 0 "memory_operand" ""))
15553     (use (match_operand:SI 1 "nonmemory_operand" ""))
15554     (use (match_operand 2 "const_int_operand" ""))]
15555   ""
15556 {
15557  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15558    DONE;
15559  else
15560    FAIL;
15561 })
15562
15563 (define_expand "clrstrdi"
15564    [(use (match_operand:BLK 0 "memory_operand" ""))
15565     (use (match_operand:DI 1 "nonmemory_operand" ""))
15566     (use (match_operand 2 "const_int_operand" ""))]
15567   "TARGET_64BIT"
15568 {
15569  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15570    DONE;
15571  else
15572    FAIL;
15573 })
15574
15575 ;; Most CPUs don't like single string operations
15576 ;; Handle this case here to simplify previous expander.
15577
15578 (define_expand "strsetdi_rex64"
15579   [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15580         (match_operand:DI 1 "register_operand" ""))
15581    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15582               (clobber (reg:CC 17))])]
15583   "TARGET_64BIT"
15584 {
15585   if (TARGET_SINGLE_STRINGOP || optimize_size)
15586     {
15587       emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15588       DONE;
15589     }
15590 })
15591
15592 (define_expand "strsetsi"
15593   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15594         (match_operand:SI 1 "register_operand" ""))
15595    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15596               (clobber (reg:CC 17))])]
15597   ""
15598 {
15599   if (TARGET_64BIT)
15600     {
15601       emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15602       DONE;
15603     }
15604   else if (TARGET_SINGLE_STRINGOP || optimize_size)
15605     {
15606       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15607       DONE;
15608     }
15609 })
15610
15611 (define_expand "strsetsi_rex64"
15612   [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15613         (match_operand:SI 1 "register_operand" ""))
15614    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15615               (clobber (reg:CC 17))])]
15616   "TARGET_64BIT"
15617 {
15618   if (TARGET_SINGLE_STRINGOP || optimize_size)
15619     {
15620       emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15621       DONE;
15622     }
15623 })
15624
15625 (define_expand "strsethi"
15626   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15627         (match_operand:HI 1 "register_operand" ""))
15628    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15629               (clobber (reg:CC 17))])]
15630   ""
15631 {
15632   if (TARGET_64BIT)
15633     {
15634       emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15635       DONE;
15636     }
15637   else if (TARGET_SINGLE_STRINGOP || optimize_size)
15638     {
15639       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15640       DONE;
15641     }
15642 })
15643
15644 (define_expand "strsethi_rex64"
15645   [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15646         (match_operand:HI 1 "register_operand" ""))
15647    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15648               (clobber (reg:CC 17))])]
15649   "TARGET_64BIT"
15650 {
15651   if (TARGET_SINGLE_STRINGOP || optimize_size)
15652     {
15653       emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15654       DONE;
15655     }
15656 })
15657
15658 (define_expand "strsetqi"
15659   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15660         (match_operand:QI 1 "register_operand" ""))
15661    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15662               (clobber (reg:CC 17))])]
15663   ""
15664 {
15665   if (TARGET_64BIT)
15666     {
15667       emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15668       DONE;
15669     }
15670   else if (TARGET_SINGLE_STRINGOP || optimize_size)
15671     {
15672       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15673       DONE;
15674     }
15675 })
15676
15677 (define_expand "strsetqi_rex64"
15678   [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15679         (match_operand:QI 1 "register_operand" ""))
15680    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15681               (clobber (reg:CC 17))])]
15682   "TARGET_64BIT"
15683 {
15684   if (TARGET_SINGLE_STRINGOP || optimize_size)
15685     {
15686       emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15687       DONE;
15688     }
15689 })
15690
15691 (define_insn "strsetdi_rex_1"
15692   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15693         (match_operand:SI 2 "register_operand" "a"))
15694    (set (match_operand:DI 0 "register_operand" "=D")
15695         (plus:DI (match_dup 1)
15696                  (const_int 8)))
15697    (use (reg:SI 19))]
15698   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15699   "stosq"
15700   [(set_attr "type" "str")
15701    (set_attr "memory" "store")
15702    (set_attr "mode" "DI")])
15703
15704 (define_insn "strsetsi_1"
15705   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15706         (match_operand:SI 2 "register_operand" "a"))
15707    (set (match_operand:SI 0 "register_operand" "=D")
15708         (plus:SI (match_dup 1)
15709                  (const_int 4)))
15710    (use (reg:SI 19))]
15711   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15712   "{stosl|stosd}"
15713   [(set_attr "type" "str")
15714    (set_attr "memory" "store")
15715    (set_attr "mode" "SI")])
15716
15717 (define_insn "strsetsi_rex_1"
15718   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15719         (match_operand:SI 2 "register_operand" "a"))
15720    (set (match_operand:DI 0 "register_operand" "=D")
15721         (plus:DI (match_dup 1)
15722                  (const_int 4)))
15723    (use (reg:SI 19))]
15724   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15725   "{stosl|stosd}"
15726   [(set_attr "type" "str")
15727    (set_attr "memory" "store")
15728    (set_attr "mode" "SI")])
15729
15730 (define_insn "strsethi_1"
15731   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15732         (match_operand:HI 2 "register_operand" "a"))
15733    (set (match_operand:SI 0 "register_operand" "=D")
15734         (plus:SI (match_dup 1)
15735                  (const_int 2)))
15736    (use (reg:SI 19))]
15737   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15738   "stosw"
15739   [(set_attr "type" "str")
15740    (set_attr "memory" "store")
15741    (set_attr "mode" "HI")])
15742
15743 (define_insn "strsethi_rex_1"
15744   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15745         (match_operand:HI 2 "register_operand" "a"))
15746    (set (match_operand:DI 0 "register_operand" "=D")
15747         (plus:DI (match_dup 1)
15748                  (const_int 2)))
15749    (use (reg:SI 19))]
15750   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15751   "stosw"
15752   [(set_attr "type" "str")
15753    (set_attr "memory" "store")
15754    (set_attr "mode" "HI")])
15755
15756 (define_insn "strsetqi_1"
15757   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15758         (match_operand:QI 2 "register_operand" "a"))
15759    (set (match_operand:SI 0 "register_operand" "=D")
15760         (plus:SI (match_dup 1)
15761                  (const_int 1)))
15762    (use (reg:SI 19))]
15763   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15764   "stosb"
15765   [(set_attr "type" "str")
15766    (set_attr "memory" "store")
15767    (set_attr "mode" "QI")])
15768
15769 (define_insn "strsetqi_rex_1"
15770   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15771         (match_operand:QI 2 "register_operand" "a"))
15772    (set (match_operand:DI 0 "register_operand" "=D")
15773         (plus:DI (match_dup 1)
15774                  (const_int 1)))
15775    (use (reg:SI 19))]
15776   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15777   "stosb"
15778   [(set_attr "type" "str")
15779    (set_attr "memory" "store")
15780    (set_attr "mode" "QI")])
15781
15782 (define_insn "rep_stosdi_rex64"
15783   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15784    (set (match_operand:DI 0 "register_operand" "=D") 
15785         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15786                             (const_int 3))
15787                  (match_operand:DI 3 "register_operand" "0")))
15788    (set (mem:BLK (match_dup 3))
15789         (const_int 0))
15790    (use (match_operand:DI 2 "register_operand" "a"))
15791    (use (match_dup 4))
15792    (use (reg:SI 19))]
15793   "TARGET_64BIT"
15794   "{rep\;stosq|rep stosq}"
15795   [(set_attr "type" "str")
15796    (set_attr "prefix_rep" "1")
15797    (set_attr "memory" "store")
15798    (set_attr "mode" "DI")])
15799
15800 (define_insn "rep_stossi"
15801   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15802    (set (match_operand:SI 0 "register_operand" "=D") 
15803         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15804                             (const_int 2))
15805                  (match_operand:SI 3 "register_operand" "0")))
15806    (set (mem:BLK (match_dup 3))
15807         (const_int 0))
15808    (use (match_operand:SI 2 "register_operand" "a"))
15809    (use (match_dup 4))
15810    (use (reg:SI 19))]
15811   "!TARGET_64BIT"
15812   "{rep\;stosl|rep stosd}"
15813   [(set_attr "type" "str")
15814    (set_attr "prefix_rep" "1")
15815    (set_attr "memory" "store")
15816    (set_attr "mode" "SI")])
15817
15818 (define_insn "rep_stossi_rex64"
15819   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15820    (set (match_operand:DI 0 "register_operand" "=D") 
15821         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15822                             (const_int 2))
15823                  (match_operand:DI 3 "register_operand" "0")))
15824    (set (mem:BLK (match_dup 3))
15825         (const_int 0))
15826    (use (match_operand:SI 2 "register_operand" "a"))
15827    (use (match_dup 4))
15828    (use (reg:SI 19))]
15829   "TARGET_64BIT"
15830   "{rep\;stosl|rep stosd}"
15831   [(set_attr "type" "str")
15832    (set_attr "prefix_rep" "1")
15833    (set_attr "memory" "store")
15834    (set_attr "mode" "SI")])
15835
15836 (define_insn "rep_stosqi"
15837   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15838    (set (match_operand:SI 0 "register_operand" "=D") 
15839         (plus:SI (match_operand:SI 3 "register_operand" "0")
15840                  (match_operand:SI 4 "register_operand" "1")))
15841    (set (mem:BLK (match_dup 3))
15842         (const_int 0))
15843    (use (match_operand:QI 2 "register_operand" "a"))
15844    (use (match_dup 4))
15845    (use (reg:SI 19))]
15846   "!TARGET_64BIT"
15847   "{rep\;stosb|rep stosb}"
15848   [(set_attr "type" "str")
15849    (set_attr "prefix_rep" "1")
15850    (set_attr "memory" "store")
15851    (set_attr "mode" "QI")])
15852
15853 (define_insn "rep_stosqi_rex64"
15854   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15855    (set (match_operand:DI 0 "register_operand" "=D") 
15856         (plus:DI (match_operand:DI 3 "register_operand" "0")
15857                  (match_operand:DI 4 "register_operand" "1")))
15858    (set (mem:BLK (match_dup 3))
15859         (const_int 0))
15860    (use (match_operand:QI 2 "register_operand" "a"))
15861    (use (match_dup 4))
15862    (use (reg:DI 19))]
15863   "TARGET_64BIT"
15864   "{rep\;stosb|rep stosb}"
15865   [(set_attr "type" "str")
15866    (set_attr "prefix_rep" "1")
15867    (set_attr "memory" "store")
15868    (set_attr "mode" "QI")])
15869
15870 (define_expand "cmpstrsi"
15871   [(set (match_operand:SI 0 "register_operand" "")
15872         (compare:SI (match_operand:BLK 1 "general_operand" "")
15873                     (match_operand:BLK 2 "general_operand" "")))
15874    (use (match_operand 3 "general_operand" ""))
15875    (use (match_operand 4 "immediate_operand" ""))]
15876   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15877 {
15878   rtx addr1, addr2, out, outlow, count, countreg, align;
15879
15880   /* Can't use this if the user has appropriated esi or edi.  */
15881   if (global_regs[4] || global_regs[5])
15882     FAIL;
15883
15884   out = operands[0];
15885   if (GET_CODE (out) != REG)
15886     out = gen_reg_rtx (SImode);
15887
15888   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15889   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15890   
15891   count = operands[3];
15892   countreg = ix86_zero_extend_to_Pmode (count);
15893
15894   /* %%% Iff we are testing strict equality, we can use known alignment
15895      to good advantage.  This may be possible with combine, particularly
15896      once cc0 is dead.  */
15897   align = operands[4];
15898
15899   emit_insn (gen_cld ());
15900   if (GET_CODE (count) == CONST_INT)
15901     {
15902       if (INTVAL (count) == 0)
15903         {
15904           emit_move_insn (operands[0], const0_rtx);
15905           DONE;
15906         }
15907       if (TARGET_64BIT)
15908         emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15909                                           addr1, addr2, countreg));
15910       else
15911         emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15912                                       addr1, addr2, countreg));
15913     }
15914   else
15915     {
15916       if (TARGET_64BIT)
15917         {
15918           emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15919           emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15920                                          addr1, addr2, countreg));
15921         }
15922       else
15923         {
15924           emit_insn (gen_cmpsi_1 (countreg, countreg));
15925           emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15926                                      addr1, addr2, countreg));
15927         }
15928     }
15929
15930   outlow = gen_lowpart (QImode, out);
15931   emit_insn (gen_cmpintqi (outlow));
15932   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15933
15934   if (operands[0] != out)
15935     emit_move_insn (operands[0], out);
15936
15937   DONE;
15938 })
15939
15940 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15941
15942 (define_expand "cmpintqi"
15943   [(set (match_dup 1)
15944         (gtu:QI (reg:CC 17) (const_int 0)))
15945    (set (match_dup 2)
15946         (ltu:QI (reg:CC 17) (const_int 0)))
15947    (parallel [(set (match_operand:QI 0 "register_operand" "")
15948                    (minus:QI (match_dup 1)
15949                              (match_dup 2)))
15950               (clobber (reg:CC 17))])]
15951   ""
15952   "operands[1] = gen_reg_rtx (QImode);
15953    operands[2] = gen_reg_rtx (QImode);")
15954
15955 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15956 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15957
15958 (define_insn "cmpstrqi_nz_1"
15959   [(set (reg:CC 17)
15960         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15961                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15962    (use (match_operand:SI 6 "register_operand" "2"))
15963    (use (match_operand:SI 3 "immediate_operand" "i"))
15964    (use (reg:SI 19))
15965    (clobber (match_operand:SI 0 "register_operand" "=S"))
15966    (clobber (match_operand:SI 1 "register_operand" "=D"))
15967    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15968   "!TARGET_64BIT"
15969   "repz{\;| }cmpsb"
15970   [(set_attr "type" "str")
15971    (set_attr "mode" "QI")
15972    (set_attr "prefix_rep" "1")])
15973
15974 (define_insn "cmpstrqi_nz_rex_1"
15975   [(set (reg:CC 17)
15976         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15977                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15978    (use (match_operand:DI 6 "register_operand" "2"))
15979    (use (match_operand:SI 3 "immediate_operand" "i"))
15980    (use (reg:SI 19))
15981    (clobber (match_operand:DI 0 "register_operand" "=S"))
15982    (clobber (match_operand:DI 1 "register_operand" "=D"))
15983    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15984   "TARGET_64BIT"
15985   "repz{\;| }cmpsb"
15986   [(set_attr "type" "str")
15987    (set_attr "mode" "QI")
15988    (set_attr "prefix_rep" "1")])
15989
15990 ;; The same, but the count is not known to not be zero.
15991
15992 (define_insn "cmpstrqi_1"
15993   [(set (reg:CC 17)
15994         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15995                              (const_int 0))
15996           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15997                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15998           (const_int 0)))
15999    (use (match_operand:SI 3 "immediate_operand" "i"))
16000    (use (reg:CC 17))
16001    (use (reg:SI 19))
16002    (clobber (match_operand:SI 0 "register_operand" "=S"))
16003    (clobber (match_operand:SI 1 "register_operand" "=D"))
16004    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16005   "!TARGET_64BIT"
16006   "repz{\;| }cmpsb"
16007   [(set_attr "type" "str")
16008    (set_attr "mode" "QI")
16009    (set_attr "prefix_rep" "1")])
16010
16011 (define_insn "cmpstrqi_rex_1"
16012   [(set (reg:CC 17)
16013         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16014                              (const_int 0))
16015           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16016                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16017           (const_int 0)))
16018    (use (match_operand:SI 3 "immediate_operand" "i"))
16019    (use (reg:CC 17))
16020    (use (reg:SI 19))
16021    (clobber (match_operand:DI 0 "register_operand" "=S"))
16022    (clobber (match_operand:DI 1 "register_operand" "=D"))
16023    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16024   "TARGET_64BIT"
16025   "repz{\;| }cmpsb"
16026   [(set_attr "type" "str")
16027    (set_attr "mode" "QI")
16028    (set_attr "prefix_rep" "1")])
16029
16030 (define_expand "strlensi"
16031   [(set (match_operand:SI 0 "register_operand" "")
16032         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16033                     (match_operand:QI 2 "immediate_operand" "")
16034                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16035   ""
16036 {
16037  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16038    DONE;
16039  else
16040    FAIL;
16041 })
16042
16043 (define_expand "strlendi"
16044   [(set (match_operand:DI 0 "register_operand" "")
16045         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16046                     (match_operand:QI 2 "immediate_operand" "")
16047                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16048   ""
16049 {
16050  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16051    DONE;
16052  else
16053    FAIL;
16054 })
16055
16056 (define_insn "strlenqi_1"
16057   [(set (match_operand:SI 0 "register_operand" "=&c")
16058         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16059                     (match_operand:QI 2 "register_operand" "a")
16060                     (match_operand:SI 3 "immediate_operand" "i")
16061                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16062    (use (reg:SI 19))
16063    (clobber (match_operand:SI 1 "register_operand" "=D"))
16064    (clobber (reg:CC 17))]
16065   "!TARGET_64BIT"
16066   "repnz{\;| }scasb"
16067   [(set_attr "type" "str")
16068    (set_attr "mode" "QI")
16069    (set_attr "prefix_rep" "1")])
16070
16071 (define_insn "strlenqi_rex_1"
16072   [(set (match_operand:DI 0 "register_operand" "=&c")
16073         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16074                     (match_operand:QI 2 "register_operand" "a")
16075                     (match_operand:DI 3 "immediate_operand" "i")
16076                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16077    (use (reg:SI 19))
16078    (clobber (match_operand:DI 1 "register_operand" "=D"))
16079    (clobber (reg:CC 17))]
16080   "TARGET_64BIT"
16081   "repnz{\;| }scasb"
16082   [(set_attr "type" "str")
16083    (set_attr "mode" "QI")
16084    (set_attr "prefix_rep" "1")])
16085
16086 ;; Peephole optimizations to clean up after cmpstr*.  This should be
16087 ;; handled in combine, but it is not currently up to the task.
16088 ;; When used for their truth value, the cmpstr* expanders generate
16089 ;; code like this:
16090 ;;
16091 ;;   repz cmpsb
16092 ;;   seta       %al
16093 ;;   setb       %dl
16094 ;;   cmpb       %al, %dl
16095 ;;   jcc        label
16096 ;;
16097 ;; The intermediate three instructions are unnecessary.
16098
16099 ;; This one handles cmpstr*_nz_1...
16100 (define_peephole2
16101   [(parallel[
16102      (set (reg:CC 17)
16103           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16104                       (mem:BLK (match_operand 5 "register_operand" ""))))
16105      (use (match_operand 6 "register_operand" ""))
16106      (use (match_operand:SI 3 "immediate_operand" ""))
16107      (use (reg:SI 19))
16108      (clobber (match_operand 0 "register_operand" ""))
16109      (clobber (match_operand 1 "register_operand" ""))
16110      (clobber (match_operand 2 "register_operand" ""))])
16111    (set (match_operand:QI 7 "register_operand" "")
16112         (gtu:QI (reg:CC 17) (const_int 0)))
16113    (set (match_operand:QI 8 "register_operand" "")
16114         (ltu:QI (reg:CC 17) (const_int 0)))
16115    (set (reg 17)
16116         (compare (match_dup 7) (match_dup 8)))
16117   ]
16118   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16119   [(parallel[
16120      (set (reg:CC 17)
16121           (compare:CC (mem:BLK (match_dup 4))
16122                       (mem:BLK (match_dup 5))))
16123      (use (match_dup 6))
16124      (use (match_dup 3))
16125      (use (reg:SI 19))
16126      (clobber (match_dup 0))
16127      (clobber (match_dup 1))
16128      (clobber (match_dup 2))])]
16129   "")
16130
16131 ;; ...and this one handles cmpstr*_1.
16132 (define_peephole2
16133   [(parallel[
16134      (set (reg:CC 17)
16135           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16136                                (const_int 0))
16137             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16138                         (mem:BLK (match_operand 5 "register_operand" "")))
16139             (const_int 0)))
16140      (use (match_operand:SI 3 "immediate_operand" ""))
16141      (use (reg:CC 17))
16142      (use (reg:SI 19))
16143      (clobber (match_operand 0 "register_operand" ""))
16144      (clobber (match_operand 1 "register_operand" ""))
16145      (clobber (match_operand 2 "register_operand" ""))])
16146    (set (match_operand:QI 7 "register_operand" "")
16147         (gtu:QI (reg:CC 17) (const_int 0)))
16148    (set (match_operand:QI 8 "register_operand" "")
16149         (ltu:QI (reg:CC 17) (const_int 0)))
16150    (set (reg 17)
16151         (compare (match_dup 7) (match_dup 8)))
16152   ]
16153   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16154   [(parallel[
16155      (set (reg:CC 17)
16156           (if_then_else:CC (ne (match_dup 6)
16157                                (const_int 0))
16158             (compare:CC (mem:BLK (match_dup 4))
16159                         (mem:BLK (match_dup 5)))
16160             (const_int 0)))
16161      (use (match_dup 3))
16162      (use (reg:CC 17))
16163      (use (reg:SI 19))
16164      (clobber (match_dup 0))
16165      (clobber (match_dup 1))
16166      (clobber (match_dup 2))])]
16167   "")
16168
16169
16170 \f
16171 ;; Conditional move instructions.
16172
16173 (define_expand "movdicc"
16174   [(set (match_operand:DI 0 "register_operand" "")
16175         (if_then_else:DI (match_operand 1 "comparison_operator" "")
16176                          (match_operand:DI 2 "general_operand" "")
16177                          (match_operand:DI 3 "general_operand" "")))]
16178   "TARGET_64BIT"
16179   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16180
16181 (define_insn "x86_movdicc_0_m1_rex64"
16182   [(set (match_operand:DI 0 "register_operand" "=r")
16183         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16184           (const_int -1)
16185           (const_int 0)))
16186    (clobber (reg:CC 17))]
16187   "TARGET_64BIT"
16188   "sbb{q}\t%0, %0"
16189   ; Since we don't have the proper number of operands for an alu insn,
16190   ; fill in all the blanks.
16191   [(set_attr "type" "alu")
16192    (set_attr "pent_pair" "pu")
16193    (set_attr "memory" "none")
16194    (set_attr "imm_disp" "false")
16195    (set_attr "mode" "DI")
16196    (set_attr "length_immediate" "0")])
16197
16198 (define_insn "movdicc_c_rex64"
16199   [(set (match_operand:DI 0 "register_operand" "=r,r")
16200         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
16201                                 [(reg 17) (const_int 0)])
16202                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16203                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16204   "TARGET_64BIT && TARGET_CMOVE
16205    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16206   "@
16207    cmov%O2%C1\t{%2, %0|%0, %2}
16208    cmov%O2%c1\t{%3, %0|%0, %3}"
16209   [(set_attr "type" "icmov")
16210    (set_attr "mode" "DI")])
16211
16212 (define_expand "movsicc"
16213   [(set (match_operand:SI 0 "register_operand" "")
16214         (if_then_else:SI (match_operand 1 "comparison_operator" "")
16215                          (match_operand:SI 2 "general_operand" "")
16216                          (match_operand:SI 3 "general_operand" "")))]
16217   ""
16218   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16219
16220 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16221 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16222 ;; So just document what we're doing explicitly.
16223
16224 (define_insn "x86_movsicc_0_m1"
16225   [(set (match_operand:SI 0 "register_operand" "=r")
16226         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16227           (const_int -1)
16228           (const_int 0)))
16229    (clobber (reg:CC 17))]
16230   ""
16231   "sbb{l}\t%0, %0"
16232   ; Since we don't have the proper number of operands for an alu insn,
16233   ; fill in all the blanks.
16234   [(set_attr "type" "alu")
16235    (set_attr "pent_pair" "pu")
16236    (set_attr "memory" "none")
16237    (set_attr "imm_disp" "false")
16238    (set_attr "mode" "SI")
16239    (set_attr "length_immediate" "0")])
16240
16241 (define_insn "*movsicc_noc"
16242   [(set (match_operand:SI 0 "register_operand" "=r,r")
16243         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
16244                                 [(reg 17) (const_int 0)])
16245                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16246                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16247   "TARGET_CMOVE
16248    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16249   "@
16250    cmov%O2%C1\t{%2, %0|%0, %2}
16251    cmov%O2%c1\t{%3, %0|%0, %3}"
16252   [(set_attr "type" "icmov")
16253    (set_attr "mode" "SI")])
16254
16255 (define_expand "movhicc"
16256   [(set (match_operand:HI 0 "register_operand" "")
16257         (if_then_else:HI (match_operand 1 "comparison_operator" "")
16258                          (match_operand:HI 2 "general_operand" "")
16259                          (match_operand:HI 3 "general_operand" "")))]
16260   "TARGET_HIMODE_MATH"
16261   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16262
16263 (define_insn "*movhicc_noc"
16264   [(set (match_operand:HI 0 "register_operand" "=r,r")
16265         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
16266                                 [(reg 17) (const_int 0)])
16267                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16268                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16269   "TARGET_CMOVE
16270    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16271   "@
16272    cmov%O2%C1\t{%2, %0|%0, %2}
16273    cmov%O2%c1\t{%3, %0|%0, %3}"
16274   [(set_attr "type" "icmov")
16275    (set_attr "mode" "HI")])
16276
16277 (define_expand "movqicc"
16278   [(set (match_operand:QI 0 "register_operand" "")
16279         (if_then_else:QI (match_operand 1 "comparison_operator" "")
16280                          (match_operand:QI 2 "general_operand" "")
16281                          (match_operand:QI 3 "general_operand" "")))]
16282   "TARGET_QIMODE_MATH"
16283   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16284
16285 (define_insn_and_split "*movqicc_noc"
16286   [(set (match_operand:QI 0 "register_operand" "=r,r")
16287         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16288                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16289                       (match_operand:QI 2 "register_operand" "r,0")
16290                       (match_operand:QI 3 "register_operand" "0,r")))]
16291   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16292   "#"
16293   "&& reload_completed"
16294   [(set (match_dup 0)
16295         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16296                       (match_dup 2)
16297                       (match_dup 3)))]
16298   "operands[0] = gen_lowpart (SImode, operands[0]);
16299    operands[2] = gen_lowpart (SImode, operands[2]);
16300    operands[3] = gen_lowpart (SImode, operands[3]);"
16301   [(set_attr "type" "icmov")
16302    (set_attr "mode" "SI")])
16303
16304 (define_expand "movsfcc"
16305   [(set (match_operand:SF 0 "register_operand" "")
16306         (if_then_else:SF (match_operand 1 "comparison_operator" "")
16307                          (match_operand:SF 2 "register_operand" "")
16308                          (match_operand:SF 3 "register_operand" "")))]
16309   "TARGET_CMOVE"
16310   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16311
16312 (define_insn "*movsfcc_1"
16313   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16314         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
16315                                 [(reg 17) (const_int 0)])
16316                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16317                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16318   "TARGET_CMOVE
16319    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16320   "@
16321    fcmov%F1\t{%2, %0|%0, %2}
16322    fcmov%f1\t{%3, %0|%0, %3}
16323    cmov%O2%C1\t{%2, %0|%0, %2}
16324    cmov%O2%c1\t{%3, %0|%0, %3}"
16325   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16326    (set_attr "mode" "SF,SF,SI,SI")])
16327
16328 (define_expand "movdfcc"
16329   [(set (match_operand:DF 0 "register_operand" "")
16330         (if_then_else:DF (match_operand 1 "comparison_operator" "")
16331                          (match_operand:DF 2 "register_operand" "")
16332                          (match_operand:DF 3 "register_operand" "")))]
16333   "TARGET_CMOVE"
16334   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16335
16336 (define_insn "*movdfcc_1"
16337   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16338         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16339                                 [(reg 17) (const_int 0)])
16340                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16341                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16342   "!TARGET_64BIT && TARGET_CMOVE
16343    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16344   "@
16345    fcmov%F1\t{%2, %0|%0, %2}
16346    fcmov%f1\t{%3, %0|%0, %3}
16347    #
16348    #"
16349   [(set_attr "type" "fcmov,fcmov,multi,multi")
16350    (set_attr "mode" "DF")])
16351
16352 (define_insn "*movdfcc_1_rex64"
16353   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16354         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16355                                 [(reg 17) (const_int 0)])
16356                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16357                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16358   "TARGET_64BIT && TARGET_CMOVE
16359    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16360   "@
16361    fcmov%F1\t{%2, %0|%0, %2}
16362    fcmov%f1\t{%3, %0|%0, %3}
16363    cmov%O2%C1\t{%2, %0|%0, %2}
16364    cmov%O2%c1\t{%3, %0|%0, %3}"
16365   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16366    (set_attr "mode" "DF")])
16367
16368 (define_split
16369   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16370         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16371                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16372                       (match_operand:DF 2 "nonimmediate_operand" "")
16373                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16374   "!TARGET_64BIT && reload_completed"
16375   [(set (match_dup 2)
16376         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16377                       (match_dup 5)
16378                       (match_dup 7)))
16379    (set (match_dup 3)
16380         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16381                       (match_dup 6)
16382                       (match_dup 8)))]
16383   "split_di (operands+2, 1, operands+5, operands+6);
16384    split_di (operands+3, 1, operands+7, operands+8);
16385    split_di (operands, 1, operands+2, operands+3);")
16386
16387 (define_expand "movxfcc"
16388   [(set (match_operand:XF 0 "register_operand" "")
16389         (if_then_else:XF (match_operand 1 "comparison_operator" "")
16390                          (match_operand:XF 2 "register_operand" "")
16391                          (match_operand:XF 3 "register_operand" "")))]
16392   "TARGET_CMOVE"
16393   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16394
16395 (define_insn "*movxfcc_1"
16396   [(set (match_operand:XF 0 "register_operand" "=f,f")
16397         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16398                                 [(reg 17) (const_int 0)])
16399                       (match_operand:XF 2 "register_operand" "f,0")
16400                       (match_operand:XF 3 "register_operand" "0,f")))]
16401   "TARGET_CMOVE"
16402   "@
16403    fcmov%F1\t{%2, %0|%0, %2}
16404    fcmov%f1\t{%3, %0|%0, %3}"
16405   [(set_attr "type" "fcmov")
16406    (set_attr "mode" "XF")])
16407
16408 (define_expand "minsf3"
16409   [(parallel [
16410      (set (match_operand:SF 0 "register_operand" "")
16411           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16412                                (match_operand:SF 2 "nonimmediate_operand" ""))
16413                            (match_dup 1)
16414                            (match_dup 2)))
16415      (clobber (reg:CC 17))])]
16416   "TARGET_SSE"
16417   "")
16418
16419 (define_insn "*minsf"
16420   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16421         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16422                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16423                          (match_dup 1)
16424                          (match_dup 2)))
16425    (clobber (reg:CC 17))]
16426   "TARGET_SSE && TARGET_IEEE_FP"
16427   "#")
16428
16429 (define_insn "*minsf_nonieee"
16430   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16431         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16432                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16433                          (match_dup 1)
16434                          (match_dup 2)))
16435    (clobber (reg:CC 17))]
16436   "TARGET_SSE && !TARGET_IEEE_FP
16437    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16438   "#")
16439
16440 (define_split
16441   [(set (match_operand:SF 0 "register_operand" "")
16442         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16443                              (match_operand:SF 2 "nonimmediate_operand" ""))
16444                          (match_operand:SF 3 "register_operand" "")
16445                          (match_operand:SF 4 "nonimmediate_operand" "")))
16446    (clobber (reg:CC 17))]
16447   "SSE_REG_P (operands[0]) && reload_completed
16448    && ((operands_match_p (operands[1], operands[3])
16449         && operands_match_p (operands[2], operands[4]))
16450        || (operands_match_p (operands[1], operands[4])
16451            && operands_match_p (operands[2], operands[3])))"
16452   [(set (match_dup 0)
16453         (if_then_else:SF (lt (match_dup 1)
16454                              (match_dup 2))
16455                          (match_dup 1)
16456                          (match_dup 2)))])
16457
16458 ;; Conditional addition patterns
16459 (define_expand "addqicc"
16460   [(match_operand:QI 0 "register_operand" "")
16461    (match_operand 1 "comparison_operator" "")
16462    (match_operand:QI 2 "register_operand" "")
16463    (match_operand:QI 3 "const_int_operand" "")]
16464   ""
16465   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16466
16467 (define_expand "addhicc"
16468   [(match_operand:HI 0 "register_operand" "")
16469    (match_operand 1 "comparison_operator" "")
16470    (match_operand:HI 2 "register_operand" "")
16471    (match_operand:HI 3 "const_int_operand" "")]
16472   ""
16473   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16474
16475 (define_expand "addsicc"
16476   [(match_operand:SI 0 "register_operand" "")
16477    (match_operand 1 "comparison_operator" "")
16478    (match_operand:SI 2 "register_operand" "")
16479    (match_operand:SI 3 "const_int_operand" "")]
16480   ""
16481   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16482
16483 (define_expand "adddicc"
16484   [(match_operand:DI 0 "register_operand" "")
16485    (match_operand 1 "comparison_operator" "")
16486    (match_operand:DI 2 "register_operand" "")
16487    (match_operand:DI 3 "const_int_operand" "")]
16488   "TARGET_64BIT"
16489   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16490
16491 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16492
16493 (define_split
16494   [(set (match_operand:SF 0 "fp_register_operand" "")
16495         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16496                              (match_operand:SF 2 "register_operand" ""))
16497                          (match_operand:SF 3 "register_operand" "")
16498                          (match_operand:SF 4 "register_operand" "")))
16499    (clobber (reg:CC 17))]
16500   "reload_completed
16501    && ((operands_match_p (operands[1], operands[3])
16502         && operands_match_p (operands[2], operands[4]))
16503        || (operands_match_p (operands[1], operands[4])
16504            && operands_match_p (operands[2], operands[3])))"
16505   [(set (reg:CCFP 17)
16506         (compare:CCFP (match_dup 2)
16507                       (match_dup 1)))
16508    (set (match_dup 0)
16509         (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16510                          (match_dup 1)
16511                          (match_dup 2)))])
16512
16513 (define_insn "*minsf_sse"
16514   [(set (match_operand:SF 0 "register_operand" "=x")
16515         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16516                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16517                          (match_dup 1)
16518                          (match_dup 2)))]
16519   "TARGET_SSE && reload_completed"
16520   "minss\t{%2, %0|%0, %2}"
16521   [(set_attr "type" "sse")
16522    (set_attr "mode" "SF")])
16523
16524 (define_expand "mindf3"
16525   [(parallel [
16526      (set (match_operand:DF 0 "register_operand" "")
16527           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16528                                (match_operand:DF 2 "nonimmediate_operand" ""))
16529                            (match_dup 1)
16530                            (match_dup 2)))
16531      (clobber (reg:CC 17))])]
16532   "TARGET_SSE2 && TARGET_SSE_MATH"
16533   "#")
16534
16535 (define_insn "*mindf"
16536   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16537         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16538                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16539                          (match_dup 1)
16540                          (match_dup 2)))
16541    (clobber (reg:CC 17))]
16542   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16543   "#")
16544
16545 (define_insn "*mindf_nonieee"
16546   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16547         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16548                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16549                          (match_dup 1)
16550                          (match_dup 2)))
16551    (clobber (reg:CC 17))]
16552   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16553    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16554   "#")
16555
16556 (define_split
16557   [(set (match_operand:DF 0 "register_operand" "")
16558         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16559                              (match_operand:DF 2 "nonimmediate_operand" ""))
16560                          (match_operand:DF 3 "register_operand" "")
16561                          (match_operand:DF 4 "nonimmediate_operand" "")))
16562    (clobber (reg:CC 17))]
16563   "SSE_REG_P (operands[0]) && reload_completed
16564    && ((operands_match_p (operands[1], operands[3])
16565         && operands_match_p (operands[2], operands[4]))
16566        || (operands_match_p (operands[1], operands[4])
16567            && operands_match_p (operands[2], operands[3])))"
16568   [(set (match_dup 0)
16569         (if_then_else:DF (lt (match_dup 1)
16570                              (match_dup 2))
16571                          (match_dup 1)
16572                          (match_dup 2)))])
16573
16574 ;; We can't represent the LT test directly.  Do this by swapping the operands.
16575 (define_split
16576   [(set (match_operand:DF 0 "fp_register_operand" "")
16577         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16578                              (match_operand:DF 2 "register_operand" ""))
16579                          (match_operand:DF 3 "register_operand" "")
16580                          (match_operand:DF 4 "register_operand" "")))
16581    (clobber (reg:CC 17))]
16582   "reload_completed
16583    && ((operands_match_p (operands[1], operands[3])
16584         && operands_match_p (operands[2], operands[4]))
16585        || (operands_match_p (operands[1], operands[4])
16586            && operands_match_p (operands[2], operands[3])))"
16587   [(set (reg:CCFP 17)
16588         (compare:CCFP (match_dup 2)
16589                       (match_dup 2)))
16590    (set (match_dup 0)
16591         (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16592                          (match_dup 1)
16593                          (match_dup 2)))])
16594
16595 (define_insn "*mindf_sse"
16596   [(set (match_operand:DF 0 "register_operand" "=Y")
16597         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16598                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16599                          (match_dup 1)
16600                          (match_dup 2)))]
16601   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16602   "minsd\t{%2, %0|%0, %2}"
16603   [(set_attr "type" "sse")
16604    (set_attr "mode" "DF")])
16605
16606 (define_expand "maxsf3"
16607   [(parallel [
16608      (set (match_operand:SF 0 "register_operand" "")
16609           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16610                                (match_operand:SF 2 "nonimmediate_operand" ""))
16611                            (match_dup 1)
16612                            (match_dup 2)))
16613      (clobber (reg:CC 17))])]
16614   "TARGET_SSE"
16615   "#")
16616
16617 (define_insn "*maxsf"
16618   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16619         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16620                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16621                          (match_dup 1)
16622                          (match_dup 2)))
16623    (clobber (reg:CC 17))]
16624   "TARGET_SSE && TARGET_IEEE_FP"
16625   "#")
16626
16627 (define_insn "*maxsf_nonieee"
16628   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16629         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16630                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16631                          (match_dup 1)
16632                          (match_dup 2)))
16633    (clobber (reg:CC 17))]
16634   "TARGET_SSE && !TARGET_IEEE_FP
16635    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16636   "#")
16637
16638 (define_split
16639   [(set (match_operand:SF 0 "register_operand" "")
16640         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16641                              (match_operand:SF 2 "nonimmediate_operand" ""))
16642                          (match_operand:SF 3 "register_operand" "")
16643                          (match_operand:SF 4 "nonimmediate_operand" "")))
16644    (clobber (reg:CC 17))]
16645   "SSE_REG_P (operands[0]) && reload_completed
16646    && ((operands_match_p (operands[1], operands[3])
16647         && operands_match_p (operands[2], operands[4]))
16648        || (operands_match_p (operands[1], operands[4])
16649            && operands_match_p (operands[2], operands[3])))"
16650   [(set (match_dup 0)
16651         (if_then_else:SF (gt (match_dup 1)
16652                              (match_dup 2))
16653                          (match_dup 1)
16654                          (match_dup 2)))])
16655
16656 (define_split
16657   [(set (match_operand:SF 0 "fp_register_operand" "")
16658         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16659                              (match_operand:SF 2 "register_operand" ""))
16660                          (match_operand:SF 3 "register_operand" "")
16661                          (match_operand:SF 4 "register_operand" "")))
16662    (clobber (reg:CC 17))]
16663   "reload_completed
16664    && ((operands_match_p (operands[1], operands[3])
16665         && operands_match_p (operands[2], operands[4]))
16666        || (operands_match_p (operands[1], operands[4])
16667            && operands_match_p (operands[2], operands[3])))"
16668   [(set (reg:CCFP 17)
16669         (compare:CCFP (match_dup 1)
16670                       (match_dup 2)))
16671    (set (match_dup 0)
16672         (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16673                          (match_dup 1)
16674                          (match_dup 2)))])
16675
16676 (define_insn "*maxsf_sse"
16677   [(set (match_operand:SF 0 "register_operand" "=x")
16678         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16679                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
16680                          (match_dup 1)
16681                          (match_dup 2)))]
16682   "TARGET_SSE && reload_completed"
16683   "maxss\t{%2, %0|%0, %2}"
16684   [(set_attr "type" "sse")
16685    (set_attr "mode" "SF")])
16686
16687 (define_expand "maxdf3"
16688   [(parallel [
16689      (set (match_operand:DF 0 "register_operand" "")
16690           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16691                                (match_operand:DF 2 "nonimmediate_operand" ""))
16692                            (match_dup 1)
16693                            (match_dup 2)))
16694      (clobber (reg:CC 17))])]
16695   "TARGET_SSE2 && TARGET_SSE_MATH"
16696   "#")
16697
16698 (define_insn "*maxdf"
16699   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16700         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16701                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16702                          (match_dup 1)
16703                          (match_dup 2)))
16704    (clobber (reg:CC 17))]
16705   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16706   "#")
16707
16708 (define_insn "*maxdf_nonieee"
16709   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16710         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16711                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16712                          (match_dup 1)
16713                          (match_dup 2)))
16714    (clobber (reg:CC 17))]
16715   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16716    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16717   "#")
16718
16719 (define_split
16720   [(set (match_operand:DF 0 "register_operand" "")
16721         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16722                              (match_operand:DF 2 "nonimmediate_operand" ""))
16723                          (match_operand:DF 3 "register_operand" "")
16724                          (match_operand:DF 4 "nonimmediate_operand" "")))
16725    (clobber (reg:CC 17))]
16726   "SSE_REG_P (operands[0]) && reload_completed
16727    && ((operands_match_p (operands[1], operands[3])
16728         && operands_match_p (operands[2], operands[4]))
16729        || (operands_match_p (operands[1], operands[4])
16730            && operands_match_p (operands[2], operands[3])))"
16731   [(set (match_dup 0)
16732         (if_then_else:DF (gt (match_dup 1)
16733                              (match_dup 2))
16734                          (match_dup 1)
16735                          (match_dup 2)))])
16736
16737 (define_split
16738   [(set (match_operand:DF 0 "fp_register_operand" "")
16739         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16740                              (match_operand:DF 2 "register_operand" ""))
16741                          (match_operand:DF 3 "register_operand" "")
16742                          (match_operand:DF 4 "register_operand" "")))
16743    (clobber (reg:CC 17))]
16744   "reload_completed
16745    && ((operands_match_p (operands[1], operands[3])
16746         && operands_match_p (operands[2], operands[4]))
16747        || (operands_match_p (operands[1], operands[4])
16748            && operands_match_p (operands[2], operands[3])))"
16749   [(set (reg:CCFP 17)
16750         (compare:CCFP (match_dup 1)
16751                       (match_dup 2)))
16752    (set (match_dup 0)
16753         (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16754                          (match_dup 1)
16755                          (match_dup 2)))])
16756
16757 (define_insn "*maxdf_sse"
16758   [(set (match_operand:DF 0 "register_operand" "=Y")
16759         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16760                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16761                          (match_dup 1)
16762                          (match_dup 2)))]
16763   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16764   "maxsd\t{%2, %0|%0, %2}"
16765   [(set_attr "type" "sse")
16766    (set_attr "mode" "DF")])
16767 \f
16768 ;; Misc patterns (?)
16769
16770 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16771 ;; Otherwise there will be nothing to keep
16772 ;; 
16773 ;; [(set (reg ebp) (reg esp))]
16774 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16775 ;;  (clobber (eflags)]
16776 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16777 ;;
16778 ;; in proper program order.
16779 (define_insn "pro_epilogue_adjust_stack_1"
16780   [(set (match_operand:SI 0 "register_operand" "=r,r")
16781         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16782                  (match_operand:SI 2 "immediate_operand" "i,i")))
16783    (clobber (reg:CC 17))
16784    (clobber (mem:BLK (scratch)))]
16785   "!TARGET_64BIT"
16786 {
16787   switch (get_attr_type (insn))
16788     {
16789     case TYPE_IMOV:
16790       return "mov{l}\t{%1, %0|%0, %1}";
16791
16792     case TYPE_ALU:
16793       if (GET_CODE (operands[2]) == CONST_INT
16794           && (INTVAL (operands[2]) == 128
16795               || (INTVAL (operands[2]) < 0
16796                   && INTVAL (operands[2]) != -128)))
16797         {
16798           operands[2] = GEN_INT (-INTVAL (operands[2]));
16799           return "sub{l}\t{%2, %0|%0, %2}";
16800         }
16801       return "add{l}\t{%2, %0|%0, %2}";
16802
16803     case TYPE_LEA:
16804       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16805       return "lea{l}\t{%a2, %0|%0, %a2}";
16806
16807     default:
16808       abort ();
16809     }
16810 }
16811   [(set (attr "type")
16812         (cond [(eq_attr "alternative" "0")
16813                  (const_string "alu")
16814                (match_operand:SI 2 "const0_operand" "")
16815                  (const_string "imov")
16816               ]
16817               (const_string "lea")))
16818    (set_attr "mode" "SI")])
16819
16820 (define_insn "pro_epilogue_adjust_stack_rex64"
16821   [(set (match_operand:DI 0 "register_operand" "=r,r")
16822         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16823                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16824    (clobber (reg:CC 17))
16825    (clobber (mem:BLK (scratch)))]
16826   "TARGET_64BIT"
16827 {
16828   switch (get_attr_type (insn))
16829     {
16830     case TYPE_IMOV:
16831       return "mov{q}\t{%1, %0|%0, %1}";
16832
16833     case TYPE_ALU:
16834       if (GET_CODE (operands[2]) == CONST_INT
16835           /* Avoid overflows.  */
16836           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16837           && (INTVAL (operands[2]) == 128
16838               || (INTVAL (operands[2]) < 0
16839                   && INTVAL (operands[2]) != -128)))
16840         {
16841           operands[2] = GEN_INT (-INTVAL (operands[2]));
16842           return "sub{q}\t{%2, %0|%0, %2}";
16843         }
16844       return "add{q}\t{%2, %0|%0, %2}";
16845
16846     case TYPE_LEA:
16847       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16848       return "lea{q}\t{%a2, %0|%0, %a2}";
16849
16850     default:
16851       abort ();
16852     }
16853 }
16854   [(set (attr "type")
16855         (cond [(eq_attr "alternative" "0")
16856                  (const_string "alu")
16857                (match_operand:DI 2 "const0_operand" "")
16858                  (const_string "imov")
16859               ]
16860               (const_string "lea")))
16861    (set_attr "mode" "DI")])
16862
16863 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16864   [(set (match_operand:DI 0 "register_operand" "=r,r")
16865         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16866                  (match_operand:DI 3 "immediate_operand" "i,i")))
16867    (use (match_operand:DI 2 "register_operand" "r,r"))
16868    (clobber (reg:CC 17))
16869    (clobber (mem:BLK (scratch)))]
16870   "TARGET_64BIT"
16871 {
16872   switch (get_attr_type (insn))
16873     {
16874     case TYPE_ALU:
16875       return "add{q}\t{%2, %0|%0, %2}";
16876
16877     case TYPE_LEA:
16878       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16879       return "lea{q}\t{%a2, %0|%0, %a2}";
16880
16881     default:
16882       abort ();
16883     }
16884 }
16885   [(set_attr "type" "alu,lea")
16886    (set_attr "mode" "DI")])
16887
16888 ;; Placeholder for the conditional moves.  This one is split either to SSE
16889 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
16890 ;; fact is that compares supported by the cmp??ss instructions are exactly
16891 ;; swapped of those supported by cmove sequence.
16892 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16893 ;; supported by i387 comparisons and we do need to emit two conditional moves
16894 ;; in tandem.
16895
16896 (define_insn "sse_movsfcc"
16897   [(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")
16898         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16899                         [(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")
16900                          (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")])
16901                       (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")
16902                       (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")))
16903    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16904    (clobber (reg:CC 17))]
16905   "TARGET_SSE
16906    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16907    /* Avoid combine from being smart and converting min/max
16908       instruction patterns into conditional moves.  */
16909    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16910         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16911        || !rtx_equal_p (operands[4], operands[2])
16912        || !rtx_equal_p (operands[5], operands[3]))
16913    && (!TARGET_IEEE_FP
16914        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16915   "#")
16916
16917 (define_insn "sse_movsfcc_eq"
16918   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16919         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16920                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16921                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16922                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16923    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16924    (clobber (reg:CC 17))]
16925   "TARGET_SSE
16926    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16927   "#")
16928
16929 (define_insn "sse_movdfcc"
16930   [(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")
16931         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16932                         [(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")
16933                          (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")])
16934                       (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")
16935                       (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")))
16936    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16937    (clobber (reg:CC 17))]
16938   "TARGET_SSE2
16939    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16940    /* Avoid combine from being smart and converting min/max
16941       instruction patterns into conditional moves.  */
16942    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16943         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16944        || !rtx_equal_p (operands[4], operands[2])
16945        || !rtx_equal_p (operands[5], operands[3]))
16946    && (!TARGET_IEEE_FP
16947        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16948   "#")
16949
16950 (define_insn "sse_movdfcc_eq"
16951   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16952         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16953                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16954                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16955                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16956    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16957    (clobber (reg:CC 17))]
16958   "TARGET_SSE
16959    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16960   "#")
16961
16962 ;; For non-sse moves just expand the usual cmove sequence.
16963 (define_split
16964   [(set (match_operand 0 "register_operand" "")
16965         (if_then_else (match_operator 1 "comparison_operator"
16966                         [(match_operand 4 "nonimmediate_operand" "")
16967                          (match_operand 5 "register_operand" "")])
16968                       (match_operand 2 "nonimmediate_operand" "")
16969                       (match_operand 3 "nonimmediate_operand" "")))
16970    (clobber (match_operand 6 "" ""))
16971    (clobber (reg:CC 17))]
16972   "!SSE_REG_P (operands[0]) && reload_completed
16973    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16974   [(const_int 0)]
16975 {
16976    ix86_compare_op0 = operands[5];
16977    ix86_compare_op1 = operands[4];
16978    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16979                                  VOIDmode, operands[5], operands[4]);
16980    ix86_expand_fp_movcc (operands);
16981    DONE;
16982 })
16983
16984 ;; Split SSE based conditional move into sequence:
16985 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
16986 ;; and   op2, op0   -  zero op2 if comparison was false
16987 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
16988 ;; or    op2, op0   -  get the nonzero one into the result.
16989 (define_split
16990   [(set (match_operand 0 "register_operand" "")
16991         (if_then_else (match_operator 1 "sse_comparison_operator"
16992                         [(match_operand 4 "register_operand" "")
16993                          (match_operand 5 "nonimmediate_operand" "")])
16994                       (match_operand 2 "register_operand" "")
16995                       (match_operand 3 "register_operand" "")))
16996    (clobber (match_operand 6 "" ""))
16997    (clobber (reg:CC 17))]
16998   "SSE_REG_P (operands[0]) && reload_completed"
16999   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17000    (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17001                                             (subreg:TI (match_dup 4) 0)))
17002    (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17003                                             (subreg:TI (match_dup 3) 0)))
17004    (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17005                                             (subreg:TI (match_dup 7) 0)))]
17006 {
17007   if (GET_MODE (operands[2]) == DFmode
17008       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17009     {
17010       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17011       emit_insn (gen_sse2_unpcklpd (op, op, op));
17012       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17013       emit_insn (gen_sse2_unpcklpd (op, op, op));
17014     }
17015
17016   /* If op2 == op3, op3 would be clobbered before it is used.  */
17017   if (operands_match_p (operands[2], operands[3]))
17018     {
17019       emit_move_insn (operands[0], operands[2]);
17020       DONE;
17021     }
17022
17023   PUT_MODE (operands[1], GET_MODE (operands[0]));
17024   if (operands_match_p (operands[0], operands[4]))
17025     operands[6] = operands[4], operands[7] = operands[2];
17026   else
17027     operands[6] = operands[2], operands[7] = operands[4];
17028 })
17029
17030 ;; Special case of conditional move we can handle effectively.
17031 ;; Do not brother with the integer/floating point case, since these are
17032 ;; bot considerably slower, unlike in the generic case.
17033 (define_insn "*sse_movsfcc_const0_1"
17034   [(set (match_operand:SF 0 "register_operand" "=&x")
17035         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17036                         [(match_operand:SF 4 "register_operand" "0")
17037                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17038                       (match_operand:SF 2 "register_operand" "x")
17039                       (match_operand:SF 3 "const0_operand" "X")))]
17040   "TARGET_SSE"
17041   "#")
17042
17043 (define_insn "*sse_movsfcc_const0_2"
17044   [(set (match_operand:SF 0 "register_operand" "=&x")
17045         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17046                         [(match_operand:SF 4 "register_operand" "0")
17047                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17048                       (match_operand:SF 2 "const0_operand" "X")
17049                       (match_operand:SF 3 "register_operand" "x")))]
17050   "TARGET_SSE"
17051   "#")
17052
17053 (define_insn "*sse_movsfcc_const0_3"
17054   [(set (match_operand:SF 0 "register_operand" "=&x")
17055         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17056                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17057                          (match_operand:SF 5 "register_operand" "0")])
17058                       (match_operand:SF 2 "register_operand" "x")
17059                       (match_operand:SF 3 "const0_operand" "X")))]
17060   "TARGET_SSE"
17061   "#")
17062
17063 (define_insn "*sse_movsfcc_const0_4"
17064   [(set (match_operand:SF 0 "register_operand" "=&x")
17065         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17066                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17067                          (match_operand:SF 5 "register_operand" "0")])
17068                       (match_operand:SF 2 "const0_operand" "X")
17069                       (match_operand:SF 3 "register_operand" "x")))]
17070   "TARGET_SSE"
17071   "#")
17072
17073 (define_insn "*sse_movdfcc_const0_1"
17074   [(set (match_operand:DF 0 "register_operand" "=&Y")
17075         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17076                         [(match_operand:DF 4 "register_operand" "0")
17077                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17078                       (match_operand:DF 2 "register_operand" "Y")
17079                       (match_operand:DF 3 "const0_operand" "X")))]
17080   "TARGET_SSE2"
17081   "#")
17082
17083 (define_insn "*sse_movdfcc_const0_2"
17084   [(set (match_operand:DF 0 "register_operand" "=&Y")
17085         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17086                         [(match_operand:DF 4 "register_operand" "0")
17087                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17088                       (match_operand:DF 2 "const0_operand" "X")
17089                       (match_operand:DF 3 "register_operand" "Y")))]
17090   "TARGET_SSE2"
17091   "#")
17092
17093 (define_insn "*sse_movdfcc_const0_3"
17094   [(set (match_operand:DF 0 "register_operand" "=&Y")
17095         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17096                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17097                          (match_operand:DF 5 "register_operand" "0")])
17098                       (match_operand:DF 2 "register_operand" "Y")
17099                       (match_operand:DF 3 "const0_operand" "X")))]
17100   "TARGET_SSE2"
17101   "#")
17102
17103 (define_insn "*sse_movdfcc_const0_4"
17104   [(set (match_operand:DF 0 "register_operand" "=&Y")
17105         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17106                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17107                          (match_operand:DF 5 "register_operand" "0")])
17108                       (match_operand:DF 2 "const0_operand" "X")
17109                       (match_operand:DF 3 "register_operand" "Y")))]
17110   "TARGET_SSE2"
17111   "#")
17112
17113 (define_split
17114   [(set (match_operand 0 "register_operand" "")
17115         (if_then_else (match_operator 1 "comparison_operator"
17116                         [(match_operand 4 "nonimmediate_operand" "")
17117                          (match_operand 5 "nonimmediate_operand" "")])
17118                       (match_operand 2 "nonmemory_operand" "")
17119                       (match_operand 3 "nonmemory_operand" "")))]
17120   "SSE_REG_P (operands[0]) && reload_completed
17121    && (const0_operand (operands[2], GET_MODE (operands[0]))
17122        || const0_operand (operands[3], GET_MODE (operands[0])))"
17123   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17124    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17125                                             (match_dup 7)))]
17126 {
17127   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17128       && GET_MODE (operands[2]) == DFmode)
17129     {
17130       if (REG_P (operands[2]))
17131         {
17132           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17133           emit_insn (gen_sse2_unpcklpd (op, op, op));
17134         }
17135       if (REG_P (operands[3]))
17136         {
17137           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17138           emit_insn (gen_sse2_unpcklpd (op, op, op));
17139         }
17140     }
17141   PUT_MODE (operands[1], GET_MODE (operands[0]));
17142   if (!sse_comparison_operator (operands[1], VOIDmode)
17143       || !rtx_equal_p (operands[0], operands[4]))
17144     {
17145       rtx tmp = operands[5];
17146       operands[5] = operands[4];
17147       operands[4] = tmp;
17148       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17149     }
17150   if (!rtx_equal_p (operands[0], operands[4]))
17151     abort ();
17152   if (const0_operand (operands[2], GET_MODE (operands[0])))
17153     {
17154       operands[7] = operands[3];
17155       operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17156                                                          0));
17157     }
17158   else
17159     {
17160       operands[7] = operands[2];
17161       operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17162     }
17163   operands[7] = simplify_gen_subreg (TImode, operands[7],
17164                                      GET_MODE (operands[7]), 0);
17165 })
17166
17167 (define_expand "allocate_stack_worker"
17168   [(match_operand:SI 0 "register_operand" "")]
17169   "TARGET_STACK_PROBE"
17170 {
17171   if (TARGET_64BIT)
17172     emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17173   else
17174     emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17175   DONE;
17176 })
17177
17178 (define_insn "allocate_stack_worker_1"
17179   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17180    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17181    (clobber (match_dup 0))
17182    (clobber (reg:CC 17))]
17183   "!TARGET_64BIT && TARGET_STACK_PROBE"
17184   "call\t__alloca"
17185   [(set_attr "type" "multi")
17186    (set_attr "length" "5")])
17187
17188 (define_insn "allocate_stack_worker_rex64"
17189   [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17190    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17191    (clobber (match_dup 0))
17192    (clobber (reg:CC 17))]
17193   "TARGET_64BIT && TARGET_STACK_PROBE"
17194   "call\t__alloca"
17195   [(set_attr "type" "multi")
17196    (set_attr "length" "5")])
17197
17198 (define_expand "allocate_stack"
17199   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17200                    (minus:SI (reg:SI 7)
17201                              (match_operand:SI 1 "general_operand" "")))
17202               (clobber (reg:CC 17))])
17203    (parallel [(set (reg:SI 7)
17204                    (minus:SI (reg:SI 7) (match_dup 1)))
17205               (clobber (reg:CC 17))])]
17206   "TARGET_STACK_PROBE"
17207 {
17208 #ifdef CHECK_STACK_LIMIT
17209   if (GET_CODE (operands[1]) == CONST_INT
17210       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17211     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17212                            operands[1]));
17213   else 
17214 #endif
17215     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17216                                                             operands[1])));
17217
17218   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17219   DONE;
17220 })
17221
17222 (define_expand "builtin_setjmp_receiver"
17223   [(label_ref (match_operand 0 "" ""))]
17224   "!TARGET_64BIT && flag_pic"
17225 {
17226   emit_insn (gen_set_got (pic_offset_table_rtx));
17227   DONE;
17228 })
17229 \f
17230 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17231
17232 (define_split
17233   [(set (match_operand 0 "register_operand" "")
17234         (match_operator 3 "promotable_binary_operator"
17235            [(match_operand 1 "register_operand" "")
17236             (match_operand 2 "aligned_operand" "")]))
17237    (clobber (reg:CC 17))]
17238   "! TARGET_PARTIAL_REG_STALL && reload_completed
17239    && ((GET_MODE (operands[0]) == HImode 
17240         && ((!optimize_size && !TARGET_FAST_PREFIX)
17241             || GET_CODE (operands[2]) != CONST_INT
17242             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17243        || (GET_MODE (operands[0]) == QImode 
17244            && (TARGET_PROMOTE_QImode || optimize_size)))"
17245   [(parallel [(set (match_dup 0)
17246                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17247               (clobber (reg:CC 17))])]
17248   "operands[0] = gen_lowpart (SImode, operands[0]);
17249    operands[1] = gen_lowpart (SImode, operands[1]);
17250    if (GET_CODE (operands[3]) != ASHIFT)
17251      operands[2] = gen_lowpart (SImode, operands[2]);
17252    PUT_MODE (operands[3], SImode);")
17253
17254 ; Promote the QImode tests, as i386 has encoding of the AND
17255 ; instruction with 32-bit sign-extended immediate and thus the
17256 ; instruction size is unchanged, except in the %eax case for
17257 ; which it is increased by one byte, hence the ! optimize_size.
17258 (define_split
17259   [(set (reg 17)
17260         (compare (and (match_operand 1 "aligned_operand" "")
17261                       (match_operand 2 "const_int_operand" ""))
17262                  (const_int 0)))
17263    (set (match_operand 0 "register_operand" "")
17264         (and (match_dup 1) (match_dup 2)))]
17265   "! TARGET_PARTIAL_REG_STALL && reload_completed
17266    /* Ensure that the operand will remain sign-extended immediate.  */
17267    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17268    && ! optimize_size
17269    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17270        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17271   [(parallel [(set (reg:CCNO 17)
17272                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17273                                  (const_int 0)))
17274               (set (match_dup 0)
17275                    (and:SI (match_dup 1) (match_dup 2)))])]
17276   "operands[2]
17277      = gen_int_mode (INTVAL (operands[2])
17278                      & GET_MODE_MASK (GET_MODE (operands[0])),
17279                      SImode);
17280    operands[0] = gen_lowpart (SImode, operands[0]);
17281    operands[1] = gen_lowpart (SImode, operands[1]);")
17282
17283 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17284 ; the TEST instruction with 32-bit sign-extended immediate and thus
17285 ; the instruction size would at least double, which is not what we
17286 ; want even with ! optimize_size.
17287 (define_split
17288   [(set (reg 17)
17289         (compare (and (match_operand:HI 0 "aligned_operand" "")
17290                       (match_operand:HI 1 "const_int_operand" ""))
17291                  (const_int 0)))]
17292   "! TARGET_PARTIAL_REG_STALL && reload_completed
17293    /* Ensure that the operand will remain sign-extended immediate.  */
17294    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17295    && ! TARGET_FAST_PREFIX
17296    && ! optimize_size"
17297   [(set (reg:CCNO 17)
17298         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17299                       (const_int 0)))]
17300   "operands[1]
17301      = gen_int_mode (INTVAL (operands[1])
17302                      & GET_MODE_MASK (GET_MODE (operands[0])),
17303                      SImode);
17304    operands[0] = gen_lowpart (SImode, operands[0]);")
17305
17306 (define_split
17307   [(set (match_operand 0 "register_operand" "")
17308         (neg (match_operand 1 "register_operand" "")))
17309    (clobber (reg:CC 17))]
17310   "! TARGET_PARTIAL_REG_STALL && reload_completed
17311    && (GET_MODE (operands[0]) == HImode
17312        || (GET_MODE (operands[0]) == QImode 
17313            && (TARGET_PROMOTE_QImode || optimize_size)))"
17314   [(parallel [(set (match_dup 0)
17315                    (neg:SI (match_dup 1)))
17316               (clobber (reg:CC 17))])]
17317   "operands[0] = gen_lowpart (SImode, operands[0]);
17318    operands[1] = gen_lowpart (SImode, operands[1]);")
17319
17320 (define_split
17321   [(set (match_operand 0 "register_operand" "")
17322         (not (match_operand 1 "register_operand" "")))]
17323   "! TARGET_PARTIAL_REG_STALL && reload_completed
17324    && (GET_MODE (operands[0]) == HImode
17325        || (GET_MODE (operands[0]) == QImode 
17326            && (TARGET_PROMOTE_QImode || optimize_size)))"
17327   [(set (match_dup 0)
17328         (not:SI (match_dup 1)))]
17329   "operands[0] = gen_lowpart (SImode, operands[0]);
17330    operands[1] = gen_lowpart (SImode, operands[1]);")
17331
17332 (define_split 
17333   [(set (match_operand 0 "register_operand" "")
17334         (if_then_else (match_operator 1 "comparison_operator" 
17335                                 [(reg 17) (const_int 0)])
17336                       (match_operand 2 "register_operand" "")
17337                       (match_operand 3 "register_operand" "")))]
17338   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17339    && (GET_MODE (operands[0]) == HImode
17340        || (GET_MODE (operands[0]) == QImode 
17341            && (TARGET_PROMOTE_QImode || optimize_size)))"
17342   [(set (match_dup 0)
17343         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17344   "operands[0] = gen_lowpart (SImode, operands[0]);
17345    operands[2] = gen_lowpart (SImode, operands[2]);
17346    operands[3] = gen_lowpart (SImode, operands[3]);")
17347                         
17348 \f
17349 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17350 ;; transform a complex memory operation into two memory to register operations.
17351
17352 ;; Don't push memory operands
17353 (define_peephole2
17354   [(set (match_operand:SI 0 "push_operand" "")
17355         (match_operand:SI 1 "memory_operand" ""))
17356    (match_scratch:SI 2 "r")]
17357   "! optimize_size && ! TARGET_PUSH_MEMORY"
17358   [(set (match_dup 2) (match_dup 1))
17359    (set (match_dup 0) (match_dup 2))]
17360   "")
17361
17362 (define_peephole2
17363   [(set (match_operand:DI 0 "push_operand" "")
17364         (match_operand:DI 1 "memory_operand" ""))
17365    (match_scratch:DI 2 "r")]
17366   "! optimize_size && ! TARGET_PUSH_MEMORY"
17367   [(set (match_dup 2) (match_dup 1))
17368    (set (match_dup 0) (match_dup 2))]
17369   "")
17370
17371 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17372 ;; SImode pushes.
17373 (define_peephole2
17374   [(set (match_operand:SF 0 "push_operand" "")
17375         (match_operand:SF 1 "memory_operand" ""))
17376    (match_scratch:SF 2 "r")]
17377   "! optimize_size && ! TARGET_PUSH_MEMORY"
17378   [(set (match_dup 2) (match_dup 1))
17379    (set (match_dup 0) (match_dup 2))]
17380   "")
17381
17382 (define_peephole2
17383   [(set (match_operand:HI 0 "push_operand" "")
17384         (match_operand:HI 1 "memory_operand" ""))
17385    (match_scratch:HI 2 "r")]
17386   "! optimize_size && ! TARGET_PUSH_MEMORY"
17387   [(set (match_dup 2) (match_dup 1))
17388    (set (match_dup 0) (match_dup 2))]
17389   "")
17390
17391 (define_peephole2
17392   [(set (match_operand:QI 0 "push_operand" "")
17393         (match_operand:QI 1 "memory_operand" ""))
17394    (match_scratch:QI 2 "q")]
17395   "! optimize_size && ! TARGET_PUSH_MEMORY"
17396   [(set (match_dup 2) (match_dup 1))
17397    (set (match_dup 0) (match_dup 2))]
17398   "")
17399
17400 ;; Don't move an immediate directly to memory when the instruction
17401 ;; gets too big.
17402 (define_peephole2
17403   [(match_scratch:SI 1 "r")
17404    (set (match_operand:SI 0 "memory_operand" "")
17405         (const_int 0))]
17406   "! optimize_size
17407    && ! TARGET_USE_MOV0
17408    && TARGET_SPLIT_LONG_MOVES
17409    && get_attr_length (insn) >= ix86_cost->large_insn
17410    && peep2_regno_dead_p (0, FLAGS_REG)"
17411   [(parallel [(set (match_dup 1) (const_int 0))
17412               (clobber (reg:CC 17))])
17413    (set (match_dup 0) (match_dup 1))]
17414   "")
17415
17416 (define_peephole2
17417   [(match_scratch:HI 1 "r")
17418    (set (match_operand:HI 0 "memory_operand" "")
17419         (const_int 0))]
17420   "! optimize_size
17421    && ! TARGET_USE_MOV0
17422    && TARGET_SPLIT_LONG_MOVES
17423    && get_attr_length (insn) >= ix86_cost->large_insn
17424    && peep2_regno_dead_p (0, FLAGS_REG)"
17425   [(parallel [(set (match_dup 2) (const_int 0))
17426               (clobber (reg:CC 17))])
17427    (set (match_dup 0) (match_dup 1))]
17428   "operands[2] = gen_lowpart (SImode, operands[1]);")
17429
17430 (define_peephole2
17431   [(match_scratch:QI 1 "q")
17432    (set (match_operand:QI 0 "memory_operand" "")
17433         (const_int 0))]
17434   "! optimize_size
17435    && ! TARGET_USE_MOV0
17436    && TARGET_SPLIT_LONG_MOVES
17437    && get_attr_length (insn) >= ix86_cost->large_insn
17438    && peep2_regno_dead_p (0, FLAGS_REG)"
17439   [(parallel [(set (match_dup 2) (const_int 0))
17440               (clobber (reg:CC 17))])
17441    (set (match_dup 0) (match_dup 1))]
17442   "operands[2] = gen_lowpart (SImode, operands[1]);")
17443
17444 (define_peephole2
17445   [(match_scratch:SI 2 "r")
17446    (set (match_operand:SI 0 "memory_operand" "")
17447         (match_operand:SI 1 "immediate_operand" ""))]
17448   "! optimize_size
17449    && get_attr_length (insn) >= ix86_cost->large_insn
17450    && TARGET_SPLIT_LONG_MOVES"
17451   [(set (match_dup 2) (match_dup 1))
17452    (set (match_dup 0) (match_dup 2))]
17453   "")
17454
17455 (define_peephole2
17456   [(match_scratch:HI 2 "r")
17457    (set (match_operand:HI 0 "memory_operand" "")
17458         (match_operand:HI 1 "immediate_operand" ""))]
17459   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17460   && TARGET_SPLIT_LONG_MOVES"
17461   [(set (match_dup 2) (match_dup 1))
17462    (set (match_dup 0) (match_dup 2))]
17463   "")
17464
17465 (define_peephole2
17466   [(match_scratch:QI 2 "q")
17467    (set (match_operand:QI 0 "memory_operand" "")
17468         (match_operand:QI 1 "immediate_operand" ""))]
17469   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17470   && TARGET_SPLIT_LONG_MOVES"
17471   [(set (match_dup 2) (match_dup 1))
17472    (set (match_dup 0) (match_dup 2))]
17473   "")
17474
17475 ;; Don't compare memory with zero, load and use a test instead.
17476 (define_peephole2
17477   [(set (reg 17)
17478         (compare (match_operand:SI 0 "memory_operand" "")
17479                  (const_int 0)))
17480    (match_scratch:SI 3 "r")]
17481   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17482   [(set (match_dup 3) (match_dup 0))
17483    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17484   "")
17485
17486 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17487 ;; Don't split NOTs with a displacement operand, because resulting XOR
17488 ;; will not be pairable anyway.
17489 ;;
17490 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17491 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17492 ;; so this split helps here as well.
17493 ;;
17494 ;; Note: Can't do this as a regular split because we can't get proper
17495 ;; lifetime information then.
17496
17497 (define_peephole2
17498   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17499         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17500   "!optimize_size
17501    && peep2_regno_dead_p (0, FLAGS_REG)
17502    && ((TARGET_PENTIUM 
17503         && (GET_CODE (operands[0]) != MEM
17504             || !memory_displacement_operand (operands[0], SImode)))
17505        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17506   [(parallel [(set (match_dup 0)
17507                    (xor:SI (match_dup 1) (const_int -1)))
17508               (clobber (reg:CC 17))])]
17509   "")
17510
17511 (define_peephole2
17512   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17513         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17514   "!optimize_size
17515    && peep2_regno_dead_p (0, FLAGS_REG)
17516    && ((TARGET_PENTIUM 
17517         && (GET_CODE (operands[0]) != MEM
17518             || !memory_displacement_operand (operands[0], HImode)))
17519        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17520   [(parallel [(set (match_dup 0)
17521                    (xor:HI (match_dup 1) (const_int -1)))
17522               (clobber (reg:CC 17))])]
17523   "")
17524
17525 (define_peephole2
17526   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17527         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17528   "!optimize_size
17529    && peep2_regno_dead_p (0, FLAGS_REG)
17530    && ((TARGET_PENTIUM 
17531         && (GET_CODE (operands[0]) != MEM
17532             || !memory_displacement_operand (operands[0], QImode)))
17533        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17534   [(parallel [(set (match_dup 0)
17535                    (xor:QI (match_dup 1) (const_int -1)))
17536               (clobber (reg:CC 17))])]
17537   "")
17538
17539 ;; Non pairable "test imm, reg" instructions can be translated to
17540 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17541 ;; byte opcode instead of two, have a short form for byte operands),
17542 ;; so do it for other CPUs as well.  Given that the value was dead,
17543 ;; this should not create any new dependencies.  Pass on the sub-word
17544 ;; versions if we're concerned about partial register stalls.
17545
17546 (define_peephole2
17547   [(set (reg 17)
17548         (compare (and:SI (match_operand:SI 0 "register_operand" "")
17549                          (match_operand:SI 1 "immediate_operand" ""))
17550                  (const_int 0)))]
17551   "ix86_match_ccmode (insn, CCNOmode)
17552    && (true_regnum (operands[0]) != 0
17553        || (GET_CODE (operands[1]) == CONST_INT
17554            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17555    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17556   [(parallel
17557      [(set (reg:CCNO 17)
17558            (compare:CCNO (and:SI (match_dup 0)
17559                                  (match_dup 1))
17560                          (const_int 0)))
17561       (set (match_dup 0)
17562            (and:SI (match_dup 0) (match_dup 1)))])]
17563   "")
17564
17565 ;; We don't need to handle HImode case, because it will be promoted to SImode
17566 ;; on ! TARGET_PARTIAL_REG_STALL
17567
17568 (define_peephole2
17569   [(set (reg 17)
17570         (compare (and:QI (match_operand:QI 0 "register_operand" "")
17571                          (match_operand:QI 1 "immediate_operand" ""))
17572                  (const_int 0)))]
17573   "! TARGET_PARTIAL_REG_STALL
17574    && ix86_match_ccmode (insn, CCNOmode)
17575    && true_regnum (operands[0]) != 0
17576    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17577   [(parallel
17578      [(set (reg:CCNO 17)
17579            (compare:CCNO (and:QI (match_dup 0)
17580                                  (match_dup 1))
17581                          (const_int 0)))
17582       (set (match_dup 0)
17583            (and:QI (match_dup 0) (match_dup 1)))])]
17584   "")
17585
17586 (define_peephole2
17587   [(set (reg 17)
17588         (compare
17589           (and:SI
17590             (zero_extract:SI
17591               (match_operand 0 "ext_register_operand" "")
17592               (const_int 8)
17593               (const_int 8))
17594             (match_operand 1 "const_int_operand" ""))
17595           (const_int 0)))]
17596   "! TARGET_PARTIAL_REG_STALL
17597    && ix86_match_ccmode (insn, CCNOmode)
17598    && true_regnum (operands[0]) != 0
17599    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17600   [(parallel [(set (reg:CCNO 17)
17601                    (compare:CCNO
17602                        (and:SI
17603                          (zero_extract:SI
17604                          (match_dup 0)
17605                          (const_int 8)
17606                          (const_int 8))
17607                         (match_dup 1))
17608                    (const_int 0)))
17609               (set (zero_extract:SI (match_dup 0)
17610                                     (const_int 8)
17611                                     (const_int 8))
17612                    (and:SI 
17613                      (zero_extract:SI
17614                        (match_dup 0)
17615                        (const_int 8)
17616                        (const_int 8))
17617                      (match_dup 1)))])]
17618   "")
17619
17620 ;; Don't do logical operations with memory inputs.
17621 (define_peephole2
17622   [(match_scratch:SI 2 "r")
17623    (parallel [(set (match_operand:SI 0 "register_operand" "")
17624                    (match_operator:SI 3 "arith_or_logical_operator"
17625                      [(match_dup 0)
17626                       (match_operand:SI 1 "memory_operand" "")]))
17627               (clobber (reg:CC 17))])]
17628   "! optimize_size && ! TARGET_READ_MODIFY"
17629   [(set (match_dup 2) (match_dup 1))
17630    (parallel [(set (match_dup 0)
17631                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17632               (clobber (reg:CC 17))])]
17633   "")
17634
17635 (define_peephole2
17636   [(match_scratch:SI 2 "r")
17637    (parallel [(set (match_operand:SI 0 "register_operand" "")
17638                    (match_operator:SI 3 "arith_or_logical_operator"
17639                      [(match_operand:SI 1 "memory_operand" "")
17640                       (match_dup 0)]))
17641               (clobber (reg:CC 17))])]
17642   "! optimize_size && ! TARGET_READ_MODIFY"
17643   [(set (match_dup 2) (match_dup 1))
17644    (parallel [(set (match_dup 0)
17645                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17646               (clobber (reg:CC 17))])]
17647   "")
17648
17649 ; Don't do logical operations with memory outputs
17650 ;
17651 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17652 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17653 ; the same decoder scheduling characteristics as the original.
17654
17655 (define_peephole2
17656   [(match_scratch:SI 2 "r")
17657    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17658                    (match_operator:SI 3 "arith_or_logical_operator"
17659                      [(match_dup 0)
17660                       (match_operand:SI 1 "nonmemory_operand" "")]))
17661               (clobber (reg:CC 17))])]
17662   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17663   [(set (match_dup 2) (match_dup 0))
17664    (parallel [(set (match_dup 2)
17665                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17666               (clobber (reg:CC 17))])
17667    (set (match_dup 0) (match_dup 2))]
17668   "")
17669
17670 (define_peephole2
17671   [(match_scratch:SI 2 "r")
17672    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17673                    (match_operator:SI 3 "arith_or_logical_operator"
17674                      [(match_operand:SI 1 "nonmemory_operand" "")
17675                       (match_dup 0)]))
17676               (clobber (reg:CC 17))])]
17677   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17678   [(set (match_dup 2) (match_dup 0))
17679    (parallel [(set (match_dup 2)
17680                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17681               (clobber (reg:CC 17))])
17682    (set (match_dup 0) (match_dup 2))]
17683   "")
17684
17685 ;; Attempt to always use XOR for zeroing registers.
17686 (define_peephole2
17687   [(set (match_operand 0 "register_operand" "")
17688         (const_int 0))]
17689   "(GET_MODE (operands[0]) == QImode
17690     || GET_MODE (operands[0]) == HImode
17691     || GET_MODE (operands[0]) == SImode
17692     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17693    && (! TARGET_USE_MOV0 || optimize_size)
17694    && peep2_regno_dead_p (0, FLAGS_REG)"
17695   [(parallel [(set (match_dup 0) (const_int 0))
17696               (clobber (reg:CC 17))])]
17697   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17698                               operands[0]);")
17699
17700 (define_peephole2
17701   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17702         (const_int 0))]
17703   "(GET_MODE (operands[0]) == QImode
17704     || GET_MODE (operands[0]) == HImode)
17705    && (! TARGET_USE_MOV0 || optimize_size)
17706    && peep2_regno_dead_p (0, FLAGS_REG)"
17707   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17708               (clobber (reg:CC 17))])])
17709
17710 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17711 (define_peephole2
17712   [(set (match_operand 0 "register_operand" "")
17713         (const_int -1))]
17714   "(GET_MODE (operands[0]) == HImode
17715     || GET_MODE (operands[0]) == SImode 
17716     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17717    && (optimize_size || TARGET_PENTIUM)
17718    && peep2_regno_dead_p (0, FLAGS_REG)"
17719   [(parallel [(set (match_dup 0) (const_int -1))
17720               (clobber (reg:CC 17))])]
17721   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17722                               operands[0]);")
17723
17724 ;; Attempt to convert simple leas to adds. These can be created by
17725 ;; move expanders.
17726 (define_peephole2
17727   [(set (match_operand:SI 0 "register_operand" "")
17728         (plus:SI (match_dup 0)
17729                  (match_operand:SI 1 "nonmemory_operand" "")))]
17730   "peep2_regno_dead_p (0, FLAGS_REG)"
17731   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17732               (clobber (reg:CC 17))])]
17733   "")
17734
17735 (define_peephole2
17736   [(set (match_operand:SI 0 "register_operand" "")
17737         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17738                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17739   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17740   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17741               (clobber (reg:CC 17))])]
17742   "operands[2] = gen_lowpart (SImode, operands[2]);")
17743
17744 (define_peephole2
17745   [(set (match_operand:DI 0 "register_operand" "")
17746         (plus:DI (match_dup 0)
17747                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17748   "peep2_regno_dead_p (0, FLAGS_REG)"
17749   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17750               (clobber (reg:CC 17))])]
17751   "")
17752
17753 (define_peephole2
17754   [(set (match_operand:SI 0 "register_operand" "")
17755         (mult:SI (match_dup 0)
17756                  (match_operand:SI 1 "const_int_operand" "")))]
17757   "exact_log2 (INTVAL (operands[1])) >= 0
17758    && peep2_regno_dead_p (0, FLAGS_REG)"
17759   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17760               (clobber (reg:CC 17))])]
17761   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17762
17763 (define_peephole2
17764   [(set (match_operand:DI 0 "register_operand" "")
17765         (mult:DI (match_dup 0)
17766                  (match_operand:DI 1 "const_int_operand" "")))]
17767   "exact_log2 (INTVAL (operands[1])) >= 0
17768    && peep2_regno_dead_p (0, FLAGS_REG)"
17769   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17770               (clobber (reg:CC 17))])]
17771   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17772
17773 (define_peephole2
17774   [(set (match_operand:SI 0 "register_operand" "")
17775         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17776                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17777   "exact_log2 (INTVAL (operands[2])) >= 0
17778    && REGNO (operands[0]) == REGNO (operands[1])
17779    && peep2_regno_dead_p (0, FLAGS_REG)"
17780   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17781               (clobber (reg:CC 17))])]
17782   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17783
17784 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17785 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17786 ;; many CPUs it is also faster, since special hardware to avoid esp
17787 ;; dependencies is present.
17788
17789 ;; While some of these conversions may be done using splitters, we use peepholes
17790 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17791
17792 ;; Convert prologue esp subtractions to push.
17793 ;; We need register to push.  In order to keep verify_flow_info happy we have
17794 ;; two choices
17795 ;; - use scratch and clobber it in order to avoid dependencies
17796 ;; - use already live register
17797 ;; We can't use the second way right now, since there is no reliable way how to
17798 ;; verify that given register is live.  First choice will also most likely in
17799 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17800 ;; call clobbered registers are dead.  We may want to use base pointer as an
17801 ;; alternative when no register is available later.
17802
17803 (define_peephole2
17804   [(match_scratch:SI 0 "r")
17805    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17806               (clobber (reg:CC 17))
17807               (clobber (mem:BLK (scratch)))])]
17808   "optimize_size || !TARGET_SUB_ESP_4"
17809   [(clobber (match_dup 0))
17810    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17811               (clobber (mem:BLK (scratch)))])])
17812
17813 (define_peephole2
17814   [(match_scratch:SI 0 "r")
17815    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17816               (clobber (reg:CC 17))
17817               (clobber (mem:BLK (scratch)))])]
17818   "optimize_size || !TARGET_SUB_ESP_8"
17819   [(clobber (match_dup 0))
17820    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17821    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17822               (clobber (mem:BLK (scratch)))])])
17823
17824 ;; Convert esp subtractions to push.
17825 (define_peephole2
17826   [(match_scratch:SI 0 "r")
17827    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17828               (clobber (reg:CC 17))])]
17829   "optimize_size || !TARGET_SUB_ESP_4"
17830   [(clobber (match_dup 0))
17831    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17832
17833 (define_peephole2
17834   [(match_scratch:SI 0 "r")
17835    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17836               (clobber (reg:CC 17))])]
17837   "optimize_size || !TARGET_SUB_ESP_8"
17838   [(clobber (match_dup 0))
17839    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17840    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17841
17842 ;; Convert epilogue deallocator to pop.
17843 (define_peephole2
17844   [(match_scratch:SI 0 "r")
17845    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17846               (clobber (reg:CC 17))
17847               (clobber (mem:BLK (scratch)))])]
17848   "optimize_size || !TARGET_ADD_ESP_4"
17849   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17850               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17851               (clobber (mem:BLK (scratch)))])]
17852   "")
17853
17854 ;; Two pops case is tricky, since pop causes dependency on destination register.
17855 ;; We use two registers if available.
17856 (define_peephole2
17857   [(match_scratch:SI 0 "r")
17858    (match_scratch:SI 1 "r")
17859    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17860               (clobber (reg:CC 17))
17861               (clobber (mem:BLK (scratch)))])]
17862   "optimize_size || !TARGET_ADD_ESP_8"
17863   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17864               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17865               (clobber (mem:BLK (scratch)))])
17866    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17867               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17868   "")
17869
17870 (define_peephole2
17871   [(match_scratch:SI 0 "r")
17872    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17873               (clobber (reg:CC 17))
17874               (clobber (mem:BLK (scratch)))])]
17875   "optimize_size"
17876   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17877               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17878               (clobber (mem:BLK (scratch)))])
17879    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17880               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17881   "")
17882
17883 ;; Convert esp additions to pop.
17884 (define_peephole2
17885   [(match_scratch:SI 0 "r")
17886    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17887               (clobber (reg:CC 17))])]
17888   ""
17889   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17890               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17891   "")
17892
17893 ;; Two pops case is tricky, since pop causes dependency on destination register.
17894 ;; We use two registers if available.
17895 (define_peephole2
17896   [(match_scratch:SI 0 "r")
17897    (match_scratch:SI 1 "r")
17898    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17899               (clobber (reg:CC 17))])]
17900   ""
17901   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17902               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17903    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17904               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17905   "")
17906
17907 (define_peephole2
17908   [(match_scratch:SI 0 "r")
17909    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17910               (clobber (reg:CC 17))])]
17911   "optimize_size"
17912   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17913               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17914    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17915               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17916   "")
17917 \f
17918 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17919 ;; required and register dies.
17920 (define_peephole2
17921   [(set (reg 17)
17922         (compare (match_operand:SI 0 "register_operand" "")
17923                  (match_operand:SI 1 "incdec_operand" "")))]
17924   "ix86_match_ccmode (insn, CCGCmode)
17925    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17926   [(parallel [(set (reg:CCGC 17)
17927                    (compare:CCGC (match_dup 0)
17928                                  (match_dup 1)))
17929               (clobber (match_dup 0))])]
17930   "")
17931
17932 (define_peephole2
17933   [(set (reg 17)
17934         (compare (match_operand:HI 0 "register_operand" "")
17935                  (match_operand:HI 1 "incdec_operand" "")))]
17936   "ix86_match_ccmode (insn, CCGCmode)
17937    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17938   [(parallel [(set (reg:CCGC 17)
17939                    (compare:CCGC (match_dup 0)
17940                                  (match_dup 1)))
17941               (clobber (match_dup 0))])]
17942   "")
17943
17944 (define_peephole2
17945   [(set (reg 17)
17946         (compare (match_operand:QI 0 "register_operand" "")
17947                  (match_operand:QI 1 "incdec_operand" "")))]
17948   "ix86_match_ccmode (insn, CCGCmode)
17949    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17950   [(parallel [(set (reg:CCGC 17)
17951                    (compare:CCGC (match_dup 0)
17952                                  (match_dup 1)))
17953               (clobber (match_dup 0))])]
17954   "")
17955
17956 ;; Convert compares with 128 to shorter add -128
17957 (define_peephole2
17958   [(set (reg 17)
17959         (compare (match_operand:SI 0 "register_operand" "")
17960                  (const_int 128)))]
17961   "ix86_match_ccmode (insn, CCGCmode)
17962    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17963   [(parallel [(set (reg:CCGC 17)
17964                    (compare:CCGC (match_dup 0)
17965                                  (const_int 128)))
17966               (clobber (match_dup 0))])]
17967   "")
17968
17969 (define_peephole2
17970   [(set (reg 17)
17971         (compare (match_operand:HI 0 "register_operand" "")
17972                  (const_int 128)))]
17973   "ix86_match_ccmode (insn, CCGCmode)
17974    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17975   [(parallel [(set (reg:CCGC 17)
17976                    (compare:CCGC (match_dup 0)
17977                                  (const_int 128)))
17978               (clobber (match_dup 0))])]
17979   "")
17980 \f
17981 (define_peephole2
17982   [(match_scratch:DI 0 "r")
17983    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17984               (clobber (reg:CC 17))
17985               (clobber (mem:BLK (scratch)))])]
17986   "optimize_size || !TARGET_SUB_ESP_4"
17987   [(clobber (match_dup 0))
17988    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17989               (clobber (mem:BLK (scratch)))])])
17990
17991 (define_peephole2
17992   [(match_scratch:DI 0 "r")
17993    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17994               (clobber (reg:CC 17))
17995               (clobber (mem:BLK (scratch)))])]
17996   "optimize_size || !TARGET_SUB_ESP_8"
17997   [(clobber (match_dup 0))
17998    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17999    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18000               (clobber (mem:BLK (scratch)))])])
18001
18002 ;; Convert esp subtractions to push.
18003 (define_peephole2
18004   [(match_scratch:DI 0 "r")
18005    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18006               (clobber (reg:CC 17))])]
18007   "optimize_size || !TARGET_SUB_ESP_4"
18008   [(clobber (match_dup 0))
18009    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18010
18011 (define_peephole2
18012   [(match_scratch:DI 0 "r")
18013    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18014               (clobber (reg:CC 17))])]
18015   "optimize_size || !TARGET_SUB_ESP_8"
18016   [(clobber (match_dup 0))
18017    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18018    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18019
18020 ;; Convert epilogue deallocator to pop.
18021 (define_peephole2
18022   [(match_scratch:DI 0 "r")
18023    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18024               (clobber (reg:CC 17))
18025               (clobber (mem:BLK (scratch)))])]
18026   "optimize_size || !TARGET_ADD_ESP_4"
18027   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18028               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18029               (clobber (mem:BLK (scratch)))])]
18030   "")
18031
18032 ;; Two pops case is tricky, since pop causes dependency on destination register.
18033 ;; We use two registers if available.
18034 (define_peephole2
18035   [(match_scratch:DI 0 "r")
18036    (match_scratch:DI 1 "r")
18037    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18038               (clobber (reg:CC 17))
18039               (clobber (mem:BLK (scratch)))])]
18040   "optimize_size || !TARGET_ADD_ESP_8"
18041   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18042               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18043               (clobber (mem:BLK (scratch)))])
18044    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18045               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18046   "")
18047
18048 (define_peephole2
18049   [(match_scratch:DI 0 "r")
18050    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18051               (clobber (reg:CC 17))
18052               (clobber (mem:BLK (scratch)))])]
18053   "optimize_size"
18054   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18055               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18056               (clobber (mem:BLK (scratch)))])
18057    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18058               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18059   "")
18060
18061 ;; Convert esp additions to pop.
18062 (define_peephole2
18063   [(match_scratch:DI 0 "r")
18064    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18065               (clobber (reg:CC 17))])]
18066   ""
18067   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18068               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18069   "")
18070
18071 ;; Two pops case is tricky, since pop causes dependency on destination register.
18072 ;; We use two registers if available.
18073 (define_peephole2
18074   [(match_scratch:DI 0 "r")
18075    (match_scratch:DI 1 "r")
18076    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18077               (clobber (reg:CC 17))])]
18078   ""
18079   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18080               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18081    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18082               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18083   "")
18084
18085 (define_peephole2
18086   [(match_scratch:DI 0 "r")
18087    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18088               (clobber (reg:CC 17))])]
18089   "optimize_size"
18090   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18091               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18092    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18093               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18094   "")
18095 \f
18096 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18097 ;; imul $32bit_imm, reg, reg is direct decoded.
18098 (define_peephole2
18099   [(match_scratch:DI 3 "r")
18100    (parallel [(set (match_operand:DI 0 "register_operand" "")
18101                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18102                             (match_operand:DI 2 "immediate_operand" "")))
18103               (clobber (reg:CC 17))])]
18104   "TARGET_K8 && !optimize_size
18105    && (GET_CODE (operands[2]) != CONST_INT
18106        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18107   [(set (match_dup 3) (match_dup 1))
18108    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18109               (clobber (reg:CC 17))])]
18110 "")
18111
18112 (define_peephole2
18113   [(match_scratch:SI 3 "r")
18114    (parallel [(set (match_operand:SI 0 "register_operand" "")
18115                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18116                             (match_operand:SI 2 "immediate_operand" "")))
18117               (clobber (reg:CC 17))])]
18118   "TARGET_K8 && !optimize_size
18119    && (GET_CODE (operands[2]) != CONST_INT
18120        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18121   [(set (match_dup 3) (match_dup 1))
18122    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18123               (clobber (reg:CC 17))])]
18124 "")
18125
18126 (define_peephole2
18127   [(match_scratch:SI 3 "r")
18128    (parallel [(set (match_operand:DI 0 "register_operand" "")
18129                    (zero_extend:DI
18130                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18131                               (match_operand:SI 2 "immediate_operand" ""))))
18132               (clobber (reg:CC 17))])]
18133   "TARGET_K8 && !optimize_size
18134    && (GET_CODE (operands[2]) != CONST_INT
18135        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18136   [(set (match_dup 3) (match_dup 1))
18137    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18138               (clobber (reg:CC 17))])]
18139 "")
18140
18141 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18142 ;; Convert it into imul reg, reg
18143 ;; It would be better to force assembler to encode instruction using long
18144 ;; immediate, but there is apparently no way to do so.
18145 (define_peephole2
18146   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18147                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18148                             (match_operand:DI 2 "const_int_operand" "")))
18149               (clobber (reg:CC 17))])
18150    (match_scratch:DI 3 "r")]
18151   "TARGET_K8 && !optimize_size
18152    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18153   [(set (match_dup 3) (match_dup 2))
18154    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18155               (clobber (reg:CC 17))])]
18156 {
18157   if (!rtx_equal_p (operands[0], operands[1]))
18158     emit_move_insn (operands[0], operands[1]);
18159 })
18160
18161 (define_peephole2
18162   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18163                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18164                             (match_operand:SI 2 "const_int_operand" "")))
18165               (clobber (reg:CC 17))])
18166    (match_scratch:SI 3 "r")]
18167   "TARGET_K8 && !optimize_size
18168    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18169   [(set (match_dup 3) (match_dup 2))
18170    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18171               (clobber (reg:CC 17))])]
18172 {
18173   if (!rtx_equal_p (operands[0], operands[1]))
18174     emit_move_insn (operands[0], operands[1]);
18175 })
18176
18177 (define_peephole2
18178   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18179                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18180                             (match_operand:HI 2 "immediate_operand" "")))
18181               (clobber (reg:CC 17))])
18182    (match_scratch:HI 3 "r")]
18183   "TARGET_K8 && !optimize_size"
18184   [(set (match_dup 3) (match_dup 2))
18185    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18186               (clobber (reg:CC 17))])]
18187 {
18188   if (!rtx_equal_p (operands[0], operands[1]))
18189     emit_move_insn (operands[0], operands[1]);
18190 })
18191 \f
18192 ;; Call-value patterns last so that the wildcard operand does not
18193 ;; disrupt insn-recog's switch tables.
18194
18195 (define_insn "*call_value_pop_0"
18196   [(set (match_operand 0 "" "")
18197         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18198               (match_operand:SI 2 "" "")))
18199    (set (reg:SI 7) (plus:SI (reg:SI 7)
18200                             (match_operand:SI 3 "immediate_operand" "")))]
18201   "!TARGET_64BIT"
18202 {
18203   if (SIBLING_CALL_P (insn))
18204     return "jmp\t%P1";
18205   else
18206     return "call\t%P1";
18207 }
18208   [(set_attr "type" "callv")])
18209
18210 (define_insn "*call_value_pop_1"
18211   [(set (match_operand 0 "" "")
18212         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18213               (match_operand:SI 2 "" "")))
18214    (set (reg:SI 7) (plus:SI (reg:SI 7)
18215                             (match_operand:SI 3 "immediate_operand" "i")))]
18216   "!TARGET_64BIT"
18217 {
18218   if (constant_call_address_operand (operands[1], QImode))
18219     {
18220       if (SIBLING_CALL_P (insn))
18221         return "jmp\t%P1";
18222       else
18223         return "call\t%P1";
18224     }
18225   if (SIBLING_CALL_P (insn))
18226     return "jmp\t%A1";
18227   else
18228     return "call\t%A1";
18229 }
18230   [(set_attr "type" "callv")])
18231
18232 (define_insn "*call_value_0"
18233   [(set (match_operand 0 "" "")
18234         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18235               (match_operand:SI 2 "" "")))]
18236   "!TARGET_64BIT"
18237 {
18238   if (SIBLING_CALL_P (insn))
18239     return "jmp\t%P1";
18240   else
18241     return "call\t%P1";
18242 }
18243   [(set_attr "type" "callv")])
18244
18245 (define_insn "*call_value_0_rex64"
18246   [(set (match_operand 0 "" "")
18247         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18248               (match_operand:DI 2 "const_int_operand" "")))]
18249   "TARGET_64BIT"
18250 {
18251   if (SIBLING_CALL_P (insn))
18252     return "jmp\t%P1";
18253   else
18254     return "call\t%P1";
18255 }
18256   [(set_attr "type" "callv")])
18257
18258 (define_insn "*call_value_1"
18259   [(set (match_operand 0 "" "")
18260         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18261               (match_operand:SI 2 "" "")))]
18262   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18263 {
18264   if (constant_call_address_operand (operands[1], QImode))
18265     return "call\t%P1";
18266   return "call\t%*%1";
18267 }
18268   [(set_attr "type" "callv")])
18269
18270 (define_insn "*sibcall_value_1"
18271   [(set (match_operand 0 "" "")
18272         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18273               (match_operand:SI 2 "" "")))]
18274   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18275 {
18276   if (constant_call_address_operand (operands[1], QImode))
18277     return "jmp\t%P1";
18278   return "jmp\t%*%1";
18279 }
18280   [(set_attr "type" "callv")])
18281
18282 (define_insn "*call_value_1_rex64"
18283   [(set (match_operand 0 "" "")
18284         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18285               (match_operand:DI 2 "" "")))]
18286   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18287 {
18288   if (constant_call_address_operand (operands[1], QImode))
18289     return "call\t%P1";
18290   return "call\t%A1";
18291 }
18292   [(set_attr "type" "callv")])
18293
18294 (define_insn "*sibcall_value_1_rex64"
18295   [(set (match_operand 0 "" "")
18296         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18297               (match_operand:DI 2 "" "")))]
18298   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18299   "jmp\t%P1"
18300   [(set_attr "type" "callv")])
18301
18302 (define_insn "*sibcall_value_1_rex64_v"
18303   [(set (match_operand 0 "" "")
18304         (call (mem:QI (reg:DI 40))
18305               (match_operand:DI 1 "" "")))]
18306   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18307   "jmp\t*%%r11"
18308   [(set_attr "type" "callv")])
18309 \f
18310 (define_insn "trap"
18311   [(trap_if (const_int 1) (const_int 5))]
18312   ""
18313   "int\t$5")
18314
18315 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18316 ;;; for the sake of bounds checking.  By emitting bounds checks as
18317 ;;; conditional traps rather than as conditional jumps around
18318 ;;; unconditional traps we avoid introducing spurious basic-block
18319 ;;; boundaries and facilitate elimination of redundant checks.  In
18320 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18321 ;;; interrupt 5.
18322 ;;; 
18323 ;;; FIXME: Static branch prediction rules for ix86 are such that
18324 ;;; forward conditional branches predict as untaken.  As implemented
18325 ;;; below, pseudo conditional traps violate that rule.  We should use
18326 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18327 ;;; section loaded at the end of the text segment and branch forward
18328 ;;; there on bounds-failure, and then jump back immediately (in case
18329 ;;; the system chooses to ignore bounds violations, or to report
18330 ;;; violations and continue execution).
18331
18332 (define_expand "conditional_trap"
18333   [(trap_if (match_operator 0 "comparison_operator"
18334              [(match_dup 2) (const_int 0)])
18335             (match_operand 1 "const_int_operand" ""))]
18336   ""
18337 {
18338   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18339                               ix86_expand_compare (GET_CODE (operands[0]),
18340                                                    NULL, NULL),
18341                               operands[1]));
18342   DONE;
18343 })
18344
18345 (define_insn "*conditional_trap_1"
18346   [(trap_if (match_operator 0 "comparison_operator"
18347              [(reg 17) (const_int 0)])
18348             (match_operand 1 "const_int_operand" ""))]
18349   ""
18350 {
18351   operands[2] = gen_label_rtx ();
18352   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18353   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18354                              CODE_LABEL_NUMBER (operands[2]));
18355   RET;
18356 })
18357
18358         ;; Pentium III SIMD instructions.
18359
18360 ;; Moves for SSE/MMX regs.
18361
18362 (define_insn "movv4sf_internal"
18363   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18364         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18365   "TARGET_SSE"
18366   "@
18367     xorps\t%0, %0
18368     movaps\t{%1, %0|%0, %1}
18369     movaps\t{%1, %0|%0, %1}"
18370   [(set_attr "type" "ssemov")
18371    (set_attr "mode" "V4SF")])
18372
18373 (define_split
18374   [(set (match_operand:V4SF 0 "register_operand" "")
18375         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18376   "TARGET_SSE"
18377   [(set (match_dup 0)
18378         (vec_merge:V4SF
18379          (vec_duplicate:V4SF (match_dup 1))
18380          (match_dup 2)
18381          (const_int 1)))]
18382 {
18383   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18384   operands[2] = CONST0_RTX (V4SFmode);
18385 })
18386
18387 (define_insn "movv4si_internal"
18388   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18389         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18390   "TARGET_SSE"
18391 {
18392   switch (which_alternative)
18393     {
18394     case 0:
18395       if (get_attr_mode (insn) == MODE_V4SF)
18396         return "xorps\t%0, %0";
18397       else
18398         return "pxor\t%0, %0";
18399     case 1:
18400     case 2:
18401       if (get_attr_mode (insn) == MODE_V4SF)
18402         return "movaps\t{%1, %0|%0, %1}";
18403       else
18404         return "movdqa\t{%1, %0|%0, %1}";
18405     default:
18406       abort ();
18407     }
18408 }
18409   [(set_attr "type" "ssemov")
18410    (set (attr "mode")
18411         (cond [(eq_attr "alternative" "0,1")
18412                  (if_then_else
18413                    (ne (symbol_ref "optimize_size")
18414                        (const_int 0))
18415                    (const_string "V4SF")
18416                    (const_string "TI"))
18417                (eq_attr "alternative" "2")
18418                  (if_then_else
18419                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18420                             (const_int 0))
18421                         (ne (symbol_ref "optimize_size")
18422                             (const_int 0)))
18423                    (const_string "V4SF")
18424                    (const_string "TI"))]
18425                (const_string "TI")))])
18426
18427 (define_insn "movv2di_internal"
18428   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18429         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18430   "TARGET_SSE2"
18431 {
18432   switch (which_alternative)
18433     {
18434     case 0:
18435       if (get_attr_mode (insn) == MODE_V4SF)
18436         return "xorps\t%0, %0";
18437       else
18438         return "pxor\t%0, %0";
18439     case 1:
18440     case 2:
18441       if (get_attr_mode (insn) == MODE_V4SF)
18442         return "movaps\t{%1, %0|%0, %1}";
18443       else
18444         return "movdqa\t{%1, %0|%0, %1}";
18445     default:
18446       abort ();
18447     }
18448 }
18449   [(set_attr "type" "ssemov")
18450    (set (attr "mode")
18451         (cond [(eq_attr "alternative" "0,1")
18452                  (if_then_else
18453                    (ne (symbol_ref "optimize_size")
18454                        (const_int 0))
18455                    (const_string "V4SF")
18456                    (const_string "TI"))
18457                (eq_attr "alternative" "2")
18458                  (if_then_else
18459                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18460                             (const_int 0))
18461                         (ne (symbol_ref "optimize_size")
18462                             (const_int 0)))
18463                    (const_string "V4SF")
18464                    (const_string "TI"))]
18465                (const_string "TI")))])
18466
18467 (define_split
18468   [(set (match_operand:V2DF 0 "register_operand" "")
18469         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18470   "TARGET_SSE2"
18471   [(set (match_dup 0)
18472         (vec_merge:V2DF
18473          (vec_duplicate:V2DF (match_dup 1))
18474          (match_dup 2)
18475          (const_int 1)))]
18476 {
18477   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18478   operands[2] = CONST0_RTX (V2DFmode);
18479 })
18480
18481 (define_insn "movv8qi_internal"
18482   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18483         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18484   "TARGET_MMX
18485    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18486   "@
18487     pxor\t%0, %0
18488     movq\t{%1, %0|%0, %1}
18489     movq\t{%1, %0|%0, %1}"
18490   [(set_attr "type" "mmxmov")
18491    (set_attr "mode" "DI")])
18492
18493 (define_insn "movv4hi_internal"
18494   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18495         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18496   "TARGET_MMX
18497    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18498   "@
18499     pxor\t%0, %0
18500     movq\t{%1, %0|%0, %1}
18501     movq\t{%1, %0|%0, %1}"
18502   [(set_attr "type" "mmxmov")
18503    (set_attr "mode" "DI")])
18504
18505 (define_insn "movv2si_internal"
18506   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18507         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18508   "TARGET_MMX
18509    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18510   "@
18511     pxor\t%0, %0
18512     movq\t{%1, %0|%0, %1}
18513     movq\t{%1, %0|%0, %1}"
18514   [(set_attr "type" "mmxcvt")
18515    (set_attr "mode" "DI")])
18516
18517 (define_insn "movv2sf_internal"
18518   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18519         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18520   "TARGET_3DNOW
18521    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18522   "@
18523     pxor\t%0, %0
18524     movq\t{%1, %0|%0, %1}
18525     movq\t{%1, %0|%0, %1}"
18526   [(set_attr "type" "mmxcvt")
18527    (set_attr "mode" "DI")])
18528
18529 (define_expand "movti"
18530   [(set (match_operand:TI 0 "nonimmediate_operand" "")
18531         (match_operand:TI 1 "nonimmediate_operand" ""))]
18532   "TARGET_SSE || TARGET_64BIT"
18533 {
18534   if (TARGET_64BIT)
18535     ix86_expand_move (TImode, operands);
18536   else
18537     ix86_expand_vector_move (TImode, operands);
18538   DONE;
18539 })
18540
18541 (define_expand "movtf"
18542   [(set (match_operand:TF 0 "nonimmediate_operand" "")
18543         (match_operand:TF 1 "nonimmediate_operand" ""))]
18544   "TARGET_64BIT"
18545 {
18546   if (TARGET_64BIT)
18547     ix86_expand_move (TFmode, operands);
18548   else
18549     ix86_expand_vector_move (TFmode, operands);
18550   DONE;
18551 })
18552
18553 (define_insn "movv2df_internal"
18554   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18555         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18556   "TARGET_SSE2
18557    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18558 {
18559   switch (which_alternative)
18560     {
18561     case 0:
18562       if (get_attr_mode (insn) == MODE_V4SF)
18563         return "xorps\t%0, %0";
18564       else
18565         return "xorpd\t%0, %0";
18566     case 1:
18567     case 2:
18568       if (get_attr_mode (insn) == MODE_V4SF)
18569         return "movaps\t{%1, %0|%0, %1}";
18570       else
18571         return "movapd\t{%1, %0|%0, %1}";
18572     default:
18573       abort ();
18574     }
18575 }
18576   [(set_attr "type" "ssemov")
18577    (set (attr "mode")
18578         (cond [(eq_attr "alternative" "0,1")
18579                  (if_then_else
18580                    (ne (symbol_ref "optimize_size")
18581                        (const_int 0))
18582                    (const_string "V4SF")
18583                    (const_string "V2DF"))
18584                (eq_attr "alternative" "2")
18585                  (if_then_else
18586                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18587                             (const_int 0))
18588                         (ne (symbol_ref "optimize_size")
18589                             (const_int 0)))
18590                    (const_string "V4SF")
18591                    (const_string "V2DF"))]
18592                (const_string "V2DF")))])
18593
18594 (define_insn "movv8hi_internal"
18595   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18596         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18597   "TARGET_SSE2
18598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18599 {
18600   switch (which_alternative)
18601     {
18602     case 0:
18603       if (get_attr_mode (insn) == MODE_V4SF)
18604         return "xorps\t%0, %0";
18605       else
18606         return "pxor\t%0, %0";
18607     case 1:
18608     case 2:
18609       if (get_attr_mode (insn) == MODE_V4SF)
18610         return "movaps\t{%1, %0|%0, %1}";
18611       else
18612         return "movdqa\t{%1, %0|%0, %1}";
18613     default:
18614       abort ();
18615     }
18616 }
18617   [(set_attr "type" "ssemov")
18618    (set (attr "mode")
18619         (cond [(eq_attr "alternative" "0,1")
18620                  (if_then_else
18621                    (ne (symbol_ref "optimize_size")
18622                        (const_int 0))
18623                    (const_string "V4SF")
18624                    (const_string "TI"))
18625                (eq_attr "alternative" "2")
18626                  (if_then_else
18627                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18628                             (const_int 0))
18629                         (ne (symbol_ref "optimize_size")
18630                             (const_int 0)))
18631                    (const_string "V4SF")
18632                    (const_string "TI"))]
18633                (const_string "TI")))])
18634
18635 (define_insn "movv16qi_internal"
18636   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18637         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18638   "TARGET_SSE2
18639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18640 {
18641   switch (which_alternative)
18642     {
18643     case 0:
18644       if (get_attr_mode (insn) == MODE_V4SF)
18645         return "xorps\t%0, %0";
18646       else
18647         return "pxor\t%0, %0";
18648     case 1:
18649     case 2:
18650       if (get_attr_mode (insn) == MODE_V4SF)
18651         return "movaps\t{%1, %0|%0, %1}";
18652       else
18653         return "movdqa\t{%1, %0|%0, %1}";
18654     default:
18655       abort ();
18656     }
18657 }
18658   [(set_attr "type" "ssemov")
18659    (set (attr "mode")
18660         (cond [(eq_attr "alternative" "0,1")
18661                  (if_then_else
18662                    (ne (symbol_ref "optimize_size")
18663                        (const_int 0))
18664                    (const_string "V4SF")
18665                    (const_string "TI"))
18666                (eq_attr "alternative" "2")
18667                  (if_then_else
18668                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18669                             (const_int 0))
18670                         (ne (symbol_ref "optimize_size")
18671                             (const_int 0)))
18672                    (const_string "V4SF")
18673                    (const_string "TI"))]
18674                (const_string "TI")))])
18675
18676 (define_expand "movv2df"
18677   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18678         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18679   "TARGET_SSE2"
18680 {
18681   ix86_expand_vector_move (V2DFmode, operands);
18682   DONE;
18683 })
18684
18685 (define_expand "movv8hi"
18686   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18687         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18688   "TARGET_SSE2"
18689 {
18690   ix86_expand_vector_move (V8HImode, operands);
18691   DONE;
18692 })
18693
18694 (define_expand "movv16qi"
18695   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18696         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18697   "TARGET_SSE2"
18698 {
18699   ix86_expand_vector_move (V16QImode, operands);
18700   DONE;
18701 })
18702
18703 (define_expand "movv4sf"
18704   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18705         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18706   "TARGET_SSE"
18707 {
18708   ix86_expand_vector_move (V4SFmode, operands);
18709   DONE;
18710 })
18711
18712 (define_expand "movv4si"
18713   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18714         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18715   "TARGET_SSE"
18716 {
18717   ix86_expand_vector_move (V4SImode, operands);
18718   DONE;
18719 })
18720
18721 (define_expand "movv2di"
18722   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18723         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18724   "TARGET_SSE"
18725 {
18726   ix86_expand_vector_move (V2DImode, operands);
18727   DONE;
18728 })
18729
18730 (define_expand "movv2si"
18731   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18732         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18733   "TARGET_MMX"
18734 {
18735   ix86_expand_vector_move (V2SImode, operands);
18736   DONE;
18737 })
18738
18739 (define_expand "movv4hi"
18740   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18741         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18742   "TARGET_MMX"
18743 {
18744   ix86_expand_vector_move (V4HImode, operands);
18745   DONE;
18746 })
18747
18748 (define_expand "movv8qi"
18749   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18750         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18751   "TARGET_MMX"
18752 {
18753   ix86_expand_vector_move (V8QImode, operands);
18754   DONE;
18755 })
18756
18757 (define_expand "movv2sf"
18758   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18759         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18760    "TARGET_3DNOW"
18761 {
18762   ix86_expand_vector_move (V2SFmode, operands);
18763   DONE;
18764 })
18765
18766 (define_insn "*pushti"
18767   [(set (match_operand:TI 0 "push_operand" "=<")
18768         (match_operand:TI 1 "register_operand" "x"))]
18769   "TARGET_SSE"
18770   "#")
18771
18772 (define_insn "*pushv2df"
18773   [(set (match_operand:V2DF 0 "push_operand" "=<")
18774         (match_operand:V2DF 1 "register_operand" "x"))]
18775   "TARGET_SSE"
18776   "#")
18777
18778 (define_insn "*pushv2di"
18779   [(set (match_operand:V2DI 0 "push_operand" "=<")
18780         (match_operand:V2DI 1 "register_operand" "x"))]
18781   "TARGET_SSE2"
18782   "#")
18783
18784 (define_insn "*pushv8hi"
18785   [(set (match_operand:V8HI 0 "push_operand" "=<")
18786         (match_operand:V8HI 1 "register_operand" "x"))]
18787   "TARGET_SSE2"
18788   "#")
18789
18790 (define_insn "*pushv16qi"
18791   [(set (match_operand:V16QI 0 "push_operand" "=<")
18792         (match_operand:V16QI 1 "register_operand" "x"))]
18793   "TARGET_SSE2"
18794   "#")
18795
18796 (define_insn "*pushv4sf"
18797   [(set (match_operand:V4SF 0 "push_operand" "=<")
18798         (match_operand:V4SF 1 "register_operand" "x"))]
18799   "TARGET_SSE"
18800   "#")
18801
18802 (define_insn "*pushv4si"
18803   [(set (match_operand:V4SI 0 "push_operand" "=<")
18804         (match_operand:V4SI 1 "register_operand" "x"))]
18805   "TARGET_SSE2"
18806   "#")
18807
18808 (define_insn "*pushv2si"
18809   [(set (match_operand:V2SI 0 "push_operand" "=<")
18810         (match_operand:V2SI 1 "register_operand" "y"))]
18811   "TARGET_MMX"
18812   "#")
18813
18814 (define_insn "*pushv4hi"
18815   [(set (match_operand:V4HI 0 "push_operand" "=<")
18816         (match_operand:V4HI 1 "register_operand" "y"))]
18817   "TARGET_MMX"
18818   "#")
18819
18820 (define_insn "*pushv8qi"
18821   [(set (match_operand:V8QI 0 "push_operand" "=<")
18822         (match_operand:V8QI 1 "register_operand" "y"))]
18823   "TARGET_MMX"
18824   "#")
18825
18826 (define_insn "*pushv2sf"
18827   [(set (match_operand:V2SF 0 "push_operand" "=<")
18828         (match_operand:V2SF 1 "register_operand" "y"))]
18829   "TARGET_3DNOW"
18830   "#")
18831
18832 (define_split
18833   [(set (match_operand 0 "push_operand" "")
18834         (match_operand 1 "register_operand" ""))]
18835   "!TARGET_64BIT && reload_completed
18836    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18837   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18838    (set (match_dup 2) (match_dup 1))]
18839   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18840                                  stack_pointer_rtx);
18841    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18842
18843 (define_split
18844   [(set (match_operand 0 "push_operand" "")
18845         (match_operand 1 "register_operand" ""))]
18846   "TARGET_64BIT && reload_completed
18847    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18848   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18849    (set (match_dup 2) (match_dup 1))]
18850   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18851                                  stack_pointer_rtx);
18852    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18853
18854
18855 (define_insn "movti_internal"
18856   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18857         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18858   "TARGET_SSE && !TARGET_64BIT
18859    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18860 {
18861   switch (which_alternative)
18862     {
18863     case 0:
18864       if (get_attr_mode (insn) == MODE_V4SF)
18865         return "xorps\t%0, %0";
18866       else
18867         return "pxor\t%0, %0";
18868     case 1:
18869     case 2:
18870       if (get_attr_mode (insn) == MODE_V4SF)
18871         return "movaps\t{%1, %0|%0, %1}";
18872       else
18873         return "movdqa\t{%1, %0|%0, %1}";
18874     default:
18875       abort ();
18876     }
18877 }
18878   [(set_attr "type" "ssemov,ssemov,ssemov")
18879    (set (attr "mode")
18880         (cond [(eq_attr "alternative" "0,1")
18881                  (if_then_else
18882                    (ne (symbol_ref "optimize_size")
18883                        (const_int 0))
18884                    (const_string "V4SF")
18885                    (const_string "TI"))
18886                (eq_attr "alternative" "2")
18887                  (if_then_else
18888                    (ne (symbol_ref "optimize_size")
18889                        (const_int 0))
18890                    (const_string "V4SF")
18891                    (const_string "TI"))]
18892                (const_string "TI")))])
18893
18894 (define_insn "*movti_rex64"
18895   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18896         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
18897   "TARGET_64BIT
18898    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18899 {
18900   switch (which_alternative)
18901     {
18902     case 0:
18903     case 1:
18904       return "#";
18905     case 2:
18906       if (get_attr_mode (insn) == MODE_V4SF)
18907         return "xorps\t%0, %0";
18908       else
18909         return "pxor\t%0, %0";
18910     case 3:
18911     case 4:
18912       if (get_attr_mode (insn) == MODE_V4SF)
18913         return "movaps\t{%1, %0|%0, %1}";
18914       else
18915         return "movdqa\t{%1, %0|%0, %1}";
18916     default:
18917       abort ();
18918     }
18919 }
18920   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18921    (set (attr "mode")
18922         (cond [(eq_attr "alternative" "2,3")
18923                  (if_then_else
18924                    (ne (symbol_ref "optimize_size")
18925                        (const_int 0))
18926                    (const_string "V4SF")
18927                    (const_string "TI"))
18928                (eq_attr "alternative" "4")
18929                  (if_then_else
18930                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18931                             (const_int 0))
18932                         (ne (symbol_ref "optimize_size")
18933                             (const_int 0)))
18934                    (const_string "V4SF")
18935                    (const_string "TI"))]
18936                (const_string "DI")))])
18937
18938 (define_insn "*movtf_rex64"
18939   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
18940         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
18941   "TARGET_64BIT
18942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18943 {
18944   switch (which_alternative)
18945     {
18946     case 0:
18947     case 1:
18948       return "#";
18949     case 2:
18950       if (get_attr_mode (insn) == MODE_V4SF)
18951         return "xorps\t%0, %0";
18952       else
18953         return "pxor\t%0, %0";
18954     case 3:
18955     case 4:
18956       if (get_attr_mode (insn) == MODE_V4SF)
18957         return "movaps\t{%1, %0|%0, %1}";
18958       else
18959         return "movdqa\t{%1, %0|%0, %1}";
18960     default:
18961       abort ();
18962     }
18963 }
18964   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18965    (set (attr "mode")
18966         (cond [(eq_attr "alternative" "2,3")
18967                  (if_then_else
18968                    (ne (symbol_ref "optimize_size")
18969                        (const_int 0))
18970                    (const_string "V4SF")
18971                    (const_string "TI"))
18972                (eq_attr "alternative" "4")
18973                  (if_then_else
18974                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18975                             (const_int 0))
18976                         (ne (symbol_ref "optimize_size")
18977                             (const_int 0)))
18978                    (const_string "V4SF")
18979                    (const_string "TI"))]
18980                (const_string "DI")))])
18981
18982 (define_split
18983   [(set (match_operand:TI 0 "nonimmediate_operand" "")
18984         (match_operand:TI 1 "general_operand" ""))]
18985   "reload_completed && !SSE_REG_P (operands[0])
18986    && !SSE_REG_P (operands[1])"
18987   [(const_int 0)]
18988   "ix86_split_long_move (operands); DONE;")
18989
18990 (define_split
18991   [(set (match_operand:TF 0 "nonimmediate_operand" "")
18992         (match_operand:TF 1 "general_operand" ""))]
18993   "reload_completed && !SSE_REG_P (operands[0])
18994    && !SSE_REG_P (operands[1])"
18995   [(const_int 0)]
18996   "ix86_split_long_move (operands); DONE;")
18997
18998 ;; These two patterns are useful for specifying exactly whether to use
18999 ;; movaps or movups
19000 (define_expand "sse_movaps"
19001   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19002         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19003                      UNSPEC_MOVA))]
19004   "TARGET_SSE"
19005 {
19006   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19007     {
19008       rtx tmp = gen_reg_rtx (V4SFmode);
19009       emit_insn (gen_sse_movaps (tmp, operands[1]));
19010       emit_move_insn (operands[0], tmp);
19011       DONE;
19012     }
19013 })
19014
19015 (define_insn "*sse_movaps_1"
19016   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19017         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19018                      UNSPEC_MOVA))]
19019   "TARGET_SSE
19020    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19021   "movaps\t{%1, %0|%0, %1}"
19022   [(set_attr "type" "ssemov,ssemov")
19023    (set_attr "mode" "V4SF")])
19024
19025 (define_expand "sse_movups"
19026   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19027         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19028                      UNSPEC_MOVU))]
19029   "TARGET_SSE"
19030 {
19031   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19032     {
19033       rtx tmp = gen_reg_rtx (V4SFmode);
19034       emit_insn (gen_sse_movups (tmp, operands[1]));
19035       emit_move_insn (operands[0], tmp);
19036       DONE;
19037     }
19038 })
19039
19040 (define_insn "*sse_movups_1"
19041   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19042         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19043                      UNSPEC_MOVU))]
19044   "TARGET_SSE
19045    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19046   "movups\t{%1, %0|%0, %1}"
19047   [(set_attr "type" "ssecvt,ssecvt")
19048    (set_attr "mode" "V4SF")])
19049
19050 ;; SSE Strange Moves.
19051
19052 (define_insn "sse_movmskps"
19053   [(set (match_operand:SI 0 "register_operand" "=r")
19054         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19055                    UNSPEC_MOVMSK))]
19056   "TARGET_SSE"
19057   "movmskps\t{%1, %0|%0, %1}"
19058   [(set_attr "type" "ssecvt")
19059    (set_attr "mode" "V4SF")])
19060
19061 (define_insn "mmx_pmovmskb"
19062   [(set (match_operand:SI 0 "register_operand" "=r")
19063         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19064                    UNSPEC_MOVMSK))]
19065   "TARGET_SSE || TARGET_3DNOW_A"
19066   "pmovmskb\t{%1, %0|%0, %1}"
19067   [(set_attr "type" "ssecvt")
19068    (set_attr "mode" "V4SF")])
19069
19070
19071 (define_insn "mmx_maskmovq"
19072   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19073         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19074                       (match_operand:V8QI 2 "register_operand" "y")]
19075                      UNSPEC_MASKMOV))]
19076   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19077   ;; @@@ check ordering of operands in intel/nonintel syntax
19078   "maskmovq\t{%2, %1|%1, %2}"
19079   [(set_attr "type" "mmxcvt")
19080    (set_attr "mode" "DI")])
19081
19082 (define_insn "mmx_maskmovq_rex"
19083   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19084         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19085                       (match_operand:V8QI 2 "register_operand" "y")]
19086                      UNSPEC_MASKMOV))]
19087   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19088   ;; @@@ check ordering of operands in intel/nonintel syntax
19089   "maskmovq\t{%2, %1|%1, %2}"
19090   [(set_attr "type" "mmxcvt")
19091    (set_attr "mode" "DI")])
19092
19093 (define_insn "sse_movntv4sf"
19094   [(set (match_operand:V4SF 0 "memory_operand" "=m")
19095         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19096                      UNSPEC_MOVNT))]
19097   "TARGET_SSE"
19098   "movntps\t{%1, %0|%0, %1}"
19099   [(set_attr "type" "ssemov")
19100    (set_attr "mode" "V4SF")])
19101
19102 (define_insn "sse_movntdi"
19103   [(set (match_operand:DI 0 "memory_operand" "=m")
19104         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19105                    UNSPEC_MOVNT))]
19106   "TARGET_SSE || TARGET_3DNOW_A"
19107   "movntq\t{%1, %0|%0, %1}"
19108   [(set_attr "type" "mmxmov")
19109    (set_attr "mode" "DI")])
19110
19111 (define_insn "sse_movhlps"
19112   [(set (match_operand:V4SF 0 "register_operand" "=x")
19113         (vec_merge:V4SF
19114          (match_operand:V4SF 1 "register_operand" "0")
19115          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19116                           (parallel [(const_int 2)
19117                                      (const_int 3)
19118                                      (const_int 0)
19119                                      (const_int 1)]))
19120          (const_int 3)))]
19121   "TARGET_SSE"
19122   "movhlps\t{%2, %0|%0, %2}"
19123   [(set_attr "type" "ssecvt")
19124    (set_attr "mode" "V4SF")])
19125
19126 (define_insn "sse_movlhps"
19127   [(set (match_operand:V4SF 0 "register_operand" "=x")
19128         (vec_merge:V4SF
19129          (match_operand:V4SF 1 "register_operand" "0")
19130          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19131                           (parallel [(const_int 2)
19132                                      (const_int 3)
19133                                      (const_int 0)
19134                                      (const_int 1)]))
19135          (const_int 12)))]
19136   "TARGET_SSE"
19137   "movlhps\t{%2, %0|%0, %2}"
19138   [(set_attr "type" "ssecvt")
19139    (set_attr "mode" "V4SF")])
19140
19141 (define_insn "sse_movhps"
19142   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19143         (vec_merge:V4SF
19144          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19145          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19146          (const_int 12)))]
19147   "TARGET_SSE
19148    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19149   "movhps\t{%2, %0|%0, %2}"
19150   [(set_attr "type" "ssecvt")
19151    (set_attr "mode" "V4SF")])
19152
19153 (define_insn "sse_movlps"
19154   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19155         (vec_merge:V4SF
19156          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19157          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19158          (const_int 3)))]
19159   "TARGET_SSE
19160    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19161   "movlps\t{%2, %0|%0, %2}"
19162   [(set_attr "type" "ssecvt")
19163    (set_attr "mode" "V4SF")])
19164
19165 (define_expand "sse_loadss"
19166   [(match_operand:V4SF 0 "register_operand" "")
19167    (match_operand:SF 1 "memory_operand" "")]
19168   "TARGET_SSE"
19169 {
19170   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19171                                CONST0_RTX (V4SFmode)));
19172   DONE;
19173 })
19174
19175 (define_insn "sse_loadss_1"
19176   [(set (match_operand:V4SF 0 "register_operand" "=x")
19177         (vec_merge:V4SF
19178          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19179          (match_operand:V4SF 2 "const0_operand" "X")
19180          (const_int 1)))]
19181   "TARGET_SSE"
19182   "movss\t{%1, %0|%0, %1}"
19183   [(set_attr "type" "ssemov")
19184    (set_attr "mode" "SF")])
19185
19186 (define_insn "sse_movss"
19187   [(set (match_operand:V4SF 0 "register_operand" "=x")
19188         (vec_merge:V4SF
19189          (match_operand:V4SF 1 "register_operand" "0")
19190          (match_operand:V4SF 2 "register_operand" "x")
19191          (const_int 1)))]
19192   "TARGET_SSE"
19193   "movss\t{%2, %0|%0, %2}"
19194   [(set_attr "type" "ssemov")
19195    (set_attr "mode" "SF")])
19196
19197 (define_insn "sse_storess"
19198   [(set (match_operand:SF 0 "memory_operand" "=m")
19199         (vec_select:SF
19200          (match_operand:V4SF 1 "register_operand" "x")
19201          (parallel [(const_int 0)])))]
19202   "TARGET_SSE"
19203   "movss\t{%1, %0|%0, %1}"
19204   [(set_attr "type" "ssemov")
19205    (set_attr "mode" "SF")])
19206
19207 (define_insn "sse_shufps"
19208   [(set (match_operand:V4SF 0 "register_operand" "=x")
19209         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19210                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19211                       (match_operand:SI 3 "immediate_operand" "i")]
19212                      UNSPEC_SHUFFLE))]
19213   "TARGET_SSE"
19214   ;; @@@ check operand order for intel/nonintel syntax
19215   "shufps\t{%3, %2, %0|%0, %2, %3}"
19216   [(set_attr "type" "ssecvt")
19217    (set_attr "mode" "V4SF")])
19218
19219
19220 ;; SSE arithmetic
19221
19222 (define_insn "addv4sf3"
19223   [(set (match_operand:V4SF 0 "register_operand" "=x")
19224         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19225                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19226   "TARGET_SSE"
19227   "addps\t{%2, %0|%0, %2}"
19228   [(set_attr "type" "sseadd")
19229    (set_attr "mode" "V4SF")])
19230
19231 (define_insn "vmaddv4sf3"
19232   [(set (match_operand:V4SF 0 "register_operand" "=x")
19233         (vec_merge:V4SF
19234          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19235                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19236          (match_dup 1)
19237          (const_int 1)))]
19238   "TARGET_SSE"
19239   "addss\t{%2, %0|%0, %2}"
19240   [(set_attr "type" "sseadd")
19241    (set_attr "mode" "SF")])
19242
19243 (define_insn "subv4sf3"
19244   [(set (match_operand:V4SF 0 "register_operand" "=x")
19245         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19246                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19247   "TARGET_SSE"
19248   "subps\t{%2, %0|%0, %2}"
19249   [(set_attr "type" "sseadd")
19250    (set_attr "mode" "V4SF")])
19251
19252 (define_insn "vmsubv4sf3"
19253   [(set (match_operand:V4SF 0 "register_operand" "=x")
19254         (vec_merge:V4SF
19255          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19256                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19257          (match_dup 1)
19258          (const_int 1)))]
19259   "TARGET_SSE"
19260   "subss\t{%2, %0|%0, %2}"
19261   [(set_attr "type" "sseadd")
19262    (set_attr "mode" "SF")])
19263
19264 (define_insn "mulv4sf3"
19265   [(set (match_operand:V4SF 0 "register_operand" "=x")
19266         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19267                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19268   "TARGET_SSE"
19269   "mulps\t{%2, %0|%0, %2}"
19270   [(set_attr "type" "ssemul")
19271    (set_attr "mode" "V4SF")])
19272
19273 (define_insn "vmmulv4sf3"
19274   [(set (match_operand:V4SF 0 "register_operand" "=x")
19275         (vec_merge:V4SF
19276          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19277                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19278          (match_dup 1)
19279          (const_int 1)))]
19280   "TARGET_SSE"
19281   "mulss\t{%2, %0|%0, %2}"
19282   [(set_attr "type" "ssemul")
19283    (set_attr "mode" "SF")])
19284
19285 (define_insn "divv4sf3"
19286   [(set (match_operand:V4SF 0 "register_operand" "=x")
19287         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19288                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19289   "TARGET_SSE"
19290   "divps\t{%2, %0|%0, %2}"
19291   [(set_attr "type" "ssediv")
19292    (set_attr "mode" "V4SF")])
19293
19294 (define_insn "vmdivv4sf3"
19295   [(set (match_operand:V4SF 0 "register_operand" "=x")
19296         (vec_merge:V4SF
19297          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19298                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19299          (match_dup 1)
19300          (const_int 1)))]
19301   "TARGET_SSE"
19302   "divss\t{%2, %0|%0, %2}"
19303   [(set_attr "type" "ssediv")
19304    (set_attr "mode" "SF")])
19305
19306
19307 ;; SSE square root/reciprocal
19308
19309 (define_insn "rcpv4sf2"
19310   [(set (match_operand:V4SF 0 "register_operand" "=x")
19311         (unspec:V4SF
19312          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19313   "TARGET_SSE"
19314   "rcpps\t{%1, %0|%0, %1}"
19315   [(set_attr "type" "sse")
19316    (set_attr "mode" "V4SF")])
19317
19318 (define_insn "vmrcpv4sf2"
19319   [(set (match_operand:V4SF 0 "register_operand" "=x")
19320         (vec_merge:V4SF
19321          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19322                       UNSPEC_RCP)
19323          (match_operand:V4SF 2 "register_operand" "0")
19324          (const_int 1)))]
19325   "TARGET_SSE"
19326   "rcpss\t{%1, %0|%0, %1}"
19327   [(set_attr "type" "sse")
19328    (set_attr "mode" "SF")])
19329
19330 (define_insn "rsqrtv4sf2"
19331   [(set (match_operand:V4SF 0 "register_operand" "=x")
19332         (unspec:V4SF
19333          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19334   "TARGET_SSE"
19335   "rsqrtps\t{%1, %0|%0, %1}"
19336   [(set_attr "type" "sse")
19337    (set_attr "mode" "V4SF")])
19338
19339 (define_insn "vmrsqrtv4sf2"
19340   [(set (match_operand:V4SF 0 "register_operand" "=x")
19341         (vec_merge:V4SF
19342          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19343                       UNSPEC_RSQRT)
19344          (match_operand:V4SF 2 "register_operand" "0")
19345          (const_int 1)))]
19346   "TARGET_SSE"
19347   "rsqrtss\t{%1, %0|%0, %1}"
19348   [(set_attr "type" "sse")
19349    (set_attr "mode" "SF")])
19350
19351 (define_insn "sqrtv4sf2"
19352   [(set (match_operand:V4SF 0 "register_operand" "=x")
19353         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19354   "TARGET_SSE"
19355   "sqrtps\t{%1, %0|%0, %1}"
19356   [(set_attr "type" "sse")
19357    (set_attr "mode" "V4SF")])
19358
19359 (define_insn "vmsqrtv4sf2"
19360   [(set (match_operand:V4SF 0 "register_operand" "=x")
19361         (vec_merge:V4SF
19362          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19363          (match_operand:V4SF 2 "register_operand" "0")
19364          (const_int 1)))]
19365   "TARGET_SSE"
19366   "sqrtss\t{%1, %0|%0, %1}"
19367   [(set_attr "type" "sse")
19368    (set_attr "mode" "SF")])
19369
19370 ;; SSE logical operations.
19371
19372 ;; SSE defines logical operations on floating point values.  This brings
19373 ;; interesting challenge to RTL representation where logicals are only valid
19374 ;; on integral types.  We deal with this by representing the floating point
19375 ;; logical as logical on arguments casted to TImode as this is what hardware
19376 ;; really does.  Unfortunately hardware requires the type information to be
19377 ;; present and thus we must avoid subregs from being simplified and eliminated
19378 ;; in later compilation phases.
19379 ;;
19380 ;; We have following variants from each instruction:
19381 ;; sse_andsf3 - the operation taking V4SF vector operands
19382 ;;              and doing TImode cast on them
19383 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19384 ;;                      TImode, since backend insist on eliminating casts
19385 ;;                      on memory operands
19386 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19387 ;;                   We can not accept memory operand here as instruction reads
19388 ;;                   whole scalar.  This is generated only post reload by GCC
19389 ;;                   scalar float operations that expands to logicals (fabs)
19390 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19391 ;;                   memory operand.  Eventually combine can be able
19392 ;;                   to synthesize these using splitter.
19393 ;; sse2_anddf3, *sse2_anddf3_memory
19394 ;;              
19395 ;; 
19396 ;; These are not called andti3 etc. because we really really don't want
19397 ;; the compiler to widen DImode ands to TImode ands and then try to move
19398 ;; into DImode subregs of SSE registers, and them together, and move out
19399 ;; of DImode subregs again!
19400 ;; SSE1 single precision floating point logical operation
19401 (define_expand "sse_andv4sf3"
19402   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19403         (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19404                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19405   "TARGET_SSE"
19406   "")
19407
19408 (define_insn "*sse_andv4sf3"
19409   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19410         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19411                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19412   "TARGET_SSE
19413    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19414   "andps\t{%2, %0|%0, %2}"
19415   [(set_attr "type" "sselog")
19416    (set_attr "mode" "V4SF")])
19417
19418 (define_insn "*sse_andsf3"
19419   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19420         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19421                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19422   "TARGET_SSE
19423    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19424   "andps\t{%2, %0|%0, %2}"
19425   [(set_attr "type" "sselog")
19426    (set_attr "mode" "V4SF")])
19427
19428 (define_expand "sse_nandv4sf3"
19429   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19430         (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19431                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19432   "TARGET_SSE"
19433   "")
19434
19435 (define_insn "*sse_nandv4sf3"
19436   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19437         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19438                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19439   "TARGET_SSE"
19440   "andnps\t{%2, %0|%0, %2}"
19441   [(set_attr "type" "sselog")
19442    (set_attr "mode" "V4SF")])
19443
19444 (define_insn "*sse_nandsf3"
19445   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19446         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19447                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19448   "TARGET_SSE"
19449   "andnps\t{%2, %0|%0, %2}"
19450   [(set_attr "type" "sselog")
19451    (set_attr "mode" "V4SF")])
19452
19453 (define_expand "sse_iorv4sf3"
19454   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19455         (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19456                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19457   "TARGET_SSE"
19458   "")
19459
19460 (define_insn "*sse_iorv4sf3"
19461   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19462         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19463                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19464   "TARGET_SSE
19465    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19466   "orps\t{%2, %0|%0, %2}"
19467   [(set_attr "type" "sselog")
19468    (set_attr "mode" "V4SF")])
19469
19470 (define_insn "*sse_iorsf3"
19471   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19472         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19473                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19474   "TARGET_SSE
19475    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19476   "orps\t{%2, %0|%0, %2}"
19477   [(set_attr "type" "sselog")
19478    (set_attr "mode" "V4SF")])
19479
19480 (define_expand "sse_xorv4sf3"
19481   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19482         (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19483                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19484   "TARGET_SSE
19485    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19486   "")
19487
19488 (define_insn "*sse_xorv4sf3"
19489   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19490         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19491                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19492   "TARGET_SSE
19493    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19494   "xorps\t{%2, %0|%0, %2}"
19495   [(set_attr "type" "sselog")
19496    (set_attr "mode" "V4SF")])
19497
19498 (define_insn "*sse_xorsf3"
19499   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19500         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19501                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19502   "TARGET_SSE
19503    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19504   "xorps\t{%2, %0|%0, %2}"
19505   [(set_attr "type" "sselog")
19506    (set_attr "mode" "V4SF")])
19507
19508 ;; SSE2 double precision floating point logical operation
19509
19510 (define_expand "sse2_andv2df3"
19511   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19512         (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19513                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19514   "TARGET_SSE2"
19515   "")
19516
19517 (define_insn "*sse2_andv2df3"
19518   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19519         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19520                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19521   "TARGET_SSE2
19522    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19523   "andpd\t{%2, %0|%0, %2}"
19524   [(set_attr "type" "sselog")
19525    (set_attr "mode" "V2DF")])
19526
19527 (define_insn "*sse2_andv2df3"
19528   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19529         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19530                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19531   "TARGET_SSE2
19532    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19533   "andpd\t{%2, %0|%0, %2}"
19534   [(set_attr "type" "sselog")
19535    (set_attr "mode" "V2DF")])
19536
19537 (define_expand "sse2_nandv2df3"
19538   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19539         (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19540                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19541   "TARGET_SSE2"
19542   "")
19543
19544 (define_insn "*sse2_nandv2df3"
19545   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19546         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19547                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19548   "TARGET_SSE2"
19549   "andnpd\t{%2, %0|%0, %2}"
19550   [(set_attr "type" "sselog")
19551    (set_attr "mode" "V2DF")])
19552
19553 (define_insn "*sse_nandti3_df"
19554   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19555         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19556                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19557   "TARGET_SSE2"
19558   "andnpd\t{%2, %0|%0, %2}"
19559   [(set_attr "type" "sselog")
19560    (set_attr "mode" "V2DF")])
19561
19562 (define_expand "sse2_iorv2df3"
19563   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19564         (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19565                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19566   "TARGET_SSE2"
19567   "")
19568
19569 (define_insn "*sse2_iorv2df3"
19570   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19571         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19572                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19573   "TARGET_SSE2
19574    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19575   "orpd\t{%2, %0|%0, %2}"
19576   [(set_attr "type" "sselog")
19577    (set_attr "mode" "V2DF")])
19578
19579 (define_insn "*sse2_iordf3"
19580   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19581         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19582                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19583   "TARGET_SSE2
19584    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19585   "orpd\t{%2, %0|%0, %2}"
19586   [(set_attr "type" "sselog")
19587    (set_attr "mode" "V2DF")])
19588
19589 (define_expand "sse2_xorv2df3"
19590   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19591         (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19592                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19593   "TARGET_SSE2"
19594   "")
19595
19596 (define_insn "*sse2_xorv2df3"
19597   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19598         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19599                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19600   "TARGET_SSE2
19601    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19602   "xorpd\t{%2, %0|%0, %2}"
19603   [(set_attr "type" "sselog")
19604    (set_attr "mode" "V2DF")])
19605
19606 (define_insn "*sse2_xordf3"
19607   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19608         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19609                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19610   "TARGET_SSE2
19611    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19612   "xorpd\t{%2, %0|%0, %2}"
19613   [(set_attr "type" "sselog")
19614    (set_attr "mode" "V2DF")])
19615
19616 ;; SSE2 integral logicals.  These patterns must always come after floating
19617 ;; point ones since we don't want compiler to use integer opcodes on floating
19618 ;; point SSE values to avoid matching of subregs in the match_operand.
19619 (define_insn "*sse2_andti3"
19620   [(set (match_operand:TI 0 "register_operand" "=x")
19621         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19622                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19623   "TARGET_SSE2
19624    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19625   "pand\t{%2, %0|%0, %2}"
19626   [(set_attr "type" "sselog")
19627    (set_attr "mode" "TI")])
19628
19629 (define_insn "sse2_andv2di3"
19630   [(set (match_operand:V2DI 0 "register_operand" "=x")
19631         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19632                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19633   "TARGET_SSE2
19634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19635   "pand\t{%2, %0|%0, %2}"
19636   [(set_attr "type" "sselog")
19637    (set_attr "mode" "TI")])
19638
19639 (define_insn "*sse2_nandti3"
19640   [(set (match_operand:TI 0 "register_operand" "=x")
19641         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19642                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19643   "TARGET_SSE2"
19644   "pandn\t{%2, %0|%0, %2}"
19645   [(set_attr "type" "sselog")
19646    (set_attr "mode" "TI")])
19647
19648 (define_insn "sse2_nandv2di3"
19649   [(set (match_operand:V2DI 0 "register_operand" "=x")
19650         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19651                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19652   "TARGET_SSE2
19653    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19654   "pandn\t{%2, %0|%0, %2}"
19655   [(set_attr "type" "sselog")
19656    (set_attr "mode" "TI")])
19657
19658 (define_insn "*sse2_iorti3"
19659   [(set (match_operand:TI 0 "register_operand" "=x")
19660         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19661                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19662   "TARGET_SSE2
19663    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19664   "por\t{%2, %0|%0, %2}"
19665   [(set_attr "type" "sselog")
19666    (set_attr "mode" "TI")])
19667
19668 (define_insn "sse2_iorv2di3"
19669   [(set (match_operand:V2DI 0 "register_operand" "=x")
19670         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19671                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19672   "TARGET_SSE2
19673    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19674   "por\t{%2, %0|%0, %2}"
19675   [(set_attr "type" "sselog")
19676    (set_attr "mode" "TI")])
19677
19678 (define_insn "*sse2_xorti3"
19679   [(set (match_operand:TI 0 "register_operand" "=x")
19680         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19681                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19682   "TARGET_SSE2
19683    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19684   "pxor\t{%2, %0|%0, %2}"
19685   [(set_attr "type" "sselog")
19686    (set_attr "mode" "TI")])
19687
19688 (define_insn "sse2_xorv2di3"
19689   [(set (match_operand:V2DI 0 "register_operand" "=x")
19690         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19691                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19692   "TARGET_SSE2
19693    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19694   "pxor\t{%2, %0|%0, %2}"
19695   [(set_attr "type" "sselog")
19696    (set_attr "mode" "TI")])
19697
19698 ;; Use xor, but don't show input operands so they aren't live before
19699 ;; this insn.
19700 (define_insn "sse_clrv4sf"
19701   [(set (match_operand:V4SF 0 "register_operand" "=x")
19702         (match_operand:V4SF 1 "const0_operand" "X"))]
19703   "TARGET_SSE"
19704 {
19705   if (get_attr_mode (insn) == MODE_TI)
19706     return "pxor\t{%0, %0|%0, %0}";
19707   else
19708     return "xorps\t{%0, %0|%0, %0}";
19709 }
19710   [(set_attr "type" "sselog")
19711    (set_attr "memory" "none")
19712    (set (attr "mode")
19713         (if_then_else
19714            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19715                          (const_int 0))
19716                      (ne (symbol_ref "TARGET_SSE2")
19717                          (const_int 0)))
19718                 (eq (symbol_ref "optimize_size")
19719                     (const_int 0)))
19720          (const_string "TI")
19721          (const_string "V4SF")))])
19722
19723 ;; Use xor, but don't show input operands so they aren't live before
19724 ;; this insn.
19725 (define_insn "sse_clrv2df"
19726   [(set (match_operand:V2DF 0 "register_operand" "=x")
19727         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19728   "TARGET_SSE2"
19729   "xorpd\t{%0, %0|%0, %0}"
19730   [(set_attr "type" "sselog")
19731    (set_attr "memory" "none")
19732    (set_attr "mode" "V4SF")])
19733
19734 ;; SSE mask-generating compares
19735
19736 (define_insn "maskcmpv4sf3"
19737   [(set (match_operand:V4SI 0 "register_operand" "=x")
19738         (match_operator:V4SI 3 "sse_comparison_operator"
19739                 [(match_operand:V4SF 1 "register_operand" "0")
19740                  (match_operand:V4SF 2 "register_operand" "x")]))]
19741   "TARGET_SSE"
19742   "cmp%D3ps\t{%2, %0|%0, %2}"
19743   [(set_attr "type" "ssecmp")
19744    (set_attr "mode" "V4SF")])
19745
19746 (define_insn "maskncmpv4sf3"
19747   [(set (match_operand:V4SI 0 "register_operand" "=x")
19748         (not:V4SI
19749          (match_operator:V4SI 3 "sse_comparison_operator"
19750                 [(match_operand:V4SF 1 "register_operand" "0")
19751                  (match_operand:V4SF 2 "register_operand" "x")])))]
19752   "TARGET_SSE"
19753 {
19754   if (GET_CODE (operands[3]) == UNORDERED)
19755     return "cmpordps\t{%2, %0|%0, %2}";
19756   else
19757     return "cmpn%D3ps\t{%2, %0|%0, %2}";
19758 }
19759   [(set_attr "type" "ssecmp")
19760    (set_attr "mode" "V4SF")])
19761
19762 (define_insn "vmmaskcmpv4sf3"
19763   [(set (match_operand:V4SI 0 "register_operand" "=x")
19764         (vec_merge:V4SI
19765          (match_operator:V4SI 3 "sse_comparison_operator"
19766                 [(match_operand:V4SF 1 "register_operand" "0")
19767                  (match_operand:V4SF 2 "register_operand" "x")])
19768          (subreg:V4SI (match_dup 1) 0)
19769          (const_int 1)))]
19770   "TARGET_SSE"
19771   "cmp%D3ss\t{%2, %0|%0, %2}"
19772   [(set_attr "type" "ssecmp")
19773    (set_attr "mode" "SF")])
19774
19775 (define_insn "vmmaskncmpv4sf3"
19776   [(set (match_operand:V4SI 0 "register_operand" "=x")
19777         (vec_merge:V4SI
19778          (not:V4SI
19779           (match_operator:V4SI 3 "sse_comparison_operator"
19780                 [(match_operand:V4SF 1 "register_operand" "0")
19781                  (match_operand:V4SF 2 "register_operand" "x")]))
19782          (subreg:V4SI (match_dup 1) 0)
19783          (const_int 1)))]
19784   "TARGET_SSE"
19785 {
19786   if (GET_CODE (operands[3]) == UNORDERED)
19787     return "cmpordss\t{%2, %0|%0, %2}";
19788   else
19789     return "cmpn%D3ss\t{%2, %0|%0, %2}";
19790 }
19791   [(set_attr "type" "ssecmp")
19792    (set_attr "mode" "SF")])
19793
19794 (define_insn "sse_comi"
19795   [(set (reg:CCFP 17)
19796         (compare:CCFP (vec_select:SF
19797                        (match_operand:V4SF 0 "register_operand" "x")
19798                        (parallel [(const_int 0)]))
19799                       (vec_select:SF
19800                        (match_operand:V4SF 1 "register_operand" "x")
19801                        (parallel [(const_int 0)]))))]
19802   "TARGET_SSE"
19803   "comiss\t{%1, %0|%0, %1}"
19804   [(set_attr "type" "ssecomi")
19805    (set_attr "mode" "SF")])
19806
19807 (define_insn "sse_ucomi"
19808   [(set (reg:CCFPU 17)
19809         (compare:CCFPU (vec_select:SF
19810                         (match_operand:V4SF 0 "register_operand" "x")
19811                         (parallel [(const_int 0)]))
19812                        (vec_select:SF
19813                         (match_operand:V4SF 1 "register_operand" "x")
19814                         (parallel [(const_int 0)]))))]
19815   "TARGET_SSE"
19816   "ucomiss\t{%1, %0|%0, %1}"
19817   [(set_attr "type" "ssecomi")
19818    (set_attr "mode" "SF")])
19819
19820
19821 ;; SSE unpack
19822
19823 (define_insn "sse_unpckhps"
19824   [(set (match_operand:V4SF 0 "register_operand" "=x")
19825         (vec_merge:V4SF
19826          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19827                           (parallel [(const_int 2)
19828                                      (const_int 0)
19829                                      (const_int 3)
19830                                      (const_int 1)]))
19831          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19832                           (parallel [(const_int 0)
19833                                      (const_int 2)
19834                                      (const_int 1)
19835                                      (const_int 3)]))
19836          (const_int 5)))]
19837   "TARGET_SSE"
19838   "unpckhps\t{%2, %0|%0, %2}"
19839   [(set_attr "type" "ssecvt")
19840    (set_attr "mode" "V4SF")])
19841
19842 (define_insn "sse_unpcklps"
19843   [(set (match_operand:V4SF 0 "register_operand" "=x")
19844         (vec_merge:V4SF
19845          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19846                           (parallel [(const_int 0)
19847                                      (const_int 2)
19848                                      (const_int 1)
19849                                      (const_int 3)]))
19850          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19851                           (parallel [(const_int 2)
19852                                      (const_int 0)
19853                                      (const_int 3)
19854                                      (const_int 1)]))
19855          (const_int 5)))]
19856   "TARGET_SSE"
19857   "unpcklps\t{%2, %0|%0, %2}"
19858   [(set_attr "type" "ssecvt")
19859    (set_attr "mode" "V4SF")])
19860
19861
19862 ;; SSE min/max
19863
19864 (define_insn "smaxv4sf3"
19865   [(set (match_operand:V4SF 0 "register_operand" "=x")
19866         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19867                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19868   "TARGET_SSE"
19869   "maxps\t{%2, %0|%0, %2}"
19870   [(set_attr "type" "sse")
19871    (set_attr "mode" "V4SF")])
19872
19873 (define_insn "vmsmaxv4sf3"
19874   [(set (match_operand:V4SF 0 "register_operand" "=x")
19875         (vec_merge:V4SF
19876          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19877                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19878          (match_dup 1)
19879          (const_int 1)))]
19880   "TARGET_SSE"
19881   "maxss\t{%2, %0|%0, %2}"
19882   [(set_attr "type" "sse")
19883    (set_attr "mode" "SF")])
19884
19885 (define_insn "sminv4sf3"
19886   [(set (match_operand:V4SF 0 "register_operand" "=x")
19887         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19888                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19889   "TARGET_SSE"
19890   "minps\t{%2, %0|%0, %2}"
19891   [(set_attr "type" "sse")
19892    (set_attr "mode" "V4SF")])
19893
19894 (define_insn "vmsminv4sf3"
19895   [(set (match_operand:V4SF 0 "register_operand" "=x")
19896         (vec_merge:V4SF
19897          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19898                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19899          (match_dup 1)
19900          (const_int 1)))]
19901   "TARGET_SSE"
19902   "minss\t{%2, %0|%0, %2}"
19903   [(set_attr "type" "sse")
19904    (set_attr "mode" "SF")])
19905
19906 ;; SSE <-> integer/MMX conversions
19907
19908 (define_insn "cvtpi2ps"
19909   [(set (match_operand:V4SF 0 "register_operand" "=x")
19910         (vec_merge:V4SF
19911          (match_operand:V4SF 1 "register_operand" "0")
19912          (vec_duplicate:V4SF
19913           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19914          (const_int 12)))]
19915   "TARGET_SSE"
19916   "cvtpi2ps\t{%2, %0|%0, %2}"
19917   [(set_attr "type" "ssecvt")
19918    (set_attr "mode" "V4SF")])
19919
19920 (define_insn "cvtps2pi"
19921   [(set (match_operand:V2SI 0 "register_operand" "=y")
19922         (vec_select:V2SI
19923          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19924          (parallel [(const_int 0) (const_int 1)])))]
19925   "TARGET_SSE"
19926   "cvtps2pi\t{%1, %0|%0, %1}"
19927   [(set_attr "type" "ssecvt")
19928    (set_attr "mode" "V4SF")])
19929
19930 (define_insn "cvttps2pi"
19931   [(set (match_operand:V2SI 0 "register_operand" "=y")
19932         (vec_select:V2SI
19933          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19934                       UNSPEC_FIX)
19935          (parallel [(const_int 0) (const_int 1)])))]
19936   "TARGET_SSE"
19937   "cvttps2pi\t{%1, %0|%0, %1}"
19938   [(set_attr "type" "ssecvt")
19939    (set_attr "mode" "SF")])
19940
19941 (define_insn "cvtsi2ss"
19942   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
19943         (vec_merge:V4SF
19944          (match_operand:V4SF 1 "register_operand" "0,0")
19945          (vec_duplicate:V4SF
19946           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
19947          (const_int 14)))]
19948   "TARGET_SSE"
19949   "cvtsi2ss\t{%2, %0|%0, %2}"
19950   [(set_attr "type" "sseicvt")
19951    (set_attr "athlon_decode" "vector,double")
19952    (set_attr "mode" "SF")])
19953
19954 (define_insn "cvtsi2ssq"
19955   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
19956         (vec_merge:V4SF
19957          (match_operand:V4SF 1 "register_operand" "0,0")
19958          (vec_duplicate:V4SF
19959           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
19960          (const_int 14)))]
19961   "TARGET_SSE && TARGET_64BIT"
19962   "cvtsi2ssq\t{%2, %0|%0, %2}"
19963   [(set_attr "type" "sseicvt")
19964    (set_attr "athlon_decode" "vector,double")
19965    (set_attr "mode" "SF")])
19966
19967 (define_insn "cvtss2si"
19968   [(set (match_operand:SI 0 "register_operand" "=r,r")
19969         (vec_select:SI
19970          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
19971          (parallel [(const_int 0)])))]
19972   "TARGET_SSE"
19973   "cvtss2si\t{%1, %0|%0, %1}"
19974   [(set_attr "type" "sseicvt")
19975    (set_attr "athlon_decode" "double,vector")
19976    (set_attr "mode" "SI")])
19977
19978 (define_insn "cvtss2siq"
19979   [(set (match_operand:DI 0 "register_operand" "=r,r")
19980         (vec_select:DI
19981          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
19982          (parallel [(const_int 0)])))]
19983   "TARGET_SSE"
19984   "cvtss2siq\t{%1, %0|%0, %1}"
19985   [(set_attr "type" "sseicvt")
19986    (set_attr "athlon_decode" "double,vector")
19987    (set_attr "mode" "DI")])
19988
19989 (define_insn "cvttss2si"
19990   [(set (match_operand:SI 0 "register_operand" "=r,r")
19991         (vec_select:SI
19992          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
19993                       UNSPEC_FIX)
19994          (parallel [(const_int 0)])))]
19995   "TARGET_SSE"
19996   "cvttss2si\t{%1, %0|%0, %1}"
19997   [(set_attr "type" "sseicvt")
19998    (set_attr "mode" "SF")
19999    (set_attr "athlon_decode" "double,vector")])
20000
20001 (define_insn "cvttss2siq"
20002   [(set (match_operand:DI 0 "register_operand" "=r,r")
20003         (vec_select:DI
20004          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20005                       UNSPEC_FIX)
20006          (parallel [(const_int 0)])))]
20007   "TARGET_SSE && TARGET_64BIT"
20008   "cvttss2siq\t{%1, %0|%0, %1}"
20009   [(set_attr "type" "sseicvt")
20010    (set_attr "mode" "SF")
20011    (set_attr "athlon_decode" "double,vector")])
20012
20013
20014 ;; MMX insns
20015
20016 ;; MMX arithmetic
20017
20018 (define_insn "addv8qi3"
20019   [(set (match_operand:V8QI 0 "register_operand" "=y")
20020         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20021                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20022   "TARGET_MMX"
20023   "paddb\t{%2, %0|%0, %2}"
20024   [(set_attr "type" "mmxadd")
20025    (set_attr "mode" "DI")])
20026
20027 (define_insn "addv4hi3"
20028   [(set (match_operand:V4HI 0 "register_operand" "=y")
20029         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20030                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20031   "TARGET_MMX"
20032   "paddw\t{%2, %0|%0, %2}"
20033   [(set_attr "type" "mmxadd")
20034    (set_attr "mode" "DI")])
20035
20036 (define_insn "addv2si3"
20037   [(set (match_operand:V2SI 0 "register_operand" "=y")
20038         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20039                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20040   "TARGET_MMX"
20041   "paddd\t{%2, %0|%0, %2}"
20042   [(set_attr "type" "mmxadd")
20043    (set_attr "mode" "DI")])
20044
20045 (define_insn "mmx_adddi3"
20046   [(set (match_operand:DI 0 "register_operand" "=y")
20047         (unspec:DI
20048          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20049                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20050          UNSPEC_NOP))]
20051   "TARGET_MMX"
20052   "paddq\t{%2, %0|%0, %2}"
20053   [(set_attr "type" "mmxadd")
20054    (set_attr "mode" "DI")])
20055
20056 (define_insn "ssaddv8qi3"
20057   [(set (match_operand:V8QI 0 "register_operand" "=y")
20058         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20059                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20060   "TARGET_MMX"
20061   "paddsb\t{%2, %0|%0, %2}"
20062   [(set_attr "type" "mmxadd")
20063    (set_attr "mode" "DI")])
20064
20065 (define_insn "ssaddv4hi3"
20066   [(set (match_operand:V4HI 0 "register_operand" "=y")
20067         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20068                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20069   "TARGET_MMX"
20070   "paddsw\t{%2, %0|%0, %2}"
20071   [(set_attr "type" "mmxadd")
20072    (set_attr "mode" "DI")])
20073
20074 (define_insn "usaddv8qi3"
20075   [(set (match_operand:V8QI 0 "register_operand" "=y")
20076         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20077                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20078   "TARGET_MMX"
20079   "paddusb\t{%2, %0|%0, %2}"
20080   [(set_attr "type" "mmxadd")
20081    (set_attr "mode" "DI")])
20082
20083 (define_insn "usaddv4hi3"
20084   [(set (match_operand:V4HI 0 "register_operand" "=y")
20085         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20086                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20087   "TARGET_MMX"
20088   "paddusw\t{%2, %0|%0, %2}"
20089   [(set_attr "type" "mmxadd")
20090    (set_attr "mode" "DI")])
20091
20092 (define_insn "subv8qi3"
20093   [(set (match_operand:V8QI 0 "register_operand" "=y")
20094         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20095                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20096   "TARGET_MMX"
20097   "psubb\t{%2, %0|%0, %2}"
20098   [(set_attr "type" "mmxadd")
20099    (set_attr "mode" "DI")])
20100
20101 (define_insn "subv4hi3"
20102   [(set (match_operand:V4HI 0 "register_operand" "=y")
20103         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20104                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20105   "TARGET_MMX"
20106   "psubw\t{%2, %0|%0, %2}"
20107   [(set_attr "type" "mmxadd")
20108    (set_attr "mode" "DI")])
20109
20110 (define_insn "subv2si3"
20111   [(set (match_operand:V2SI 0 "register_operand" "=y")
20112         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20113                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20114   "TARGET_MMX"
20115   "psubd\t{%2, %0|%0, %2}"
20116   [(set_attr "type" "mmxadd")
20117    (set_attr "mode" "DI")])
20118
20119 (define_insn "mmx_subdi3"
20120   [(set (match_operand:DI 0 "register_operand" "=y")
20121         (unspec:DI
20122          [(minus:DI (match_operand:DI 1 "register_operand" "0")
20123                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20124          UNSPEC_NOP))]
20125   "TARGET_MMX"
20126   "psubq\t{%2, %0|%0, %2}"
20127   [(set_attr "type" "mmxadd")
20128    (set_attr "mode" "DI")])
20129
20130 (define_insn "sssubv8qi3"
20131   [(set (match_operand:V8QI 0 "register_operand" "=y")
20132         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20133                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20134   "TARGET_MMX"
20135   "psubsb\t{%2, %0|%0, %2}"
20136   [(set_attr "type" "mmxadd")
20137    (set_attr "mode" "DI")])
20138
20139 (define_insn "sssubv4hi3"
20140   [(set (match_operand:V4HI 0 "register_operand" "=y")
20141         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20142                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20143   "TARGET_MMX"
20144   "psubsw\t{%2, %0|%0, %2}"
20145   [(set_attr "type" "mmxadd")
20146    (set_attr "mode" "DI")])
20147
20148 (define_insn "ussubv8qi3"
20149   [(set (match_operand:V8QI 0 "register_operand" "=y")
20150         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20151                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20152   "TARGET_MMX"
20153   "psubusb\t{%2, %0|%0, %2}"
20154   [(set_attr "type" "mmxadd")
20155    (set_attr "mode" "DI")])
20156
20157 (define_insn "ussubv4hi3"
20158   [(set (match_operand:V4HI 0 "register_operand" "=y")
20159         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20160                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20161   "TARGET_MMX"
20162   "psubusw\t{%2, %0|%0, %2}"
20163   [(set_attr "type" "mmxadd")
20164    (set_attr "mode" "DI")])
20165
20166 (define_insn "mulv4hi3"
20167   [(set (match_operand:V4HI 0 "register_operand" "=y")
20168         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20169                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20170   "TARGET_MMX"
20171   "pmullw\t{%2, %0|%0, %2}"
20172   [(set_attr "type" "mmxmul")
20173    (set_attr "mode" "DI")])
20174
20175 (define_insn "smulv4hi3_highpart"
20176   [(set (match_operand:V4HI 0 "register_operand" "=y")
20177         (truncate:V4HI
20178          (lshiftrt:V4SI
20179           (mult:V4SI (sign_extend:V4SI
20180                       (match_operand:V4HI 1 "register_operand" "0"))
20181                      (sign_extend:V4SI
20182                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20183           (const_int 16))))]
20184   "TARGET_MMX"
20185   "pmulhw\t{%2, %0|%0, %2}"
20186   [(set_attr "type" "mmxmul")
20187    (set_attr "mode" "DI")])
20188
20189 (define_insn "umulv4hi3_highpart"
20190   [(set (match_operand:V4HI 0 "register_operand" "=y")
20191         (truncate:V4HI
20192          (lshiftrt:V4SI
20193           (mult:V4SI (zero_extend:V4SI
20194                       (match_operand:V4HI 1 "register_operand" "0"))
20195                      (zero_extend:V4SI
20196                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20197           (const_int 16))))]
20198   "TARGET_SSE || TARGET_3DNOW_A"
20199   "pmulhuw\t{%2, %0|%0, %2}"
20200   [(set_attr "type" "mmxmul")
20201    (set_attr "mode" "DI")])
20202
20203 (define_insn "mmx_pmaddwd"
20204   [(set (match_operand:V2SI 0 "register_operand" "=y")
20205         (plus:V2SI
20206          (mult:V2SI
20207           (sign_extend:V2SI
20208            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20209                             (parallel [(const_int 0) (const_int 2)])))
20210           (sign_extend:V2SI
20211            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20212                             (parallel [(const_int 0) (const_int 2)]))))
20213          (mult:V2SI
20214           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20215                                              (parallel [(const_int 1)
20216                                                         (const_int 3)])))
20217           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20218                                              (parallel [(const_int 1)
20219                                                         (const_int 3)]))))))]
20220   "TARGET_MMX"
20221   "pmaddwd\t{%2, %0|%0, %2}"
20222   [(set_attr "type" "mmxmul")
20223    (set_attr "mode" "DI")])
20224
20225
20226 ;; MMX logical operations
20227 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20228 ;; normal code that also wants to use the FPU from getting broken.
20229 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20230 (define_insn "mmx_iordi3"
20231   [(set (match_operand:DI 0 "register_operand" "=y")
20232         (unspec:DI
20233          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20234                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20235          UNSPEC_NOP))]
20236   "TARGET_MMX"
20237   "por\t{%2, %0|%0, %2}"
20238   [(set_attr "type" "mmxadd")
20239    (set_attr "mode" "DI")])
20240
20241 (define_insn "mmx_xordi3"
20242   [(set (match_operand:DI 0 "register_operand" "=y")
20243         (unspec:DI
20244          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20245                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20246          UNSPEC_NOP))]
20247   "TARGET_MMX"
20248   "pxor\t{%2, %0|%0, %2}"
20249   [(set_attr "type" "mmxadd")
20250    (set_attr "mode" "DI")
20251    (set_attr "memory" "none")])
20252
20253 ;; Same as pxor, but don't show input operands so that we don't think
20254 ;; they are live.
20255 (define_insn "mmx_clrdi"
20256   [(set (match_operand:DI 0 "register_operand" "=y")
20257         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20258   "TARGET_MMX"
20259   "pxor\t{%0, %0|%0, %0}"
20260   [(set_attr "type" "mmxadd")
20261    (set_attr "mode" "DI")
20262    (set_attr "memory" "none")])
20263
20264 (define_insn "mmx_anddi3"
20265   [(set (match_operand:DI 0 "register_operand" "=y")
20266         (unspec:DI
20267          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20268                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20269          UNSPEC_NOP))]
20270   "TARGET_MMX"
20271   "pand\t{%2, %0|%0, %2}"
20272   [(set_attr "type" "mmxadd")
20273    (set_attr "mode" "DI")])
20274
20275 (define_insn "mmx_nanddi3"
20276   [(set (match_operand:DI 0 "register_operand" "=y")
20277         (unspec:DI
20278          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20279                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20280          UNSPEC_NOP))]
20281   "TARGET_MMX"
20282   "pandn\t{%2, %0|%0, %2}"
20283   [(set_attr "type" "mmxadd")
20284    (set_attr "mode" "DI")])
20285
20286
20287 ;; MMX unsigned averages/sum of absolute differences
20288
20289 (define_insn "mmx_uavgv8qi3"
20290   [(set (match_operand:V8QI 0 "register_operand" "=y")
20291         (ashiftrt:V8QI
20292          (plus:V8QI (plus:V8QI
20293                      (match_operand:V8QI 1 "register_operand" "0")
20294                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20295                     (const_vector:V8QI [(const_int 1)
20296                                         (const_int 1)
20297                                         (const_int 1)
20298                                         (const_int 1)
20299                                         (const_int 1)
20300                                         (const_int 1)
20301                                         (const_int 1)
20302                                         (const_int 1)]))
20303          (const_int 1)))]
20304   "TARGET_SSE || TARGET_3DNOW_A"
20305   "pavgb\t{%2, %0|%0, %2}"
20306   [(set_attr "type" "mmxshft")
20307    (set_attr "mode" "DI")])
20308
20309 (define_insn "mmx_uavgv4hi3"
20310   [(set (match_operand:V4HI 0 "register_operand" "=y")
20311         (ashiftrt:V4HI
20312          (plus:V4HI (plus:V4HI
20313                      (match_operand:V4HI 1 "register_operand" "0")
20314                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20315                     (const_vector:V4HI [(const_int 1)
20316                                         (const_int 1)
20317                                         (const_int 1)
20318                                         (const_int 1)]))
20319          (const_int 1)))]
20320   "TARGET_SSE || TARGET_3DNOW_A"
20321   "pavgw\t{%2, %0|%0, %2}"
20322   [(set_attr "type" "mmxshft")
20323    (set_attr "mode" "DI")])
20324
20325 (define_insn "mmx_psadbw"
20326   [(set (match_operand:DI 0 "register_operand" "=y")
20327         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20328                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20329                    UNSPEC_PSADBW))]
20330   "TARGET_SSE || TARGET_3DNOW_A"
20331   "psadbw\t{%2, %0|%0, %2}"
20332   [(set_attr "type" "mmxshft")
20333    (set_attr "mode" "DI")])
20334
20335
20336 ;; MMX insert/extract/shuffle
20337
20338 (define_insn "mmx_pinsrw"
20339   [(set (match_operand:V4HI 0 "register_operand" "=y")
20340         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20341                         (vec_duplicate:V4HI
20342                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20343                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20344   "TARGET_SSE || TARGET_3DNOW_A"
20345   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20346   [(set_attr "type" "mmxcvt")
20347    (set_attr "mode" "DI")])
20348
20349 (define_insn "mmx_pextrw"
20350   [(set (match_operand:SI 0 "register_operand" "=r")
20351         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20352                                        (parallel
20353                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20354   "TARGET_SSE || TARGET_3DNOW_A"
20355   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20356   [(set_attr "type" "mmxcvt")
20357    (set_attr "mode" "DI")])
20358
20359 (define_insn "mmx_pshufw"
20360   [(set (match_operand:V4HI 0 "register_operand" "=y")
20361         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20362                       (match_operand:SI 2 "immediate_operand" "i")]
20363                      UNSPEC_SHUFFLE))]
20364   "TARGET_SSE || TARGET_3DNOW_A"
20365   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20366   [(set_attr "type" "mmxcvt")
20367    (set_attr "mode" "DI")])
20368
20369
20370 ;; MMX mask-generating comparisons
20371
20372 (define_insn "eqv8qi3"
20373   [(set (match_operand:V8QI 0 "register_operand" "=y")
20374         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20375                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20376   "TARGET_MMX"
20377   "pcmpeqb\t{%2, %0|%0, %2}"
20378   [(set_attr "type" "mmxcmp")
20379    (set_attr "mode" "DI")])
20380
20381 (define_insn "eqv4hi3"
20382   [(set (match_operand:V4HI 0 "register_operand" "=y")
20383         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20384                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20385   "TARGET_MMX"
20386   "pcmpeqw\t{%2, %0|%0, %2}"
20387   [(set_attr "type" "mmxcmp")
20388    (set_attr "mode" "DI")])
20389
20390 (define_insn "eqv2si3"
20391   [(set (match_operand:V2SI 0 "register_operand" "=y")
20392         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20393                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20394   "TARGET_MMX"
20395   "pcmpeqd\t{%2, %0|%0, %2}"
20396   [(set_attr "type" "mmxcmp")
20397    (set_attr "mode" "DI")])
20398
20399 (define_insn "gtv8qi3"
20400   [(set (match_operand:V8QI 0 "register_operand" "=y")
20401         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20402                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20403   "TARGET_MMX"
20404   "pcmpgtb\t{%2, %0|%0, %2}"
20405   [(set_attr "type" "mmxcmp")
20406    (set_attr "mode" "DI")])
20407
20408 (define_insn "gtv4hi3"
20409   [(set (match_operand:V4HI 0 "register_operand" "=y")
20410         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20411                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20412   "TARGET_MMX"
20413   "pcmpgtw\t{%2, %0|%0, %2}"
20414   [(set_attr "type" "mmxcmp")
20415    (set_attr "mode" "DI")])
20416
20417 (define_insn "gtv2si3"
20418   [(set (match_operand:V2SI 0 "register_operand" "=y")
20419         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20420                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20421   "TARGET_MMX"
20422   "pcmpgtd\t{%2, %0|%0, %2}"
20423   [(set_attr "type" "mmxcmp")
20424    (set_attr "mode" "DI")])
20425
20426
20427 ;; MMX max/min insns
20428
20429 (define_insn "umaxv8qi3"
20430   [(set (match_operand:V8QI 0 "register_operand" "=y")
20431         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20432                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20433   "TARGET_SSE || TARGET_3DNOW_A"
20434   "pmaxub\t{%2, %0|%0, %2}"
20435   [(set_attr "type" "mmxadd")
20436    (set_attr "mode" "DI")])
20437
20438 (define_insn "smaxv4hi3"
20439   [(set (match_operand:V4HI 0 "register_operand" "=y")
20440         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20441                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20442   "TARGET_SSE || TARGET_3DNOW_A"
20443   "pmaxsw\t{%2, %0|%0, %2}"
20444   [(set_attr "type" "mmxadd")
20445    (set_attr "mode" "DI")])
20446
20447 (define_insn "uminv8qi3"
20448   [(set (match_operand:V8QI 0 "register_operand" "=y")
20449         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20450                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20451   "TARGET_SSE || TARGET_3DNOW_A"
20452   "pminub\t{%2, %0|%0, %2}"
20453   [(set_attr "type" "mmxadd")
20454    (set_attr "mode" "DI")])
20455
20456 (define_insn "sminv4hi3"
20457   [(set (match_operand:V4HI 0 "register_operand" "=y")
20458         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20459                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20460   "TARGET_SSE || TARGET_3DNOW_A"
20461   "pminsw\t{%2, %0|%0, %2}"
20462   [(set_attr "type" "mmxadd")
20463    (set_attr "mode" "DI")])
20464
20465
20466 ;; MMX shifts
20467
20468 (define_insn "ashrv4hi3"
20469   [(set (match_operand:V4HI 0 "register_operand" "=y")
20470         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20471                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20472   "TARGET_MMX"
20473   "psraw\t{%2, %0|%0, %2}"
20474   [(set_attr "type" "mmxshft")
20475    (set_attr "mode" "DI")])
20476
20477 (define_insn "ashrv2si3"
20478   [(set (match_operand:V2SI 0 "register_operand" "=y")
20479         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20480                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20481   "TARGET_MMX"
20482   "psrad\t{%2, %0|%0, %2}"
20483   [(set_attr "type" "mmxshft")
20484    (set_attr "mode" "DI")])
20485
20486 (define_insn "lshrv4hi3"
20487   [(set (match_operand:V4HI 0 "register_operand" "=y")
20488         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20489                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20490   "TARGET_MMX"
20491   "psrlw\t{%2, %0|%0, %2}"
20492   [(set_attr "type" "mmxshft")
20493    (set_attr "mode" "DI")])
20494
20495 (define_insn "lshrv2si3"
20496   [(set (match_operand:V2SI 0 "register_operand" "=y")
20497         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20498                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20499   "TARGET_MMX"
20500   "psrld\t{%2, %0|%0, %2}"
20501   [(set_attr "type" "mmxshft")
20502    (set_attr "mode" "DI")])
20503
20504 ;; See logical MMX insns.
20505 (define_insn "mmx_lshrdi3"
20506   [(set (match_operand:DI 0 "register_operand" "=y")
20507         (unspec:DI
20508           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20509                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
20510           UNSPEC_NOP))]
20511   "TARGET_MMX"
20512   "psrlq\t{%2, %0|%0, %2}"
20513   [(set_attr "type" "mmxshft")
20514    (set_attr "mode" "DI")])
20515
20516 (define_insn "ashlv4hi3"
20517   [(set (match_operand:V4HI 0 "register_operand" "=y")
20518         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20519                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20520   "TARGET_MMX"
20521   "psllw\t{%2, %0|%0, %2}"
20522   [(set_attr "type" "mmxshft")
20523    (set_attr "mode" "DI")])
20524
20525 (define_insn "ashlv2si3"
20526   [(set (match_operand:V2SI 0 "register_operand" "=y")
20527         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20528                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20529   "TARGET_MMX"
20530   "pslld\t{%2, %0|%0, %2}"
20531   [(set_attr "type" "mmxshft")
20532    (set_attr "mode" "DI")])
20533
20534 ;; See logical MMX insns.
20535 (define_insn "mmx_ashldi3"
20536   [(set (match_operand:DI 0 "register_operand" "=y")
20537         (unspec:DI
20538          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20539                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
20540          UNSPEC_NOP))]
20541   "TARGET_MMX"
20542   "psllq\t{%2, %0|%0, %2}"
20543   [(set_attr "type" "mmxshft")
20544    (set_attr "mode" "DI")])
20545
20546
20547 ;; MMX pack/unpack insns.
20548
20549 (define_insn "mmx_packsswb"
20550   [(set (match_operand:V8QI 0 "register_operand" "=y")
20551         (vec_concat:V8QI
20552          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20553          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20554   "TARGET_MMX"
20555   "packsswb\t{%2, %0|%0, %2}"
20556   [(set_attr "type" "mmxshft")
20557    (set_attr "mode" "DI")])
20558
20559 (define_insn "mmx_packssdw"
20560   [(set (match_operand:V4HI 0 "register_operand" "=y")
20561         (vec_concat:V4HI
20562          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20563          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20564   "TARGET_MMX"
20565   "packssdw\t{%2, %0|%0, %2}"
20566   [(set_attr "type" "mmxshft")
20567    (set_attr "mode" "DI")])
20568
20569 (define_insn "mmx_packuswb"
20570   [(set (match_operand:V8QI 0 "register_operand" "=y")
20571         (vec_concat:V8QI
20572          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20573          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20574   "TARGET_MMX"
20575   "packuswb\t{%2, %0|%0, %2}"
20576   [(set_attr "type" "mmxshft")
20577    (set_attr "mode" "DI")])
20578
20579 (define_insn "mmx_punpckhbw"
20580   [(set (match_operand:V8QI 0 "register_operand" "=y")
20581         (vec_merge:V8QI
20582          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20583                           (parallel [(const_int 4)
20584                                      (const_int 0)
20585                                      (const_int 5)
20586                                      (const_int 1)
20587                                      (const_int 6)
20588                                      (const_int 2)
20589                                      (const_int 7)
20590                                      (const_int 3)]))
20591          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20592                           (parallel [(const_int 0)
20593                                      (const_int 4)
20594                                      (const_int 1)
20595                                      (const_int 5)
20596                                      (const_int 2)
20597                                      (const_int 6)
20598                                      (const_int 3)
20599                                      (const_int 7)]))
20600          (const_int 85)))]
20601   "TARGET_MMX"
20602   "punpckhbw\t{%2, %0|%0, %2}"
20603   [(set_attr "type" "mmxcvt")
20604    (set_attr "mode" "DI")])
20605
20606 (define_insn "mmx_punpckhwd"
20607   [(set (match_operand:V4HI 0 "register_operand" "=y")
20608         (vec_merge:V4HI
20609          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20610                           (parallel [(const_int 0)
20611                                      (const_int 2)
20612                                      (const_int 1)
20613                                      (const_int 3)]))
20614          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20615                           (parallel [(const_int 2)
20616                                      (const_int 0)
20617                                      (const_int 3)
20618                                      (const_int 1)]))
20619          (const_int 5)))]
20620   "TARGET_MMX"
20621   "punpckhwd\t{%2, %0|%0, %2}"
20622   [(set_attr "type" "mmxcvt")
20623    (set_attr "mode" "DI")])
20624
20625 (define_insn "mmx_punpckhdq"
20626   [(set (match_operand:V2SI 0 "register_operand" "=y")
20627         (vec_merge:V2SI
20628          (match_operand:V2SI 1 "register_operand" "0")
20629          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20630                           (parallel [(const_int 1)
20631                                      (const_int 0)]))
20632          (const_int 1)))]
20633   "TARGET_MMX"
20634   "punpckhdq\t{%2, %0|%0, %2}"
20635   [(set_attr "type" "mmxcvt")
20636    (set_attr "mode" "DI")])
20637
20638 (define_insn "mmx_punpcklbw"
20639   [(set (match_operand:V8QI 0 "register_operand" "=y")
20640         (vec_merge:V8QI
20641          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20642                           (parallel [(const_int 0)
20643                                      (const_int 4)
20644                                      (const_int 1)
20645                                      (const_int 5)
20646                                      (const_int 2)
20647                                      (const_int 6)
20648                                      (const_int 3)
20649                                      (const_int 7)]))
20650          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20651                           (parallel [(const_int 4)
20652                                      (const_int 0)
20653                                      (const_int 5)
20654                                      (const_int 1)
20655                                      (const_int 6)
20656                                      (const_int 2)
20657                                      (const_int 7)
20658                                      (const_int 3)]))
20659          (const_int 85)))]
20660   "TARGET_MMX"
20661   "punpcklbw\t{%2, %0|%0, %2}"
20662   [(set_attr "type" "mmxcvt")
20663    (set_attr "mode" "DI")])
20664
20665 (define_insn "mmx_punpcklwd"
20666   [(set (match_operand:V4HI 0 "register_operand" "=y")
20667         (vec_merge:V4HI
20668          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20669                           (parallel [(const_int 2)
20670                                      (const_int 0)
20671                                      (const_int 3)
20672                                      (const_int 1)]))
20673          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20674                           (parallel [(const_int 0)
20675                                      (const_int 2)
20676                                      (const_int 1)
20677                                      (const_int 3)]))
20678          (const_int 5)))]
20679   "TARGET_MMX"
20680   "punpcklwd\t{%2, %0|%0, %2}"
20681   [(set_attr "type" "mmxcvt")
20682    (set_attr "mode" "DI")])
20683
20684 (define_insn "mmx_punpckldq"
20685   [(set (match_operand:V2SI 0 "register_operand" "=y")
20686         (vec_merge:V2SI
20687          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20688                            (parallel [(const_int 1)
20689                                       (const_int 0)]))
20690          (match_operand:V2SI 2 "register_operand" "y")
20691          (const_int 1)))]
20692   "TARGET_MMX"
20693   "punpckldq\t{%2, %0|%0, %2}"
20694   [(set_attr "type" "mmxcvt")
20695    (set_attr "mode" "DI")])
20696
20697
20698 ;; Miscellaneous stuff
20699
20700 (define_insn "emms"
20701   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20702    (clobber (reg:XF 8))
20703    (clobber (reg:XF 9))
20704    (clobber (reg:XF 10))
20705    (clobber (reg:XF 11))
20706    (clobber (reg:XF 12))
20707    (clobber (reg:XF 13))
20708    (clobber (reg:XF 14))
20709    (clobber (reg:XF 15))
20710    (clobber (reg:DI 29))
20711    (clobber (reg:DI 30))
20712    (clobber (reg:DI 31))
20713    (clobber (reg:DI 32))
20714    (clobber (reg:DI 33))
20715    (clobber (reg:DI 34))
20716    (clobber (reg:DI 35))
20717    (clobber (reg:DI 36))]
20718   "TARGET_MMX"
20719   "emms"
20720   [(set_attr "type" "mmx")
20721    (set_attr "memory" "unknown")])
20722
20723 (define_insn "ldmxcsr"
20724   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20725                     UNSPECV_LDMXCSR)]
20726   "TARGET_SSE"
20727   "ldmxcsr\t%0"
20728   [(set_attr "type" "sse")
20729    (set_attr "memory" "load")])
20730
20731 (define_insn "stmxcsr"
20732   [(set (match_operand:SI 0 "memory_operand" "=m")
20733         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20734   "TARGET_SSE"
20735   "stmxcsr\t%0"
20736   [(set_attr "type" "sse")
20737    (set_attr "memory" "store")])
20738
20739 (define_expand "sfence"
20740   [(set (match_dup 0)
20741         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20742   "TARGET_SSE || TARGET_3DNOW_A"
20743 {
20744   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20745   MEM_VOLATILE_P (operands[0]) = 1;
20746 })
20747
20748 (define_insn "*sfence_insn"
20749   [(set (match_operand:BLK 0 "" "")
20750         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20751   "TARGET_SSE || TARGET_3DNOW_A"
20752   "sfence"
20753   [(set_attr "type" "sse")
20754    (set_attr "memory" "unknown")])
20755
20756 (define_expand "sse_prologue_save"
20757   [(parallel [(set (match_operand:BLK 0 "" "")
20758                    (unspec:BLK [(reg:DI 21)
20759                                 (reg:DI 22)
20760                                 (reg:DI 23)
20761                                 (reg:DI 24)
20762                                 (reg:DI 25)
20763                                 (reg:DI 26)
20764                                 (reg:DI 27)
20765                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20766               (use (match_operand:DI 1 "register_operand" ""))
20767               (use (match_operand:DI 2 "immediate_operand" ""))
20768               (use (label_ref:DI (match_operand 3 "" "")))])]
20769   "TARGET_64BIT"
20770   "")
20771
20772 (define_insn "*sse_prologue_save_insn"
20773   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20774                           (match_operand:DI 4 "const_int_operand" "n")))
20775         (unspec:BLK [(reg:DI 21)
20776                      (reg:DI 22)
20777                      (reg:DI 23)
20778                      (reg:DI 24)
20779                      (reg:DI 25)
20780                      (reg:DI 26)
20781                      (reg:DI 27)
20782                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20783    (use (match_operand:DI 1 "register_operand" "r"))
20784    (use (match_operand:DI 2 "const_int_operand" "i"))
20785    (use (label_ref:DI (match_operand 3 "" "X")))]
20786   "TARGET_64BIT
20787    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20788    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20789   "*
20790 {
20791   int i;
20792   operands[0] = gen_rtx_MEM (Pmode,
20793                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20794   output_asm_insn (\"jmp\\t%A1\", operands);
20795   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20796     {
20797       operands[4] = adjust_address (operands[0], DImode, i*16);
20798       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20799       PUT_MODE (operands[4], TImode);
20800       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20801         output_asm_insn (\"rex\", operands);
20802       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20803     }
20804   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20805                              CODE_LABEL_NUMBER (operands[3]));
20806   RET;
20807 }
20808   "
20809   [(set_attr "type" "other")
20810    (set_attr "length_immediate" "0")
20811    (set_attr "length_address" "0")
20812    (set_attr "length" "135")
20813    (set_attr "memory" "store")
20814    (set_attr "modrm" "0")
20815    (set_attr "mode" "DI")])
20816
20817 ;; 3Dnow! instructions
20818
20819 (define_insn "addv2sf3"
20820   [(set (match_operand:V2SF 0 "register_operand" "=y")
20821         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20822                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20823   "TARGET_3DNOW"
20824   "pfadd\\t{%2, %0|%0, %2}"
20825   [(set_attr "type" "mmxadd")
20826    (set_attr "mode" "V2SF")])
20827
20828 (define_insn "subv2sf3"
20829   [(set (match_operand:V2SF 0 "register_operand" "=y")
20830         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20831                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20832   "TARGET_3DNOW"
20833   "pfsub\\t{%2, %0|%0, %2}"
20834   [(set_attr "type" "mmxadd")
20835    (set_attr "mode" "V2SF")])
20836
20837 (define_insn "subrv2sf3"
20838   [(set (match_operand:V2SF 0 "register_operand" "=y")
20839         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20840                     (match_operand:V2SF 1 "register_operand" "0")))]
20841   "TARGET_3DNOW"
20842   "pfsubr\\t{%2, %0|%0, %2}"
20843   [(set_attr "type" "mmxadd")
20844    (set_attr "mode" "V2SF")])
20845
20846 (define_insn "gtv2sf3"
20847   [(set (match_operand:V2SI 0 "register_operand" "=y")
20848         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20849                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20850  "TARGET_3DNOW"
20851   "pfcmpgt\\t{%2, %0|%0, %2}"
20852   [(set_attr "type" "mmxcmp")
20853    (set_attr "mode" "V2SF")])
20854
20855 (define_insn "gev2sf3"
20856   [(set (match_operand:V2SI 0 "register_operand" "=y")
20857         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20858                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20859   "TARGET_3DNOW"
20860   "pfcmpge\\t{%2, %0|%0, %2}"
20861   [(set_attr "type" "mmxcmp")
20862    (set_attr "mode" "V2SF")])
20863
20864 (define_insn "eqv2sf3"
20865   [(set (match_operand:V2SI 0 "register_operand" "=y")
20866         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20867                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20868   "TARGET_3DNOW"
20869   "pfcmpeq\\t{%2, %0|%0, %2}"
20870   [(set_attr "type" "mmxcmp")
20871    (set_attr "mode" "V2SF")])
20872
20873 (define_insn "pfmaxv2sf3"
20874   [(set (match_operand:V2SF 0 "register_operand" "=y")
20875         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20876                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20877   "TARGET_3DNOW"
20878   "pfmax\\t{%2, %0|%0, %2}"
20879   [(set_attr "type" "mmxadd")
20880    (set_attr "mode" "V2SF")])
20881
20882 (define_insn "pfminv2sf3"
20883   [(set (match_operand:V2SF 0 "register_operand" "=y")
20884         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20885                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20886   "TARGET_3DNOW"
20887   "pfmin\\t{%2, %0|%0, %2}"
20888   [(set_attr "type" "mmxadd")
20889    (set_attr "mode" "V2SF")])
20890
20891 (define_insn "mulv2sf3"
20892   [(set (match_operand:V2SF 0 "register_operand" "=y")
20893         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20894                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20895   "TARGET_3DNOW"
20896   "pfmul\\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "mmxmul")
20898    (set_attr "mode" "V2SF")])
20899
20900 (define_insn "femms"
20901   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20902    (clobber (reg:XF 8))
20903    (clobber (reg:XF 9))
20904    (clobber (reg:XF 10))
20905    (clobber (reg:XF 11))
20906    (clobber (reg:XF 12))
20907    (clobber (reg:XF 13))
20908    (clobber (reg:XF 14))
20909    (clobber (reg:XF 15))
20910    (clobber (reg:DI 29))
20911    (clobber (reg:DI 30))
20912    (clobber (reg:DI 31))
20913    (clobber (reg:DI 32))
20914    (clobber (reg:DI 33))
20915    (clobber (reg:DI 34))
20916    (clobber (reg:DI 35))
20917    (clobber (reg:DI 36))]
20918   "TARGET_3DNOW"
20919   "femms"
20920   [(set_attr "type" "mmx")
20921    (set_attr "memory" "none")]) 
20922
20923 (define_insn "pf2id"
20924   [(set (match_operand:V2SI 0 "register_operand" "=y")
20925         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20926   "TARGET_3DNOW"
20927   "pf2id\\t{%1, %0|%0, %1}"
20928   [(set_attr "type" "mmxcvt")
20929    (set_attr "mode" "V2SF")])
20930
20931 (define_insn "pf2iw"
20932   [(set (match_operand:V2SI 0 "register_operand" "=y")
20933         (sign_extend:V2SI
20934            (ss_truncate:V2HI
20935               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20936   "TARGET_3DNOW_A"
20937   "pf2iw\\t{%1, %0|%0, %1}"
20938   [(set_attr "type" "mmxcvt")
20939    (set_attr "mode" "V2SF")])
20940
20941 (define_insn "pfacc"
20942   [(set (match_operand:V2SF 0 "register_operand" "=y")
20943         (vec_concat:V2SF
20944            (plus:SF
20945               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20946                              (parallel [(const_int  0)]))
20947               (vec_select:SF (match_dup 1)
20948                              (parallel [(const_int 1)])))
20949            (plus:SF
20950               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20951                              (parallel [(const_int  0)]))
20952               (vec_select:SF (match_dup 2)
20953                              (parallel [(const_int 1)])))))]
20954   "TARGET_3DNOW"
20955   "pfacc\\t{%2, %0|%0, %2}"
20956   [(set_attr "type" "mmxadd")
20957    (set_attr "mode" "V2SF")])
20958
20959 (define_insn "pfnacc"
20960   [(set (match_operand:V2SF 0 "register_operand" "=y")
20961         (vec_concat:V2SF
20962            (minus:SF
20963               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20964                              (parallel [(const_int 0)]))
20965               (vec_select:SF (match_dup 1)
20966                              (parallel [(const_int 1)])))
20967            (minus:SF
20968               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20969                              (parallel [(const_int  0)]))
20970               (vec_select:SF (match_dup 2)
20971                              (parallel [(const_int 1)])))))]
20972   "TARGET_3DNOW_A"
20973   "pfnacc\\t{%2, %0|%0, %2}"
20974   [(set_attr "type" "mmxadd")
20975    (set_attr "mode" "V2SF")])
20976
20977 (define_insn "pfpnacc"
20978   [(set (match_operand:V2SF 0 "register_operand" "=y")
20979         (vec_concat:V2SF
20980            (minus:SF
20981               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20982                              (parallel [(const_int 0)]))
20983               (vec_select:SF (match_dup 1)
20984                              (parallel [(const_int 1)])))
20985            (plus:SF
20986               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20987                              (parallel [(const_int 0)]))
20988               (vec_select:SF (match_dup 2)
20989                              (parallel [(const_int 1)])))))]
20990   "TARGET_3DNOW_A"
20991   "pfpnacc\\t{%2, %0|%0, %2}"
20992   [(set_attr "type" "mmxadd")
20993    (set_attr "mode" "V2SF")])
20994
20995 (define_insn "pi2fw"
20996   [(set (match_operand:V2SF 0 "register_operand" "=y")
20997         (float:V2SF
20998            (vec_concat:V2SI
20999               (sign_extend:SI
21000                  (truncate:HI
21001                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21002                                    (parallel [(const_int 0)]))))
21003               (sign_extend:SI
21004                  (truncate:HI
21005                     (vec_select:SI (match_dup 1)
21006                                    (parallel [(const_int  1)])))))))]
21007   "TARGET_3DNOW_A"
21008   "pi2fw\\t{%1, %0|%0, %1}"
21009   [(set_attr "type" "mmxcvt")
21010    (set_attr "mode" "V2SF")])
21011
21012 (define_insn "floatv2si2"
21013   [(set (match_operand:V2SF 0 "register_operand" "=y")
21014         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21015   "TARGET_3DNOW"
21016   "pi2fd\\t{%1, %0|%0, %1}"
21017   [(set_attr "type" "mmxcvt")
21018    (set_attr "mode" "V2SF")])
21019
21020 ;; This insn is identical to pavgb in operation, but the opcode is
21021 ;; different.  To avoid accidentally matching pavgb, use an unspec.
21022
21023 (define_insn "pavgusb"
21024  [(set (match_operand:V8QI 0 "register_operand" "=y")
21025        (unspec:V8QI
21026           [(match_operand:V8QI 1 "register_operand" "0")
21027            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21028           UNSPEC_PAVGUSB))]
21029   "TARGET_3DNOW"
21030   "pavgusb\\t{%2, %0|%0, %2}"
21031   [(set_attr "type" "mmxshft")
21032    (set_attr "mode" "TI")])
21033
21034 ;; 3DNow reciprocal and sqrt
21035  
21036 (define_insn "pfrcpv2sf2"
21037   [(set (match_operand:V2SF 0 "register_operand" "=y")
21038         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21039         UNSPEC_PFRCP))]
21040   "TARGET_3DNOW"
21041   "pfrcp\\t{%1, %0|%0, %1}"
21042   [(set_attr "type" "mmx")
21043    (set_attr "mode" "TI")])
21044
21045 (define_insn "pfrcpit1v2sf3"
21046   [(set (match_operand:V2SF 0 "register_operand" "=y")
21047         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21048                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21049                      UNSPEC_PFRCPIT1))]
21050   "TARGET_3DNOW"
21051   "pfrcpit1\\t{%2, %0|%0, %2}"
21052   [(set_attr "type" "mmx")
21053    (set_attr "mode" "TI")])
21054
21055 (define_insn "pfrcpit2v2sf3"
21056   [(set (match_operand:V2SF 0 "register_operand" "=y")
21057         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21058                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21059                      UNSPEC_PFRCPIT2))]
21060   "TARGET_3DNOW"
21061   "pfrcpit2\\t{%2, %0|%0, %2}"
21062   [(set_attr "type" "mmx")
21063    (set_attr "mode" "TI")])
21064
21065 (define_insn "pfrsqrtv2sf2"
21066   [(set (match_operand:V2SF 0 "register_operand" "=y")
21067         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21068                      UNSPEC_PFRSQRT))]
21069   "TARGET_3DNOW"
21070   "pfrsqrt\\t{%1, %0|%0, %1}"
21071   [(set_attr "type" "mmx")
21072    (set_attr "mode" "TI")])
21073                 
21074 (define_insn "pfrsqit1v2sf3"
21075   [(set (match_operand:V2SF 0 "register_operand" "=y")
21076         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21077                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21078                      UNSPEC_PFRSQIT1))]
21079   "TARGET_3DNOW"
21080   "pfrsqit1\\t{%2, %0|%0, %2}"
21081   [(set_attr "type" "mmx")
21082    (set_attr "mode" "TI")])
21083
21084 (define_insn "pmulhrwv4hi3"
21085   [(set (match_operand:V4HI 0 "register_operand" "=y")
21086         (truncate:V4HI
21087            (lshiftrt:V4SI
21088               (plus:V4SI
21089                  (mult:V4SI
21090                     (sign_extend:V4SI
21091                        (match_operand:V4HI 1 "register_operand" "0"))
21092                     (sign_extend:V4SI
21093                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21094                  (const_vector:V4SI [(const_int 32768)
21095                                      (const_int 32768)
21096                                      (const_int 32768)
21097                                      (const_int 32768)]))
21098               (const_int 16))))]
21099   "TARGET_3DNOW"
21100   "pmulhrw\\t{%2, %0|%0, %2}"
21101   [(set_attr "type" "mmxmul")
21102    (set_attr "mode" "TI")])
21103
21104 (define_insn "pswapdv2si2"
21105   [(set (match_operand:V2SI 0 "register_operand" "=y")
21106         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21107                          (parallel [(const_int 1) (const_int 0)])))]
21108   "TARGET_3DNOW_A"
21109   "pswapd\\t{%1, %0|%0, %1}"
21110   [(set_attr "type" "mmxcvt")
21111    (set_attr "mode" "TI")])
21112
21113 (define_insn "pswapdv2sf2"
21114   [(set (match_operand:V2SF 0 "register_operand" "=y")
21115         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21116                          (parallel [(const_int 1) (const_int 0)])))]
21117   "TARGET_3DNOW_A"
21118   "pswapd\\t{%1, %0|%0, %1}"
21119   [(set_attr "type" "mmxcvt")
21120    (set_attr "mode" "TI")])
21121
21122 (define_expand "prefetch"
21123   [(prefetch (match_operand 0 "address_operand" "")
21124              (match_operand:SI 1 "const_int_operand" "")
21125              (match_operand:SI 2 "const_int_operand" ""))]
21126   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21127 {
21128   int rw = INTVAL (operands[1]);
21129   int locality = INTVAL (operands[2]);
21130
21131   if (rw != 0 && rw != 1)
21132     abort ();
21133   if (locality < 0 || locality > 3)
21134     abort ();
21135   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21136     abort ();
21137
21138   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21139      suported by SSE counterpart or the SSE prefetch is not available
21140      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21141      of locality.  */
21142   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21143     operands[2] = GEN_INT (3);
21144   else
21145     operands[1] = const0_rtx;
21146 })
21147
21148 (define_insn "*prefetch_sse"
21149   [(prefetch (match_operand:SI 0 "address_operand" "p")
21150              (const_int 0)
21151              (match_operand:SI 1 "const_int_operand" ""))]
21152   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21153 {
21154   static const char * const patterns[4] = {
21155    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21156   };
21157
21158   int locality = INTVAL (operands[1]);
21159   if (locality < 0 || locality > 3)
21160     abort ();
21161
21162   return patterns[locality];  
21163 }
21164   [(set_attr "type" "sse")
21165    (set_attr "memory" "none")])
21166
21167 (define_insn "*prefetch_sse_rex"
21168   [(prefetch (match_operand:DI 0 "address_operand" "p")
21169              (const_int 0)
21170              (match_operand:SI 1 "const_int_operand" ""))]
21171   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21172 {
21173   static const char * const patterns[4] = {
21174    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21175   };
21176
21177   int locality = INTVAL (operands[1]);
21178   if (locality < 0 || locality > 3)
21179     abort ();
21180
21181   return patterns[locality];  
21182 }
21183   [(set_attr "type" "sse")
21184    (set_attr "memory" "none")])
21185
21186 (define_insn "*prefetch_3dnow"
21187   [(prefetch (match_operand:SI 0 "address_operand" "p")
21188              (match_operand:SI 1 "const_int_operand" "n")
21189              (const_int 3))]
21190   "TARGET_3DNOW && !TARGET_64BIT"
21191 {
21192   if (INTVAL (operands[1]) == 0)
21193     return "prefetch\t%a0";
21194   else
21195     return "prefetchw\t%a0";
21196 }
21197   [(set_attr "type" "mmx")
21198    (set_attr "memory" "none")])
21199
21200 (define_insn "*prefetch_3dnow_rex"
21201   [(prefetch (match_operand:DI 0 "address_operand" "p")
21202              (match_operand:SI 1 "const_int_operand" "n")
21203              (const_int 3))]
21204   "TARGET_3DNOW && TARGET_64BIT"
21205 {
21206   if (INTVAL (operands[1]) == 0)
21207     return "prefetch\t%a0";
21208   else
21209     return "prefetchw\t%a0";
21210 }
21211   [(set_attr "type" "mmx")
21212    (set_attr "memory" "none")])
21213
21214 ;; SSE2 support
21215
21216 (define_insn "addv2df3"
21217   [(set (match_operand:V2DF 0 "register_operand" "=x")
21218         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21219                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21220   "TARGET_SSE2"
21221   "addpd\t{%2, %0|%0, %2}"
21222   [(set_attr "type" "sseadd")
21223    (set_attr "mode" "V2DF")])
21224
21225 (define_insn "vmaddv2df3"
21226   [(set (match_operand:V2DF 0 "register_operand" "=x")
21227         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21228                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21229                         (match_dup 1)
21230                         (const_int 1)))]
21231   "TARGET_SSE2"
21232   "addsd\t{%2, %0|%0, %2}"
21233   [(set_attr "type" "sseadd")
21234    (set_attr "mode" "DF")])
21235
21236 (define_insn "subv2df3"
21237   [(set (match_operand:V2DF 0 "register_operand" "=x")
21238         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21239                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21240   "TARGET_SSE2"
21241   "subpd\t{%2, %0|%0, %2}"
21242   [(set_attr "type" "sseadd")
21243    (set_attr "mode" "V2DF")])
21244
21245 (define_insn "vmsubv2df3"
21246   [(set (match_operand:V2DF 0 "register_operand" "=x")
21247         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21248                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21249                         (match_dup 1)
21250                         (const_int 1)))]
21251   "TARGET_SSE2"
21252   "subsd\t{%2, %0|%0, %2}"
21253   [(set_attr "type" "sseadd")
21254    (set_attr "mode" "DF")])
21255
21256 (define_insn "mulv2df3"
21257   [(set (match_operand:V2DF 0 "register_operand" "=x")
21258         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21259                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21260   "TARGET_SSE2"
21261   "mulpd\t{%2, %0|%0, %2}"
21262   [(set_attr "type" "ssemul")
21263    (set_attr "mode" "V2DF")])
21264
21265 (define_insn "vmmulv2df3"
21266   [(set (match_operand:V2DF 0 "register_operand" "=x")
21267         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21268                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21269                         (match_dup 1)
21270                         (const_int 1)))]
21271   "TARGET_SSE2"
21272   "mulsd\t{%2, %0|%0, %2}"
21273   [(set_attr "type" "ssemul")
21274    (set_attr "mode" "DF")])
21275
21276 (define_insn "divv2df3"
21277   [(set (match_operand:V2DF 0 "register_operand" "=x")
21278         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21279                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21280   "TARGET_SSE2"
21281   "divpd\t{%2, %0|%0, %2}"
21282   [(set_attr "type" "ssediv")
21283    (set_attr "mode" "V2DF")])
21284
21285 (define_insn "vmdivv2df3"
21286   [(set (match_operand:V2DF 0 "register_operand" "=x")
21287         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21288                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21289                         (match_dup 1)
21290                         (const_int 1)))]
21291   "TARGET_SSE2"
21292   "divsd\t{%2, %0|%0, %2}"
21293   [(set_attr "type" "ssediv")
21294    (set_attr "mode" "DF")])
21295
21296 ;; SSE min/max
21297
21298 (define_insn "smaxv2df3"
21299   [(set (match_operand:V2DF 0 "register_operand" "=x")
21300         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21301                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21302   "TARGET_SSE2"
21303   "maxpd\t{%2, %0|%0, %2}"
21304   [(set_attr "type" "sseadd")
21305    (set_attr "mode" "V2DF")])
21306
21307 (define_insn "vmsmaxv2df3"
21308   [(set (match_operand:V2DF 0 "register_operand" "=x")
21309         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21310                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21311                         (match_dup 1)
21312                         (const_int 1)))]
21313   "TARGET_SSE2"
21314   "maxsd\t{%2, %0|%0, %2}"
21315   [(set_attr "type" "sseadd")
21316    (set_attr "mode" "DF")])
21317
21318 (define_insn "sminv2df3"
21319   [(set (match_operand:V2DF 0 "register_operand" "=x")
21320         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21321                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21322   "TARGET_SSE2"
21323   "minpd\t{%2, %0|%0, %2}"
21324   [(set_attr "type" "sseadd")
21325    (set_attr "mode" "V2DF")])
21326
21327 (define_insn "vmsminv2df3"
21328   [(set (match_operand:V2DF 0 "register_operand" "=x")
21329         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21330                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21331                         (match_dup 1)
21332                         (const_int 1)))]
21333   "TARGET_SSE2"
21334   "minsd\t{%2, %0|%0, %2}"
21335   [(set_attr "type" "sseadd")
21336    (set_attr "mode" "DF")])
21337 ;; SSE2 square root.  There doesn't appear to be an extension for the
21338 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21339
21340 (define_insn "sqrtv2df2"
21341   [(set (match_operand:V2DF 0 "register_operand" "=x")
21342         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21343   "TARGET_SSE2"
21344   "sqrtpd\t{%1, %0|%0, %1}"
21345   [(set_attr "type" "sse")
21346    (set_attr "mode" "V2DF")])
21347
21348 (define_insn "vmsqrtv2df2"
21349   [(set (match_operand:V2DF 0 "register_operand" "=x")
21350         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21351                         (match_operand:V2DF 2 "register_operand" "0")
21352                         (const_int 1)))]
21353   "TARGET_SSE2"
21354   "sqrtsd\t{%1, %0|%0, %1}"
21355   [(set_attr "type" "sse")
21356    (set_attr "mode" "SF")])
21357
21358 ;; SSE mask-generating compares
21359
21360 (define_insn "maskcmpv2df3"
21361   [(set (match_operand:V2DI 0 "register_operand" "=x")
21362         (match_operator:V2DI 3 "sse_comparison_operator"
21363                              [(match_operand:V2DF 1 "register_operand" "0")
21364                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21365   "TARGET_SSE2"
21366   "cmp%D3pd\t{%2, %0|%0, %2}"
21367   [(set_attr "type" "ssecmp")
21368    (set_attr "mode" "V2DF")])
21369
21370 (define_insn "maskncmpv2df3"
21371   [(set (match_operand:V2DI 0 "register_operand" "=x")
21372         (not:V2DI
21373          (match_operator:V2DI 3 "sse_comparison_operator"
21374                               [(match_operand:V2DF 1 "register_operand" "0")
21375                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21376   "TARGET_SSE2"
21377 {
21378   if (GET_CODE (operands[3]) == UNORDERED)
21379     return "cmpordps\t{%2, %0|%0, %2}";
21380   else
21381     return "cmpn%D3pd\t{%2, %0|%0, %2}";
21382 }
21383   [(set_attr "type" "ssecmp")
21384    (set_attr "mode" "V2DF")])
21385
21386 (define_insn "vmmaskcmpv2df3"
21387   [(set (match_operand:V2DI 0 "register_operand" "=x")
21388         (vec_merge:V2DI
21389          (match_operator:V2DI 3 "sse_comparison_operator"
21390                               [(match_operand:V2DF 1 "register_operand" "0")
21391                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21392          (subreg:V2DI (match_dup 1) 0)
21393          (const_int 1)))]
21394   "TARGET_SSE2"
21395   "cmp%D3sd\t{%2, %0|%0, %2}"
21396   [(set_attr "type" "ssecmp")
21397    (set_attr "mode" "DF")])
21398
21399 (define_insn "vmmaskncmpv2df3"
21400   [(set (match_operand:V2DI 0 "register_operand" "=x")
21401         (vec_merge:V2DI
21402          (not:V2DI
21403           (match_operator:V2DI 3 "sse_comparison_operator"
21404                                [(match_operand:V2DF 1 "register_operand" "0")
21405                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21406          (subreg:V2DI (match_dup 1) 0)
21407          (const_int 1)))]
21408   "TARGET_SSE2"
21409 {
21410   if (GET_CODE (operands[3]) == UNORDERED)
21411     return "cmpordsd\t{%2, %0|%0, %2}";
21412   else
21413     return "cmpn%D3sd\t{%2, %0|%0, %2}";
21414 }
21415   [(set_attr "type" "ssecmp")
21416    (set_attr "mode" "DF")])
21417
21418 (define_insn "sse2_comi"
21419   [(set (reg:CCFP 17)
21420         (compare:CCFP (vec_select:DF
21421                        (match_operand:V2DF 0 "register_operand" "x")
21422                        (parallel [(const_int 0)]))
21423                       (vec_select:DF
21424                        (match_operand:V2DF 1 "register_operand" "x")
21425                        (parallel [(const_int 0)]))))]
21426   "TARGET_SSE2"
21427   "comisd\t{%1, %0|%0, %1}"
21428   [(set_attr "type" "ssecomi")
21429    (set_attr "mode" "DF")])
21430
21431 (define_insn "sse2_ucomi"
21432   [(set (reg:CCFPU 17)
21433         (compare:CCFPU (vec_select:DF
21434                          (match_operand:V2DF 0 "register_operand" "x")
21435                          (parallel [(const_int 0)]))
21436                         (vec_select:DF
21437                          (match_operand:V2DF 1 "register_operand" "x")
21438                          (parallel [(const_int 0)]))))]
21439   "TARGET_SSE2"
21440   "ucomisd\t{%1, %0|%0, %1}"
21441   [(set_attr "type" "ssecomi")
21442    (set_attr "mode" "DF")])
21443
21444 ;; SSE Strange Moves.
21445
21446 (define_insn "sse2_movmskpd"
21447   [(set (match_operand:SI 0 "register_operand" "=r")
21448         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21449                    UNSPEC_MOVMSK))]
21450   "TARGET_SSE2"
21451   "movmskpd\t{%1, %0|%0, %1}"
21452   [(set_attr "type" "ssecvt")
21453    (set_attr "mode" "V2DF")])
21454
21455 (define_insn "sse2_pmovmskb"
21456   [(set (match_operand:SI 0 "register_operand" "=r")
21457         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21458                    UNSPEC_MOVMSK))]
21459   "TARGET_SSE2"
21460   "pmovmskb\t{%1, %0|%0, %1}"
21461   [(set_attr "type" "ssecvt")
21462    (set_attr "mode" "V2DF")])
21463
21464 (define_insn "sse2_maskmovdqu"
21465   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21466         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21467                        (match_operand:V16QI 2 "register_operand" "x")]
21468                       UNSPEC_MASKMOV))]
21469   "TARGET_SSE2"
21470   ;; @@@ check ordering of operands in intel/nonintel syntax
21471   "maskmovdqu\t{%2, %1|%1, %2}"
21472   [(set_attr "type" "ssecvt")
21473    (set_attr "mode" "TI")])
21474
21475 (define_insn "sse2_maskmovdqu_rex64"
21476   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21477         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21478                        (match_operand:V16QI 2 "register_operand" "x")]
21479                       UNSPEC_MASKMOV))]
21480   "TARGET_SSE2"
21481   ;; @@@ check ordering of operands in intel/nonintel syntax
21482   "maskmovdqu\t{%2, %1|%1, %2}"
21483   [(set_attr "type" "ssecvt")
21484    (set_attr "mode" "TI")])
21485
21486 (define_insn "sse2_movntv2df"
21487   [(set (match_operand:V2DF 0 "memory_operand" "=m")
21488         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21489                      UNSPEC_MOVNT))]
21490   "TARGET_SSE2"
21491   "movntpd\t{%1, %0|%0, %1}"
21492   [(set_attr "type" "ssecvt")
21493    (set_attr "mode" "V2DF")])
21494
21495 (define_insn "sse2_movntv2di"
21496   [(set (match_operand:V2DI 0 "memory_operand" "=m")
21497         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21498                      UNSPEC_MOVNT))]
21499   "TARGET_SSE2"
21500   "movntdq\t{%1, %0|%0, %1}"
21501   [(set_attr "type" "ssecvt")
21502    (set_attr "mode" "TI")])
21503
21504 (define_insn "sse2_movntsi"
21505   [(set (match_operand:SI 0 "memory_operand" "=m")
21506         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21507                    UNSPEC_MOVNT))]
21508   "TARGET_SSE2"
21509   "movnti\t{%1, %0|%0, %1}"
21510   [(set_attr "type" "ssecvt")
21511    (set_attr "mode" "V2DF")])
21512
21513 ;; SSE <-> integer/MMX conversions
21514
21515 ;; Conversions between SI and SF
21516
21517 (define_insn "cvtdq2ps"
21518   [(set (match_operand:V4SF 0 "register_operand" "=x")
21519         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21520   "TARGET_SSE2"
21521   "cvtdq2ps\t{%1, %0|%0, %1}"
21522   [(set_attr "type" "ssecvt")
21523    (set_attr "mode" "V2DF")])
21524
21525 (define_insn "cvtps2dq"
21526   [(set (match_operand:V4SI 0 "register_operand" "=x")
21527         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21528   "TARGET_SSE2"
21529   "cvtps2dq\t{%1, %0|%0, %1}"
21530   [(set_attr "type" "ssecvt")
21531    (set_attr "mode" "TI")])
21532
21533 (define_insn "cvttps2dq"
21534   [(set (match_operand:V4SI 0 "register_operand" "=x")
21535         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21536                      UNSPEC_FIX))]
21537   "TARGET_SSE2"
21538   "cvttps2dq\t{%1, %0|%0, %1}"
21539   [(set_attr "type" "ssecvt")
21540    (set_attr "mode" "TI")])
21541
21542 ;; Conversions between SI and DF
21543
21544 (define_insn "cvtdq2pd"
21545   [(set (match_operand:V2DF 0 "register_operand" "=x")
21546         (float:V2DF (vec_select:V2SI
21547                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21548                      (parallel
21549                       [(const_int 0)
21550                        (const_int 1)]))))]
21551   "TARGET_SSE2"
21552   "cvtdq2pd\t{%1, %0|%0, %1}"
21553   [(set_attr "type" "ssecvt")
21554    (set_attr "mode" "V2DF")])
21555
21556 (define_insn "cvtpd2dq"
21557   [(set (match_operand:V4SI 0 "register_operand" "=x")
21558         (vec_concat:V4SI
21559          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21560          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21561   "TARGET_SSE2"
21562   "cvtpd2dq\t{%1, %0|%0, %1}"
21563   [(set_attr "type" "ssecvt")
21564    (set_attr "mode" "TI")])
21565
21566 (define_insn "cvttpd2dq"
21567   [(set (match_operand:V4SI 0 "register_operand" "=x")
21568         (vec_concat:V4SI
21569          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21570                       UNSPEC_FIX)
21571          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21572   "TARGET_SSE2"
21573   "cvttpd2dq\t{%1, %0|%0, %1}"
21574   [(set_attr "type" "ssecvt")
21575    (set_attr "mode" "TI")])
21576
21577 (define_insn "cvtpd2pi"
21578   [(set (match_operand:V2SI 0 "register_operand" "=y")
21579         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21580   "TARGET_SSE2"
21581   "cvtpd2pi\t{%1, %0|%0, %1}"
21582   [(set_attr "type" "ssecvt")
21583    (set_attr "mode" "TI")])
21584
21585 (define_insn "cvttpd2pi"
21586   [(set (match_operand:V2SI 0 "register_operand" "=y")
21587         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21588                      UNSPEC_FIX))]
21589   "TARGET_SSE2"
21590   "cvttpd2pi\t{%1, %0|%0, %1}"
21591   [(set_attr "type" "ssecvt")
21592    (set_attr "mode" "TI")])
21593
21594 (define_insn "cvtpi2pd"
21595   [(set (match_operand:V2DF 0 "register_operand" "=x")
21596         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21597   "TARGET_SSE2"
21598   "cvtpi2pd\t{%1, %0|%0, %1}"
21599   [(set_attr "type" "ssecvt")
21600    (set_attr "mode" "TI")])
21601
21602 ;; Conversions between SI and DF
21603
21604 (define_insn "cvtsd2si"
21605   [(set (match_operand:SI 0 "register_operand" "=r,r")
21606         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21607                                (parallel [(const_int 0)]))))]
21608   "TARGET_SSE2"
21609   "cvtsd2si\t{%1, %0|%0, %1}"
21610   [(set_attr "type" "sseicvt")
21611    (set_attr "athlon_decode" "double,vector")
21612    (set_attr "mode" "SI")])
21613
21614 (define_insn "cvtsd2siq"
21615   [(set (match_operand:DI 0 "register_operand" "=r,r")
21616         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21617                                (parallel [(const_int 0)]))))]
21618   "TARGET_SSE2 && TARGET_64BIT"
21619   "cvtsd2siq\t{%1, %0|%0, %1}"
21620   [(set_attr "type" "sseicvt")
21621    (set_attr "athlon_decode" "double,vector")
21622    (set_attr "mode" "DI")])
21623
21624 (define_insn "cvttsd2si"
21625   [(set (match_operand:SI 0 "register_operand" "=r,r")
21626         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21627                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21628   "TARGET_SSE2"
21629   "cvttsd2si\t{%1, %0|%0, %1}"
21630   [(set_attr "type" "sseicvt")
21631    (set_attr "mode" "SI")
21632    (set_attr "athlon_decode" "double,vector")])
21633
21634 (define_insn "cvttsd2siq"
21635   [(set (match_operand:DI 0 "register_operand" "=r,r")
21636         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21637                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
21638   "TARGET_SSE2 && TARGET_64BIT"
21639   "cvttsd2siq\t{%1, %0|%0, %1}"
21640   [(set_attr "type" "sseicvt")
21641    (set_attr "mode" "DI")
21642    (set_attr "athlon_decode" "double,vector")])
21643
21644 (define_insn "cvtsi2sd"
21645   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21646         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21647                         (vec_duplicate:V2DF
21648                           (float:DF
21649                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21650                         (const_int 2)))]
21651   "TARGET_SSE2"
21652   "cvtsi2sd\t{%2, %0|%0, %2}"
21653   [(set_attr "type" "sseicvt")
21654    (set_attr "mode" "DF")
21655    (set_attr "athlon_decode" "double,direct")])
21656
21657 (define_insn "cvtsi2sdq"
21658   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21659         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21660                         (vec_duplicate:V2DF
21661                           (float:DF
21662                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21663                         (const_int 2)))]
21664   "TARGET_SSE2 && TARGET_64BIT"
21665   "cvtsi2sdq\t{%2, %0|%0, %2}"
21666   [(set_attr "type" "sseicvt")
21667    (set_attr "mode" "DF")
21668    (set_attr "athlon_decode" "double,direct")])
21669
21670 ;; Conversions between SF and DF
21671
21672 (define_insn "cvtsd2ss"
21673   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21674         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21675                         (vec_duplicate:V4SF
21676                           (float_truncate:V2SF
21677                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21678                         (const_int 14)))]
21679   "TARGET_SSE2"
21680   "cvtsd2ss\t{%2, %0|%0, %2}"
21681   [(set_attr "type" "ssecvt")
21682    (set_attr "athlon_decode" "vector,double")
21683    (set_attr "mode" "SF")])
21684
21685 (define_insn "cvtss2sd"
21686   [(set (match_operand:V2DF 0 "register_operand" "=x")
21687         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21688                         (float_extend:V2DF
21689                           (vec_select:V2SF
21690                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21691                             (parallel [(const_int 0)
21692                                        (const_int 1)])))
21693                         (const_int 2)))]
21694   "TARGET_SSE2"
21695   "cvtss2sd\t{%2, %0|%0, %2}"
21696   [(set_attr "type" "ssecvt")
21697    (set_attr "mode" "DF")])
21698
21699 (define_insn "cvtpd2ps"
21700   [(set (match_operand:V4SF 0 "register_operand" "=x")
21701         (subreg:V4SF
21702           (vec_concat:V4SI
21703             (subreg:V2SI (float_truncate:V2SF
21704                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21705             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21706   "TARGET_SSE2"
21707   "cvtpd2ps\t{%1, %0|%0, %1}"
21708   [(set_attr "type" "ssecvt")
21709    (set_attr "mode" "V4SF")])
21710
21711 (define_insn "cvtps2pd"
21712   [(set (match_operand:V2DF 0 "register_operand" "=x")
21713         (float_extend:V2DF
21714           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21715                            (parallel [(const_int 0)
21716                                       (const_int 1)]))))]
21717   "TARGET_SSE2"
21718   "cvtps2pd\t{%1, %0|%0, %1}"
21719   [(set_attr "type" "ssecvt")
21720    (set_attr "mode" "V2DF")])
21721
21722 ;; SSE2 variants of MMX insns
21723
21724 ;; MMX arithmetic
21725
21726 (define_insn "addv16qi3"
21727   [(set (match_operand:V16QI 0 "register_operand" "=x")
21728         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21729                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21730   "TARGET_SSE2"
21731   "paddb\t{%2, %0|%0, %2}"
21732   [(set_attr "type" "sseiadd")
21733    (set_attr "mode" "TI")])
21734
21735 (define_insn "addv8hi3"
21736   [(set (match_operand:V8HI 0 "register_operand" "=x")
21737         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21738                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21739   "TARGET_SSE2"
21740   "paddw\t{%2, %0|%0, %2}"
21741   [(set_attr "type" "sseiadd")
21742    (set_attr "mode" "TI")])
21743
21744 (define_insn "addv4si3"
21745   [(set (match_operand:V4SI 0 "register_operand" "=x")
21746         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21747                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21748   "TARGET_SSE2"
21749   "paddd\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "sseiadd")
21751    (set_attr "mode" "TI")])
21752
21753 (define_insn "addv2di3"
21754   [(set (match_operand:V2DI 0 "register_operand" "=x")
21755         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21756                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21757   "TARGET_SSE2"
21758   "paddq\t{%2, %0|%0, %2}"
21759   [(set_attr "type" "sseiadd")
21760    (set_attr "mode" "TI")])
21761
21762 (define_insn "ssaddv16qi3"
21763   [(set (match_operand:V16QI 0 "register_operand" "=x")
21764         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21765                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21766   "TARGET_SSE2"
21767   "paddsb\t{%2, %0|%0, %2}"
21768   [(set_attr "type" "sseiadd")
21769    (set_attr "mode" "TI")])
21770
21771 (define_insn "ssaddv8hi3"
21772   [(set (match_operand:V8HI 0 "register_operand" "=x")
21773         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21774                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21775   "TARGET_SSE2"
21776   "paddsw\t{%2, %0|%0, %2}"
21777   [(set_attr "type" "sseiadd")
21778    (set_attr "mode" "TI")])
21779
21780 (define_insn "usaddv16qi3"
21781   [(set (match_operand:V16QI 0 "register_operand" "=x")
21782         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21783                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21784   "TARGET_SSE2"
21785   "paddusb\t{%2, %0|%0, %2}"
21786   [(set_attr "type" "sseiadd")
21787    (set_attr "mode" "TI")])
21788
21789 (define_insn "usaddv8hi3"
21790   [(set (match_operand:V8HI 0 "register_operand" "=x")
21791         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21792                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21793   "TARGET_SSE2"
21794   "paddusw\t{%2, %0|%0, %2}"
21795   [(set_attr "type" "sseiadd")
21796    (set_attr "mode" "TI")])
21797
21798 (define_insn "subv16qi3"
21799   [(set (match_operand:V16QI 0 "register_operand" "=x")
21800         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21801                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21802   "TARGET_SSE2"
21803   "psubb\t{%2, %0|%0, %2}"
21804   [(set_attr "type" "sseiadd")
21805    (set_attr "mode" "TI")])
21806
21807 (define_insn "subv8hi3"
21808   [(set (match_operand:V8HI 0 "register_operand" "=x")
21809         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21810                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21811   "TARGET_SSE2"
21812   "psubw\t{%2, %0|%0, %2}"
21813   [(set_attr "type" "sseiadd")
21814    (set_attr "mode" "TI")])
21815
21816 (define_insn "subv4si3"
21817   [(set (match_operand:V4SI 0 "register_operand" "=x")
21818         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21819                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21820   "TARGET_SSE2"
21821   "psubd\t{%2, %0|%0, %2}"
21822   [(set_attr "type" "sseiadd")
21823    (set_attr "mode" "TI")])
21824
21825 (define_insn "subv2di3"
21826   [(set (match_operand:V2DI 0 "register_operand" "=x")
21827         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21828                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21829   "TARGET_SSE2"
21830   "psubq\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "sseiadd")
21832    (set_attr "mode" "TI")])
21833
21834 (define_insn "sssubv16qi3"
21835   [(set (match_operand:V16QI 0 "register_operand" "=x")
21836         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21837                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21838   "TARGET_SSE2"
21839   "psubsb\t{%2, %0|%0, %2}"
21840   [(set_attr "type" "sseiadd")
21841    (set_attr "mode" "TI")])
21842
21843 (define_insn "sssubv8hi3"
21844   [(set (match_operand:V8HI 0 "register_operand" "=x")
21845         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21846                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21847   "TARGET_SSE2"
21848   "psubsw\t{%2, %0|%0, %2}"
21849   [(set_attr "type" "sseiadd")
21850    (set_attr "mode" "TI")])
21851
21852 (define_insn "ussubv16qi3"
21853   [(set (match_operand:V16QI 0 "register_operand" "=x")
21854         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21855                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21856   "TARGET_SSE2"
21857   "psubusb\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "sseiadd")
21859    (set_attr "mode" "TI")])
21860
21861 (define_insn "ussubv8hi3"
21862   [(set (match_operand:V8HI 0 "register_operand" "=x")
21863         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21864                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21865   "TARGET_SSE2"
21866   "psubusw\t{%2, %0|%0, %2}"
21867   [(set_attr "type" "sseiadd")
21868    (set_attr "mode" "TI")])
21869
21870 (define_insn "mulv8hi3"
21871   [(set (match_operand:V8HI 0 "register_operand" "=x")
21872         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21873                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21874   "TARGET_SSE2"
21875   "pmullw\t{%2, %0|%0, %2}"
21876   [(set_attr "type" "sseimul")
21877    (set_attr "mode" "TI")])
21878
21879 (define_insn "smulv8hi3_highpart"
21880   [(set (match_operand:V8HI 0 "register_operand" "=x")
21881         (truncate:V8HI
21882          (lshiftrt:V8SI
21883           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21884                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21885           (const_int 16))))]
21886   "TARGET_SSE2"
21887   "pmulhw\t{%2, %0|%0, %2}"
21888   [(set_attr "type" "sseimul")
21889    (set_attr "mode" "TI")])
21890
21891 (define_insn "umulv8hi3_highpart"
21892   [(set (match_operand:V8HI 0 "register_operand" "=x")
21893         (truncate:V8HI
21894          (lshiftrt:V8SI
21895           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21896                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21897           (const_int 16))))]
21898   "TARGET_SSE2"
21899   "pmulhuw\t{%2, %0|%0, %2}"
21900   [(set_attr "type" "sseimul")
21901    (set_attr "mode" "TI")])
21902
21903 (define_insn "sse2_umulsidi3"
21904   [(set (match_operand:DI 0 "register_operand" "=y")
21905         (mult:DI (zero_extend:DI (vec_select:SI
21906                                   (match_operand:V2SI 1 "register_operand" "0")
21907                                   (parallel [(const_int 0)])))
21908                  (zero_extend:DI (vec_select:SI
21909                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21910                                   (parallel [(const_int 0)])))))]
21911   "TARGET_SSE2"
21912   "pmuludq\t{%2, %0|%0, %2}"
21913   [(set_attr "type" "sseimul")
21914    (set_attr "mode" "TI")])
21915
21916 (define_insn "sse2_umulv2siv2di3"
21917   [(set (match_operand:V2DI 0 "register_operand" "=x")
21918         (mult:V2DI (zero_extend:V2DI
21919                      (vec_select:V2SI
21920                        (match_operand:V4SI 1 "register_operand" "0")
21921                        (parallel [(const_int 0) (const_int 2)])))
21922                    (zero_extend:V2DI
21923                      (vec_select:V2SI
21924                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21925                        (parallel [(const_int 0) (const_int 2)])))))]
21926   "TARGET_SSE2"
21927   "pmuludq\t{%2, %0|%0, %2}"
21928   [(set_attr "type" "sseimul")
21929    (set_attr "mode" "TI")])
21930
21931 (define_insn "sse2_pmaddwd"
21932   [(set (match_operand:V4SI 0 "register_operand" "=x")
21933         (plus:V4SI
21934          (mult:V4SI
21935           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21936                                              (parallel [(const_int 0)
21937                                                         (const_int 2)
21938                                                         (const_int 4)
21939                                                         (const_int 6)])))
21940           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
21941                                              (parallel [(const_int 0)
21942                                                         (const_int 2)
21943                                                         (const_int 4)
21944                                                         (const_int 6)]))))
21945          (mult:V4SI
21946           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
21947                                              (parallel [(const_int 1)
21948                                                         (const_int 3)
21949                                                         (const_int 5)
21950                                                         (const_int 7)])))
21951           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
21952                                              (parallel [(const_int 1)
21953                                                         (const_int 3)
21954                                                         (const_int 5)
21955                                                         (const_int 7)]))))))]
21956   "TARGET_SSE2"
21957   "pmaddwd\t{%2, %0|%0, %2}"
21958   [(set_attr "type" "sseiadd")
21959    (set_attr "mode" "TI")])
21960
21961 ;; Same as pxor, but don't show input operands so that we don't think
21962 ;; they are live.
21963 (define_insn "sse2_clrti"
21964   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
21965   "TARGET_SSE2"
21966 {
21967   if (get_attr_mode (insn) == MODE_TI)
21968     return "pxor\t%0, %0";
21969   else
21970     return "xorps\t%0, %0";
21971 }
21972   [(set_attr "type" "ssemov")
21973    (set_attr "memory" "none")
21974    (set (attr "mode")
21975               (if_then_else
21976                 (ne (symbol_ref "optimize_size")
21977                     (const_int 0))
21978                 (const_string "V4SF")
21979                 (const_string "TI")))])
21980
21981 ;; MMX unsigned averages/sum of absolute differences
21982
21983 (define_insn "sse2_uavgv16qi3"
21984   [(set (match_operand:V16QI 0 "register_operand" "=x")
21985         (ashiftrt:V16QI
21986          (plus:V16QI (plus:V16QI
21987                      (match_operand:V16QI 1 "register_operand" "0")
21988                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
21989                      (const_vector:V16QI [(const_int 1) (const_int 1)
21990                                           (const_int 1) (const_int 1)
21991                                           (const_int 1) (const_int 1)
21992                                           (const_int 1) (const_int 1)
21993                                           (const_int 1) (const_int 1)
21994                                           (const_int 1) (const_int 1)
21995                                           (const_int 1) (const_int 1)
21996                                           (const_int 1) (const_int 1)]))
21997          (const_int 1)))]
21998   "TARGET_SSE2"
21999   "pavgb\t{%2, %0|%0, %2}"
22000   [(set_attr "type" "sseiadd")
22001    (set_attr "mode" "TI")])
22002
22003 (define_insn "sse2_uavgv8hi3"
22004   [(set (match_operand:V8HI 0 "register_operand" "=x")
22005         (ashiftrt:V8HI
22006          (plus:V8HI (plus:V8HI
22007                      (match_operand:V8HI 1 "register_operand" "0")
22008                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22009                     (const_vector:V8HI [(const_int 1) (const_int 1)
22010                                         (const_int 1) (const_int 1)
22011                                         (const_int 1) (const_int 1)
22012                                         (const_int 1) (const_int 1)]))
22013          (const_int 1)))]
22014   "TARGET_SSE2"
22015   "pavgw\t{%2, %0|%0, %2}"
22016   [(set_attr "type" "sseiadd")
22017    (set_attr "mode" "TI")])
22018
22019 ;; @@@ this isn't the right representation.
22020 (define_insn "sse2_psadbw"
22021   [(set (match_operand:V2DI 0 "register_operand" "=x")
22022         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22023                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22024                      UNSPEC_PSADBW))]
22025   "TARGET_SSE2"
22026   "psadbw\t{%2, %0|%0, %2}"
22027   [(set_attr "type" "sseiadd")
22028    (set_attr "mode" "TI")])
22029
22030
22031 ;; MMX insert/extract/shuffle
22032
22033 (define_insn "sse2_pinsrw"
22034   [(set (match_operand:V8HI 0 "register_operand" "=x")
22035         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22036                         (vec_duplicate:V8HI
22037                          (truncate:HI
22038                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
22039                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22040   "TARGET_SSE2"
22041   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22042   [(set_attr "type" "ssecvt")
22043    (set_attr "mode" "TI")])
22044
22045 (define_insn "sse2_pextrw"
22046   [(set (match_operand:SI 0 "register_operand" "=r")
22047         (zero_extend:SI
22048           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22049                          (parallel
22050                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22051   "TARGET_SSE2"
22052   "pextrw\t{%2, %1, %0|%0, %1, %2}"
22053   [(set_attr "type" "ssecvt")
22054    (set_attr "mode" "TI")])
22055
22056 (define_insn "sse2_pshufd"
22057   [(set (match_operand:V4SI 0 "register_operand" "=x")
22058         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22059                       (match_operand:SI 2 "immediate_operand" "i")]
22060                      UNSPEC_SHUFFLE))]
22061   "TARGET_SSE2"
22062   "pshufd\t{%2, %1, %0|%0, %1, %2}"
22063   [(set_attr "type" "ssecvt")
22064    (set_attr "mode" "TI")])
22065
22066 (define_insn "sse2_pshuflw"
22067   [(set (match_operand:V8HI 0 "register_operand" "=x")
22068         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22069                       (match_operand:SI 2 "immediate_operand" "i")]
22070                      UNSPEC_PSHUFLW))]
22071   "TARGET_SSE2"
22072   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22073   [(set_attr "type" "ssecvt")
22074    (set_attr "mode" "TI")])
22075
22076 (define_insn "sse2_pshufhw"
22077   [(set (match_operand:V8HI 0 "register_operand" "=x")
22078         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22079                       (match_operand:SI 2 "immediate_operand" "i")]
22080                      UNSPEC_PSHUFHW))]
22081   "TARGET_SSE2"
22082   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22083   [(set_attr "type" "ssecvt")
22084    (set_attr "mode" "TI")])
22085
22086 ;; MMX mask-generating comparisons
22087
22088 (define_insn "eqv16qi3"
22089   [(set (match_operand:V16QI 0 "register_operand" "=x")
22090         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22091                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22092   "TARGET_SSE2"
22093   "pcmpeqb\t{%2, %0|%0, %2}"
22094   [(set_attr "type" "ssecmp")
22095    (set_attr "mode" "TI")])
22096
22097 (define_insn "eqv8hi3"
22098   [(set (match_operand:V8HI 0 "register_operand" "=x")
22099         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22100                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22101   "TARGET_SSE2"
22102   "pcmpeqw\t{%2, %0|%0, %2}"
22103   [(set_attr "type" "ssecmp")
22104    (set_attr "mode" "TI")])
22105
22106 (define_insn "eqv4si3"
22107   [(set (match_operand:V4SI 0 "register_operand" "=x")
22108         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22109                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22110   "TARGET_SSE2"
22111   "pcmpeqd\t{%2, %0|%0, %2}"
22112   [(set_attr "type" "ssecmp")
22113    (set_attr "mode" "TI")])
22114
22115 (define_insn "gtv16qi3"
22116   [(set (match_operand:V16QI 0 "register_operand" "=x")
22117         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22118                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22119   "TARGET_SSE2"
22120   "pcmpgtb\t{%2, %0|%0, %2}"
22121   [(set_attr "type" "ssecmp")
22122    (set_attr "mode" "TI")])
22123
22124 (define_insn "gtv8hi3"
22125   [(set (match_operand:V8HI 0 "register_operand" "=x")
22126         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22127                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22128   "TARGET_SSE2"
22129   "pcmpgtw\t{%2, %0|%0, %2}"
22130   [(set_attr "type" "ssecmp")
22131    (set_attr "mode" "TI")])
22132
22133 (define_insn "gtv4si3"
22134   [(set (match_operand:V4SI 0 "register_operand" "=x")
22135         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22136                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22137   "TARGET_SSE2"
22138   "pcmpgtd\t{%2, %0|%0, %2}"
22139   [(set_attr "type" "ssecmp")
22140    (set_attr "mode" "TI")])
22141
22142
22143 ;; MMX max/min insns
22144
22145 (define_insn "umaxv16qi3"
22146   [(set (match_operand:V16QI 0 "register_operand" "=x")
22147         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22148                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22149   "TARGET_SSE2"
22150   "pmaxub\t{%2, %0|%0, %2}"
22151   [(set_attr "type" "sseiadd")
22152    (set_attr "mode" "TI")])
22153
22154 (define_insn "smaxv8hi3"
22155   [(set (match_operand:V8HI 0 "register_operand" "=x")
22156         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22157                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22158   "TARGET_SSE2"
22159   "pmaxsw\t{%2, %0|%0, %2}"
22160   [(set_attr "type" "sseiadd")
22161    (set_attr "mode" "TI")])
22162
22163 (define_insn "uminv16qi3"
22164   [(set (match_operand:V16QI 0 "register_operand" "=x")
22165         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22166                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22167   "TARGET_SSE2"
22168   "pminub\t{%2, %0|%0, %2}"
22169   [(set_attr "type" "sseiadd")
22170    (set_attr "mode" "TI")])
22171
22172 (define_insn "sminv8hi3"
22173   [(set (match_operand:V8HI 0 "register_operand" "=x")
22174         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22175                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22176   "TARGET_SSE2"
22177   "pminsw\t{%2, %0|%0, %2}"
22178   [(set_attr "type" "sseiadd")
22179    (set_attr "mode" "TI")])
22180
22181
22182 ;; MMX shifts
22183
22184 (define_insn "ashrv8hi3"
22185   [(set (match_operand:V8HI 0 "register_operand" "=x")
22186         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22187                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22188   "TARGET_SSE2"
22189   "psraw\t{%2, %0|%0, %2}"
22190   [(set_attr "type" "sseishft")
22191    (set_attr "mode" "TI")])
22192
22193 (define_insn "ashrv4si3"
22194   [(set (match_operand:V4SI 0 "register_operand" "=x")
22195         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22196                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22197   "TARGET_SSE2"
22198   "psrad\t{%2, %0|%0, %2}"
22199   [(set_attr "type" "sseishft")
22200    (set_attr "mode" "TI")])
22201
22202 (define_insn "lshrv8hi3"
22203   [(set (match_operand:V8HI 0 "register_operand" "=x")
22204         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22206   "TARGET_SSE2"
22207   "psrlw\t{%2, %0|%0, %2}"
22208   [(set_attr "type" "sseishft")
22209    (set_attr "mode" "TI")])
22210
22211 (define_insn "lshrv4si3"
22212   [(set (match_operand:V4SI 0 "register_operand" "=x")
22213         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22215   "TARGET_SSE2"
22216   "psrld\t{%2, %0|%0, %2}"
22217   [(set_attr "type" "sseishft")
22218    (set_attr "mode" "TI")])
22219
22220 (define_insn "lshrv2di3"
22221   [(set (match_operand:V2DI 0 "register_operand" "=x")
22222         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22223                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22224   "TARGET_SSE2"
22225   "psrlq\t{%2, %0|%0, %2}"
22226   [(set_attr "type" "sseishft")
22227    (set_attr "mode" "TI")])
22228
22229 (define_insn "ashlv8hi3"
22230   [(set (match_operand:V8HI 0 "register_operand" "=x")
22231         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22233   "TARGET_SSE2"
22234   "psllw\t{%2, %0|%0, %2}"
22235   [(set_attr "type" "sseishft")
22236    (set_attr "mode" "TI")])
22237
22238 (define_insn "ashlv4si3"
22239   [(set (match_operand:V4SI 0 "register_operand" "=x")
22240         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22242   "TARGET_SSE2"
22243   "pslld\t{%2, %0|%0, %2}"
22244   [(set_attr "type" "sseishft")
22245    (set_attr "mode" "TI")])
22246
22247 (define_insn "ashlv2di3"
22248   [(set (match_operand:V2DI 0 "register_operand" "=x")
22249         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22250                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22251   "TARGET_SSE2"
22252   "psllq\t{%2, %0|%0, %2}"
22253   [(set_attr "type" "sseishft")
22254    (set_attr "mode" "TI")])
22255
22256 (define_insn "ashrv8hi3_ti"
22257   [(set (match_operand:V8HI 0 "register_operand" "=x")
22258         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22259                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22260   "TARGET_SSE2"
22261   "psraw\t{%2, %0|%0, %2}"
22262   [(set_attr "type" "sseishft")
22263    (set_attr "mode" "TI")])
22264
22265 (define_insn "ashrv4si3_ti"
22266   [(set (match_operand:V4SI 0 "register_operand" "=x")
22267         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22268                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22269   "TARGET_SSE2"
22270   "psrad\t{%2, %0|%0, %2}"
22271   [(set_attr "type" "sseishft")
22272    (set_attr "mode" "TI")])
22273
22274 (define_insn "lshrv8hi3_ti"
22275   [(set (match_operand:V8HI 0 "register_operand" "=x")
22276         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22277                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22278   "TARGET_SSE2"
22279   "psrlw\t{%2, %0|%0, %2}"
22280   [(set_attr "type" "sseishft")
22281    (set_attr "mode" "TI")])
22282
22283 (define_insn "lshrv4si3_ti"
22284   [(set (match_operand:V4SI 0 "register_operand" "=x")
22285         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22286                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22287   "TARGET_SSE2"
22288   "psrld\t{%2, %0|%0, %2}"
22289   [(set_attr "type" "sseishft")
22290    (set_attr "mode" "TI")])
22291
22292 (define_insn "lshrv2di3_ti"
22293   [(set (match_operand:V2DI 0 "register_operand" "=x")
22294         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22295                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22296   "TARGET_SSE2"
22297   "psrlq\t{%2, %0|%0, %2}"
22298   [(set_attr "type" "sseishft")
22299    (set_attr "mode" "TI")])
22300
22301 (define_insn "ashlv8hi3_ti"
22302   [(set (match_operand:V8HI 0 "register_operand" "=x")
22303         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22304                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22305   "TARGET_SSE2"
22306   "psllw\t{%2, %0|%0, %2}"
22307   [(set_attr "type" "sseishft")
22308    (set_attr "mode" "TI")])
22309
22310 (define_insn "ashlv4si3_ti"
22311   [(set (match_operand:V4SI 0 "register_operand" "=x")
22312         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22313                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22314   "TARGET_SSE2"
22315   "pslld\t{%2, %0|%0, %2}"
22316   [(set_attr "type" "sseishft")
22317    (set_attr "mode" "TI")])
22318
22319 (define_insn "ashlv2di3_ti"
22320   [(set (match_operand:V2DI 0 "register_operand" "=x")
22321         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22322                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22323   "TARGET_SSE2"
22324   "psllq\t{%2, %0|%0, %2}"
22325   [(set_attr "type" "sseishft")
22326    (set_attr "mode" "TI")])
22327
22328 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22329 ;; we wouldn't need here it since we never generate TImode arithmetic.
22330
22331 ;; There has to be some kind of prize for the weirdest new instruction...
22332 (define_insn "sse2_ashlti3"
22333   [(set (match_operand:TI 0 "register_operand" "=x")
22334         (unspec:TI
22335          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22336                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22337                                (const_int 8)))] UNSPEC_NOP))]
22338   "TARGET_SSE2"
22339   "pslldq\t{%2, %0|%0, %2}"
22340   [(set_attr "type" "sseishft")
22341    (set_attr "mode" "TI")])
22342
22343 (define_insn "sse2_lshrti3"
22344   [(set (match_operand:TI 0 "register_operand" "=x")
22345         (unspec:TI
22346          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22347                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22348                                 (const_int 8)))] UNSPEC_NOP))]
22349   "TARGET_SSE2"
22350   "psrldq\t{%2, %0|%0, %2}"
22351   [(set_attr "type" "sseishft")
22352    (set_attr "mode" "TI")])
22353
22354 ;; SSE unpack
22355
22356 (define_insn "sse2_unpckhpd"
22357   [(set (match_operand:V2DF 0 "register_operand" "=x")
22358         (vec_concat:V2DF
22359          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22360                         (parallel [(const_int 1)]))
22361          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22362                         (parallel [(const_int 0)]))))]
22363   "TARGET_SSE2"
22364   "unpckhpd\t{%2, %0|%0, %2}"
22365   [(set_attr "type" "ssecvt")
22366    (set_attr "mode" "TI")])
22367
22368 (define_insn "sse2_unpcklpd"
22369   [(set (match_operand:V2DF 0 "register_operand" "=x")
22370         (vec_concat:V2DF
22371          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22372                         (parallel [(const_int 0)]))
22373          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22374                         (parallel [(const_int 1)]))))]
22375   "TARGET_SSE2"
22376   "unpcklpd\t{%2, %0|%0, %2}"
22377   [(set_attr "type" "ssecvt")
22378    (set_attr "mode" "TI")])
22379
22380 ;; MMX pack/unpack insns.
22381
22382 (define_insn "sse2_packsswb"
22383   [(set (match_operand:V16QI 0 "register_operand" "=x")
22384         (vec_concat:V16QI
22385          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22386          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22387   "TARGET_SSE2"
22388   "packsswb\t{%2, %0|%0, %2}"
22389   [(set_attr "type" "ssecvt")
22390    (set_attr "mode" "TI")])
22391
22392 (define_insn "sse2_packssdw"
22393   [(set (match_operand:V8HI 0 "register_operand" "=x")
22394         (vec_concat:V8HI
22395          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22396          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22397   "TARGET_SSE2"
22398   "packssdw\t{%2, %0|%0, %2}"
22399   [(set_attr "type" "ssecvt")
22400    (set_attr "mode" "TI")])
22401
22402 (define_insn "sse2_packuswb"
22403   [(set (match_operand:V16QI 0 "register_operand" "=x")
22404         (vec_concat:V16QI
22405          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22406          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22407   "TARGET_SSE2"
22408   "packuswb\t{%2, %0|%0, %2}"
22409   [(set_attr "type" "ssecvt")
22410    (set_attr "mode" "TI")])
22411
22412 (define_insn "sse2_punpckhbw"
22413   [(set (match_operand:V16QI 0 "register_operand" "=x")
22414         (vec_merge:V16QI
22415          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22416                            (parallel [(const_int 8) (const_int 0)
22417                                       (const_int 9) (const_int 1)
22418                                       (const_int 10) (const_int 2)
22419                                       (const_int 11) (const_int 3)
22420                                       (const_int 12) (const_int 4)
22421                                       (const_int 13) (const_int 5)
22422                                       (const_int 14) (const_int 6)
22423                                       (const_int 15) (const_int 7)]))
22424          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22425                            (parallel [(const_int 0) (const_int 8)
22426                                       (const_int 1) (const_int 9)
22427                                       (const_int 2) (const_int 10)
22428                                       (const_int 3) (const_int 11)
22429                                       (const_int 4) (const_int 12)
22430                                       (const_int 5) (const_int 13)
22431                                       (const_int 6) (const_int 14)
22432                                       (const_int 7) (const_int 15)]))
22433          (const_int 21845)))]
22434   "TARGET_SSE2"
22435   "punpckhbw\t{%2, %0|%0, %2}"
22436   [(set_attr "type" "ssecvt")
22437    (set_attr "mode" "TI")])
22438
22439 (define_insn "sse2_punpckhwd"
22440   [(set (match_operand:V8HI 0 "register_operand" "=x")
22441         (vec_merge:V8HI
22442          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22443                           (parallel [(const_int 4) (const_int 0)
22444                                      (const_int 5) (const_int 1)
22445                                      (const_int 6) (const_int 2)
22446                                      (const_int 7) (const_int 3)]))
22447          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22448                           (parallel [(const_int 0) (const_int 4)
22449                                      (const_int 1) (const_int 5)
22450                                      (const_int 2) (const_int 6)
22451                                      (const_int 3) (const_int 7)]))
22452          (const_int 85)))]
22453   "TARGET_SSE2"
22454   "punpckhwd\t{%2, %0|%0, %2}"
22455   [(set_attr "type" "ssecvt")
22456    (set_attr "mode" "TI")])
22457
22458 (define_insn "sse2_punpckhdq"
22459   [(set (match_operand:V4SI 0 "register_operand" "=x")
22460         (vec_merge:V4SI
22461          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22462                           (parallel [(const_int 2) (const_int 0)
22463                                      (const_int 3) (const_int 1)]))
22464          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22465                           (parallel [(const_int 0) (const_int 2)
22466                                      (const_int 1) (const_int 3)]))
22467          (const_int 5)))]
22468   "TARGET_SSE2"
22469   "punpckhdq\t{%2, %0|%0, %2}"
22470   [(set_attr "type" "ssecvt")
22471    (set_attr "mode" "TI")])
22472
22473 (define_insn "sse2_punpcklbw"
22474   [(set (match_operand:V16QI 0 "register_operand" "=x")
22475         (vec_merge:V16QI
22476          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22477                            (parallel [(const_int 0) (const_int 8)
22478                                       (const_int 1) (const_int 9)
22479                                       (const_int 2) (const_int 10)
22480                                       (const_int 3) (const_int 11)
22481                                       (const_int 4) (const_int 12)
22482                                       (const_int 5) (const_int 13)
22483                                       (const_int 6) (const_int 14)
22484                                       (const_int 7) (const_int 15)]))
22485          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22486                            (parallel [(const_int 8) (const_int 0)
22487                                       (const_int 9) (const_int 1)
22488                                       (const_int 10) (const_int 2)
22489                                       (const_int 11) (const_int 3)
22490                                       (const_int 12) (const_int 4)
22491                                       (const_int 13) (const_int 5)
22492                                       (const_int 14) (const_int 6)
22493                                       (const_int 15) (const_int 7)]))
22494          (const_int 21845)))]
22495   "TARGET_SSE2"
22496   "punpcklbw\t{%2, %0|%0, %2}"
22497   [(set_attr "type" "ssecvt")
22498    (set_attr "mode" "TI")])
22499
22500 (define_insn "sse2_punpcklwd"
22501   [(set (match_operand:V8HI 0 "register_operand" "=x")
22502         (vec_merge:V8HI
22503          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22504                           (parallel [(const_int 0) (const_int 4)
22505                                      (const_int 1) (const_int 5)
22506                                      (const_int 2) (const_int 6)
22507                                      (const_int 3) (const_int 7)]))
22508          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22509                           (parallel [(const_int 4) (const_int 0)
22510                                      (const_int 5) (const_int 1)
22511                                      (const_int 6) (const_int 2)
22512                                      (const_int 7) (const_int 3)]))
22513          (const_int 85)))]
22514   "TARGET_SSE2"
22515   "punpcklwd\t{%2, %0|%0, %2}"
22516   [(set_attr "type" "ssecvt")
22517    (set_attr "mode" "TI")])
22518
22519 (define_insn "sse2_punpckldq"
22520   [(set (match_operand:V4SI 0 "register_operand" "=x")
22521         (vec_merge:V4SI
22522          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22523                           (parallel [(const_int 0) (const_int 2)
22524                                      (const_int 1) (const_int 3)]))
22525          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22526                           (parallel [(const_int 2) (const_int 0)
22527                                      (const_int 3) (const_int 1)]))
22528          (const_int 5)))]
22529   "TARGET_SSE2"
22530   "punpckldq\t{%2, %0|%0, %2}"
22531   [(set_attr "type" "ssecvt")
22532    (set_attr "mode" "TI")])
22533
22534 (define_insn "sse2_punpcklqdq"
22535   [(set (match_operand:V2DI 0 "register_operand" "=x")
22536         (vec_merge:V2DI
22537          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22538                           (parallel [(const_int 1)
22539                                      (const_int 0)]))
22540          (match_operand:V2DI 1 "register_operand" "0")
22541          (const_int 1)))]
22542   "TARGET_SSE2"
22543   "punpcklqdq\t{%2, %0|%0, %2}"
22544   [(set_attr "type" "ssecvt")
22545    (set_attr "mode" "TI")])
22546
22547 (define_insn "sse2_punpckhqdq"
22548   [(set (match_operand:V2DI 0 "register_operand" "=x")
22549         (vec_merge:V2DI
22550          (match_operand:V2DI 1 "register_operand" "0")
22551          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22552                           (parallel [(const_int 1)
22553                                      (const_int 0)]))
22554          (const_int 1)))]
22555   "TARGET_SSE2"
22556   "punpckhqdq\t{%2, %0|%0, %2}"
22557   [(set_attr "type" "ssecvt")
22558    (set_attr "mode" "TI")])
22559
22560 ;; SSE2 moves
22561
22562 (define_insn "sse2_movapd"
22563   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22564         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22565                      UNSPEC_MOVA))]
22566   "TARGET_SSE2
22567    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22568   "movapd\t{%1, %0|%0, %1}"
22569   [(set_attr "type" "ssemov")
22570    (set_attr "mode" "V2DF")])
22571
22572 (define_insn "sse2_movupd"
22573   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22574         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22575                      UNSPEC_MOVU))]
22576   "TARGET_SSE2
22577    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22578   "movupd\t{%1, %0|%0, %1}"
22579   [(set_attr "type" "ssecvt")
22580    (set_attr "mode" "V2DF")])
22581
22582 (define_insn "sse2_movdqa"
22583   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22584         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22585                        UNSPEC_MOVA))]
22586   "TARGET_SSE2
22587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22588   "movdqa\t{%1, %0|%0, %1}"
22589   [(set_attr "type" "ssemov")
22590    (set_attr "mode" "TI")])
22591
22592 (define_insn "sse2_movdqu"
22593   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22594         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22595                        UNSPEC_MOVU))]
22596   "TARGET_SSE2
22597    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22598   "movdqu\t{%1, %0|%0, %1}"
22599   [(set_attr "type" "ssecvt")
22600    (set_attr "mode" "TI")])
22601
22602 (define_insn "sse2_movdq2q"
22603   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22604         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22605                        (parallel [(const_int 0)])))]
22606   "TARGET_SSE2 && !TARGET_64BIT"
22607   "@
22608    movq\t{%1, %0|%0, %1}
22609    movdq2q\t{%1, %0|%0, %1}"
22610   [(set_attr "type" "ssecvt")
22611    (set_attr "mode" "TI")])
22612
22613 (define_insn "sse2_movdq2q_rex64"
22614   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22615         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22616                        (parallel [(const_int 0)])))]
22617   "TARGET_SSE2 && TARGET_64BIT"
22618   "@
22619    movq\t{%1, %0|%0, %1}
22620    movdq2q\t{%1, %0|%0, %1}
22621    movd\t{%1, %0|%0, %1}"
22622   [(set_attr "type" "ssecvt")
22623    (set_attr "mode" "TI")])
22624
22625 (define_insn "sse2_movq2dq"
22626   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22627         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22628                          (const_int 0)))]
22629   "TARGET_SSE2 && !TARGET_64BIT"
22630   "@
22631    movq\t{%1, %0|%0, %1}
22632    movq2dq\t{%1, %0|%0, %1}"
22633   [(set_attr "type" "ssecvt,ssemov")
22634    (set_attr "mode" "TI")])
22635
22636 (define_insn "sse2_movq2dq_rex64"
22637   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22638         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22639                          (const_int 0)))]
22640   "TARGET_SSE2 && TARGET_64BIT"
22641   "@
22642    movq\t{%1, %0|%0, %1}
22643    movq2dq\t{%1, %0|%0, %1}
22644    movd\t{%1, %0|%0, %1}"
22645   [(set_attr "type" "ssecvt,ssemov,ssecvt")
22646    (set_attr "mode" "TI")])
22647
22648 (define_insn "sse2_movq"
22649   [(set (match_operand:V2DI 0 "register_operand" "=x")
22650         (vec_concat:V2DI (vec_select:DI
22651                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22652                           (parallel [(const_int 0)]))
22653                          (const_int 0)))]
22654   "TARGET_SSE2"
22655   "movq\t{%1, %0|%0, %1}"
22656   [(set_attr "type" "ssemov")
22657    (set_attr "mode" "TI")])
22658
22659 (define_insn "sse2_loadd"
22660   [(set (match_operand:V4SI 0 "register_operand" "=x")
22661         (vec_merge:V4SI
22662          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22663          (const_vector:V4SI [(const_int 0)
22664                              (const_int 0)
22665                              (const_int 0)
22666                              (const_int 0)])
22667          (const_int 1)))]
22668   "TARGET_SSE2"
22669   "movd\t{%1, %0|%0, %1}"
22670   [(set_attr "type" "ssemov")
22671    (set_attr "mode" "TI")])
22672
22673 (define_insn "sse2_stored"
22674   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22675         (vec_select:SI
22676          (match_operand:V4SI 1 "register_operand" "x")
22677          (parallel [(const_int 0)])))]
22678   "TARGET_SSE2"
22679   "movd\t{%1, %0|%0, %1}"
22680   [(set_attr "type" "ssemov")
22681    (set_attr "mode" "TI")])
22682
22683 (define_insn "sse2_movhpd"
22684   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22685         (vec_merge:V2DF
22686          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22687          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22688          (const_int 2)))]
22689   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22690   "movhpd\t{%2, %0|%0, %2}"
22691   [(set_attr "type" "ssecvt")
22692    (set_attr "mode" "V2DF")])
22693
22694 (define_insn "sse2_movlpd"
22695   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22696         (vec_merge:V2DF
22697          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22698          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22699          (const_int 1)))]
22700   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22701   "movlpd\t{%2, %0|%0, %2}"
22702   [(set_attr "type" "ssecvt")
22703    (set_attr "mode" "V2DF")])
22704
22705 (define_expand "sse2_loadsd"
22706   [(match_operand:V2DF 0 "register_operand" "")
22707    (match_operand:DF 1 "memory_operand" "")]
22708   "TARGET_SSE2"
22709 {
22710   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22711                                 CONST0_RTX (V2DFmode)));
22712   DONE;
22713 })
22714
22715 (define_insn "sse2_loadsd_1"
22716   [(set (match_operand:V2DF 0 "register_operand" "=x")
22717         (vec_merge:V2DF
22718          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22719          (match_operand:V2DF 2 "const0_operand" "X")
22720          (const_int 1)))]
22721   "TARGET_SSE2"
22722   "movsd\t{%1, %0|%0, %1}"
22723   [(set_attr "type" "ssecvt")
22724    (set_attr "mode" "DF")])
22725
22726 (define_insn "sse2_movsd"
22727   [(set (match_operand:V2DF 0 "register_operand" "=x")
22728         (vec_merge:V2DF
22729          (match_operand:V2DF 1 "register_operand" "0")
22730          (match_operand:V2DF 2 "register_operand" "x")
22731          (const_int 1)))]
22732   "TARGET_SSE2"
22733   "movsd\t{%2, %0|%0, %2}"
22734   [(set_attr "type" "ssecvt")
22735    (set_attr "mode" "DF")])
22736
22737 (define_insn "sse2_storesd"
22738   [(set (match_operand:DF 0 "memory_operand" "=m")
22739         (vec_select:DF
22740          (match_operand:V2DF 1 "register_operand" "x")
22741          (parallel [(const_int 0)])))]
22742   "TARGET_SSE2"
22743   "movsd\t{%1, %0|%0, %1}"
22744   [(set_attr "type" "ssecvt")
22745    (set_attr "mode" "DF")])
22746
22747 (define_insn "sse2_shufpd"
22748   [(set (match_operand:V2DF 0 "register_operand" "=x")
22749         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22750                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22751                       (match_operand:SI 3 "immediate_operand" "i")]
22752                      UNSPEC_SHUFFLE))]
22753   "TARGET_SSE2"
22754   ;; @@@ check operand order for intel/nonintel syntax
22755   "shufpd\t{%3, %2, %0|%0, %2, %3}"
22756   [(set_attr "type" "ssecvt")
22757    (set_attr "mode" "V2DF")])
22758
22759 (define_insn "sse2_clflush"
22760   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22761                     UNSPECV_CLFLUSH)]
22762   "TARGET_SSE2"
22763   "clflush %0"
22764   [(set_attr "type" "sse")
22765    (set_attr "memory" "unknown")])
22766
22767 (define_expand "sse2_mfence"
22768   [(set (match_dup 0)
22769         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22770   "TARGET_SSE2"
22771 {
22772   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22773   MEM_VOLATILE_P (operands[0]) = 1;
22774 })
22775
22776 (define_insn "*mfence_insn"
22777   [(set (match_operand:BLK 0 "" "")
22778         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22779   "TARGET_SSE2"
22780   "mfence"
22781   [(set_attr "type" "sse")
22782    (set_attr "memory" "unknown")])
22783
22784 (define_expand "sse2_lfence"
22785   [(set (match_dup 0)
22786         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22787   "TARGET_SSE2"
22788 {
22789   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22790   MEM_VOLATILE_P (operands[0]) = 1;
22791 })
22792
22793 (define_insn "*lfence_insn"
22794   [(set (match_operand:BLK 0 "" "")
22795         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22796   "TARGET_SSE2"
22797   "lfence"
22798   [(set_attr "type" "sse")
22799    (set_attr "memory" "unknown")])
22800
22801 ;; PNI
22802
22803 (define_insn "mwait"
22804   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22805                      (match_operand:SI 1 "register_operand" "c")]
22806                     UNSPECV_MWAIT)]
22807   "TARGET_PNI"
22808   "mwait\t%0, %1"
22809   [(set_attr "length" "3")])
22810
22811 (define_insn "monitor"
22812   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22813                      (match_operand:SI 1 "register_operand" "c")
22814                      (match_operand:SI 2 "register_operand" "d")]
22815                     UNSPECV_MONITOR)]
22816   "TARGET_PNI"
22817   "monitor\t%0, %1, %2"
22818   [(set_attr "length" "3")])
22819
22820 ;; PNI arithmetic
22821
22822 (define_insn "addsubv4sf3"
22823   [(set (match_operand:V4SF 0 "register_operand" "=x")
22824         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22825                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22826                      UNSPEC_ADDSUB))]
22827   "TARGET_PNI"
22828   "addsubps\t{%2, %0|%0, %2}"
22829   [(set_attr "type" "sseadd")
22830    (set_attr "mode" "V4SF")])
22831
22832 (define_insn "addsubv2df3"
22833   [(set (match_operand:V2DF 0 "register_operand" "=x")
22834         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22835                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22836                      UNSPEC_ADDSUB))]
22837   "TARGET_PNI"
22838   "addsubpd\t{%2, %0|%0, %2}"
22839   [(set_attr "type" "sseadd")
22840    (set_attr "mode" "V2DF")])
22841
22842 (define_insn "haddv4sf3"
22843   [(set (match_operand:V4SF 0 "register_operand" "=x")
22844         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22845                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22846                      UNSPEC_HADD))]
22847   "TARGET_PNI"
22848   "haddps\t{%2, %0|%0, %2}"
22849   [(set_attr "type" "sseadd")
22850    (set_attr "mode" "V4SF")])
22851
22852 (define_insn "haddv2df3"
22853   [(set (match_operand:V2DF 0 "register_operand" "=x")
22854         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22855                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22856                      UNSPEC_HADD))]
22857   "TARGET_PNI"
22858   "haddpd\t{%2, %0|%0, %2}"
22859   [(set_attr "type" "sseadd")
22860    (set_attr "mode" "V2DF")])
22861
22862 (define_insn "hsubv4sf3"
22863   [(set (match_operand:V4SF 0 "register_operand" "=x")
22864         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22865                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22866                      UNSPEC_HSUB))]
22867   "TARGET_PNI"
22868   "hsubps\t{%2, %0|%0, %2}"
22869   [(set_attr "type" "sseadd")
22870    (set_attr "mode" "V4SF")])
22871
22872 (define_insn "hsubv2df3"
22873   [(set (match_operand:V2DF 0 "register_operand" "=x")
22874         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22875                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22876                      UNSPEC_HSUB))]
22877   "TARGET_PNI"
22878   "hsubpd\t{%2, %0|%0, %2}"
22879   [(set_attr "type" "sseadd")
22880    (set_attr "mode" "V2DF")])
22881
22882 (define_insn "movshdup"
22883   [(set (match_operand:V4SF 0 "register_operand" "=x")
22884         (unspec:V4SF
22885          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22886   "TARGET_PNI"
22887   "movshdup\t{%1, %0|%0, %1}"
22888   [(set_attr "type" "sse")
22889    (set_attr "mode" "V4SF")])
22890
22891 (define_insn "movsldup"
22892   [(set (match_operand:V4SF 0 "register_operand" "=x")
22893         (unspec:V4SF
22894          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22895   "TARGET_PNI"
22896   "movsldup\t{%1, %0|%0, %1}"
22897   [(set_attr "type" "sse")
22898    (set_attr "mode" "V4SF")])
22899
22900 (define_insn "lddqu"
22901   [(set (match_operand:V16QI 0 "register_operand" "=x")
22902         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22903                        UNSPEC_LDQQU))]
22904   "TARGET_PNI"
22905   "lddqu\t{%1, %0|%0, %1}"
22906   [(set_attr "type" "ssecvt")
22907    (set_attr "mode" "TI")])
22908
22909 (define_insn "loadddup"
22910   [(set (match_operand:V2DF 0 "register_operand" "=x")
22911         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
22912   "TARGET_PNI"
22913   "movddup\t{%1, %0|%0, %1}"
22914   [(set_attr "type" "ssecvt")
22915    (set_attr "mode" "DF")])
22916
22917 (define_insn "movddup"
22918   [(set (match_operand:V2DF 0 "register_operand" "=x")
22919         (vec_duplicate:V2DF
22920          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
22921                         (parallel [(const_int 0)]))))]
22922   "TARGET_PNI"
22923   "movddup\t{%1, %0|%0, %1}"
22924   [(set_attr "type" "ssecvt")
22925    (set_attr "mode" "DF")])