OSDN Git Service

* config/i386/i386.c (ix86_prepare_fp_compare_args): Do not
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg 17)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg 17)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg 17)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg 17)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg 17)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg 17)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg 17)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg 17)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg 17)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg 17)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg 17)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg 17)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg 17)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg 17)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg 17)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg 17)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg 17)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg 17)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 (define_insn "*cmpfp_0_sf"
801   [(set (match_operand:HI 0 "register_operand" "=a")
802         (unspec:HI
803           [(compare:CCFP
804              (match_operand:SF 1 "register_operand" "f")
805              (match_operand:SF 2 "const0_operand" "X"))]
806         UNSPEC_FNSTSW))]
807   "TARGET_80387"
808 {
809   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
810     {
811       output_asm_insn ("ftst\;fnstsw\t%0", operands);
812       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
813     }
814   else
815     return "ftst\;fnstsw\t%0";
816 }
817   [(set_attr "type" "multi")
818    (set_attr "mode" "SF")])
819
820 (define_insn "*cmpfp_0_df"
821   [(set (match_operand:HI 0 "register_operand" "=a")
822         (unspec:HI
823           [(compare:CCFP
824              (match_operand:DF 1 "register_operand" "f")
825              (match_operand:DF 2 "const0_operand" "X"))]
826         UNSPEC_FNSTSW))]
827   "TARGET_80387"
828 {
829   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
830     {
831       output_asm_insn ("ftst\;fnstsw\t%0", operands);
832       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
833     }
834   else
835     return "ftst\;fnstsw\t%0";
836 }
837   [(set_attr "type" "multi")
838    (set_attr "mode" "DF")])
839
840 (define_insn "*cmpfp_0_xf"
841   [(set (match_operand:HI 0 "register_operand" "=a")
842         (unspec:HI
843           [(compare:CCFP
844              (match_operand:XF 1 "register_operand" "f")
845              (match_operand:XF 2 "const0_operand" "X"))]
846         UNSPEC_FNSTSW))]
847   "TARGET_80387"
848 {
849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
850     {
851       output_asm_insn ("ftst\;fnstsw\t%0", operands);
852       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
853     }
854   else
855     return "ftst\;fnstsw\t%0";
856 }
857   [(set_attr "type" "multi")
858    (set_attr "mode" "XF")])
859
860 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
861 ;; used to manage the reg stack popping would not be preserved.
862
863 (define_insn "*cmpfp_2_sf"
864   [(set (reg:CCFP FPSR_REG)
865         (compare:CCFP
866           (match_operand:SF 0 "register_operand" "f")
867           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
868   "TARGET_80387"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "fcmp")
871    (set_attr "mode" "SF")])
872
873 (define_insn "*cmpfp_2_sf_1"
874   [(set (match_operand:HI 0 "register_operand" "=a")
875         (unspec:HI
876           [(compare:CCFP
877              (match_operand:SF 1 "register_operand" "f")
878              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
879           UNSPEC_FNSTSW))]
880   "TARGET_80387"
881   "* return output_fp_compare (insn, operands, 2, 0);"
882   [(set_attr "type" "fcmp")
883    (set_attr "mode" "SF")])
884
885 (define_insn "*cmpfp_2_df"
886   [(set (reg:CCFP FPSR_REG)
887         (compare:CCFP
888           (match_operand:DF 0 "register_operand" "f")
889           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "fcmp")
893    (set_attr "mode" "DF")])
894
895 (define_insn "*cmpfp_2_df_1"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand:DF 1 "register_operand" "f")
900              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901           UNSPEC_FNSTSW))]
902   "TARGET_80387"
903   "* return output_fp_compare (insn, operands, 2, 0);"
904   [(set_attr "type" "multi")
905    (set_attr "mode" "DF")])
906
907 (define_insn "*cmpfp_2_xf"
908   [(set (reg:CCFP FPSR_REG)
909         (compare:CCFP
910           (match_operand:XF 0 "register_operand" "f")
911           (match_operand:XF 1 "register_operand" "f")))]
912   "TARGET_80387"
913   "* return output_fp_compare (insn, operands, 0, 0);"
914   [(set_attr "type" "fcmp")
915    (set_attr "mode" "XF")])
916
917 (define_insn "*cmpfp_2_xf_1"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI
920           [(compare:CCFP
921              (match_operand:XF 1 "register_operand" "f")
922              (match_operand:XF 2 "register_operand" "f"))]
923           UNSPEC_FNSTSW))]
924   "TARGET_80387"
925   "* return output_fp_compare (insn, operands, 2, 0);"
926   [(set_attr "type" "multi")
927    (set_attr "mode" "XF")])
928
929 (define_insn "*cmpfp_2u"
930   [(set (reg:CCFPU FPSR_REG)
931         (compare:CCFPU
932           (match_operand 0 "register_operand" "f")
933           (match_operand 1 "register_operand" "f")))]
934   "TARGET_80387
935    && FLOAT_MODE_P (GET_MODE (operands[0]))
936    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
937   "* return output_fp_compare (insn, operands, 0, 1);"
938   [(set_attr "type" "fcmp")
939    (set (attr "mode")
940      (cond [(match_operand:SF 1 "" "")
941               (const_string "SF")
942             (match_operand:DF 1 "" "")
943               (const_string "DF")
944            ]
945            (const_string "XF")))])
946
947 (define_insn "*cmpfp_2u_1"
948   [(set (match_operand:HI 0 "register_operand" "=a")
949         (unspec:HI
950           [(compare:CCFPU
951              (match_operand 1 "register_operand" "f")
952              (match_operand 2 "register_operand" "f"))]
953           UNSPEC_FNSTSW))]
954   "TARGET_80387
955    && FLOAT_MODE_P (GET_MODE (operands[1]))
956    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
957   "* return output_fp_compare (insn, operands, 2, 1);"
958   [(set_attr "type" "multi")
959    (set (attr "mode")
960      (cond [(match_operand:SF 1 "" "")
961               (const_string "SF")
962             (match_operand:DF 1 "" "")
963               (const_string "DF")
964            ]
965            (const_string "XF")))])
966
967 ;; Patterns to match the SImode-in-memory ficom instructions.
968 ;;
969 ;; %%% Play games with accepting gp registers, as otherwise we have to
970 ;; force them to memory during rtl generation, which is no good.  We
971 ;; can get rid of this once we teach reload to do memory input reloads 
972 ;; via pushes.
973
974 (define_insn "*ficom_1"
975   [(set (reg:CCFP FPSR_REG)
976         (compare:CCFP
977           (match_operand 0 "register_operand" "f,f")
978           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
979   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
980    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
981   "#")
982
983 ;; Split the not-really-implemented gp register case into a
984 ;; push-op-pop sequence.
985 ;;
986 ;; %%% This is most efficient, but am I gonna get in trouble
987 ;; for separating cc0_setter and cc0_user?
988
989 (define_split
990   [(set (reg:CCFP FPSR_REG)
991         (compare:CCFP
992           (match_operand:SF 0 "register_operand" "")
993           (float (match_operand:SI 1 "register_operand" ""))))]
994   "0 && TARGET_80387 && reload_completed"
995   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
996    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
997    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
998               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
999   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1000    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1001
1002 ;; FP compares, step 2
1003 ;; Move the fpsw to ax.
1004
1005 (define_insn "x86_fnstsw_1"
1006   [(set (match_operand:HI 0 "register_operand" "=a")
1007         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1008   "TARGET_80387"
1009   "fnstsw\t%0"
1010   [(set_attr "length" "2")
1011    (set_attr "mode" "SI")
1012    (set_attr "unit" "i387")])
1013
1014 ;; FP compares, step 3
1015 ;; Get ax into flags, general case.
1016
1017 (define_insn "x86_sahf_1"
1018   [(set (reg:CC FLAGS_REG)
1019         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
1020   "!TARGET_64BIT"
1021   "sahf"
1022   [(set_attr "length" "1")
1023    (set_attr "athlon_decode" "vector")
1024    (set_attr "mode" "SI")])
1025
1026 ;; Pentium Pro can do steps 1 through 3 in one go.
1027
1028 (define_insn "*cmpfp_i"
1029   [(set (reg:CCFP FLAGS_REG)
1030         (compare:CCFP (match_operand 0 "register_operand" "f")
1031                       (match_operand 1 "register_operand" "f")))]
1032   "TARGET_80387 && TARGET_CMOVE
1033    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1034    && FLOAT_MODE_P (GET_MODE (operands[0]))
1035    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036   "* return output_fp_compare (insn, operands, 1, 0);"
1037   [(set_attr "type" "fcmp")
1038    (set (attr "mode")
1039      (cond [(match_operand:SF 1 "" "")
1040               (const_string "SF")
1041             (match_operand:DF 1 "" "")
1042               (const_string "DF")
1043            ]
1044            (const_string "XF")))
1045    (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_i_sse"
1048   [(set (reg:CCFP FLAGS_REG)
1049         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1050                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1051   "TARGET_80387
1052    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1054   "* return output_fp_compare (insn, operands, 1, 0);"
1055   [(set_attr "type" "fcmp,ssecomi")
1056    (set (attr "mode")
1057      (if_then_else (match_operand:SF 1 "" "")
1058         (const_string "SF")
1059         (const_string "DF")))
1060    (set_attr "athlon_decode" "vector")])
1061
1062 (define_insn "*cmpfp_i_sse_only"
1063   [(set (reg:CCFP FLAGS_REG)
1064         (compare:CCFP (match_operand 0 "register_operand" "x")
1065                       (match_operand 1 "nonimmediate_operand" "xm")))]
1066   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1068   "* return output_fp_compare (insn, operands, 1, 0);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")])
1075
1076 (define_insn "*cmpfp_iu"
1077   [(set (reg:CCFPU FLAGS_REG)
1078         (compare:CCFPU (match_operand 0 "register_operand" "f")
1079                        (match_operand 1 "register_operand" "f")))]
1080   "TARGET_80387 && TARGET_CMOVE
1081    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1082    && FLOAT_MODE_P (GET_MODE (operands[0]))
1083    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084   "* return output_fp_compare (insn, operands, 1, 1);"
1085   [(set_attr "type" "fcmp")
1086    (set (attr "mode")
1087      (cond [(match_operand:SF 1 "" "")
1088               (const_string "SF")
1089             (match_operand:DF 1 "" "")
1090               (const_string "DF")
1091            ]
1092            (const_string "XF")))
1093    (set_attr "athlon_decode" "vector")])
1094
1095 (define_insn "*cmpfp_iu_sse"
1096   [(set (reg:CCFPU FLAGS_REG)
1097         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1098                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1099   "TARGET_80387
1100    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1101    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1102   "* return output_fp_compare (insn, operands, 1, 1);"
1103   [(set_attr "type" "fcmp,ssecomi")
1104    (set (attr "mode")
1105      (if_then_else (match_operand:SF 1 "" "")
1106         (const_string "SF")
1107         (const_string "DF")))
1108    (set_attr "athlon_decode" "vector")])
1109
1110 (define_insn "*cmpfp_iu_sse_only"
1111   [(set (reg:CCFPU FLAGS_REG)
1112         (compare:CCFPU (match_operand 0 "register_operand" "x")
1113                        (match_operand 1 "nonimmediate_operand" "xm")))]
1114   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1115    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1116   "* return output_fp_compare (insn, operands, 1, 1);"
1117   [(set_attr "type" "ssecomi")
1118    (set (attr "mode")
1119      (if_then_else (match_operand:SF 1 "" "")
1120         (const_string "SF")
1121         (const_string "DF")))
1122    (set_attr "athlon_decode" "vector")])
1123 \f
1124 ;; Move instructions.
1125
1126 ;; General case of fullword move.
1127
1128 (define_expand "movsi"
1129   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1130         (match_operand:SI 1 "general_operand" ""))]
1131   ""
1132   "ix86_expand_move (SImode, operands); DONE;")
1133
1134 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1135 ;; general_operand.
1136 ;;
1137 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1138 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1139 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1140 ;; targets without our curiosities, and it is just as easy to represent
1141 ;; this differently.
1142
1143 (define_insn "*pushsi2"
1144   [(set (match_operand:SI 0 "push_operand" "=<")
1145         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1146   "!TARGET_64BIT"
1147   "push{l}\t%1"
1148   [(set_attr "type" "push")
1149    (set_attr "mode" "SI")])
1150
1151 ;; For 64BIT abi we always round up to 8 bytes.
1152 (define_insn "*pushsi2_rex64"
1153   [(set (match_operand:SI 0 "push_operand" "=X")
1154         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1155   "TARGET_64BIT"
1156   "push{q}\t%q1"
1157   [(set_attr "type" "push")
1158    (set_attr "mode" "SI")])
1159
1160 (define_insn "*pushsi2_prologue"
1161   [(set (match_operand:SI 0 "push_operand" "=<")
1162         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1163    (clobber (mem:BLK (scratch)))]
1164   "!TARGET_64BIT"
1165   "push{l}\t%1"
1166   [(set_attr "type" "push")
1167    (set_attr "mode" "SI")])
1168
1169 (define_insn "*popsi1_epilogue"
1170   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1171         (mem:SI (reg:SI SP_REG)))
1172    (set (reg:SI SP_REG)
1173         (plus:SI (reg:SI SP_REG) (const_int 4)))
1174    (clobber (mem:BLK (scratch)))]
1175   "!TARGET_64BIT"
1176   "pop{l}\t%0"
1177   [(set_attr "type" "pop")
1178    (set_attr "mode" "SI")])
1179
1180 (define_insn "popsi1"
1181   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1182         (mem:SI (reg:SI SP_REG)))
1183    (set (reg:SI SP_REG)
1184         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1185   "!TARGET_64BIT"
1186   "pop{l}\t%0"
1187   [(set_attr "type" "pop")
1188    (set_attr "mode" "SI")])
1189
1190 (define_insn "*movsi_xor"
1191   [(set (match_operand:SI 0 "register_operand" "=r")
1192         (match_operand:SI 1 "const0_operand" "i"))
1193    (clobber (reg:CC FLAGS_REG))]
1194   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1195   "xor{l}\t{%0, %0|%0, %0}"
1196   [(set_attr "type" "alu1")
1197    (set_attr "mode" "SI")
1198    (set_attr "length_immediate" "0")])
1199  
1200 (define_insn "*movsi_or"
1201   [(set (match_operand:SI 0 "register_operand" "=r")
1202         (match_operand:SI 1 "immediate_operand" "i"))
1203    (clobber (reg:CC FLAGS_REG))]
1204   "reload_completed
1205    && operands[1] == constm1_rtx
1206    && (TARGET_PENTIUM || optimize_size)"
1207 {
1208   operands[1] = constm1_rtx;
1209   return "or{l}\t{%1, %0|%0, %1}";
1210 }
1211   [(set_attr "type" "alu1")
1212    (set_attr "mode" "SI")
1213    (set_attr "length_immediate" "1")])
1214
1215 (define_insn "*movsi_1"
1216   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1217         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1218   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1219    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1220 {
1221   switch (get_attr_type (insn))
1222     {
1223     case TYPE_SSEMOV:
1224       if (get_attr_mode (insn) == MODE_TI)
1225         return "movdqa\t{%1, %0|%0, %1}";
1226       return "movd\t{%1, %0|%0, %1}";
1227
1228     case TYPE_MMXMOV:
1229       if (get_attr_mode (insn) == MODE_DI)
1230         return "movq\t{%1, %0|%0, %1}";
1231       return "movd\t{%1, %0|%0, %1}";
1232
1233     case TYPE_LEA:
1234       return "lea{l}\t{%1, %0|%0, %1}";
1235
1236     default:
1237       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1238         abort();
1239       return "mov{l}\t{%1, %0|%0, %1}";
1240     }
1241 }
1242   [(set (attr "type")
1243      (cond [(eq_attr "alternative" "2,3,4")
1244               (const_string "mmxmov")
1245             (eq_attr "alternative" "5,6,7")
1246               (const_string "ssemov")
1247             (and (ne (symbol_ref "flag_pic") (const_int 0))
1248                  (match_operand:SI 1 "symbolic_operand" ""))
1249               (const_string "lea")
1250            ]
1251            (const_string "imov")))
1252    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1253
1254 (define_insn "*movsi_1_nointernunit"
1255   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1256         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1257   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1258    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1259 {
1260   switch (get_attr_type (insn))
1261     {
1262     case TYPE_SSEMOV:
1263       if (get_attr_mode (insn) == MODE_TI)
1264         return "movdqa\t{%1, %0|%0, %1}";
1265       return "movd\t{%1, %0|%0, %1}";
1266
1267     case TYPE_MMXMOV:
1268       if (get_attr_mode (insn) == MODE_DI)
1269         return "movq\t{%1, %0|%0, %1}";
1270       return "movd\t{%1, %0|%0, %1}";
1271
1272     case TYPE_LEA:
1273       return "lea{l}\t{%1, %0|%0, %1}";
1274
1275     default:
1276       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1277         abort();
1278       return "mov{l}\t{%1, %0|%0, %1}";
1279     }
1280 }
1281   [(set (attr "type")
1282      (cond [(eq_attr "alternative" "2,3,4")
1283               (const_string "mmxmov")
1284             (eq_attr "alternative" "5,6,7")
1285               (const_string "ssemov")
1286             (and (ne (symbol_ref "flag_pic") (const_int 0))
1287                  (match_operand:SI 1 "symbolic_operand" ""))
1288               (const_string "lea")
1289            ]
1290            (const_string "imov")))
1291    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1292
1293 ;; Stores and loads of ax to arbitrary constant address.
1294 ;; We fake an second form of instruction to force reload to load address
1295 ;; into register when rax is not available
1296 (define_insn "*movabssi_1_rex64"
1297   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1298         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1299   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1300   "@
1301    movabs{l}\t{%1, %P0|%P0, %1}
1302    mov{l}\t{%1, %a0|%a0, %1}"
1303   [(set_attr "type" "imov")
1304    (set_attr "modrm" "0,*")
1305    (set_attr "length_address" "8,0")
1306    (set_attr "length_immediate" "0,*")
1307    (set_attr "memory" "store")
1308    (set_attr "mode" "SI")])
1309
1310 (define_insn "*movabssi_2_rex64"
1311   [(set (match_operand:SI 0 "register_operand" "=a,r")
1312         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1313   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1314   "@
1315    movabs{l}\t{%P1, %0|%0, %P1}
1316    mov{l}\t{%a1, %0|%0, %a1}"
1317   [(set_attr "type" "imov")
1318    (set_attr "modrm" "0,*")
1319    (set_attr "length_address" "8,0")
1320    (set_attr "length_immediate" "0")
1321    (set_attr "memory" "load")
1322    (set_attr "mode" "SI")])
1323
1324 (define_insn "*swapsi"
1325   [(set (match_operand:SI 0 "register_operand" "+r")
1326         (match_operand:SI 1 "register_operand" "+r"))
1327    (set (match_dup 1)
1328         (match_dup 0))]
1329   ""
1330   "xchg{l}\t%1, %0"
1331   [(set_attr "type" "imov")
1332    (set_attr "pent_pair" "np")
1333    (set_attr "athlon_decode" "vector")
1334    (set_attr "mode" "SI")
1335    (set_attr "modrm" "0")])
1336
1337 (define_expand "movhi"
1338   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1339         (match_operand:HI 1 "general_operand" ""))]
1340   ""
1341   "ix86_expand_move (HImode, operands); DONE;")
1342
1343 (define_insn "*pushhi2"
1344   [(set (match_operand:HI 0 "push_operand" "=<,<")
1345         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1346   "!TARGET_64BIT"
1347   "@
1348    push{w}\t{|WORD PTR }%1
1349    push{w}\t%1"
1350   [(set_attr "type" "push")
1351    (set_attr "mode" "HI")])
1352
1353 ;; For 64BIT abi we always round up to 8 bytes.
1354 (define_insn "*pushhi2_rex64"
1355   [(set (match_operand:HI 0 "push_operand" "=X")
1356         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1357   "TARGET_64BIT"
1358   "push{q}\t%q1"
1359   [(set_attr "type" "push")
1360    (set_attr "mode" "QI")])
1361
1362 (define_insn "*movhi_1"
1363   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1364         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1365   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1366 {
1367   switch (get_attr_type (insn))
1368     {
1369     case TYPE_IMOVX:
1370       /* movzwl is faster than movw on p2 due to partial word stalls,
1371          though not as fast as an aligned movl.  */
1372       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1373     default:
1374       if (get_attr_mode (insn) == MODE_SI)
1375         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1376       else
1377         return "mov{w}\t{%1, %0|%0, %1}";
1378     }
1379 }
1380   [(set (attr "type")
1381      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1382               (const_string "imov")
1383             (and (eq_attr "alternative" "0")
1384                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1385                           (const_int 0))
1386                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1387                           (const_int 0))))
1388               (const_string "imov")
1389             (and (eq_attr "alternative" "1,2")
1390                  (match_operand:HI 1 "aligned_operand" ""))
1391               (const_string "imov")
1392             (and (ne (symbol_ref "TARGET_MOVX")
1393                      (const_int 0))
1394                  (eq_attr "alternative" "0,2"))
1395               (const_string "imovx")
1396            ]
1397            (const_string "imov")))
1398     (set (attr "mode")
1399       (cond [(eq_attr "type" "imovx")
1400                (const_string "SI")
1401              (and (eq_attr "alternative" "1,2")
1402                   (match_operand:HI 1 "aligned_operand" ""))
1403                (const_string "SI")
1404              (and (eq_attr "alternative" "0")
1405                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1406                            (const_int 0))
1407                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1408                            (const_int 0))))
1409                (const_string "SI")
1410             ]
1411             (const_string "HI")))])
1412
1413 ;; Stores and loads of ax to arbitrary constant address.
1414 ;; We fake an second form of instruction to force reload to load address
1415 ;; into register when rax is not available
1416 (define_insn "*movabshi_1_rex64"
1417   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1418         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1419   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1420   "@
1421    movabs{w}\t{%1, %P0|%P0, %1}
1422    mov{w}\t{%1, %a0|%a0, %1}"
1423   [(set_attr "type" "imov")
1424    (set_attr "modrm" "0,*")
1425    (set_attr "length_address" "8,0")
1426    (set_attr "length_immediate" "0,*")
1427    (set_attr "memory" "store")
1428    (set_attr "mode" "HI")])
1429
1430 (define_insn "*movabshi_2_rex64"
1431   [(set (match_operand:HI 0 "register_operand" "=a,r")
1432         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1433   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1434   "@
1435    movabs{w}\t{%P1, %0|%0, %P1}
1436    mov{w}\t{%a1, %0|%0, %a1}"
1437   [(set_attr "type" "imov")
1438    (set_attr "modrm" "0,*")
1439    (set_attr "length_address" "8,0")
1440    (set_attr "length_immediate" "0")
1441    (set_attr "memory" "load")
1442    (set_attr "mode" "HI")])
1443
1444 (define_insn "*swaphi_1"
1445   [(set (match_operand:HI 0 "register_operand" "+r")
1446         (match_operand:HI 1 "register_operand" "+r"))
1447    (set (match_dup 1)
1448         (match_dup 0))]
1449   "TARGET_PARTIAL_REG_STALL"
1450   "xchg{w}\t%1, %0"
1451   [(set_attr "type" "imov")
1452    (set_attr "pent_pair" "np")
1453    (set_attr "mode" "HI")
1454    (set_attr "modrm" "0")])
1455
1456 (define_insn "*swaphi_2"
1457   [(set (match_operand:HI 0 "register_operand" "+r")
1458         (match_operand:HI 1 "register_operand" "+r"))
1459    (set (match_dup 1)
1460         (match_dup 0))]
1461   "! TARGET_PARTIAL_REG_STALL"
1462   "xchg{l}\t%k1, %k0"
1463   [(set_attr "type" "imov")
1464    (set_attr "pent_pair" "np")
1465    (set_attr "mode" "SI")
1466    (set_attr "modrm" "0")])
1467
1468 (define_expand "movstricthi"
1469   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1470         (match_operand:HI 1 "general_operand" ""))]
1471   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1472 {
1473   /* Don't generate memory->memory moves, go through a register */
1474   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1475     operands[1] = force_reg (HImode, operands[1]);
1476 })
1477
1478 (define_insn "*movstricthi_1"
1479   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1480         (match_operand:HI 1 "general_operand" "rn,m"))]
1481   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1482    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1483   "mov{w}\t{%1, %0|%0, %1}"
1484   [(set_attr "type" "imov")
1485    (set_attr "mode" "HI")])
1486
1487 (define_insn "*movstricthi_xor"
1488   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1489         (match_operand:HI 1 "const0_operand" "i"))
1490    (clobber (reg:CC FLAGS_REG))]
1491   "reload_completed
1492    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1493   "xor{w}\t{%0, %0|%0, %0}"
1494   [(set_attr "type" "alu1")
1495    (set_attr "mode" "HI")
1496    (set_attr "length_immediate" "0")])
1497
1498 (define_expand "movqi"
1499   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1500         (match_operand:QI 1 "general_operand" ""))]
1501   ""
1502   "ix86_expand_move (QImode, operands); DONE;")
1503
1504 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1505 ;; "push a byte".  But actually we use pushw, which has the effect
1506 ;; of rounding the amount pushed up to a halfword.
1507
1508 (define_insn "*pushqi2"
1509   [(set (match_operand:QI 0 "push_operand" "=X,X")
1510         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1511   "!TARGET_64BIT"
1512   "@
1513    push{w}\t{|word ptr }%1
1514    push{w}\t%w1"
1515   [(set_attr "type" "push")
1516    (set_attr "mode" "HI")])
1517
1518 ;; For 64BIT abi we always round up to 8 bytes.
1519 (define_insn "*pushqi2_rex64"
1520   [(set (match_operand:QI 0 "push_operand" "=X")
1521         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1522   "TARGET_64BIT"
1523   "push{q}\t%q1"
1524   [(set_attr "type" "push")
1525    (set_attr "mode" "QI")])
1526
1527 ;; Situation is quite tricky about when to choose full sized (SImode) move
1528 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1529 ;; partial register dependency machines (such as AMD Athlon), where QImode
1530 ;; moves issue extra dependency and for partial register stalls machines
1531 ;; that don't use QImode patterns (and QImode move cause stall on the next
1532 ;; instruction).
1533 ;;
1534 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1535 ;; register stall machines with, where we use QImode instructions, since
1536 ;; partial register stall can be caused there.  Then we use movzx.
1537 (define_insn "*movqi_1"
1538   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1539         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1540   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1541 {
1542   switch (get_attr_type (insn))
1543     {
1544     case TYPE_IMOVX:
1545       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1546         abort ();
1547       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1548     default:
1549       if (get_attr_mode (insn) == MODE_SI)
1550         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1551       else
1552         return "mov{b}\t{%1, %0|%0, %1}";
1553     }
1554 }
1555   [(set (attr "type")
1556      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1557               (const_string "imov")
1558             (and (eq_attr "alternative" "3")
1559                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560                           (const_int 0))
1561                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1562                           (const_int 0))))
1563               (const_string "imov")
1564             (eq_attr "alternative" "3,5")
1565               (const_string "imovx")
1566             (and (ne (symbol_ref "TARGET_MOVX")
1567                      (const_int 0))
1568                  (eq_attr "alternative" "2"))
1569               (const_string "imovx")
1570            ]
1571            (const_string "imov")))
1572    (set (attr "mode")
1573       (cond [(eq_attr "alternative" "3,4,5")
1574                (const_string "SI")
1575              (eq_attr "alternative" "6")
1576                (const_string "QI")
1577              (eq_attr "type" "imovx")
1578                (const_string "SI")
1579              (and (eq_attr "type" "imov")
1580                   (and (eq_attr "alternative" "0,1,2")
1581                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1582                            (const_int 0))))
1583                (const_string "SI")
1584              ;; Avoid partial register stalls when not using QImode arithmetic
1585              (and (eq_attr "type" "imov")
1586                   (and (eq_attr "alternative" "0,1,2")
1587                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1588                                 (const_int 0))
1589                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1590                                 (const_int 0)))))
1591                (const_string "SI")
1592            ]
1593            (const_string "QI")))])
1594
1595 (define_expand "reload_outqi"
1596   [(parallel [(match_operand:QI 0 "" "=m")
1597               (match_operand:QI 1 "register_operand" "r")
1598               (match_operand:QI 2 "register_operand" "=&q")])]
1599   ""
1600 {
1601   rtx op0, op1, op2;
1602   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1603
1604   if (reg_overlap_mentioned_p (op2, op0))
1605     abort ();
1606   if (! q_regs_operand (op1, QImode))
1607     {
1608       emit_insn (gen_movqi (op2, op1));
1609       op1 = op2;
1610     }
1611   emit_insn (gen_movqi (op0, op1));
1612   DONE;
1613 })
1614
1615 (define_insn "*swapqi"
1616   [(set (match_operand:QI 0 "register_operand" "+r")
1617         (match_operand:QI 1 "register_operand" "+r"))
1618    (set (match_dup 1)
1619         (match_dup 0))]
1620   ""
1621   "xchg{b}\t%1, %0"
1622   [(set_attr "type" "imov")
1623    (set_attr "pent_pair" "np")
1624    (set_attr "mode" "QI")
1625    (set_attr "modrm" "0")])
1626
1627 (define_expand "movstrictqi"
1628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1629         (match_operand:QI 1 "general_operand" ""))]
1630   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1631 {
1632   /* Don't generate memory->memory moves, go through a register.  */
1633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1634     operands[1] = force_reg (QImode, operands[1]);
1635 })
1636
1637 (define_insn "*movstrictqi_1"
1638   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1639         (match_operand:QI 1 "general_operand" "*qn,m"))]
1640   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1642   "mov{b}\t{%1, %0|%0, %1}"
1643   [(set_attr "type" "imov")
1644    (set_attr "mode" "QI")])
1645
1646 (define_insn "*movstrictqi_xor"
1647   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1648         (match_operand:QI 1 "const0_operand" "i"))
1649    (clobber (reg:CC FLAGS_REG))]
1650   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1651   "xor{b}\t{%0, %0|%0, %0}"
1652   [(set_attr "type" "alu1")
1653    (set_attr "mode" "QI")
1654    (set_attr "length_immediate" "0")])
1655
1656 (define_insn "*movsi_extv_1"
1657   [(set (match_operand:SI 0 "register_operand" "=R")
1658         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1659                          (const_int 8)
1660                          (const_int 8)))]
1661   ""
1662   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1663   [(set_attr "type" "imovx")
1664    (set_attr "mode" "SI")])
1665
1666 (define_insn "*movhi_extv_1"
1667   [(set (match_operand:HI 0 "register_operand" "=R")
1668         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1669                          (const_int 8)
1670                          (const_int 8)))]
1671   ""
1672   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1673   [(set_attr "type" "imovx")
1674    (set_attr "mode" "SI")])
1675
1676 (define_insn "*movqi_extv_1"
1677   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1678         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1679                          (const_int 8)
1680                          (const_int 8)))]
1681   "!TARGET_64BIT"
1682 {
1683   switch (get_attr_type (insn))
1684     {
1685     case TYPE_IMOVX:
1686       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1687     default:
1688       return "mov{b}\t{%h1, %0|%0, %h1}";
1689     }
1690 }
1691   [(set (attr "type")
1692      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1693                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1694                              (ne (symbol_ref "TARGET_MOVX")
1695                                  (const_int 0))))
1696         (const_string "imovx")
1697         (const_string "imov")))
1698    (set (attr "mode")
1699      (if_then_else (eq_attr "type" "imovx")
1700         (const_string "SI")
1701         (const_string "QI")))])
1702
1703 (define_insn "*movqi_extv_1_rex64"
1704   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1705         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1706                          (const_int 8)
1707                          (const_int 8)))]
1708   "TARGET_64BIT"
1709 {
1710   switch (get_attr_type (insn))
1711     {
1712     case TYPE_IMOVX:
1713       return "movs{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 ;; Stores and loads of ax to arbitrary constant address.
1731 ;; We fake an second form of instruction to force reload to load address
1732 ;; into register when rax is not available
1733 (define_insn "*movabsqi_1_rex64"
1734   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1735         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1736   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1737   "@
1738    movabs{b}\t{%1, %P0|%P0, %1}
1739    mov{b}\t{%1, %a0|%a0, %1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "modrm" "0,*")
1742    (set_attr "length_address" "8,0")
1743    (set_attr "length_immediate" "0,*")
1744    (set_attr "memory" "store")
1745    (set_attr "mode" "QI")])
1746
1747 (define_insn "*movabsqi_2_rex64"
1748   [(set (match_operand:QI 0 "register_operand" "=a,r")
1749         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1750   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1751   "@
1752    movabs{b}\t{%P1, %0|%0, %P1}
1753    mov{b}\t{%a1, %0|%0, %a1}"
1754   [(set_attr "type" "imov")
1755    (set_attr "modrm" "0,*")
1756    (set_attr "length_address" "8,0")
1757    (set_attr "length_immediate" "0")
1758    (set_attr "memory" "load")
1759    (set_attr "mode" "QI")])
1760
1761 (define_insn "*movsi_extzv_1"
1762   [(set (match_operand:SI 0 "register_operand" "=R")
1763         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1764                          (const_int 8)
1765                          (const_int 8)))]
1766   ""
1767   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768   [(set_attr "type" "imovx")
1769    (set_attr "mode" "SI")])
1770
1771 (define_insn "*movqi_extzv_2"
1772   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774                                     (const_int 8)
1775                                     (const_int 8)) 0))]
1776   "!TARGET_64BIT"
1777 {
1778   switch (get_attr_type (insn))
1779     {
1780     case TYPE_IMOVX:
1781       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782     default:
1783       return "mov{b}\t{%h1, %0|%0, %h1}";
1784     }
1785 }
1786   [(set (attr "type")
1787      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                              (ne (symbol_ref "TARGET_MOVX")
1790                                  (const_int 0))))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1797
1798 (define_insn "*movqi_extzv_2_rex64"
1799   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1801                                     (const_int 8)
1802                                     (const_int 8)) 0))]
1803   "TARGET_64BIT"
1804 {
1805   switch (get_attr_type (insn))
1806     {
1807     case TYPE_IMOVX:
1808       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1809     default:
1810       return "mov{b}\t{%h1, %0|%0, %h1}";
1811     }
1812 }
1813   [(set (attr "type")
1814      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815                         (ne (symbol_ref "TARGET_MOVX")
1816                             (const_int 0)))
1817         (const_string "imovx")
1818         (const_string "imov")))
1819    (set (attr "mode")
1820      (if_then_else (eq_attr "type" "imovx")
1821         (const_string "SI")
1822         (const_string "QI")))])
1823
1824 (define_insn "movsi_insv_1"
1825   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1826                          (const_int 8)
1827                          (const_int 8))
1828         (match_operand:SI 1 "general_operand" "Qmn"))]
1829   "!TARGET_64BIT"
1830   "mov{b}\t{%b1, %h0|%h0, %b1}"
1831   [(set_attr "type" "imov")
1832    (set_attr "mode" "QI")])
1833
1834 (define_insn "movdi_insv_1_rex64"
1835   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1836                          (const_int 8)
1837                          (const_int 8))
1838         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1839   "TARGET_64BIT"
1840   "mov{b}\t{%b1, %h0|%h0, %b1}"
1841   [(set_attr "type" "imov")
1842    (set_attr "mode" "QI")])
1843
1844 (define_insn "*movqi_insv_2"
1845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1846                          (const_int 8)
1847                          (const_int 8))
1848         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1849                      (const_int 8)))]
1850   ""
1851   "mov{b}\t{%h1, %h0|%h0, %h1}"
1852   [(set_attr "type" "imov")
1853    (set_attr "mode" "QI")])
1854
1855 (define_expand "movdi"
1856   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1857         (match_operand:DI 1 "general_operand" ""))]
1858   ""
1859   "ix86_expand_move (DImode, operands); DONE;")
1860
1861 (define_insn "*pushdi"
1862   [(set (match_operand:DI 0 "push_operand" "=<")
1863         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1864   "!TARGET_64BIT"
1865   "#")
1866
1867 (define_insn "pushdi2_rex64"
1868   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1869         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1870   "TARGET_64BIT"
1871   "@
1872    push{q}\t%1
1873    #"
1874   [(set_attr "type" "push,multi")
1875    (set_attr "mode" "DI")])
1876
1877 ;; Convert impossible pushes of immediate to existing instructions.
1878 ;; First try to get scratch register and go through it.  In case this
1879 ;; fails, push sign extended lower part first and then overwrite
1880 ;; upper part by 32bit move.
1881 (define_peephole2
1882   [(match_scratch:DI 2 "r")
1883    (set (match_operand:DI 0 "push_operand" "")
1884         (match_operand:DI 1 "immediate_operand" ""))]
1885   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1886    && !x86_64_immediate_operand (operands[1], DImode)"
1887   [(set (match_dup 2) (match_dup 1))
1888    (set (match_dup 0) (match_dup 2))]
1889   "")
1890
1891 ;; We need to define this as both peepholer and splitter for case
1892 ;; peephole2 pass is not run.
1893 (define_peephole2
1894   [(set (match_operand:DI 0 "push_operand" "")
1895         (match_operand:DI 1 "immediate_operand" ""))]
1896   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1897    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1898   [(set (match_dup 0) (match_dup 1))
1899    (set (match_dup 2) (match_dup 3))]
1900   "split_di (operands + 1, 1, operands + 2, operands + 3);
1901    operands[1] = gen_lowpart (DImode, operands[2]);
1902    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1903                                                     GEN_INT (4)));
1904   ")
1905
1906 (define_split
1907   [(set (match_operand:DI 0 "push_operand" "")
1908         (match_operand:DI 1 "immediate_operand" ""))]
1909   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1910    && !symbolic_operand (operands[1], DImode)
1911    && !x86_64_immediate_operand (operands[1], DImode)"
1912   [(set (match_dup 0) (match_dup 1))
1913    (set (match_dup 2) (match_dup 3))]
1914   "split_di (operands + 1, 1, operands + 2, operands + 3);
1915    operands[1] = gen_lowpart (DImode, operands[2]);
1916    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1917                                                     GEN_INT (4)));
1918   ")
1919
1920 (define_insn "*pushdi2_prologue_rex64"
1921   [(set (match_operand:DI 0 "push_operand" "=<")
1922         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1923    (clobber (mem:BLK (scratch)))]
1924   "TARGET_64BIT"
1925   "push{q}\t%1"
1926   [(set_attr "type" "push")
1927    (set_attr "mode" "DI")])
1928
1929 (define_insn "*popdi1_epilogue_rex64"
1930   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1931         (mem:DI (reg:DI SP_REG)))
1932    (set (reg:DI SP_REG)
1933         (plus:DI (reg:DI SP_REG) (const_int 8)))
1934    (clobber (mem:BLK (scratch)))]
1935   "TARGET_64BIT"
1936   "pop{q}\t%0"
1937   [(set_attr "type" "pop")
1938    (set_attr "mode" "DI")])
1939
1940 (define_insn "popdi1"
1941   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1942         (mem:DI (reg:DI SP_REG)))
1943    (set (reg:DI SP_REG)
1944         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1945   "TARGET_64BIT"
1946   "pop{q}\t%0"
1947   [(set_attr "type" "pop")
1948    (set_attr "mode" "DI")])
1949
1950 (define_insn "*movdi_xor_rex64"
1951   [(set (match_operand:DI 0 "register_operand" "=r")
1952         (match_operand:DI 1 "const0_operand" "i"))
1953    (clobber (reg:CC FLAGS_REG))]
1954   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1955    && reload_completed"
1956   "xor{l}\t{%k0, %k0|%k0, %k0}"
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "SI")
1959    (set_attr "length_immediate" "0")])
1960
1961 (define_insn "*movdi_or_rex64"
1962   [(set (match_operand:DI 0 "register_operand" "=r")
1963         (match_operand:DI 1 "const_int_operand" "i"))
1964    (clobber (reg:CC FLAGS_REG))]
1965   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1966    && reload_completed
1967    && operands[1] == constm1_rtx"
1968 {
1969   operands[1] = constm1_rtx;
1970   return "or{q}\t{%1, %0|%0, %1}";
1971 }
1972   [(set_attr "type" "alu1")
1973    (set_attr "mode" "DI")
1974    (set_attr "length_immediate" "1")])
1975
1976 (define_insn "*movdi_2"
1977   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1978         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1979   "!TARGET_64BIT
1980    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1981   "@
1982    #
1983    #
1984    movq\t{%1, %0|%0, %1}
1985    movq\t{%1, %0|%0, %1}
1986    movq\t{%1, %0|%0, %1}
1987    movdqa\t{%1, %0|%0, %1}
1988    movq\t{%1, %0|%0, %1}"
1989   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1990    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1991
1992 (define_split
1993   [(set (match_operand:DI 0 "push_operand" "")
1994         (match_operand:DI 1 "general_operand" ""))]
1995   "!TARGET_64BIT && reload_completed
1996    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1997   [(const_int 0)]
1998   "ix86_split_long_move (operands); DONE;")
1999
2000 ;; %%% This multiword shite has got to go.
2001 (define_split
2002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2003         (match_operand:DI 1 "general_operand" ""))]
2004   "!TARGET_64BIT && reload_completed
2005    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2006    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2007   [(const_int 0)]
2008   "ix86_split_long_move (operands); DONE;")
2009
2010 (define_insn "*movdi_1_rex64"
2011   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
2012         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
2013   "TARGET_64BIT
2014    && (TARGET_INTER_UNIT_MOVES || optimize_size)
2015    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2016 {
2017   switch (get_attr_type (insn))
2018     {
2019     case TYPE_SSECVT:
2020       if (which_alternative == 11)
2021         return "movq2dq\t{%1, %0|%0, %1}";
2022       else
2023         return "movdq2q\t{%1, %0|%0, %1}";
2024     case TYPE_SSEMOV:
2025       if (get_attr_mode (insn) == MODE_TI)
2026           return "movdqa\t{%1, %0|%0, %1}";
2027       /* FALLTHRU */
2028     case TYPE_MMXMOV:
2029       /* Moves from and into integer register is done using movd opcode with
2030          REX prefix.  */
2031       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2032           return "movd\t{%1, %0|%0, %1}";
2033       return "movq\t{%1, %0|%0, %1}";
2034     case TYPE_MULTI:
2035       return "#";
2036     case TYPE_LEA:
2037       return "lea{q}\t{%a1, %0|%0, %a1}";
2038     default:
2039       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2040         abort ();
2041       if (get_attr_mode (insn) == MODE_SI)
2042         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2043       else if (which_alternative == 2)
2044         return "movabs{q}\t{%1, %0|%0, %1}";
2045       else
2046         return "mov{q}\t{%1, %0|%0, %1}";
2047     }
2048 }
2049   [(set (attr "type")
2050      (cond [(eq_attr "alternative" "5,6,7")
2051               (const_string "mmxmov")
2052             (eq_attr "alternative" "8,9,10")
2053               (const_string "ssemov")
2054             (eq_attr "alternative" "11,12")
2055               (const_string "ssecvt")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (and (ne (symbol_ref "flag_pic") (const_int 0))
2059                  (match_operand:DI 1 "symbolic_operand" ""))
2060               (const_string "lea")
2061            ]
2062            (const_string "imov")))
2063    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2064    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2065    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2066
2067 (define_insn "*movdi_1_rex64_nointerunit"
2068   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2069         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2070   "TARGET_64BIT
2071    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2072    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2073 {
2074   switch (get_attr_type (insn))
2075     {
2076     case TYPE_SSEMOV:
2077       if (get_attr_mode (insn) == MODE_TI)
2078           return "movdqa\t{%1, %0|%0, %1}";
2079       /* FALLTHRU */
2080     case TYPE_MMXMOV:
2081       return "movq\t{%1, %0|%0, %1}";
2082     case TYPE_MULTI:
2083       return "#";
2084     case TYPE_LEA:
2085       return "lea{q}\t{%a1, %0|%0, %a1}";
2086     default:
2087       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2088         abort ();
2089       if (get_attr_mode (insn) == MODE_SI)
2090         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2091       else if (which_alternative == 2)
2092         return "movabs{q}\t{%1, %0|%0, %1}";
2093       else
2094         return "mov{q}\t{%1, %0|%0, %1}";
2095     }
2096 }
2097   [(set (attr "type")
2098      (cond [(eq_attr "alternative" "5,6,7")
2099               (const_string "mmxmov")
2100             (eq_attr "alternative" "8,9,10")
2101               (const_string "ssemov")
2102             (eq_attr "alternative" "4")
2103               (const_string "multi")
2104             (and (ne (symbol_ref "flag_pic") (const_int 0))
2105                  (match_operand:DI 1 "symbolic_operand" ""))
2106               (const_string "lea")
2107            ]
2108            (const_string "imov")))
2109    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2110    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2111    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2112
2113 ;; Stores and loads of ax to arbitrary constant address.
2114 ;; We fake an second form of instruction to force reload to load address
2115 ;; into register when rax is not available
2116 (define_insn "*movabsdi_1_rex64"
2117   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2118         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2119   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2120   "@
2121    movabs{q}\t{%1, %P0|%P0, %1}
2122    mov{q}\t{%1, %a0|%a0, %1}"
2123   [(set_attr "type" "imov")
2124    (set_attr "modrm" "0,*")
2125    (set_attr "length_address" "8,0")
2126    (set_attr "length_immediate" "0,*")
2127    (set_attr "memory" "store")
2128    (set_attr "mode" "DI")])
2129
2130 (define_insn "*movabsdi_2_rex64"
2131   [(set (match_operand:DI 0 "register_operand" "=a,r")
2132         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2133   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2134   "@
2135    movabs{q}\t{%P1, %0|%0, %P1}
2136    mov{q}\t{%a1, %0|%0, %a1}"
2137   [(set_attr "type" "imov")
2138    (set_attr "modrm" "0,*")
2139    (set_attr "length_address" "8,0")
2140    (set_attr "length_immediate" "0")
2141    (set_attr "memory" "load")
2142    (set_attr "mode" "DI")])
2143
2144 ;; Convert impossible stores of immediate to existing instructions.
2145 ;; First try to get scratch register and go through it.  In case this
2146 ;; fails, move by 32bit parts.
2147 (define_peephole2
2148   [(match_scratch:DI 2 "r")
2149    (set (match_operand:DI 0 "memory_operand" "")
2150         (match_operand:DI 1 "immediate_operand" ""))]
2151   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2152    && !x86_64_immediate_operand (operands[1], DImode)"
2153   [(set (match_dup 2) (match_dup 1))
2154    (set (match_dup 0) (match_dup 2))]
2155   "")
2156
2157 ;; We need to define this as both peepholer and splitter for case
2158 ;; peephole2 pass is not run.
2159 (define_peephole2
2160   [(set (match_operand:DI 0 "memory_operand" "")
2161         (match_operand:DI 1 "immediate_operand" ""))]
2162   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2163    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2164   [(set (match_dup 2) (match_dup 3))
2165    (set (match_dup 4) (match_dup 5))]
2166   "split_di (operands, 2, operands + 2, operands + 4);")
2167
2168 (define_split
2169   [(set (match_operand:DI 0 "memory_operand" "")
2170         (match_operand:DI 1 "immediate_operand" ""))]
2171   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2172    && !symbolic_operand (operands[1], DImode)
2173    && !x86_64_immediate_operand (operands[1], DImode)"
2174   [(set (match_dup 2) (match_dup 3))
2175    (set (match_dup 4) (match_dup 5))]
2176   "split_di (operands, 2, operands + 2, operands + 4);")
2177
2178 (define_insn "*swapdi_rex64"
2179   [(set (match_operand:DI 0 "register_operand" "+r")
2180         (match_operand:DI 1 "register_operand" "+r"))
2181    (set (match_dup 1)
2182         (match_dup 0))]
2183   "TARGET_64BIT"
2184   "xchg{q}\t%1, %0"
2185   [(set_attr "type" "imov")
2186    (set_attr "pent_pair" "np")
2187    (set_attr "athlon_decode" "vector")
2188    (set_attr "mode" "DI")
2189    (set_attr "modrm" "0")])
2190
2191   
2192 (define_expand "movsf"
2193   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2194         (match_operand:SF 1 "general_operand" ""))]
2195   ""
2196   "ix86_expand_move (SFmode, operands); DONE;")
2197
2198 (define_insn "*pushsf"
2199   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2200         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2201   "!TARGET_64BIT"
2202 {
2203   switch (which_alternative)
2204     {
2205     case 1:
2206       return "push{l}\t%1";
2207
2208     default:
2209       /* This insn should be already split before reg-stack.  */
2210       abort ();
2211     }
2212 }
2213   [(set_attr "type" "multi,push,multi")
2214    (set_attr "mode" "SF,SI,SF")])
2215
2216 (define_insn "*pushsf_rex64"
2217   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2218         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2219   "TARGET_64BIT"
2220 {
2221   switch (which_alternative)
2222     {
2223     case 1:
2224       return "push{q}\t%q1";
2225
2226     default:
2227       /* This insn should be already split before reg-stack.  */
2228       abort ();
2229     }
2230 }
2231   [(set_attr "type" "multi,push,multi")
2232    (set_attr "mode" "SF,DI,SF")])
2233
2234 (define_split
2235   [(set (match_operand:SF 0 "push_operand" "")
2236         (match_operand:SF 1 "memory_operand" ""))]
2237   "reload_completed
2238    && GET_CODE (operands[1]) == MEM
2239    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2240    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2241   [(set (match_dup 0)
2242         (match_dup 1))]
2243   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2244
2245
2246 ;; %%% Kill this when call knows how to work this out.
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "any_fp_register_operand" ""))]
2250   "!TARGET_64BIT"
2251   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2252    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2253
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "any_fp_register_operand" ""))]
2257   "TARGET_64BIT"
2258   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2259    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2260
2261 (define_insn "*movsf_1"
2262   [(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")
2263         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2264   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2265    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2266    && (reload_in_progress || reload_completed
2267        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2268        || GET_CODE (operands[1]) != CONST_DOUBLE
2269        || memory_operand (operands[0], SFmode))" 
2270 {
2271   switch (which_alternative)
2272     {
2273     case 0:
2274       return output_387_reg_move (insn, operands);
2275
2276     case 1:
2277       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2278         return "fstp%z0\t%y0";
2279       else
2280         return "fst%z0\t%y0";
2281
2282     case 2:
2283       return standard_80387_constant_opcode (operands[1]);
2284
2285     case 3:
2286     case 4:
2287       return "mov{l}\t{%1, %0|%0, %1}";
2288     case 5:
2289       if (get_attr_mode (insn) == MODE_TI)
2290         return "pxor\t%0, %0";
2291       else
2292         return "xorps\t%0, %0";
2293     case 6:
2294       if (get_attr_mode (insn) == MODE_V4SF)
2295         return "movaps\t{%1, %0|%0, %1}";
2296       else
2297         return "movss\t{%1, %0|%0, %1}";
2298     case 7:
2299     case 8:
2300       return "movss\t{%1, %0|%0, %1}";
2301
2302     case 9:
2303     case 10:
2304       return "movd\t{%1, %0|%0, %1}";
2305
2306     case 11:
2307       return "movq\t{%1, %0|%0, %1}";
2308
2309     default:
2310       abort();
2311     }
2312 }
2313   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2314    (set (attr "mode")
2315         (cond [(eq_attr "alternative" "3,4,9,10")
2316                  (const_string "SI")
2317                (eq_attr "alternative" "5")
2318                  (if_then_else
2319                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2320                                  (const_int 0))
2321                              (ne (symbol_ref "TARGET_SSE2")
2322                                  (const_int 0)))
2323                         (eq (symbol_ref "optimize_size")
2324                             (const_int 0)))
2325                    (const_string "TI")
2326                    (const_string "V4SF"))
2327                /* For architectures resolving dependencies on
2328                   whole SSE registers use APS move to break dependency
2329                   chains, otherwise use short move to avoid extra work. 
2330
2331                   Do the same for architectures resolving dependencies on
2332                   the parts.  While in DF mode it is better to always handle
2333                   just register parts, the SF mode is different due to lack
2334                   of instructions to load just part of the register.  It is
2335                   better to maintain the whole registers in single format
2336                   to avoid problems on using packed logical operations.  */
2337                (eq_attr "alternative" "6")
2338                  (if_then_else
2339                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2340                             (const_int 0))
2341                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2342                             (const_int 0)))
2343                    (const_string "V4SF")
2344                    (const_string "SF"))
2345                (eq_attr "alternative" "11")
2346                  (const_string "DI")]
2347                (const_string "SF")))])
2348
2349 (define_insn "*movsf_1_nointerunit"
2350   [(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")
2351         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2352   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2353    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2354    && (reload_in_progress || reload_completed
2355        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2356        || GET_CODE (operands[1]) != CONST_DOUBLE
2357        || memory_operand (operands[0], SFmode))" 
2358 {
2359   switch (which_alternative)
2360     {
2361     case 0:
2362       return output_387_reg_move (insn, operands);
2363
2364     case 1:
2365       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2366         return "fstp%z0\t%y0";
2367       else
2368         return "fst%z0\t%y0";
2369
2370     case 2:
2371       return standard_80387_constant_opcode (operands[1]);
2372
2373     case 3:
2374     case 4:
2375       return "mov{l}\t{%1, %0|%0, %1}";
2376     case 5:
2377       if (get_attr_mode (insn) == MODE_TI)
2378         return "pxor\t%0, %0";
2379       else
2380         return "xorps\t%0, %0";
2381     case 6:
2382       if (get_attr_mode (insn) == MODE_V4SF)
2383         return "movaps\t{%1, %0|%0, %1}";
2384       else
2385         return "movss\t{%1, %0|%0, %1}";
2386     case 7:
2387     case 8:
2388       return "movss\t{%1, %0|%0, %1}";
2389
2390     case 9:
2391     case 10:
2392       return "movd\t{%1, %0|%0, %1}";
2393
2394     case 11:
2395       return "movq\t{%1, %0|%0, %1}";
2396
2397     default:
2398       abort();
2399     }
2400 }
2401   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2402    (set (attr "mode")
2403         (cond [(eq_attr "alternative" "3,4,9,10")
2404                  (const_string "SI")
2405                (eq_attr "alternative" "5")
2406                  (if_then_else
2407                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2408                                  (const_int 0))
2409                              (ne (symbol_ref "TARGET_SSE2")
2410                                  (const_int 0)))
2411                         (eq (symbol_ref "optimize_size")
2412                             (const_int 0)))
2413                    (const_string "TI")
2414                    (const_string "V4SF"))
2415                /* For architectures resolving dependencies on
2416                   whole SSE registers use APS move to break dependency
2417                   chains, otherwise use short move to avoid extra work. 
2418
2419                   Do the same for architectures resolving dependencies on
2420                   the parts.  While in DF mode it is better to always handle
2421                   just register parts, the SF mode is different due to lack
2422                   of instructions to load just part of the register.  It is
2423                   better to maintain the whole registers in single format
2424                   to avoid problems on using packed logical operations.  */
2425                (eq_attr "alternative" "6")
2426                  (if_then_else
2427                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2428                             (const_int 0))
2429                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2430                             (const_int 0)))
2431                    (const_string "V4SF")
2432                    (const_string "SF"))
2433                (eq_attr "alternative" "11")
2434                  (const_string "DI")]
2435                (const_string "SF")))])
2436
2437 (define_insn "*swapsf"
2438   [(set (match_operand:SF 0 "register_operand" "+f")
2439         (match_operand:SF 1 "register_operand" "+f"))
2440    (set (match_dup 1)
2441         (match_dup 0))]
2442   "reload_completed || !TARGET_SSE"
2443 {
2444   if (STACK_TOP_P (operands[0]))
2445     return "fxch\t%1";
2446   else
2447     return "fxch\t%0";
2448 }
2449   [(set_attr "type" "fxch")
2450    (set_attr "mode" "SF")])
2451
2452 (define_expand "movdf"
2453   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2454         (match_operand:DF 1 "general_operand" ""))]
2455   ""
2456   "ix86_expand_move (DFmode, operands); DONE;")
2457
2458 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2459 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2460 ;; On the average, pushdf using integers can be still shorter.  Allow this
2461 ;; pattern for optimize_size too.
2462
2463 (define_insn "*pushdf_nointeger"
2464   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2465         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2466   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2467 {
2468   /* This insn should be already split before reg-stack.  */
2469   abort ();
2470 }
2471   [(set_attr "type" "multi")
2472    (set_attr "mode" "DF,SI,SI,DF")])
2473
2474 (define_insn "*pushdf_integer"
2475   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2476         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2477   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2478 {
2479   /* This insn should be already split before reg-stack.  */
2480   abort ();
2481 }
2482   [(set_attr "type" "multi")
2483    (set_attr "mode" "DF,SI,DF")])
2484
2485 ;; %%% Kill this when call knows how to work this out.
2486 (define_split
2487   [(set (match_operand:DF 0 "push_operand" "")
2488         (match_operand:DF 1 "any_fp_register_operand" ""))]
2489   "!TARGET_64BIT && reload_completed"
2490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2492   "")
2493
2494 (define_split
2495   [(set (match_operand:DF 0 "push_operand" "")
2496         (match_operand:DF 1 "any_fp_register_operand" ""))]
2497   "TARGET_64BIT && reload_completed"
2498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2500   "")
2501
2502 (define_split
2503   [(set (match_operand:DF 0 "push_operand" "")
2504         (match_operand:DF 1 "general_operand" ""))]
2505   "reload_completed"
2506   [(const_int 0)]
2507   "ix86_split_long_move (operands); DONE;")
2508
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2512
2513 (define_insn "*movdf_nointeger"
2514   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2515         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2516   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2517    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2518    && (reload_in_progress || reload_completed
2519        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2520        || GET_CODE (operands[1]) != CONST_DOUBLE
2521        || memory_operand (operands[0], DFmode))" 
2522 {
2523   switch (which_alternative)
2524     {
2525     case 0:
2526       return output_387_reg_move (insn, operands);
2527
2528     case 1:
2529       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2530         return "fstp%z0\t%y0";
2531       else
2532         return "fst%z0\t%y0";
2533
2534     case 2:
2535       return standard_80387_constant_opcode (operands[1]);
2536
2537     case 3:
2538     case 4:
2539       return "#";
2540     case 5:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "xorps\t%0, %0";
2545         case MODE_V2DF:
2546           return "xorpd\t%0, %0";
2547         case MODE_TI:
2548           return "pxor\t%0, %0";
2549         default:
2550           abort ();
2551         }
2552     case 6:
2553       switch (get_attr_mode (insn))
2554         {
2555         case MODE_V4SF:
2556           return "movaps\t{%1, %0|%0, %1}";
2557         case MODE_V2DF:
2558           return "movapd\t{%1, %0|%0, %1}";
2559         case MODE_DF:
2560           return "movsd\t{%1, %0|%0, %1}";
2561         default:
2562           abort ();
2563         }
2564     case 7:
2565       if (get_attr_mode (insn) == MODE_V2DF)
2566         return "movlpd\t{%1, %0|%0, %1}";
2567       else
2568         return "movsd\t{%1, %0|%0, %1}";
2569     case 8:
2570       return "movsd\t{%1, %0|%0, %1}";
2571
2572     default:
2573       abort();
2574     }
2575 }
2576   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2577    (set (attr "mode")
2578         (cond [(eq_attr "alternative" "3,4")
2579                  (const_string "SI")
2580                /* xorps is one byte shorter.  */
2581                (eq_attr "alternative" "5")
2582                  (cond [(ne (symbol_ref "optimize_size")
2583                             (const_int 0))
2584                           (const_string "V4SF")
2585                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2586                             (const_int 0))
2587                           (const_string "TI")]
2588                        (const_string "V2DF"))
2589                /* For architectures resolving dependencies on
2590                   whole SSE registers use APD move to break dependency
2591                   chains, otherwise use short move to avoid extra work.
2592
2593                   movaps encodes one byte shorter.  */
2594                (eq_attr "alternative" "6")
2595                  (cond
2596                   [(ne (symbol_ref "optimize_size")
2597                        (const_int 0))
2598                      (const_string "V4SF")
2599                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2600                        (const_int 0))
2601                      (const_string "V2DF")]
2602                    (const_string "DF"))
2603                /* For architectures resolving dependencies on register
2604                   parts we may avoid extra work to zero out upper part
2605                   of register.  */
2606                (eq_attr "alternative" "7")
2607                  (if_then_else
2608                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2609                        (const_int 0))
2610                    (const_string "V2DF")
2611                    (const_string "DF"))]
2612                (const_string "DF")))])
2613
2614 (define_insn "*movdf_integer"
2615   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2616         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2618    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2619    && (reload_in_progress || reload_completed
2620        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2621        || GET_CODE (operands[1]) != CONST_DOUBLE
2622        || memory_operand (operands[0], DFmode))" 
2623 {
2624   switch (which_alternative)
2625     {
2626     case 0:
2627       return output_387_reg_move (insn, operands);
2628
2629     case 1:
2630       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2631         return "fstp%z0\t%y0";
2632       else
2633         return "fst%z0\t%y0";
2634
2635     case 2:
2636       return standard_80387_constant_opcode (operands[1]);
2637
2638     case 3:
2639     case 4:
2640       return "#";
2641
2642     case 5:
2643       switch (get_attr_mode (insn))
2644         {
2645         case MODE_V4SF:
2646           return "xorps\t%0, %0";
2647         case MODE_V2DF:
2648           return "xorpd\t%0, %0";
2649         case MODE_TI:
2650           return "pxor\t%0, %0";
2651         default:
2652           abort ();
2653         }
2654     case 6:
2655       switch (get_attr_mode (insn))
2656         {
2657         case MODE_V4SF:
2658           return "movaps\t{%1, %0|%0, %1}";
2659         case MODE_V2DF:
2660           return "movapd\t{%1, %0|%0, %1}";
2661         case MODE_DF:
2662           return "movsd\t{%1, %0|%0, %1}";
2663         default:
2664           abort ();
2665         }
2666     case 7:
2667       if (get_attr_mode (insn) == MODE_V2DF)
2668         return "movlpd\t{%1, %0|%0, %1}";
2669       else
2670         return "movsd\t{%1, %0|%0, %1}";
2671     case 8:
2672       return "movsd\t{%1, %0|%0, %1}";
2673
2674     default:
2675       abort();
2676     }
2677 }
2678   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2679    (set (attr "mode")
2680         (cond [(eq_attr "alternative" "3,4")
2681                  (const_string "SI")
2682                /* xorps is one byte shorter.  */
2683                (eq_attr "alternative" "5")
2684                  (cond [(ne (symbol_ref "optimize_size")
2685                             (const_int 0))
2686                           (const_string "V4SF")
2687                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2688                             (const_int 0))
2689                           (const_string "TI")]
2690                        (const_string "V2DF"))
2691                /* For architectures resolving dependencies on
2692                   whole SSE registers use APD move to break dependency
2693                   chains, otherwise use short move to avoid extra work.  
2694
2695                   movaps encodes one byte shorter.  */
2696                (eq_attr "alternative" "6")
2697                  (cond
2698                   [(ne (symbol_ref "optimize_size")
2699                        (const_int 0))
2700                      (const_string "V4SF")
2701                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2702                        (const_int 0))
2703                      (const_string "V2DF")]
2704                    (const_string "DF"))
2705                /* For architectures resolving dependencies on register
2706                   parts we may avoid extra work to zero out upper part
2707                   of register.  */
2708                (eq_attr "alternative" "7")
2709                  (if_then_else
2710                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2711                        (const_int 0))
2712                    (const_string "V2DF")
2713                    (const_string "DF"))]
2714                (const_string "DF")))])
2715
2716 (define_split
2717   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2718         (match_operand:DF 1 "general_operand" ""))]
2719   "reload_completed
2720    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2721    && ! (ANY_FP_REG_P (operands[0]) || 
2722          (GET_CODE (operands[0]) == SUBREG
2723           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2724    && ! (ANY_FP_REG_P (operands[1]) || 
2725          (GET_CODE (operands[1]) == SUBREG
2726           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2727   [(const_int 0)]
2728   "ix86_split_long_move (operands); DONE;")
2729
2730 (define_insn "*swapdf"
2731   [(set (match_operand:DF 0 "register_operand" "+f")
2732         (match_operand:DF 1 "register_operand" "+f"))
2733    (set (match_dup 1)
2734         (match_dup 0))]
2735   "reload_completed || !TARGET_SSE2"
2736 {
2737   if (STACK_TOP_P (operands[0]))
2738     return "fxch\t%1";
2739   else
2740     return "fxch\t%0";
2741 }
2742   [(set_attr "type" "fxch")
2743    (set_attr "mode" "DF")])
2744
2745 (define_expand "movxf"
2746   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2747         (match_operand:XF 1 "general_operand" ""))]
2748   ""
2749   "ix86_expand_move (XFmode, operands); DONE;")
2750
2751 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2752 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2753 ;; Pushing using integer instructions is longer except for constants
2754 ;; and direct memory references.
2755 ;; (assuming that any given constant is pushed only once, but this ought to be
2756 ;;  handled elsewhere).
2757
2758 (define_insn "*pushxf_nointeger"
2759   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2760         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2761   "optimize_size"
2762 {
2763   /* This insn should be already split before reg-stack.  */
2764   abort ();
2765 }
2766   [(set_attr "type" "multi")
2767    (set_attr "mode" "XF,SI,SI")])
2768
2769 (define_insn "*pushxf_integer"
2770   [(set (match_operand:XF 0 "push_operand" "=<,<")
2771         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2772   "!optimize_size"
2773 {
2774   /* This insn should be already split before reg-stack.  */
2775   abort ();
2776 }
2777   [(set_attr "type" "multi")
2778    (set_attr "mode" "XF,SI")])
2779
2780 (define_split
2781   [(set (match_operand 0 "push_operand" "")
2782         (match_operand 1 "general_operand" ""))]
2783   "reload_completed
2784    && (GET_MODE (operands[0]) == XFmode
2785        || GET_MODE (operands[0]) == DFmode)
2786    && !ANY_FP_REG_P (operands[1])"
2787   [(const_int 0)]
2788   "ix86_split_long_move (operands); DONE;")
2789
2790 (define_split
2791   [(set (match_operand:XF 0 "push_operand" "")
2792         (match_operand:XF 1 "any_fp_register_operand" ""))]
2793   "!TARGET_64BIT"
2794   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2797
2798 (define_split
2799   [(set (match_operand:XF 0 "push_operand" "")
2800         (match_operand:XF 1 "any_fp_register_operand" ""))]
2801   "TARGET_64BIT"
2802   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2805
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2810   "optimize_size
2811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812    && (reload_in_progress || reload_completed
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))" 
2815 {
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2820
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2828
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2831
2832     case 3: case 4:
2833       return "#";
2834     }
2835   abort();
2836 }
2837   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2838    (set_attr "mode" "XF,XF,XF,SI,SI")])
2839
2840 (define_insn "*movxf_integer"
2841   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2842         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2843   "!optimize_size
2844    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845    && (reload_in_progress || reload_completed
2846        || GET_CODE (operands[1]) != CONST_DOUBLE
2847        || memory_operand (operands[0], XFmode))" 
2848 {
2849   switch (which_alternative)
2850     {
2851     case 0:
2852       return output_387_reg_move (insn, operands);
2853
2854     case 1:
2855       /* There is no non-popping store to memory for XFmode.  So if
2856          we need one, follow the store with a load.  */
2857       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2858         return "fstp%z0\t%y0\;fld%z0\t%y0";
2859       else
2860         return "fstp%z0\t%y0";
2861
2862     case 2:
2863       return standard_80387_constant_opcode (operands[1]);
2864
2865     case 3: case 4:
2866       return "#";
2867     }
2868   abort();
2869 }
2870   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871    (set_attr "mode" "XF,XF,XF,SI,SI")])
2872
2873 (define_split
2874   [(set (match_operand 0 "nonimmediate_operand" "")
2875         (match_operand 1 "general_operand" ""))]
2876   "reload_completed
2877    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2878    && GET_MODE (operands[0]) == XFmode
2879    && ! (ANY_FP_REG_P (operands[0]) || 
2880          (GET_CODE (operands[0]) == SUBREG
2881           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2882    && ! (ANY_FP_REG_P (operands[1]) || 
2883          (GET_CODE (operands[1]) == SUBREG
2884           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2885   [(const_int 0)]
2886   "ix86_split_long_move (operands); DONE;")
2887
2888 (define_split
2889   [(set (match_operand 0 "register_operand" "")
2890         (match_operand 1 "memory_operand" ""))]
2891   "reload_completed
2892    && GET_CODE (operands[1]) == MEM
2893    && (GET_MODE (operands[0]) == XFmode
2894        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2895    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2896    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2897   [(set (match_dup 0) (match_dup 1))]
2898 {
2899   rtx c = get_pool_constant (XEXP (operands[1], 0));
2900   rtx r = operands[0];
2901
2902   if (GET_CODE (r) == SUBREG)
2903     r = SUBREG_REG (r);
2904
2905   if (SSE_REG_P (r))
2906     {
2907       if (!standard_sse_constant_p (c))
2908         FAIL;
2909     }
2910   else if (FP_REG_P (r))
2911     {
2912       if (!standard_80387_constant_p (c))
2913         FAIL;
2914     }
2915   else if (MMX_REG_P (r))
2916     FAIL;
2917
2918   operands[1] = c;
2919 })
2920
2921 (define_insn "swapxf"
2922   [(set (match_operand:XF 0 "register_operand" "+f")
2923         (match_operand:XF 1 "register_operand" "+f"))
2924    (set (match_dup 1)
2925         (match_dup 0))]
2926   ""
2927 {
2928   if (STACK_TOP_P (operands[0]))
2929     return "fxch\t%1";
2930   else
2931     return "fxch\t%0";
2932 }
2933   [(set_attr "type" "fxch")
2934    (set_attr "mode" "XF")])
2935 \f
2936 ;; Zero extension instructions
2937
2938 (define_expand "zero_extendhisi2"
2939   [(set (match_operand:SI 0 "register_operand" "")
2940      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2941   ""
2942 {
2943   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2944     {
2945       operands[1] = force_reg (HImode, operands[1]);
2946       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2947       DONE;
2948     }
2949 })
2950
2951 (define_insn "zero_extendhisi2_and"
2952   [(set (match_operand:SI 0 "register_operand" "=r")
2953      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2954    (clobber (reg:CC FLAGS_REG))]
2955   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2956   "#"
2957   [(set_attr "type" "alu1")
2958    (set_attr "mode" "SI")])
2959
2960 (define_split
2961   [(set (match_operand:SI 0 "register_operand" "")
2962         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2966               (clobber (reg:CC FLAGS_REG))])]
2967   "")
2968
2969 (define_insn "*zero_extendhisi2_movzwl"
2970   [(set (match_operand:SI 0 "register_operand" "=r")
2971      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2972   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2973   "movz{wl|x}\t{%1, %0|%0, %1}"
2974   [(set_attr "type" "imovx")
2975    (set_attr "mode" "SI")])
2976
2977 (define_expand "zero_extendqihi2"
2978   [(parallel
2979     [(set (match_operand:HI 0 "register_operand" "")
2980        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2981      (clobber (reg:CC FLAGS_REG))])]
2982   ""
2983   "")
2984
2985 (define_insn "*zero_extendqihi2_and"
2986   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2987      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2988    (clobber (reg:CC FLAGS_REG))]
2989   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990   "#"
2991   [(set_attr "type" "alu1")
2992    (set_attr "mode" "HI")])
2993
2994 (define_insn "*zero_extendqihi2_movzbw_and"
2995   [(set (match_operand:HI 0 "register_operand" "=r,r")
2996      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2997    (clobber (reg:CC FLAGS_REG))]
2998   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2999   "#"
3000   [(set_attr "type" "imovx,alu1")
3001    (set_attr "mode" "HI")])
3002
3003 (define_insn "*zero_extendqihi2_movzbw"
3004   [(set (match_operand:HI 0 "register_operand" "=r")
3005      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3006   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3007   "movz{bw|x}\t{%1, %0|%0, %1}"
3008   [(set_attr "type" "imovx")
3009    (set_attr "mode" "HI")])
3010
3011 ;; For the movzbw case strip only the clobber
3012 (define_split
3013   [(set (match_operand:HI 0 "register_operand" "")
3014         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3015    (clobber (reg:CC FLAGS_REG))]
3016   "reload_completed 
3017    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3018    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3019   [(set (match_operand:HI 0 "register_operand" "")
3020         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3021
3022 ;; When source and destination does not overlap, clear destination
3023 ;; first and then do the movb
3024 (define_split
3025   [(set (match_operand:HI 0 "register_operand" "")
3026         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3027    (clobber (reg:CC FLAGS_REG))]
3028   "reload_completed
3029    && ANY_QI_REG_P (operands[0])
3030    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3031    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3032   [(set (match_dup 0) (const_int 0))
3033    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3034   "operands[2] = gen_lowpart (QImode, operands[0]);")
3035
3036 ;; Rest is handled by single and.
3037 (define_split
3038   [(set (match_operand:HI 0 "register_operand" "")
3039         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3040    (clobber (reg:CC FLAGS_REG))]
3041   "reload_completed
3042    && true_regnum (operands[0]) == true_regnum (operands[1])"
3043   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3044               (clobber (reg:CC FLAGS_REG))])]
3045   "")
3046
3047 (define_expand "zero_extendqisi2"
3048   [(parallel
3049     [(set (match_operand:SI 0 "register_operand" "")
3050        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3051      (clobber (reg:CC FLAGS_REG))])]
3052   ""
3053   "")
3054
3055 (define_insn "*zero_extendqisi2_and"
3056   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3057      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3060   "#"
3061   [(set_attr "type" "alu1")
3062    (set_attr "mode" "SI")])
3063
3064 (define_insn "*zero_extendqisi2_movzbw_and"
3065   [(set (match_operand:SI 0 "register_operand" "=r,r")
3066      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3069   "#"
3070   [(set_attr "type" "imovx,alu1")
3071    (set_attr "mode" "SI")])
3072
3073 (define_insn "*zero_extendqisi2_movzbw"
3074   [(set (match_operand:SI 0 "register_operand" "=r")
3075      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3076   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3077   "movz{bl|x}\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx")
3079    (set_attr "mode" "SI")])
3080
3081 ;; For the movzbl case strip only the clobber
3082 (define_split
3083   [(set (match_operand:SI 0 "register_operand" "")
3084         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3085    (clobber (reg:CC FLAGS_REG))]
3086   "reload_completed 
3087    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3088    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3089   [(set (match_dup 0)
3090         (zero_extend:SI (match_dup 1)))])
3091
3092 ;; When source and destination does not overlap, clear destination
3093 ;; first and then do the movb
3094 (define_split
3095   [(set (match_operand:SI 0 "register_operand" "")
3096         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3097    (clobber (reg:CC FLAGS_REG))]
3098   "reload_completed
3099    && ANY_QI_REG_P (operands[0])
3100    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3101    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3103   [(set (match_dup 0) (const_int 0))
3104    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3105   "operands[2] = gen_lowpart (QImode, operands[0]);")
3106
3107 ;; Rest is handled by single and.
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed
3113    && true_regnum (operands[0]) == true_regnum (operands[1])"
3114   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3115               (clobber (reg:CC FLAGS_REG))])]
3116   "")
3117
3118 ;; %%% Kill me once multi-word ops are sane.
3119 (define_expand "zero_extendsidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r")
3121      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3122   ""
3123   "if (!TARGET_64BIT)
3124      {
3125        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3126        DONE;
3127      }
3128   ")
3129
3130 (define_insn "zero_extendsidi2_32"
3131   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3132         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3133    (clobber (reg:CC FLAGS_REG))]
3134   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3135   "@
3136    #
3137    #
3138    #
3139    movd\t{%1, %0|%0, %1}
3140    movd\t{%1, %0|%0, %1}"
3141   [(set_attr "mode" "SI,SI,SI,DI,TI")
3142    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3143
3144 (define_insn "*zero_extendsidi2_32_1"
3145   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3146         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3149   "@
3150    #
3151    #
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "mode" "SI,SI,SI,DI,TI")
3156    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3157
3158 (define_insn "zero_extendsidi2_rex64"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3160      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3161   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3162   "@
3163    mov\t{%k1, %k0|%k0, %k1}
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168    (set_attr "mode" "SI,DI,DI,TI")])
3169
3170 (define_insn "*zero_extendsidi2_rex64_1"
3171   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3172      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3173   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3174   "@
3175    mov\t{%k1, %k0|%k0, %k1}
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3180    (set_attr "mode" "SI,DI,SI,SI")])
3181
3182 (define_split
3183   [(set (match_operand:DI 0 "memory_operand" "")
3184      (zero_extend:DI (match_dup 0)))]
3185   "TARGET_64BIT"
3186   [(set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_split 
3190   [(set (match_operand:DI 0 "register_operand" "")
3191         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192    (clobber (reg:CC FLAGS_REG))]
3193   "!TARGET_64BIT && reload_completed
3194    && true_regnum (operands[0]) == true_regnum (operands[1])"
3195   [(set (match_dup 4) (const_int 0))]
3196   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197
3198 (define_split 
3199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3200         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201    (clobber (reg:CC FLAGS_REG))]
3202   "!TARGET_64BIT && reload_completed
3203    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3204   [(set (match_dup 3) (match_dup 1))
3205    (set (match_dup 4) (const_int 0))]
3206   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3207
3208 (define_insn "zero_extendhidi2"
3209   [(set (match_operand:DI 0 "register_operand" "=r,r")
3210      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3211   "TARGET_64BIT"
3212   "@
3213    movz{wl|x}\t{%1, %k0|%k0, %1}
3214    movz{wq|x}\t{%1, %0|%0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "SI,DI")])
3217
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r,r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3221   "TARGET_64BIT"
3222   "@
3223    movz{bl|x}\t{%1, %k0|%k0, %1}
3224    movz{bq|x}\t{%1, %0|%0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "SI,DI")])
3227 \f
3228 ;; Sign extension instructions
3229
3230 (define_expand "extendsidi2"
3231   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3232                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3233               (clobber (reg:CC FLAGS_REG))
3234               (clobber (match_scratch:SI 2 ""))])]
3235   ""
3236 {
3237   if (TARGET_64BIT)
3238     {
3239       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3240       DONE;
3241     }
3242 })
3243
3244 (define_insn "*extendsidi2_1"
3245   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3246         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3247    (clobber (reg:CC FLAGS_REG))
3248    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3249   "!TARGET_64BIT"
3250   "#")
3251
3252 (define_insn "extendsidi2_rex64"
3253   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3254         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3255   "TARGET_64BIT"
3256   "@
3257    {cltq|cdqe}
3258    movs{lq|x}\t{%1,%0|%0, %1}"
3259   [(set_attr "type" "imovx")
3260    (set_attr "mode" "DI")
3261    (set_attr "prefix_0f" "0")
3262    (set_attr "modrm" "0,1")])
3263
3264 (define_insn "extendhidi2"
3265   [(set (match_operand:DI 0 "register_operand" "=r")
3266         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3267   "TARGET_64BIT"
3268   "movs{wq|x}\t{%1,%0|%0, %1}"
3269   [(set_attr "type" "imovx")
3270    (set_attr "mode" "DI")])
3271
3272 (define_insn "extendqidi2"
3273   [(set (match_operand:DI 0 "register_operand" "=r")
3274         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3275   "TARGET_64BIT"
3276   "movs{bq|x}\t{%1,%0|%0, %1}"
3277    [(set_attr "type" "imovx")
3278     (set_attr "mode" "DI")])
3279
3280 ;; Extend to memory case when source register does die.
3281 (define_split 
3282   [(set (match_operand:DI 0 "memory_operand" "")
3283         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))
3285    (clobber (match_operand:SI 2 "register_operand" ""))]
3286   "(reload_completed
3287     && dead_or_set_p (insn, operands[1])
3288     && !reg_mentioned_p (operands[1], operands[0]))"
3289   [(set (match_dup 3) (match_dup 1))
3290    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3291               (clobber (reg:CC FLAGS_REG))])
3292    (set (match_dup 4) (match_dup 1))]
3293   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3294
3295 ;; Extend to memory case when source register does not die.
3296 (define_split 
3297   [(set (match_operand:DI 0 "memory_operand" "")
3298         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))
3300    (clobber (match_operand:SI 2 "register_operand" ""))]
3301   "reload_completed"
3302   [(const_int 0)]
3303 {
3304   split_di (&operands[0], 1, &operands[3], &operands[4]);
3305
3306   emit_move_insn (operands[3], operands[1]);
3307
3308   /* Generate a cltd if possible and doing so it profitable.  */
3309   if (true_regnum (operands[1]) == 0
3310       && true_regnum (operands[2]) == 1
3311       && (optimize_size || TARGET_USE_CLTD))
3312     {
3313       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3314     }
3315   else
3316     {
3317       emit_move_insn (operands[2], operands[1]);
3318       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3319     }
3320   emit_move_insn (operands[4], operands[2]);
3321   DONE;
3322 })
3323
3324 ;; Extend to register case.  Optimize case where source and destination
3325 ;; registers match and cases where we can use cltd.
3326 (define_split 
3327   [(set (match_operand:DI 0 "register_operand" "")
3328         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329    (clobber (reg:CC FLAGS_REG))
3330    (clobber (match_scratch:SI 2 ""))]
3331   "reload_completed"
3332   [(const_int 0)]
3333 {
3334   split_di (&operands[0], 1, &operands[3], &operands[4]);
3335
3336   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3337     emit_move_insn (operands[3], operands[1]);
3338
3339   /* Generate a cltd if possible and doing so it profitable.  */
3340   if (true_regnum (operands[3]) == 0
3341       && (optimize_size || TARGET_USE_CLTD))
3342     {
3343       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3344       DONE;
3345     }
3346
3347   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3348     emit_move_insn (operands[4], operands[1]);
3349
3350   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3351   DONE;
3352 })
3353
3354 (define_insn "extendhisi2"
3355   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3356         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3357   ""
3358 {
3359   switch (get_attr_prefix_0f (insn))
3360     {
3361     case 0:
3362       return "{cwtl|cwde}";
3363     default:
3364       return "movs{wl|x}\t{%1,%0|%0, %1}";
3365     }
3366 }
3367   [(set_attr "type" "imovx")
3368    (set_attr "mode" "SI")
3369    (set (attr "prefix_0f")
3370      ;; movsx is short decodable while cwtl is vector decoded.
3371      (if_then_else (and (eq_attr "cpu" "!k6")
3372                         (eq_attr "alternative" "0"))
3373         (const_string "0")
3374         (const_string "1")))
3375    (set (attr "modrm")
3376      (if_then_else (eq_attr "prefix_0f" "0")
3377         (const_string "0")
3378         (const_string "1")))])
3379
3380 (define_insn "*extendhisi2_zext"
3381   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3382         (zero_extend:DI
3383           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3384   "TARGET_64BIT"
3385 {
3386   switch (get_attr_prefix_0f (insn))
3387     {
3388     case 0:
3389       return "{cwtl|cwde}";
3390     default:
3391       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3392     }
3393 }
3394   [(set_attr "type" "imovx")
3395    (set_attr "mode" "SI")
3396    (set (attr "prefix_0f")
3397      ;; movsx is short decodable while cwtl is vector decoded.
3398      (if_then_else (and (eq_attr "cpu" "!k6")
3399                         (eq_attr "alternative" "0"))
3400         (const_string "0")
3401         (const_string "1")))
3402    (set (attr "modrm")
3403      (if_then_else (eq_attr "prefix_0f" "0")
3404         (const_string "0")
3405         (const_string "1")))])
3406
3407 (define_insn "extendqihi2"
3408   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3409         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3410   ""
3411 {
3412   switch (get_attr_prefix_0f (insn))
3413     {
3414     case 0:
3415       return "{cbtw|cbw}";
3416     default:
3417       return "movs{bw|x}\t{%1,%0|%0, %1}";
3418     }
3419 }
3420   [(set_attr "type" "imovx")
3421    (set_attr "mode" "HI")
3422    (set (attr "prefix_0f")
3423      ;; movsx is short decodable while cwtl is vector decoded.
3424      (if_then_else (and (eq_attr "cpu" "!k6")
3425                         (eq_attr "alternative" "0"))
3426         (const_string "0")
3427         (const_string "1")))
3428    (set (attr "modrm")
3429      (if_then_else (eq_attr "prefix_0f" "0")
3430         (const_string "0")
3431         (const_string "1")))])
3432
3433 (define_insn "extendqisi2"
3434   [(set (match_operand:SI 0 "register_operand" "=r")
3435         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3436   ""
3437   "movs{bl|x}\t{%1,%0|%0, %1}"
3438    [(set_attr "type" "imovx")
3439     (set_attr "mode" "SI")])
3440
3441 (define_insn "*extendqisi2_zext"
3442   [(set (match_operand:DI 0 "register_operand" "=r")
3443         (zero_extend:DI
3444           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3445   "TARGET_64BIT"
3446   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3447    [(set_attr "type" "imovx")
3448     (set_attr "mode" "SI")])
3449 \f
3450 ;; Conversions between float and double.
3451
3452 ;; These are all no-ops in the model used for the 80387.  So just
3453 ;; emit moves.
3454
3455 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3456 (define_insn "*dummy_extendsfdf2"
3457   [(set (match_operand:DF 0 "push_operand" "=<")
3458         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3459   "0"
3460   "#")
3461
3462 (define_split
3463   [(set (match_operand:DF 0 "push_operand" "")
3464         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3465   "!TARGET_64BIT"
3466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3467    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3468
3469 (define_split
3470   [(set (match_operand:DF 0 "push_operand" "")
3471         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3472   "TARGET_64BIT"
3473   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3474    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3475
3476 (define_insn "*dummy_extendsfxf2"
3477   [(set (match_operand:XF 0 "push_operand" "=<")
3478         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3479   "0"
3480   "#")
3481
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3485   ""
3486   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3487    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_split
3491   [(set (match_operand:XF 0 "push_operand" "")
3492         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3493   "TARGET_64BIT"
3494   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3495    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3496   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_split
3499   [(set (match_operand:XF 0 "push_operand" "")
3500         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3501   ""
3502   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3503    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3504   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505
3506 (define_split
3507   [(set (match_operand:XF 0 "push_operand" "")
3508         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3509   "TARGET_64BIT"
3510   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3511    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3512   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513
3514 (define_expand "extendsfdf2"
3515   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3516         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3517   "TARGET_80387 || TARGET_SSE2"
3518 {
3519   /* ??? Needed for compress_float_constant since all fp constants
3520      are LEGITIMATE_CONSTANT_P.  */
3521   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3522     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3523   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3524     operands[1] = force_reg (SFmode, operands[1]);
3525 })
3526
3527 (define_insn "*extendsfdf2_1"
3528   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3529         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3530   "(TARGET_80387 || TARGET_SSE2)
3531    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3532 {
3533   switch (which_alternative)
3534     {
3535     case 0:
3536       return output_387_reg_move (insn, operands);
3537
3538     case 1:
3539       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3540         return "fstp%z0\t%y0";
3541       else
3542         return "fst%z0\t%y0";
3543
3544     case 2:
3545       return "cvtss2sd\t{%1, %0|%0, %1}";
3546
3547     default:
3548       abort ();
3549     }
3550 }
3551   [(set_attr "type" "fmov,fmov,ssecvt")
3552    (set_attr "mode" "SF,XF,DF")])
3553
3554 (define_insn "*extendsfdf2_1_sse_only"
3555   [(set (match_operand:DF 0 "register_operand" "=Y")
3556         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3557   "!TARGET_80387 && TARGET_SSE2
3558    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3559   "cvtss2sd\t{%1, %0|%0, %1}"
3560   [(set_attr "type" "ssecvt")
3561    (set_attr "mode" "DF")])
3562
3563 (define_expand "extendsfxf2"
3564   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3565         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3566   "TARGET_80387"
3567 {
3568   /* ??? Needed for compress_float_constant since all fp constants
3569      are LEGITIMATE_CONSTANT_P.  */
3570   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3571     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3572   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3573     operands[1] = force_reg (SFmode, operands[1]);
3574 })
3575
3576 (define_insn "*extendsfxf2_1"
3577   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3578         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579   "TARGET_80387
3580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581 {
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return output_387_reg_move (insn, operands);
3586
3587     case 1:
3588       /* There is no non-popping store to memory for XFmode.  So if
3589          we need one, follow the store with a load.  */
3590       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3591         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3592       else
3593         return "fstp%z0\t%y0";
3594
3595     default:
3596       abort ();
3597     }
3598 }
3599   [(set_attr "type" "fmov")
3600    (set_attr "mode" "SF,XF")])
3601
3602 (define_expand "extenddfxf2"
3603   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3604         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3605   "TARGET_80387"
3606 {
3607   /* ??? Needed for compress_float_constant since all fp constants
3608      are LEGITIMATE_CONSTANT_P.  */
3609   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3610     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3611   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3612     operands[1] = force_reg (DFmode, operands[1]);
3613 })
3614
3615 (define_insn "*extenddfxf2_1"
3616   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3618   "TARGET_80387
3619    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3620 {
3621   switch (which_alternative)
3622     {
3623     case 0:
3624       return output_387_reg_move (insn, operands);
3625
3626     case 1:
3627       /* There is no non-popping store to memory for XFmode.  So if
3628          we need one, follow the store with a load.  */
3629       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3630         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3631       else
3632         return "fstp%z0\t%y0";
3633
3634     default:
3635       abort ();
3636     }
3637 }
3638   [(set_attr "type" "fmov")
3639    (set_attr "mode" "DF,XF")])
3640
3641 ;; %%% This seems bad bad news.
3642 ;; This cannot output into an f-reg because there is no way to be sure
3643 ;; of truncating in that case.  Otherwise this is just like a simple move
3644 ;; insn.  So we pretend we can output to a reg in order to get better
3645 ;; register preferencing, but we really use a stack slot.
3646
3647 (define_expand "truncdfsf2"
3648   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3649                    (float_truncate:SF
3650                     (match_operand:DF 1 "register_operand" "")))
3651               (clobber (match_dup 2))])]
3652   "TARGET_80387 || TARGET_SSE2"
3653   "
3654    if (!TARGET_80387)
3655      {
3656         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3657         DONE;
3658      }
3659    else if (flag_unsafe_math_optimizations)
3660      {
3661         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3662         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3663         if (reg != operands[0])
3664           emit_move_insn (operands[0], reg);
3665         DONE;
3666      }
3667    else
3668      operands[2] = assign_386_stack_local (SFmode, 0);
3669 ")
3670
3671 (define_insn "truncdfsf2_noop"
3672   [(set (match_operand:SF 0 "register_operand" "=f")
3673         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3674   "TARGET_80387 && flag_unsafe_math_optimizations"
3675 {
3676   return output_387_reg_move (insn, operands);
3677 }
3678   [(set_attr "type" "fmov")
3679    (set_attr "mode" "SF")])
3680
3681 (define_insn "*truncdfsf2_1"
3682   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3683         (float_truncate:SF
3684          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3685    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3686   "TARGET_80387 && !TARGET_SSE2"
3687 {
3688   switch (which_alternative)
3689     {
3690     case 0:
3691       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3692         return "fstp%z0\t%y0";
3693       else
3694         return "fst%z0\t%y0";
3695     default:
3696       abort ();
3697     }
3698 }
3699   [(set_attr "type" "fmov,multi,multi,multi")
3700    (set_attr "mode" "SF,SF,SF,SF")])
3701
3702 (define_insn "*truncdfsf2_1_sse"
3703   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3704         (float_truncate:SF
3705          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3706    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3707   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3708 {
3709   switch (which_alternative)
3710     {
3711     case 0:
3712       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3713         return "fstp%z0\t%y0";
3714       else
3715         return "fst%z0\t%y0";
3716     case 4:
3717       return "#";
3718     default:
3719       abort ();
3720     }
3721 }
3722   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3723    (set_attr "mode" "SF,SF,SF,SF,DF")])
3724
3725 (define_insn "*truncdfsf2_1_sse_nooverlap"
3726   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3727         (float_truncate:SF
3728          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3729    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3730   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3731 {
3732   switch (which_alternative)
3733     {
3734     case 0:
3735       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736         return "fstp%z0\t%y0";
3737       else
3738         return "fst%z0\t%y0";
3739     case 4:
3740       return "#";
3741     default:
3742       abort ();
3743     }
3744 }
3745   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3746    (set_attr "mode" "SF,SF,SF,SF,DF")])
3747
3748 (define_insn "*truncdfsf2_2"
3749   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3750         (float_truncate:SF
3751          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3752   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3753    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3754 {
3755   switch (which_alternative)
3756     {
3757     case 0:
3758     case 1:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     case 2:
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,ssecvt,fmov")
3770    (set_attr "athlon_decode" "vector,double,*")
3771    (set_attr "mode" "SF,SF,SF")])
3772
3773 (define_insn "*truncdfsf2_2_nooverlap"
3774   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3775         (float_truncate:SF
3776          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3777   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3778    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3779 {
3780   switch (which_alternative)
3781     {
3782     case 0:
3783       return "#";
3784     case 1:
3785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786         return "fstp%z0\t%y0";
3787       else
3788         return "fst%z0\t%y0";
3789     default:
3790       abort ();
3791     }
3792 }
3793   [(set_attr "type" "ssecvt,fmov")
3794    (set_attr "mode" "DF,SF")])
3795
3796 (define_insn "*truncdfsf2_3"
3797   [(set (match_operand:SF 0 "memory_operand" "=m")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "register_operand" "f")))]
3800   "TARGET_80387"
3801 {
3802   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3803     return "fstp%z0\t%y0";
3804   else
3805     return "fst%z0\t%y0";
3806 }
3807   [(set_attr "type" "fmov")
3808    (set_attr "mode" "SF")])
3809
3810 (define_insn "truncdfsf2_sse_only"
3811   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3812         (float_truncate:SF
3813          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3814   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3815   "cvtsd2ss\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "athlon_decode" "vector,double")
3818    (set_attr "mode" "SF")])
3819
3820 (define_insn "*truncdfsf2_sse_only_nooverlap"
3821   [(set (match_operand:SF 0 "register_operand" "=&Y")
3822         (float_truncate:SF
3823          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3824   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3825   "#"
3826   [(set_attr "type" "ssecvt")
3827    (set_attr "mode" "DF")])
3828
3829 (define_split
3830   [(set (match_operand:SF 0 "memory_operand" "")
3831         (float_truncate:SF
3832          (match_operand:DF 1 "register_operand" "")))
3833    (clobber (match_operand:SF 2 "memory_operand" ""))]
3834   "TARGET_80387"
3835   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3836   "")
3837
3838 ; Avoid possible reformatting penalty on the destination by first
3839 ; zeroing it out
3840 (define_split
3841   [(set (match_operand:SF 0 "register_operand" "")
3842         (float_truncate:SF
3843          (match_operand:DF 1 "nonimmediate_operand" "")))
3844    (clobber (match_operand 2 "" ""))]
3845   "TARGET_80387 && reload_completed
3846    && SSE_REG_P (operands[0])
3847    && !STACK_REG_P (operands[1])"
3848   [(const_int 0)]
3849 {
3850   rtx src, dest;
3851   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3852     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3853   else
3854     {
3855       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3856       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3857       /* simplify_gen_subreg refuses to widen memory references.  */
3858       if (GET_CODE (src) == SUBREG)
3859         alter_subreg (&src);
3860       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3861         abort ();
3862       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3863       emit_insn (gen_cvtsd2ss (dest, dest, src));
3864     }
3865   DONE;
3866 })
3867
3868 (define_split
3869   [(set (match_operand:SF 0 "register_operand" "")
3870         (float_truncate:SF
3871          (match_operand:DF 1 "nonimmediate_operand" "")))]
3872   "TARGET_80387 && reload_completed
3873    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3874   [(const_int 0)]
3875 {
3876   rtx src, dest;
3877   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3878   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3879   /* simplify_gen_subreg refuses to widen memory references.  */
3880   if (GET_CODE (src) == SUBREG)
3881     alter_subreg (&src);
3882   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3883     abort ();
3884   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3885   emit_insn (gen_cvtsd2ss (dest, dest, src));
3886   DONE;
3887 })
3888
3889 (define_split
3890   [(set (match_operand:SF 0 "register_operand" "")
3891         (float_truncate:SF
3892          (match_operand:DF 1 "fp_register_operand" "")))
3893    (clobber (match_operand:SF 2 "memory_operand" ""))]
3894   "TARGET_80387 && reload_completed"
3895   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3896    (set (match_dup 0) (match_dup 2))]
3897   "")
3898
3899 (define_expand "truncxfsf2"
3900   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3901                    (float_truncate:SF
3902                     (match_operand:XF 1 "register_operand" "")))
3903               (clobber (match_dup 2))])]
3904   "TARGET_80387"
3905   "
3906   if (flag_unsafe_math_optimizations)
3907     {
3908       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3909       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3910       if (reg != operands[0])
3911         emit_move_insn (operands[0], reg);
3912       DONE;
3913     }
3914   else
3915     operands[2] = assign_386_stack_local (SFmode, 0);
3916   ")
3917
3918 (define_insn "truncxfsf2_noop"
3919   [(set (match_operand:SF 0 "register_operand" "=f")
3920         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387 && flag_unsafe_math_optimizations"
3922 {
3923   return output_387_reg_move (insn, operands);
3924 }
3925   [(set_attr "type" "fmov")
3926    (set_attr "mode" "SF")])
3927
3928 (define_insn "*truncxfsf2_1"
3929   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3932    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3933   "TARGET_80387"
3934 {
3935   switch (which_alternative)
3936     {
3937     case 0:
3938       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939         return "fstp%z0\t%y0";
3940       else
3941         return "fst%z0\t%y0";
3942     default:
3943       abort();
3944     }
3945 }
3946   [(set_attr "type" "fmov,multi,multi,multi")
3947    (set_attr "mode" "SF")])
3948
3949 (define_insn "*truncxfsf2_2"
3950   [(set (match_operand:SF 0 "memory_operand" "=m")
3951         (float_truncate:SF
3952          (match_operand:XF 1 "register_operand" "f")))]
3953   "TARGET_80387"
3954 {
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 }
3960   [(set_attr "type" "fmov")
3961    (set_attr "mode" "SF")])
3962
3963 (define_split
3964   [(set (match_operand:SF 0 "memory_operand" "")
3965         (float_truncate:SF
3966          (match_operand:XF 1 "register_operand" "")))
3967    (clobber (match_operand:SF 2 "memory_operand" ""))]
3968   "TARGET_80387"
3969   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3970   "")
3971
3972 (define_split
3973   [(set (match_operand:SF 0 "register_operand" "")
3974         (float_truncate:SF
3975          (match_operand:XF 1 "register_operand" "")))
3976    (clobber (match_operand:SF 2 "memory_operand" ""))]
3977   "TARGET_80387 && reload_completed"
3978   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3979    (set (match_dup 0) (match_dup 2))]
3980   "")
3981
3982 (define_expand "truncxfdf2"
3983   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3984                    (float_truncate:DF
3985                     (match_operand:XF 1 "register_operand" "")))
3986               (clobber (match_dup 2))])]
3987   "TARGET_80387"
3988   "
3989   if (flag_unsafe_math_optimizations)
3990     {
3991       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3992       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3993       if (reg != operands[0])
3994         emit_move_insn (operands[0], reg);
3995       DONE;
3996     }
3997   else
3998     operands[2] = assign_386_stack_local (DFmode, 0);
3999   ")
4000
4001 (define_insn "truncxfdf2_noop"
4002   [(set (match_operand:DF 0 "register_operand" "=f")
4003         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4004   "TARGET_80387 && flag_unsafe_math_optimizations"
4005 {
4006   return output_387_reg_move (insn, operands);
4007 }
4008   [(set_attr "type" "fmov")
4009    (set_attr "mode" "DF")])
4010
4011 (define_insn "*truncxfdf2_1"
4012   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4015    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4016   "TARGET_80387"
4017 {
4018   switch (which_alternative)
4019     {
4020     case 0:
4021       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022         return "fstp%z0\t%y0";
4023       else
4024         return "fst%z0\t%y0";
4025     default:
4026       abort();
4027     }
4028   abort ();
4029 }
4030   [(set_attr "type" "fmov,multi,multi,multi")
4031    (set_attr "mode" "DF")])
4032
4033 (define_insn "*truncxfdf2_2"
4034   [(set (match_operand:DF 0 "memory_operand" "=m")
4035         (float_truncate:DF
4036           (match_operand:XF 1 "register_operand" "f")))]
4037   "TARGET_80387"
4038 {
4039   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4040     return "fstp%z0\t%y0";
4041   else
4042     return "fst%z0\t%y0";
4043 }
4044   [(set_attr "type" "fmov")
4045    (set_attr "mode" "DF")])
4046
4047 (define_split
4048   [(set (match_operand:DF 0 "memory_operand" "")
4049         (float_truncate:DF
4050          (match_operand:XF 1 "register_operand" "")))
4051    (clobber (match_operand:DF 2 "memory_operand" ""))]
4052   "TARGET_80387"
4053   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4054   "")
4055
4056 (define_split
4057   [(set (match_operand:DF 0 "register_operand" "")
4058         (float_truncate:DF
4059          (match_operand:XF 1 "register_operand" "")))
4060    (clobber (match_operand:DF 2 "memory_operand" ""))]
4061   "TARGET_80387 && reload_completed"
4062   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4063    (set (match_dup 0) (match_dup 2))]
4064   "")
4065
4066 \f
4067 ;; %%% Break up all these bad boys.
4068
4069 ;; Signed conversion to DImode.
4070
4071 (define_expand "fix_truncxfdi2"
4072   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4073                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4074               (clobber (reg:CC FLAGS_REG))])]
4075   "TARGET_80387"
4076   "")
4077
4078 (define_expand "fix_truncdfdi2"
4079   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4083 {
4084   if (TARGET_64BIT && TARGET_SSE2)
4085    {
4086      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4087      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4088      if (out != operands[0])
4089         emit_move_insn (operands[0], out);
4090      DONE;
4091    }
4092 })
4093
4094 (define_expand "fix_truncsfdi2"
4095   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4096                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4097               (clobber (reg:CC FLAGS_REG))])] 
4098   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4099 {
4100   if (TARGET_SSE && TARGET_64BIT)
4101    {
4102      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4103      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4104      if (out != operands[0])
4105         emit_move_insn (operands[0], out);
4106      DONE;
4107    }
4108 })
4109
4110 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4111 ;; of the machinery.
4112 (define_insn_and_split "*fix_truncdi_1"
4113   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4114         (fix:DI (match_operand 1 "register_operand" "f,f")))
4115    (clobber (reg:CC FLAGS_REG))]
4116   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4117    && !reload_completed && !reload_in_progress
4118    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4119   "#"
4120   "&& 1"
4121   [(const_int 0)]
4122 {
4123   ix86_optimize_mode_switching = 1;
4124   operands[2] = assign_386_stack_local (HImode, 1);
4125   operands[3] = assign_386_stack_local (HImode, 2);
4126   if (memory_operand (operands[0], VOIDmode))
4127     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4128                                        operands[2], operands[3]));
4129   else
4130     {
4131       operands[4] = assign_386_stack_local (DImode, 0);
4132       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4133                                            operands[2], operands[3],
4134                                            operands[4]));
4135     }
4136   DONE;
4137 }
4138   [(set_attr "type" "fistp")
4139    (set_attr "i387_cw" "trunc")
4140    (set_attr "mode" "DI")])
4141
4142 (define_insn "fix_truncdi_nomemory"
4143   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4144         (fix:DI (match_operand 1 "register_operand" "f,f")))
4145    (use (match_operand:HI 2 "memory_operand" "m,m"))
4146    (use (match_operand:HI 3 "memory_operand" "m,m"))
4147    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4148    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4149   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4150    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4151   "#"
4152   [(set_attr "type" "fistp")
4153    (set_attr "i387_cw" "trunc")
4154    (set_attr "mode" "DI")])
4155
4156 (define_insn "fix_truncdi_memory"
4157   [(set (match_operand:DI 0 "memory_operand" "=m")
4158         (fix:DI (match_operand 1 "register_operand" "f")))
4159    (use (match_operand:HI 2 "memory_operand" "m"))
4160    (use (match_operand:HI 3 "memory_operand" "m"))
4161    (clobber (match_scratch:DF 4 "=&1f"))]
4162   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4163    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4164   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4165   [(set_attr "type" "fistp")
4166    (set_attr "i387_cw" "trunc")
4167    (set_attr "mode" "DI")])
4168
4169 (define_split 
4170   [(set (match_operand:DI 0 "register_operand" "")
4171         (fix:DI (match_operand 1 "register_operand" "")))
4172    (use (match_operand:HI 2 "memory_operand" ""))
4173    (use (match_operand:HI 3 "memory_operand" ""))
4174    (clobber (match_operand:DI 4 "memory_operand" ""))
4175    (clobber (match_scratch 5 ""))]
4176   "reload_completed"
4177   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4178               (use (match_dup 2))
4179               (use (match_dup 3))
4180               (clobber (match_dup 5))])
4181    (set (match_dup 0) (match_dup 4))]
4182   "")
4183
4184 (define_split 
4185   [(set (match_operand:DI 0 "memory_operand" "")
4186         (fix:DI (match_operand 1 "register_operand" "")))
4187    (use (match_operand:HI 2 "memory_operand" ""))
4188    (use (match_operand:HI 3 "memory_operand" ""))
4189    (clobber (match_operand:DI 4 "memory_operand" ""))
4190    (clobber (match_scratch 5 ""))]
4191   "reload_completed"
4192   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4193               (use (match_dup 2))
4194               (use (match_dup 3))
4195               (clobber (match_dup 5))])]
4196   "")
4197
4198 ;; When SSE available, it is always faster to use it!
4199 (define_insn "fix_truncsfdi_sse"
4200   [(set (match_operand:DI 0 "register_operand" "=r,r")
4201         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4202   "TARGET_64BIT && TARGET_SSE"
4203   "cvttss2si{q}\t{%1, %0|%0, %1}"
4204   [(set_attr "type" "sseicvt")
4205    (set_attr "mode" "SF")
4206    (set_attr "athlon_decode" "double,vector")])
4207
4208 ;; Avoid vector decoded form of the instruction.
4209 (define_peephole2
4210   [(match_scratch:SF 2 "x")
4211    (set (match_operand:DI 0 "register_operand" "")
4212         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4213   "TARGET_K8 && !optimize_size"
4214   [(set (match_dup 2) (match_dup 1))
4215    (set (match_dup 0) (fix:DI (match_dup 2)))]
4216   "")
4217
4218 (define_insn "fix_truncdfdi_sse"
4219   [(set (match_operand:DI 0 "register_operand" "=r,r")
4220         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4221   "TARGET_64BIT && TARGET_SSE2"
4222   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4223   [(set_attr "type" "sseicvt,sseicvt")
4224    (set_attr "mode" "DF")
4225    (set_attr "athlon_decode" "double,vector")])
4226
4227 ;; Avoid vector decoded form of the instruction.
4228 (define_peephole2
4229   [(match_scratch:DF 2 "Y")
4230    (set (match_operand:DI 0 "register_operand" "")
4231         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4232   "TARGET_K8 && !optimize_size"
4233   [(set (match_dup 2) (match_dup 1))
4234    (set (match_dup 0) (fix:DI (match_dup 2)))]
4235   "")
4236
4237 ;; Signed conversion to SImode.
4238
4239 (define_expand "fix_truncxfsi2"
4240   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4241                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4242               (clobber (reg:CC FLAGS_REG))])]
4243   "TARGET_80387"
4244   "")
4245
4246 (define_expand "fix_truncdfsi2"
4247   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4248                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387 || TARGET_SSE2"
4251 {
4252   if (TARGET_SSE2)
4253    {
4254      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4255      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4256      if (out != operands[0])
4257         emit_move_insn (operands[0], out);
4258      DONE;
4259    }
4260 })
4261
4262 (define_expand "fix_truncsfsi2"
4263   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4265               (clobber (reg:CC FLAGS_REG))])] 
4266   "TARGET_80387 || TARGET_SSE"
4267 {
4268   if (TARGET_SSE)
4269    {
4270      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4271      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4272      if (out != operands[0])
4273         emit_move_insn (operands[0], out);
4274      DONE;
4275    }
4276 })
4277
4278 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4279 ;; of the machinery.
4280 (define_insn_and_split "*fix_truncsi_1"
4281   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4282         (fix:SI (match_operand 1 "register_operand" "f,f")))
4283    (clobber (reg:CC FLAGS_REG))]
4284   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4285    && !reload_completed && !reload_in_progress
4286    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4287   "#"
4288   "&& 1"
4289   [(const_int 0)]
4290 {
4291   ix86_optimize_mode_switching = 1;
4292   operands[2] = assign_386_stack_local (HImode, 1);
4293   operands[3] = assign_386_stack_local (HImode, 2);
4294   if (memory_operand (operands[0], VOIDmode))
4295     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4296                                        operands[2], operands[3]));
4297   else
4298     {
4299       operands[4] = assign_386_stack_local (SImode, 0);
4300       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4301                                            operands[2], operands[3],
4302                                            operands[4]));
4303     }
4304   DONE;
4305 }
4306   [(set_attr "type" "fistp")
4307    (set_attr "i387_cw" "trunc")
4308    (set_attr "mode" "SI")])
4309
4310 (define_insn "fix_truncsi_nomemory"
4311   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4312         (fix:SI (match_operand 1 "register_operand" "f,f")))
4313    (use (match_operand:HI 2 "memory_operand" "m,m"))
4314    (use (match_operand:HI 3 "memory_operand" "m,m"))
4315    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4316   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4317    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4318   "#"
4319   [(set_attr "type" "fistp")
4320    (set_attr "i387_cw" "trunc")
4321    (set_attr "mode" "SI")])
4322
4323 (define_insn "fix_truncsi_memory"
4324   [(set (match_operand:SI 0 "memory_operand" "=m")
4325         (fix:SI (match_operand 1 "register_operand" "f")))
4326    (use (match_operand:HI 2 "memory_operand" "m"))
4327    (use (match_operand:HI 3 "memory_operand" "m"))]
4328   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4329    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4330   "* return output_fix_trunc (insn, operands);"
4331   [(set_attr "type" "fistp")
4332    (set_attr "i387_cw" "trunc")
4333    (set_attr "mode" "SI")])
4334
4335 ;; When SSE available, it is always faster to use it!
4336 (define_insn "fix_truncsfsi_sse"
4337   [(set (match_operand:SI 0 "register_operand" "=r,r")
4338         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4339   "TARGET_SSE"
4340   "cvttss2si\t{%1, %0|%0, %1}"
4341   [(set_attr "type" "sseicvt")
4342    (set_attr "mode" "DF")
4343    (set_attr "athlon_decode" "double,vector")])
4344
4345 ;; Avoid vector decoded form of the instruction.
4346 (define_peephole2
4347   [(match_scratch:SF 2 "x")
4348    (set (match_operand:SI 0 "register_operand" "")
4349         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4350   "TARGET_K8 && !optimize_size"
4351   [(set (match_dup 2) (match_dup 1))
4352    (set (match_dup 0) (fix:SI (match_dup 2)))]
4353   "")
4354
4355 (define_insn "fix_truncdfsi_sse"
4356   [(set (match_operand:SI 0 "register_operand" "=r,r")
4357         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4358   "TARGET_SSE2"
4359   "cvttsd2si\t{%1, %0|%0, %1}"
4360   [(set_attr "type" "sseicvt")
4361    (set_attr "mode" "DF")
4362    (set_attr "athlon_decode" "double,vector")])
4363
4364 ;; Avoid vector decoded form of the instruction.
4365 (define_peephole2
4366   [(match_scratch:DF 2 "Y")
4367    (set (match_operand:SI 0 "register_operand" "")
4368         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4369   "TARGET_K8 && !optimize_size"
4370   [(set (match_dup 2) (match_dup 1))
4371    (set (match_dup 0) (fix:SI (match_dup 2)))]
4372   "")
4373
4374 (define_split 
4375   [(set (match_operand:SI 0 "register_operand" "")
4376         (fix:SI (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:SI 4 "memory_operand" ""))]
4380   "reload_completed"
4381   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4382               (use (match_dup 2))
4383               (use (match_dup 3))])
4384    (set (match_dup 0) (match_dup 4))]
4385   "")
4386
4387 (define_split 
4388   [(set (match_operand:SI 0 "memory_operand" "")
4389         (fix:SI (match_operand 1 "register_operand" "")))
4390    (use (match_operand:HI 2 "memory_operand" ""))
4391    (use (match_operand:HI 3 "memory_operand" ""))
4392    (clobber (match_operand:SI 4 "memory_operand" ""))]
4393   "reload_completed"
4394   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4395               (use (match_dup 2))
4396               (use (match_dup 3))])]
4397   "")
4398
4399 ;; Signed conversion to HImode.
4400
4401 (define_expand "fix_truncxfhi2"
4402   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4403                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4404               (clobber (reg:CC FLAGS_REG))])] 
4405   "TARGET_80387"
4406   "")
4407
4408 (define_expand "fix_truncdfhi2"
4409   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4410                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4411               (clobber (reg:CC FLAGS_REG))])]
4412   "TARGET_80387 && !TARGET_SSE2"
4413   "")
4414
4415 (define_expand "fix_truncsfhi2"
4416   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4417                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4418                (clobber (reg:CC FLAGS_REG))])]
4419   "TARGET_80387 && !TARGET_SSE"
4420   "")
4421
4422 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4423 ;; of the machinery.
4424 (define_insn_and_split "*fix_trunchi_1"
4425   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4426         (fix:HI (match_operand 1 "register_operand" "f,f")))
4427    (clobber (reg:CC FLAGS_REG))]
4428   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4429    && !reload_completed && !reload_in_progress
4430    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4431   "#"
4432   ""
4433   [(const_int 0)]
4434 {
4435   ix86_optimize_mode_switching = 1;
4436   operands[2] = assign_386_stack_local (HImode, 1);
4437   operands[3] = assign_386_stack_local (HImode, 2);
4438   if (memory_operand (operands[0], VOIDmode))
4439     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4440                                        operands[2], operands[3]));
4441   else
4442     {
4443       operands[4] = assign_386_stack_local (HImode, 0);
4444       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4445                                            operands[2], operands[3],
4446                                            operands[4]));
4447     }
4448   DONE;
4449 }
4450   [(set_attr "type" "fistp")
4451    (set_attr "i387_cw" "trunc")
4452    (set_attr "mode" "HI")])
4453
4454 (define_insn "fix_trunchi_nomemory"
4455   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4456         (fix:HI (match_operand 1 "register_operand" "f,f")))
4457    (use (match_operand:HI 2 "memory_operand" "m,m"))
4458    (use (match_operand:HI 3 "memory_operand" "m,m"))
4459    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4460   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4461    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4462   "#"
4463   [(set_attr "type" "fistp")
4464    (set_attr "i387_cw" "trunc")
4465    (set_attr "mode" "HI")])
4466
4467 (define_insn "fix_trunchi_memory"
4468   [(set (match_operand:HI 0 "memory_operand" "=m")
4469         (fix:HI (match_operand 1 "register_operand" "f")))
4470    (use (match_operand:HI 2 "memory_operand" "m"))
4471    (use (match_operand:HI 3 "memory_operand" "m"))]
4472   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4473    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4474   "* return output_fix_trunc (insn, operands);"
4475   [(set_attr "type" "fistp")
4476    (set_attr "i387_cw" "trunc")
4477    (set_attr "mode" "HI")])
4478
4479 (define_split 
4480   [(set (match_operand:HI 0 "memory_operand" "")
4481         (fix:HI (match_operand 1 "register_operand" "")))
4482    (use (match_operand:HI 2 "memory_operand" ""))
4483    (use (match_operand:HI 3 "memory_operand" ""))
4484    (clobber (match_operand:HI 4 "memory_operand" ""))]
4485   "reload_completed"
4486   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4487               (use (match_dup 2))
4488               (use (match_dup 3))])]
4489   "")
4490
4491 (define_split 
4492   [(set (match_operand:HI 0 "register_operand" "")
4493         (fix:HI (match_operand 1 "register_operand" "")))
4494    (use (match_operand:HI 2 "memory_operand" ""))
4495    (use (match_operand:HI 3 "memory_operand" ""))
4496    (clobber (match_operand:HI 4 "memory_operand" ""))]
4497   "reload_completed"
4498   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4499               (use (match_dup 2))
4500               (use (match_dup 3))
4501               (clobber (match_dup 4))])
4502    (set (match_dup 0) (match_dup 4))]
4503   "")
4504
4505 (define_insn "x86_fnstcw_1"
4506   [(set (match_operand:HI 0 "memory_operand" "=m")
4507         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4508   "TARGET_80387"
4509   "fnstcw\t%0"
4510   [(set_attr "length" "2")
4511    (set_attr "mode" "HI")
4512    (set_attr "unit" "i387")])
4513
4514 (define_insn "x86_fldcw_1"
4515   [(set (reg:HI FPSR_REG)
4516         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4517   "TARGET_80387"
4518   "fldcw\t%0"
4519   [(set_attr "length" "2")
4520    (set_attr "mode" "HI")
4521    (set_attr "unit" "i387")
4522    (set_attr "athlon_decode" "vector")])
4523 \f
4524 ;; Conversion between fixed point and floating point.
4525
4526 ;; Even though we only accept memory inputs, the backend _really_
4527 ;; wants to be able to do this between registers.
4528
4529 (define_expand "floathisf2"
4530   [(set (match_operand:SF 0 "register_operand" "")
4531         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4532   "TARGET_SSE || TARGET_80387"
4533 {
4534   if (TARGET_SSE && TARGET_SSE_MATH)
4535     {
4536       emit_insn (gen_floatsisf2 (operands[0],
4537                                  convert_to_mode (SImode, operands[1], 0)));
4538       DONE;
4539     }
4540 })
4541
4542 (define_insn "*floathisf2_1"
4543   [(set (match_operand:SF 0 "register_operand" "=f,f")
4544         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4545   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "SF")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floatsisf2"
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556   "TARGET_SSE || TARGET_80387"
4557   "")
4558
4559 (define_insn "*floatsisf2_i387"
4560   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4561         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4563   "@
4564    fild%z1\t%1
4565    #
4566    cvtsi2ss\t{%1, %0|%0, %1}
4567    cvtsi2ss\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569    (set_attr "mode" "SF")
4570    (set_attr "athlon_decode" "*,*,vector,double")
4571    (set_attr "fp_int_src" "true")])
4572
4573 (define_insn "*floatsisf2_sse"
4574   [(set (match_operand:SF 0 "register_operand" "=x,x")
4575         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4576   "TARGET_SSE"
4577   "cvtsi2ss\t{%1, %0|%0, %1}"
4578   [(set_attr "type" "sseicvt")
4579    (set_attr "mode" "SF")
4580    (set_attr "athlon_decode" "vector,double")
4581    (set_attr "fp_int_src" "true")])
4582
4583 ; Avoid possible reformatting penalty on the destination by first
4584 ; zeroing it out
4585 (define_split
4586   [(set (match_operand:SF 0 "register_operand" "")
4587         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4588   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4589    && SSE_REG_P (operands[0])"
4590   [(const_int 0)]
4591 {
4592   rtx dest;
4593   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4594   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4595   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4596   DONE;
4597 })
4598
4599 (define_expand "floatdisf2"
4600   [(set (match_operand:SF 0 "register_operand" "")
4601         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4602   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4603   "")
4604
4605 (define_insn "*floatdisf2_i387_only"
4606   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4607         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4608   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4609   "@
4610    fild%z1\t%1
4611    #"
4612   [(set_attr "type" "fmov,multi")
4613    (set_attr "mode" "SF")
4614    (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "*floatdisf2_i387"
4617   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4618         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4619   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4620   "@
4621    fild%z1\t%1
4622    #
4623    cvtsi2ss{q}\t{%1, %0|%0, %1}
4624    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4625   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4626    (set_attr "mode" "SF")
4627    (set_attr "athlon_decode" "*,*,vector,double")
4628    (set_attr "fp_int_src" "true")])
4629
4630 (define_insn "*floatdisf2_sse"
4631   [(set (match_operand:SF 0 "register_operand" "=x,x")
4632         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4633   "TARGET_64BIT && TARGET_SSE"
4634   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4635   [(set_attr "type" "sseicvt")
4636    (set_attr "mode" "SF")
4637    (set_attr "athlon_decode" "vector,double")
4638    (set_attr "fp_int_src" "true")])
4639
4640 ; Avoid possible reformatting penalty on the destination by first
4641 ; zeroing it out
4642 (define_split
4643   [(set (match_operand:SF 0 "register_operand" "")
4644         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4645   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4646    && SSE_REG_P (operands[0])"
4647   [(const_int 0)]
4648 {
4649   rtx dest;
4650   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4651   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4652   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4653   DONE;
4654 })
4655
4656 (define_expand "floathidf2"
4657   [(set (match_operand:DF 0 "register_operand" "")
4658         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659   "TARGET_SSE2 || TARGET_80387"
4660 {
4661   if (TARGET_SSE && TARGET_SSE_MATH)
4662     {
4663       emit_insn (gen_floatsidf2 (operands[0],
4664                                  convert_to_mode (SImode, operands[1], 0)));
4665       DONE;
4666     }
4667 })
4668
4669 (define_insn "*floathidf2_1"
4670   [(set (match_operand:DF 0 "register_operand" "=f,f")
4671         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4672   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4673   "@
4674    fild%z1\t%1
4675    #"
4676   [(set_attr "type" "fmov,multi")
4677    (set_attr "mode" "DF")
4678    (set_attr "fp_int_src" "true")])
4679
4680 (define_expand "floatsidf2"
4681   [(set (match_operand:DF 0 "register_operand" "")
4682         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4683   "TARGET_80387 || TARGET_SSE2"
4684   "")
4685
4686 (define_insn "*floatsidf2_i387"
4687   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4688         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4689   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4690   "@
4691    fild%z1\t%1
4692    #
4693    cvtsi2sd\t{%1, %0|%0, %1}
4694    cvtsi2sd\t{%1, %0|%0, %1}"
4695   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4696    (set_attr "mode" "DF")
4697    (set_attr "athlon_decode" "*,*,double,direct")
4698    (set_attr "fp_int_src" "true")])
4699
4700 (define_insn "*floatsidf2_sse"
4701   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4702         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4703   "TARGET_SSE2"
4704   "cvtsi2sd\t{%1, %0|%0, %1}"
4705   [(set_attr "type" "sseicvt")
4706    (set_attr "mode" "DF")
4707    (set_attr "athlon_decode" "double,direct")
4708    (set_attr "fp_int_src" "true")])
4709
4710 (define_expand "floatdidf2"
4711   [(set (match_operand:DF 0 "register_operand" "")
4712         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4713   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4714   "")
4715
4716 (define_insn "*floatdidf2_i387_only"
4717   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4718         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4719   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "DF")
4725    (set_attr "fp_int_src" "true")])
4726
4727 (define_insn "*floatdidf2_i387"
4728   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4729         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4730   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4731   "@
4732    fild%z1\t%1
4733    #
4734    cvtsi2sd{q}\t{%1, %0|%0, %1}
4735    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4736   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4737    (set_attr "mode" "DF")
4738    (set_attr "athlon_decode" "*,*,double,direct")
4739    (set_attr "fp_int_src" "true")])
4740
4741 (define_insn "*floatdidf2_sse"
4742   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4743         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4744   "TARGET_SSE2"
4745   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4746   [(set_attr "type" "sseicvt")
4747    (set_attr "mode" "DF")
4748    (set_attr "athlon_decode" "double,direct")
4749    (set_attr "fp_int_src" "true")])
4750
4751 (define_insn "floathixf2"
4752   [(set (match_operand:XF 0 "register_operand" "=f,f")
4753         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4754   "TARGET_80387"
4755   "@
4756    fild%z1\t%1
4757    #"
4758   [(set_attr "type" "fmov,multi")
4759    (set_attr "mode" "XF")
4760    (set_attr "fp_int_src" "true")])
4761
4762 (define_insn "floatsixf2"
4763   [(set (match_operand:XF 0 "register_operand" "=f,f")
4764         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4765   "TARGET_80387"
4766   "@
4767    fild%z1\t%1
4768    #"
4769   [(set_attr "type" "fmov,multi")
4770    (set_attr "mode" "XF")
4771    (set_attr "fp_int_src" "true")])
4772
4773 (define_insn "floatdixf2"
4774   [(set (match_operand:XF 0 "register_operand" "=f,f")
4775         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4776   "TARGET_80387"
4777   "@
4778    fild%z1\t%1
4779    #"
4780   [(set_attr "type" "fmov,multi")
4781    (set_attr "mode" "XF")
4782    (set_attr "fp_int_src" "true")])
4783
4784 ;; %%% Kill these when reload knows how to do it.
4785 (define_split
4786   [(set (match_operand 0 "fp_register_operand" "")
4787         (float (match_operand 1 "register_operand" "")))]
4788   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4789   [(const_int 0)]
4790 {
4791   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4792   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4793   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4794   ix86_free_from_memory (GET_MODE (operands[1]));
4795   DONE;
4796 })
4797
4798 (define_expand "floatunssisf2"
4799   [(use (match_operand:SF 0 "register_operand" ""))
4800    (use (match_operand:SI 1 "register_operand" ""))]
4801   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4802   "x86_emit_floatuns (operands); DONE;")
4803
4804 (define_expand "floatunsdisf2"
4805   [(use (match_operand:SF 0 "register_operand" ""))
4806    (use (match_operand:DI 1 "register_operand" ""))]
4807   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4808   "x86_emit_floatuns (operands); DONE;")
4809
4810 (define_expand "floatunsdidf2"
4811   [(use (match_operand:DF 0 "register_operand" ""))
4812    (use (match_operand:DI 1 "register_operand" ""))]
4813   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4814   "x86_emit_floatuns (operands); DONE;")
4815 \f
4816 ;; SSE extract/set expanders
4817
4818 (define_expand "vec_setv2df"
4819   [(match_operand:V2DF 0 "register_operand" "")
4820    (match_operand:DF 1 "register_operand" "")
4821    (match_operand 2 "const_int_operand" "")]
4822   "TARGET_SSE2"
4823 {
4824   switch (INTVAL (operands[2]))
4825     {
4826     case 0:
4827       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4828                                  simplify_gen_subreg (V2DFmode, operands[1],
4829                                                       DFmode, 0)));
4830       break;
4831     case 1:
4832       {
4833         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4834
4835         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4836       }
4837       break;
4838     default:
4839       abort ();
4840     }
4841   DONE;
4842 })
4843
4844 (define_expand "vec_extractv2df"
4845   [(match_operand:DF 0 "register_operand" "")
4846    (match_operand:V2DF 1 "register_operand" "")
4847    (match_operand 2 "const_int_operand" "")]
4848   "TARGET_SSE2"
4849 {
4850   switch (INTVAL (operands[2]))
4851     {
4852     case 0:
4853       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4854       break;
4855     case 1:
4856       {
4857         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4858
4859         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4860       }
4861       break;
4862     default:
4863       abort ();
4864     }
4865   DONE;
4866 })
4867
4868 (define_expand "vec_initv2df"
4869   [(match_operand:V2DF 0 "register_operand" "")
4870    (match_operand 1 "" "")]
4871   "TARGET_SSE2"
4872 {
4873   ix86_expand_vector_init (operands[0], operands[1]);
4874   DONE;
4875 })
4876
4877 (define_expand "vec_setv4sf"
4878   [(match_operand:V4SF 0 "register_operand" "")
4879    (match_operand:SF 1 "register_operand" "")
4880    (match_operand 2 "const_int_operand" "")]
4881   "TARGET_SSE"
4882 {
4883   switch (INTVAL (operands[2]))
4884     {
4885     case 0:
4886       emit_insn (gen_sse_movss (operands[0], operands[0],
4887                                 simplify_gen_subreg (V4SFmode, operands[1],
4888                                                      SFmode, 0)));
4889       break;
4890     case 1:
4891       {
4892         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4893         rtx tmp = gen_reg_rtx (V4SFmode);
4894  
4895         emit_move_insn (tmp, operands[0]);
4896         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4897         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4898         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4899                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4900       }
4901       break;
4902     case 2:
4903       {
4904         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4905         rtx tmp = gen_reg_rtx (V4SFmode);
4906
4907         emit_move_insn (tmp, operands[0]);
4908         emit_insn (gen_sse_movss (tmp, tmp, op1));
4909         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4910                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4911       }
4912       break;
4913     case 3:
4914       {
4915         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4916         rtx tmp = gen_reg_rtx (V4SFmode);
4917
4918         emit_move_insn (tmp, operands[0]);
4919         emit_insn (gen_sse_movss (tmp, tmp, op1));
4920         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4921                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4922       }
4923       break;
4924     default:
4925       abort ();
4926     }
4927   DONE;
4928 })
4929
4930 (define_expand "vec_extractv4sf"
4931   [(match_operand:SF 0 "register_operand" "")
4932    (match_operand:V4SF 1 "register_operand" "")
4933    (match_operand 2 "const_int_operand" "")]
4934   "TARGET_SSE"
4935 {
4936   switch (INTVAL (operands[2]))
4937     {
4938     case 0:
4939       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4940       break;
4941     case 1:
4942       {
4943         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4944         rtx tmp = gen_reg_rtx (V4SFmode);
4945  
4946         emit_move_insn (tmp, operands[1]);
4947         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4948                                    const1_rtx));
4949       }
4950       break;
4951     case 2:
4952       {
4953         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4954         rtx tmp = gen_reg_rtx (V4SFmode);
4955  
4956         emit_move_insn (tmp, operands[1]);
4957         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4958       }
4959       break;
4960     case 3:
4961       {
4962         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4963         rtx tmp = gen_reg_rtx (V4SFmode);
4964  
4965         emit_move_insn (tmp, operands[1]);
4966         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4967                                    GEN_INT (3)));
4968       }
4969       break;
4970     default:
4971       abort ();
4972     }
4973   DONE;
4974 })
4975
4976 (define_expand "vec_initv4sf"
4977   [(match_operand:V4SF 0 "register_operand" "")
4978    (match_operand 1 "" "")]
4979   "TARGET_SSE"
4980 {
4981   ix86_expand_vector_init (operands[0], operands[1]);
4982   DONE;
4983 })
4984 \f
4985 ;; Add instructions
4986
4987 ;; %%% splits for addsidi3
4988 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4989 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4990 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4991
4992 (define_expand "adddi3"
4993   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4994         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4995                  (match_operand:DI 2 "x86_64_general_operand" "")))
4996    (clobber (reg:CC FLAGS_REG))]
4997   ""
4998   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4999
5000 (define_insn "*adddi3_1"
5001   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5002         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5003                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5004    (clobber (reg:CC FLAGS_REG))]
5005   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5006   "#")
5007
5008 (define_split
5009   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5010         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5011                  (match_operand:DI 2 "general_operand" "")))
5012    (clobber (reg:CC FLAGS_REG))]
5013   "!TARGET_64BIT && reload_completed"
5014   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5015                                           UNSPEC_ADD_CARRY))
5016               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5017    (parallel [(set (match_dup 3)
5018                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5019                                      (match_dup 4))
5020                             (match_dup 5)))
5021               (clobber (reg:CC FLAGS_REG))])]
5022   "split_di (operands+0, 1, operands+0, operands+3);
5023    split_di (operands+1, 1, operands+1, operands+4);
5024    split_di (operands+2, 1, operands+2, operands+5);")
5025
5026 (define_insn "adddi3_carry_rex64"
5027   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5028           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5029                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5030                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5033   "adc{q}\t{%2, %0|%0, %2}"
5034   [(set_attr "type" "alu")
5035    (set_attr "pent_pair" "pu")
5036    (set_attr "mode" "DI")])
5037
5038 (define_insn "*adddi3_cc_rex64"
5039   [(set (reg:CC FLAGS_REG)
5040         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5041                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5042                    UNSPEC_ADD_CARRY))
5043    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5044         (plus:DI (match_dup 1) (match_dup 2)))]
5045   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5046   "add{q}\t{%2, %0|%0, %2}"
5047   [(set_attr "type" "alu")
5048    (set_attr "mode" "DI")])
5049
5050 (define_insn "addqi3_carry"
5051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5052           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5053                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5054                    (match_operand:QI 2 "general_operand" "qi,qm")))
5055    (clobber (reg:CC FLAGS_REG))]
5056   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057   "adc{b}\t{%2, %0|%0, %2}"
5058   [(set_attr "type" "alu")
5059    (set_attr "pent_pair" "pu")
5060    (set_attr "mode" "QI")])
5061
5062 (define_insn "addhi3_carry"
5063   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5064           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5065                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5066                    (match_operand:HI 2 "general_operand" "ri,rm")))
5067    (clobber (reg:CC FLAGS_REG))]
5068   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5069   "adc{w}\t{%2, %0|%0, %2}"
5070   [(set_attr "type" "alu")
5071    (set_attr "pent_pair" "pu")
5072    (set_attr "mode" "HI")])
5073
5074 (define_insn "addsi3_carry"
5075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5076           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5077                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5078                    (match_operand:SI 2 "general_operand" "ri,rm")))
5079    (clobber (reg:CC FLAGS_REG))]
5080   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5081   "adc{l}\t{%2, %0|%0, %2}"
5082   [(set_attr "type" "alu")
5083    (set_attr "pent_pair" "pu")
5084    (set_attr "mode" "SI")])
5085
5086 (define_insn "*addsi3_carry_zext"
5087   [(set (match_operand:DI 0 "register_operand" "=r")
5088           (zero_extend:DI 
5089             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5090                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5091                      (match_operand:SI 2 "general_operand" "rim"))))
5092    (clobber (reg:CC FLAGS_REG))]
5093   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5094   "adc{l}\t{%2, %k0|%k0, %2}"
5095   [(set_attr "type" "alu")
5096    (set_attr "pent_pair" "pu")
5097    (set_attr "mode" "SI")])
5098
5099 (define_insn "*addsi3_cc"
5100   [(set (reg:CC FLAGS_REG)
5101         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5102                     (match_operand:SI 2 "general_operand" "ri,rm")]
5103                    UNSPEC_ADD_CARRY))
5104    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5105         (plus:SI (match_dup 1) (match_dup 2)))]
5106   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5107   "add{l}\t{%2, %0|%0, %2}"
5108   [(set_attr "type" "alu")
5109    (set_attr "mode" "SI")])
5110
5111 (define_insn "addqi3_cc"
5112   [(set (reg:CC FLAGS_REG)
5113         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5114                     (match_operand:QI 2 "general_operand" "qi,qm")]
5115                    UNSPEC_ADD_CARRY))
5116    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5117         (plus:QI (match_dup 1) (match_dup 2)))]
5118   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5119   "add{b}\t{%2, %0|%0, %2}"
5120   [(set_attr "type" "alu")
5121    (set_attr "mode" "QI")])
5122
5123 (define_expand "addsi3"
5124   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5125                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5126                             (match_operand:SI 2 "general_operand" "")))
5127               (clobber (reg:CC FLAGS_REG))])]
5128   ""
5129   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5130
5131 (define_insn "*lea_1"
5132   [(set (match_operand:SI 0 "register_operand" "=r")
5133         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5134   "!TARGET_64BIT"
5135   "lea{l}\t{%a1, %0|%0, %a1}"
5136   [(set_attr "type" "lea")
5137    (set_attr "mode" "SI")])
5138
5139 (define_insn "*lea_1_rex64"
5140   [(set (match_operand:SI 0 "register_operand" "=r")
5141         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5142   "TARGET_64BIT"
5143   "lea{l}\t{%a1, %0|%0, %a1}"
5144   [(set_attr "type" "lea")
5145    (set_attr "mode" "SI")])
5146
5147 (define_insn "*lea_1_zext"
5148   [(set (match_operand:DI 0 "register_operand" "=r")
5149         (zero_extend:DI
5150          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5151   "TARGET_64BIT"
5152   "lea{l}\t{%a1, %k0|%k0, %a1}"
5153   [(set_attr "type" "lea")
5154    (set_attr "mode" "SI")])
5155
5156 (define_insn "*lea_2_rex64"
5157   [(set (match_operand:DI 0 "register_operand" "=r")
5158         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5159   "TARGET_64BIT"
5160   "lea{q}\t{%a1, %0|%0, %a1}"
5161   [(set_attr "type" "lea")
5162    (set_attr "mode" "DI")])
5163
5164 ;; The lea patterns for non-Pmodes needs to be matched by several
5165 ;; insns converted to real lea by splitters.
5166
5167 (define_insn_and_split "*lea_general_1"
5168   [(set (match_operand 0 "register_operand" "=r")
5169         (plus (plus (match_operand 1 "index_register_operand" "r")
5170                     (match_operand 2 "register_operand" "r"))
5171               (match_operand 3 "immediate_operand" "i")))]
5172   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5173     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5174    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5175    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5176    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5177    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5178        || GET_MODE (operands[3]) == VOIDmode)"
5179   "#"
5180   "&& reload_completed"
5181   [(const_int 0)]
5182 {
5183   rtx pat;
5184   operands[0] = gen_lowpart (SImode, operands[0]);
5185   operands[1] = gen_lowpart (Pmode, operands[1]);
5186   operands[2] = gen_lowpart (Pmode, operands[2]);
5187   operands[3] = gen_lowpart (Pmode, operands[3]);
5188   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5189                       operands[3]);
5190   if (Pmode != SImode)
5191     pat = gen_rtx_SUBREG (SImode, pat, 0);
5192   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5193   DONE;
5194 }
5195   [(set_attr "type" "lea")
5196    (set_attr "mode" "SI")])
5197
5198 (define_insn_and_split "*lea_general_1_zext"
5199   [(set (match_operand:DI 0 "register_operand" "=r")
5200         (zero_extend:DI
5201           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5202                             (match_operand:SI 2 "register_operand" "r"))
5203                    (match_operand:SI 3 "immediate_operand" "i"))))]
5204   "TARGET_64BIT"
5205   "#"
5206   "&& reload_completed"
5207   [(set (match_dup 0)
5208         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5209                                                      (match_dup 2))
5210                                             (match_dup 3)) 0)))]
5211 {
5212   operands[1] = gen_lowpart (Pmode, operands[1]);
5213   operands[2] = gen_lowpart (Pmode, operands[2]);
5214   operands[3] = gen_lowpart (Pmode, operands[3]);
5215 }
5216   [(set_attr "type" "lea")
5217    (set_attr "mode" "SI")])
5218
5219 (define_insn_and_split "*lea_general_2"
5220   [(set (match_operand 0 "register_operand" "=r")
5221         (plus (mult (match_operand 1 "index_register_operand" "r")
5222                     (match_operand 2 "const248_operand" "i"))
5223               (match_operand 3 "nonmemory_operand" "ri")))]
5224   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5225     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5226    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5227    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5228    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5229        || GET_MODE (operands[3]) == VOIDmode)"
5230   "#"
5231   "&& reload_completed"
5232   [(const_int 0)]
5233 {
5234   rtx pat;
5235   operands[0] = gen_lowpart (SImode, operands[0]);
5236   operands[1] = gen_lowpart (Pmode, operands[1]);
5237   operands[3] = gen_lowpart (Pmode, operands[3]);
5238   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5239                       operands[3]);
5240   if (Pmode != SImode)
5241     pat = gen_rtx_SUBREG (SImode, pat, 0);
5242   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5243   DONE;
5244 }
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5247
5248 (define_insn_and_split "*lea_general_2_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5252                             (match_operand:SI 2 "const248_operand" "n"))
5253                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5254   "TARGET_64BIT"
5255   "#"
5256   "&& reload_completed"
5257   [(set (match_dup 0)
5258         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5259                                                      (match_dup 2))
5260                                             (match_dup 3)) 0)))]
5261 {
5262   operands[1] = gen_lowpart (Pmode, operands[1]);
5263   operands[3] = gen_lowpart (Pmode, operands[3]);
5264 }
5265   [(set_attr "type" "lea")
5266    (set_attr "mode" "SI")])
5267
5268 (define_insn_and_split "*lea_general_3"
5269   [(set (match_operand 0 "register_operand" "=r")
5270         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5271                           (match_operand 2 "const248_operand" "i"))
5272                     (match_operand 3 "register_operand" "r"))
5273               (match_operand 4 "immediate_operand" "i")))]
5274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5275     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5276    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5277    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5278    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5279   "#"
5280   "&& reload_completed"
5281   [(const_int 0)]
5282 {
5283   rtx pat;
5284   operands[0] = gen_lowpart (SImode, operands[0]);
5285   operands[1] = gen_lowpart (Pmode, operands[1]);
5286   operands[3] = gen_lowpart (Pmode, operands[3]);
5287   operands[4] = gen_lowpart (Pmode, operands[4]);
5288   pat = gen_rtx_PLUS (Pmode,
5289                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5290                                                          operands[2]),
5291                                     operands[3]),
5292                       operands[4]);
5293   if (Pmode != SImode)
5294     pat = gen_rtx_SUBREG (SImode, pat, 0);
5295   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5296   DONE;
5297 }
5298   [(set_attr "type" "lea")
5299    (set_attr "mode" "SI")])
5300
5301 (define_insn_and_split "*lea_general_3_zext"
5302   [(set (match_operand:DI 0 "register_operand" "=r")
5303         (zero_extend:DI
5304           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5305                                      (match_operand:SI 2 "const248_operand" "n"))
5306                             (match_operand:SI 3 "register_operand" "r"))
5307                    (match_operand:SI 4 "immediate_operand" "i"))))]
5308   "TARGET_64BIT"
5309   "#"
5310   "&& reload_completed"
5311   [(set (match_dup 0)
5312         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5313                                                               (match_dup 2))
5314                                                      (match_dup 3))
5315                                             (match_dup 4)) 0)))]
5316 {
5317   operands[1] = gen_lowpart (Pmode, operands[1]);
5318   operands[3] = gen_lowpart (Pmode, operands[3]);
5319   operands[4] = gen_lowpart (Pmode, operands[4]);
5320 }
5321   [(set_attr "type" "lea")
5322    (set_attr "mode" "SI")])
5323
5324 (define_insn "*adddi_1_rex64"
5325   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5326         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5327                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5328    (clobber (reg:CC FLAGS_REG))]
5329   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5330 {
5331   switch (get_attr_type (insn))
5332     {
5333     case TYPE_LEA:
5334       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5335       return "lea{q}\t{%a2, %0|%0, %a2}";
5336
5337     case TYPE_INCDEC:
5338       if (! rtx_equal_p (operands[0], operands[1]))
5339         abort ();
5340       if (operands[2] == const1_rtx)
5341         return "inc{q}\t%0";
5342       else if (operands[2] == constm1_rtx)
5343         return "dec{q}\t%0";
5344       else
5345         abort ();
5346
5347     default:
5348       if (! rtx_equal_p (operands[0], operands[1]))
5349         abort ();
5350
5351       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5353       if (GET_CODE (operands[2]) == CONST_INT
5354           /* Avoid overflows.  */
5355           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5356           && (INTVAL (operands[2]) == 128
5357               || (INTVAL (operands[2]) < 0
5358                   && INTVAL (operands[2]) != -128)))
5359         {
5360           operands[2] = GEN_INT (-INTVAL (operands[2]));
5361           return "sub{q}\t{%2, %0|%0, %2}";
5362         }
5363       return "add{q}\t{%2, %0|%0, %2}";
5364     }
5365 }
5366   [(set (attr "type")
5367      (cond [(eq_attr "alternative" "2")
5368               (const_string "lea")
5369             ; Current assemblers are broken and do not allow @GOTOFF in
5370             ; ought but a memory context.
5371             (match_operand:DI 2 "pic_symbolic_operand" "")
5372               (const_string "lea")
5373             (match_operand:DI 2 "incdec_operand" "")
5374               (const_string "incdec")
5375            ]
5376            (const_string "alu")))
5377    (set_attr "mode" "DI")])
5378
5379 ;; Convert lea to the lea pattern to avoid flags dependency.
5380 (define_split
5381   [(set (match_operand:DI 0 "register_operand" "")
5382         (plus:DI (match_operand:DI 1 "register_operand" "")
5383                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5384    (clobber (reg:CC FLAGS_REG))]
5385   "TARGET_64BIT && reload_completed
5386    && true_regnum (operands[0]) != true_regnum (operands[1])"
5387   [(set (match_dup 0)
5388         (plus:DI (match_dup 1)
5389                  (match_dup 2)))]
5390   "")
5391
5392 (define_insn "*adddi_2_rex64"
5393   [(set (reg 17)
5394         (compare
5395           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5396                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5397           (const_int 0)))                       
5398    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5399         (plus:DI (match_dup 1) (match_dup 2)))]
5400   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5401    && ix86_binary_operator_ok (PLUS, DImode, operands)
5402    /* Current assemblers are broken and do not allow @GOTOFF in
5403       ought but a memory context.  */
5404    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5405 {
5406   switch (get_attr_type (insn))
5407     {
5408     case TYPE_INCDEC:
5409       if (! rtx_equal_p (operands[0], operands[1]))
5410         abort ();
5411       if (operands[2] == const1_rtx)
5412         return "inc{q}\t%0";
5413       else if (operands[2] == constm1_rtx)
5414         return "dec{q}\t%0";
5415       else
5416         abort ();
5417
5418     default:
5419       if (! rtx_equal_p (operands[0], operands[1]))
5420         abort ();
5421       /* ???? We ought to handle there the 32bit case too
5422          - do we need new constraint?  */
5423       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5424          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5425       if (GET_CODE (operands[2]) == CONST_INT
5426           /* Avoid overflows.  */
5427           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5428           && (INTVAL (operands[2]) == 128
5429               || (INTVAL (operands[2]) < 0
5430                   && INTVAL (operands[2]) != -128)))
5431         {
5432           operands[2] = GEN_INT (-INTVAL (operands[2]));
5433           return "sub{q}\t{%2, %0|%0, %2}";
5434         }
5435       return "add{q}\t{%2, %0|%0, %2}";
5436     }
5437 }
5438   [(set (attr "type")
5439      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5440         (const_string "incdec")
5441         (const_string "alu")))
5442    (set_attr "mode" "DI")])
5443
5444 (define_insn "*adddi_3_rex64"
5445   [(set (reg 17)
5446         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5448    (clobber (match_scratch:DI 0 "=r"))]
5449   "TARGET_64BIT
5450    && ix86_match_ccmode (insn, CCZmode)
5451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5452    /* Current assemblers are broken and do not allow @GOTOFF in
5453       ought but a memory context.  */
5454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5455 {
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       if (! rtx_equal_p (operands[0], operands[1]))
5460         abort ();
5461       if (operands[2] == const1_rtx)
5462         return "inc{q}\t%0";
5463       else if (operands[2] == constm1_rtx)
5464         return "dec{q}\t%0";
5465       else
5466         abort ();
5467
5468     default:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       /* ???? We ought to handle there the 32bit case too
5472          - do we need new constraint?  */
5473       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5474          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5475       if (GET_CODE (operands[2]) == CONST_INT
5476           /* Avoid overflows.  */
5477           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5478           && (INTVAL (operands[2]) == 128
5479               || (INTVAL (operands[2]) < 0
5480                   && INTVAL (operands[2]) != -128)))
5481         {
5482           operands[2] = GEN_INT (-INTVAL (operands[2]));
5483           return "sub{q}\t{%2, %0|%0, %2}";
5484         }
5485       return "add{q}\t{%2, %0|%0, %2}";
5486     }
5487 }
5488   [(set (attr "type")
5489      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5490         (const_string "incdec")
5491         (const_string "alu")))
5492    (set_attr "mode" "DI")])
5493
5494 ; For comparisons against 1, -1 and 128, we may generate better code
5495 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5496 ; is matched then.  We can't accept general immediate, because for
5497 ; case of overflows,  the result is messed up.
5498 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5499 ; when negated.
5500 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5501 ; only for comparisons not depending on it.
5502 (define_insn "*adddi_4_rex64"
5503   [(set (reg 17)
5504         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5505                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5506    (clobber (match_scratch:DI 0 "=rm"))]
5507   "TARGET_64BIT
5508    &&  ix86_match_ccmode (insn, CCGCmode)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_INCDEC:
5513       if (operands[2] == constm1_rtx)
5514         return "inc{q}\t%0";
5515       else if (operands[2] == const1_rtx)
5516         return "dec{q}\t%0";
5517       else
5518         abort();
5519
5520     default:
5521       if (! rtx_equal_p (operands[0], operands[1]))
5522         abort ();
5523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5525       if ((INTVAL (operands[2]) == -128
5526            || (INTVAL (operands[2]) > 0
5527                && INTVAL (operands[2]) != 128))
5528           /* Avoid overflows.  */
5529           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5530         return "sub{q}\t{%2, %0|%0, %2}";
5531       operands[2] = GEN_INT (-INTVAL (operands[2]));
5532       return "add{q}\t{%2, %0|%0, %2}";
5533     }
5534 }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "DI")])
5540
5541 (define_insn "*adddi_5_rex64"
5542   [(set (reg 17)
5543         (compare
5544           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5546           (const_int 0)))                       
5547    (clobber (match_scratch:DI 0 "=r"))]
5548   "TARGET_64BIT
5549    && ix86_match_ccmode (insn, CCGOCmode)
5550    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (! rtx_equal_p (operands[0], operands[1]))
5559         abort ();
5560       if (operands[2] == const1_rtx)
5561         return "inc{q}\t%0";
5562       else if (operands[2] == constm1_rtx)
5563         return "dec{q}\t%0";
5564       else
5565         abort();
5566
5567     default:
5568       if (! rtx_equal_p (operands[0], operands[1]))
5569         abort ();
5570       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5571          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5572       if (GET_CODE (operands[2]) == CONST_INT
5573           /* Avoid overflows.  */
5574           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5575           && (INTVAL (operands[2]) == 128
5576               || (INTVAL (operands[2]) < 0
5577                   && INTVAL (operands[2]) != -128)))
5578         {
5579           operands[2] = GEN_INT (-INTVAL (operands[2]));
5580           return "sub{q}\t{%2, %0|%0, %2}";
5581         }
5582       return "add{q}\t{%2, %0|%0, %2}";
5583     }
5584 }
5585   [(set (attr "type")
5586      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5587         (const_string "incdec")
5588         (const_string "alu")))
5589    (set_attr "mode" "DI")])
5590
5591
5592 (define_insn "*addsi_1"
5593   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5594         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5595                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5596    (clobber (reg:CC FLAGS_REG))]
5597   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5598 {
5599   switch (get_attr_type (insn))
5600     {
5601     case TYPE_LEA:
5602       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5603       return "lea{l}\t{%a2, %0|%0, %a2}";
5604
5605     case TYPE_INCDEC:
5606       if (! rtx_equal_p (operands[0], operands[1]))
5607         abort ();
5608       if (operands[2] == const1_rtx)
5609         return "inc{l}\t%0";
5610       else if (operands[2] == constm1_rtx)
5611         return "dec{l}\t%0";
5612       else
5613         abort();
5614
5615     default:
5616       if (! rtx_equal_p (operands[0], operands[1]))
5617         abort ();
5618
5619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5621       if (GET_CODE (operands[2]) == CONST_INT
5622           && (INTVAL (operands[2]) == 128
5623               || (INTVAL (operands[2]) < 0
5624                   && INTVAL (operands[2]) != -128)))
5625         {
5626           operands[2] = GEN_INT (-INTVAL (operands[2]));
5627           return "sub{l}\t{%2, %0|%0, %2}";
5628         }
5629       return "add{l}\t{%2, %0|%0, %2}";
5630     }
5631 }
5632   [(set (attr "type")
5633      (cond [(eq_attr "alternative" "2")
5634               (const_string "lea")
5635             ; Current assemblers are broken and do not allow @GOTOFF in
5636             ; ought but a memory context.
5637             (match_operand:SI 2 "pic_symbolic_operand" "")
5638               (const_string "lea")
5639             (match_operand:SI 2 "incdec_operand" "")
5640               (const_string "incdec")
5641            ]
5642            (const_string "alu")))
5643    (set_attr "mode" "SI")])
5644
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5646 (define_split
5647   [(set (match_operand 0 "register_operand" "")
5648         (plus (match_operand 1 "register_operand" "")
5649               (match_operand 2 "nonmemory_operand" "")))
5650    (clobber (reg:CC FLAGS_REG))]
5651   "reload_completed
5652    && true_regnum (operands[0]) != true_regnum (operands[1])"
5653   [(const_int 0)]
5654 {
5655   rtx pat;
5656   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5657      may confuse gen_lowpart.  */
5658   if (GET_MODE (operands[0]) != Pmode)
5659     {
5660       operands[1] = gen_lowpart (Pmode, operands[1]);
5661       operands[2] = gen_lowpart (Pmode, operands[2]);
5662     }
5663   operands[0] = gen_lowpart (SImode, operands[0]);
5664   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5665   if (Pmode != SImode)
5666     pat = gen_rtx_SUBREG (SImode, pat, 0);
5667   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5668   DONE;
5669 })
5670
5671 ;; It may seem that nonimmediate operand is proper one for operand 1.
5672 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5673 ;; we take care in ix86_binary_operator_ok to not allow two memory
5674 ;; operands so proper swapping will be done in reload.  This allow
5675 ;; patterns constructed from addsi_1 to match.
5676 (define_insn "addsi_1_zext"
5677   [(set (match_operand:DI 0 "register_operand" "=r,r")
5678         (zero_extend:DI
5679           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5680                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5681    (clobber (reg:CC FLAGS_REG))]
5682   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5683 {
5684   switch (get_attr_type (insn))
5685     {
5686     case TYPE_LEA:
5687       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5688       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5689
5690     case TYPE_INCDEC:
5691       if (operands[2] == const1_rtx)
5692         return "inc{l}\t%k0";
5693       else if (operands[2] == constm1_rtx)
5694         return "dec{l}\t%k0";
5695       else
5696         abort();
5697
5698     default:
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (GET_CODE (operands[2]) == CONST_INT
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %k0|%k0, %2}";
5708         }
5709       return "add{l}\t{%2, %k0|%k0, %2}";
5710     }
5711 }
5712   [(set (attr "type")
5713      (cond [(eq_attr "alternative" "1")
5714               (const_string "lea")
5715             ; Current assemblers are broken and do not allow @GOTOFF in
5716             ; ought but a memory context.
5717             (match_operand:SI 2 "pic_symbolic_operand" "")
5718               (const_string "lea")
5719             (match_operand:SI 2 "incdec_operand" "")
5720               (const_string "incdec")
5721            ]
5722            (const_string "alu")))
5723    (set_attr "mode" "SI")])
5724
5725 ;; Convert lea to the lea pattern to avoid flags dependency.
5726 (define_split
5727   [(set (match_operand:DI 0 "register_operand" "")
5728         (zero_extend:DI
5729           (plus:SI (match_operand:SI 1 "register_operand" "")
5730                    (match_operand:SI 2 "nonmemory_operand" ""))))
5731    (clobber (reg:CC FLAGS_REG))]
5732   "TARGET_64BIT && reload_completed
5733    && true_regnum (operands[0]) != true_regnum (operands[1])"
5734   [(set (match_dup 0)
5735         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5736 {
5737   operands[1] = gen_lowpart (Pmode, operands[1]);
5738   operands[2] = gen_lowpart (Pmode, operands[2]);
5739 })
5740
5741 (define_insn "*addsi_2"
5742   [(set (reg 17)
5743         (compare
5744           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5745                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5746           (const_int 0)))                       
5747    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5748         (plus:SI (match_dup 1) (match_dup 2)))]
5749   "ix86_match_ccmode (insn, CCGOCmode)
5750    && ix86_binary_operator_ok (PLUS, SImode, operands)
5751    /* Current assemblers are broken and do not allow @GOTOFF in
5752       ought but a memory context.  */
5753    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5754 {
5755   switch (get_attr_type (insn))
5756     {
5757     case TYPE_INCDEC:
5758       if (! rtx_equal_p (operands[0], operands[1]))
5759         abort ();
5760       if (operands[2] == const1_rtx)
5761         return "inc{l}\t%0";
5762       else if (operands[2] == constm1_rtx)
5763         return "dec{l}\t%0";
5764       else
5765         abort();
5766
5767     default:
5768       if (! rtx_equal_p (operands[0], operands[1]))
5769         abort ();
5770       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5772       if (GET_CODE (operands[2]) == CONST_INT
5773           && (INTVAL (operands[2]) == 128
5774               || (INTVAL (operands[2]) < 0
5775                   && INTVAL (operands[2]) != -128)))
5776         {
5777           operands[2] = GEN_INT (-INTVAL (operands[2]));
5778           return "sub{l}\t{%2, %0|%0, %2}";
5779         }
5780       return "add{l}\t{%2, %0|%0, %2}";
5781     }
5782 }
5783   [(set (attr "type")
5784      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785         (const_string "incdec")
5786         (const_string "alu")))
5787    (set_attr "mode" "SI")])
5788
5789 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5790 (define_insn "*addsi_2_zext"
5791   [(set (reg 17)
5792         (compare
5793           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5794                    (match_operand:SI 2 "general_operand" "rmni"))
5795           (const_int 0)))                       
5796    (set (match_operand:DI 0 "register_operand" "=r")
5797         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5798   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5799    && ix86_binary_operator_ok (PLUS, SImode, operands)
5800    /* Current assemblers are broken and do not allow @GOTOFF in
5801       ought but a memory context.  */
5802    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5803 {
5804   switch (get_attr_type (insn))
5805     {
5806     case TYPE_INCDEC:
5807       if (operands[2] == const1_rtx)
5808         return "inc{l}\t%k0";
5809       else if (operands[2] == constm1_rtx)
5810         return "dec{l}\t%k0";
5811       else
5812         abort();
5813
5814     default:
5815       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5816          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5817       if (GET_CODE (operands[2]) == CONST_INT
5818           && (INTVAL (operands[2]) == 128
5819               || (INTVAL (operands[2]) < 0
5820                   && INTVAL (operands[2]) != -128)))
5821         {
5822           operands[2] = GEN_INT (-INTVAL (operands[2]));
5823           return "sub{l}\t{%2, %k0|%k0, %2}";
5824         }
5825       return "add{l}\t{%2, %k0|%k0, %2}";
5826     }
5827 }
5828   [(set (attr "type")
5829      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5830         (const_string "incdec")
5831         (const_string "alu")))
5832    (set_attr "mode" "SI")])
5833
5834 (define_insn "*addsi_3"
5835   [(set (reg 17)
5836         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5837                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5838    (clobber (match_scratch:SI 0 "=r"))]
5839   "ix86_match_ccmode (insn, CCZmode)
5840    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5841    /* Current assemblers are broken and do not allow @GOTOFF in
5842       ought but a memory context.  */
5843    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5844 {
5845   switch (get_attr_type (insn))
5846     {
5847     case TYPE_INCDEC:
5848       if (! rtx_equal_p (operands[0], operands[1]))
5849         abort ();
5850       if (operands[2] == const1_rtx)
5851         return "inc{l}\t%0";
5852       else if (operands[2] == constm1_rtx)
5853         return "dec{l}\t%0";
5854       else
5855         abort();
5856
5857     default:
5858       if (! rtx_equal_p (operands[0], operands[1]))
5859         abort ();
5860       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5862       if (GET_CODE (operands[2]) == CONST_INT
5863           && (INTVAL (operands[2]) == 128
5864               || (INTVAL (operands[2]) < 0
5865                   && INTVAL (operands[2]) != -128)))
5866         {
5867           operands[2] = GEN_INT (-INTVAL (operands[2]));
5868           return "sub{l}\t{%2, %0|%0, %2}";
5869         }
5870       return "add{l}\t{%2, %0|%0, %2}";
5871     }
5872 }
5873   [(set (attr "type")
5874      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875         (const_string "incdec")
5876         (const_string "alu")))
5877    (set_attr "mode" "SI")])
5878
5879 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5880 (define_insn "*addsi_3_zext"
5881   [(set (reg 17)
5882         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5883                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5884    (set (match_operand:DI 0 "register_operand" "=r")
5885         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5886   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5887    && ix86_binary_operator_ok (PLUS, SImode, operands)
5888    /* Current assemblers are broken and do not allow @GOTOFF in
5889       ought but a memory context.  */
5890    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5891 {
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (operands[2] == const1_rtx)
5896         return "inc{l}\t%k0";
5897       else if (operands[2] == constm1_rtx)
5898         return "dec{l}\t%k0";
5899       else
5900         abort();
5901
5902     default:
5903       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5905       if (GET_CODE (operands[2]) == CONST_INT
5906           && (INTVAL (operands[2]) == 128
5907               || (INTVAL (operands[2]) < 0
5908                   && INTVAL (operands[2]) != -128)))
5909         {
5910           operands[2] = GEN_INT (-INTVAL (operands[2]));
5911           return "sub{l}\t{%2, %k0|%k0, %2}";
5912         }
5913       return "add{l}\t{%2, %k0|%k0, %2}";
5914     }
5915 }
5916   [(set (attr "type")
5917      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5918         (const_string "incdec")
5919         (const_string "alu")))
5920    (set_attr "mode" "SI")])
5921
5922 ; For comparisons against 1, -1 and 128, we may generate better code
5923 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5924 ; is matched then.  We can't accept general immediate, because for
5925 ; case of overflows,  the result is messed up.
5926 ; This pattern also don't hold of 0x80000000, since the value overflows
5927 ; when negated.
5928 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5929 ; only for comparisons not depending on it.
5930 (define_insn "*addsi_4"
5931   [(set (reg 17)
5932         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5933                  (match_operand:SI 2 "const_int_operand" "n")))
5934    (clobber (match_scratch:SI 0 "=rm"))]
5935   "ix86_match_ccmode (insn, CCGCmode)
5936    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5937 {
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == constm1_rtx)
5942         return "inc{l}\t%0";
5943       else if (operands[2] == const1_rtx)
5944         return "dec{l}\t%0";
5945       else
5946         abort();
5947
5948     default:
5949       if (! rtx_equal_p (operands[0], operands[1]))
5950         abort ();
5951       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5953       if ((INTVAL (operands[2]) == -128
5954            || (INTVAL (operands[2]) > 0
5955                && INTVAL (operands[2]) != 128)))
5956         return "sub{l}\t{%2, %0|%0, %2}";
5957       operands[2] = GEN_INT (-INTVAL (operands[2]));
5958       return "add{l}\t{%2, %0|%0, %2}";
5959     }
5960 }
5961   [(set (attr "type")
5962      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5963         (const_string "incdec")
5964         (const_string "alu")))
5965    (set_attr "mode" "SI")])
5966
5967 (define_insn "*addsi_5"
5968   [(set (reg 17)
5969         (compare
5970           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5971                    (match_operand:SI 2 "general_operand" "rmni"))
5972           (const_int 0)))                       
5973    (clobber (match_scratch:SI 0 "=r"))]
5974   "ix86_match_ccmode (insn, CCGOCmode)
5975    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5976    /* Current assemblers are broken and do not allow @GOTOFF in
5977       ought but a memory context.  */
5978    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5979 {
5980   switch (get_attr_type (insn))
5981     {
5982     case TYPE_INCDEC:
5983       if (! rtx_equal_p (operands[0], operands[1]))
5984         abort ();
5985       if (operands[2] == const1_rtx)
5986         return "inc{l}\t%0";
5987       else if (operands[2] == constm1_rtx)
5988         return "dec{l}\t%0";
5989       else
5990         abort();
5991
5992     default:
5993       if (! rtx_equal_p (operands[0], operands[1]))
5994         abort ();
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if (GET_CODE (operands[2]) == CONST_INT
5998           && (INTVAL (operands[2]) == 128
5999               || (INTVAL (operands[2]) < 0
6000                   && INTVAL (operands[2]) != -128)))
6001         {
6002           operands[2] = GEN_INT (-INTVAL (operands[2]));
6003           return "sub{l}\t{%2, %0|%0, %2}";
6004         }
6005       return "add{l}\t{%2, %0|%0, %2}";
6006     }
6007 }
6008   [(set (attr "type")
6009      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6010         (const_string "incdec")
6011         (const_string "alu")))
6012    (set_attr "mode" "SI")])
6013
6014 (define_expand "addhi3"
6015   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6017                             (match_operand:HI 2 "general_operand" "")))
6018               (clobber (reg:CC FLAGS_REG))])]
6019   "TARGET_HIMODE_MATH"
6020   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6021
6022 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6023 ;; type optimizations enabled by define-splits.  This is not important
6024 ;; for PII, and in fact harmful because of partial register stalls.
6025
6026 (define_insn "*addhi_1_lea"
6027   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6028         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6029                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6030    (clobber (reg:CC FLAGS_REG))]
6031   "!TARGET_PARTIAL_REG_STALL
6032    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6033 {
6034   switch (get_attr_type (insn))
6035     {
6036     case TYPE_LEA:
6037       return "#";
6038     case TYPE_INCDEC:
6039       if (operands[2] == const1_rtx)
6040         return "inc{w}\t%0";
6041       else if (operands[2] == constm1_rtx)
6042         return "dec{w}\t%0";
6043       abort();
6044
6045     default:
6046       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6048       if (GET_CODE (operands[2]) == CONST_INT
6049           && (INTVAL (operands[2]) == 128
6050               || (INTVAL (operands[2]) < 0
6051                   && INTVAL (operands[2]) != -128)))
6052         {
6053           operands[2] = GEN_INT (-INTVAL (operands[2]));
6054           return "sub{w}\t{%2, %0|%0, %2}";
6055         }
6056       return "add{w}\t{%2, %0|%0, %2}";
6057     }
6058 }
6059   [(set (attr "type")
6060      (if_then_else (eq_attr "alternative" "2")
6061         (const_string "lea")
6062         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063            (const_string "incdec")
6064            (const_string "alu"))))
6065    (set_attr "mode" "HI,HI,SI")])
6066
6067 (define_insn "*addhi_1"
6068   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6069         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6070                  (match_operand:HI 2 "general_operand" "ri,rm")))
6071    (clobber (reg:CC FLAGS_REG))]
6072   "TARGET_PARTIAL_REG_STALL
6073    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6074 {
6075   switch (get_attr_type (insn))
6076     {
6077     case TYPE_INCDEC:
6078       if (operands[2] == const1_rtx)
6079         return "inc{w}\t%0";
6080       else if (operands[2] == constm1_rtx)
6081         return "dec{w}\t%0";
6082       abort();
6083
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           return "sub{w}\t{%2, %0|%0, %2}";
6094         }
6095       return "add{w}\t{%2, %0|%0, %2}";
6096     }
6097 }
6098   [(set (attr "type")
6099      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6100         (const_string "incdec")
6101         (const_string "alu")))
6102    (set_attr "mode" "HI")])
6103
6104 (define_insn "*addhi_2"
6105   [(set (reg 17)
6106         (compare
6107           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6108                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6109           (const_int 0)))                       
6110    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6111         (plus:HI (match_dup 1) (match_dup 2)))]
6112   "ix86_match_ccmode (insn, CCGOCmode)
6113    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6114 {
6115   switch (get_attr_type (insn))
6116     {
6117     case TYPE_INCDEC:
6118       if (operands[2] == const1_rtx)
6119         return "inc{w}\t%0";
6120       else if (operands[2] == constm1_rtx)
6121         return "dec{w}\t%0";
6122       abort();
6123
6124     default:
6125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127       if (GET_CODE (operands[2]) == CONST_INT
6128           && (INTVAL (operands[2]) == 128
6129               || (INTVAL (operands[2]) < 0
6130                   && INTVAL (operands[2]) != -128)))
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           return "sub{w}\t{%2, %0|%0, %2}";
6134         }
6135       return "add{w}\t{%2, %0|%0, %2}";
6136     }
6137 }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set_attr "mode" "HI")])
6143
6144 (define_insn "*addhi_3"
6145   [(set (reg 17)
6146         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6147                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6148    (clobber (match_scratch:HI 0 "=r"))]
6149   "ix86_match_ccmode (insn, CCZmode)
6150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6151 {
6152   switch (get_attr_type (insn))
6153     {
6154     case TYPE_INCDEC:
6155       if (operands[2] == const1_rtx)
6156         return "inc{w}\t%0";
6157       else if (operands[2] == constm1_rtx)
6158         return "dec{w}\t%0";
6159       abort();
6160
6161     default:
6162       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6164       if (GET_CODE (operands[2]) == CONST_INT
6165           && (INTVAL (operands[2]) == 128
6166               || (INTVAL (operands[2]) < 0
6167                   && INTVAL (operands[2]) != -128)))
6168         {
6169           operands[2] = GEN_INT (-INTVAL (operands[2]));
6170           return "sub{w}\t{%2, %0|%0, %2}";
6171         }
6172       return "add{w}\t{%2, %0|%0, %2}";
6173     }
6174 }
6175   [(set (attr "type")
6176      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177         (const_string "incdec")
6178         (const_string "alu")))
6179    (set_attr "mode" "HI")])
6180
6181 ; See comments above addsi_3_imm for details.
6182 (define_insn "*addhi_4"
6183   [(set (reg 17)
6184         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6185                  (match_operand:HI 2 "const_int_operand" "n")))
6186    (clobber (match_scratch:HI 0 "=rm"))]
6187   "ix86_match_ccmode (insn, CCGCmode)
6188    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6189 {
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       if (operands[2] == constm1_rtx)
6194         return "inc{w}\t%0";
6195       else if (operands[2] == const1_rtx)
6196         return "dec{w}\t%0";
6197       else
6198         abort();
6199
6200     default:
6201       if (! rtx_equal_p (operands[0], operands[1]))
6202         abort ();
6203       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6204          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6205       if ((INTVAL (operands[2]) == -128
6206            || (INTVAL (operands[2]) > 0
6207                && INTVAL (operands[2]) != 128)))
6208         return "sub{w}\t{%2, %0|%0, %2}";
6209       operands[2] = GEN_INT (-INTVAL (operands[2]));
6210       return "add{w}\t{%2, %0|%0, %2}";
6211     }
6212 }
6213   [(set (attr "type")
6214      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6215         (const_string "incdec")
6216         (const_string "alu")))
6217    (set_attr "mode" "SI")])
6218
6219
6220 (define_insn "*addhi_5"
6221   [(set (reg 17)
6222         (compare
6223           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6224                    (match_operand:HI 2 "general_operand" "rmni"))
6225           (const_int 0)))                       
6226    (clobber (match_scratch:HI 0 "=r"))]
6227   "ix86_match_ccmode (insn, CCGOCmode)
6228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6229 {
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       if (operands[2] == const1_rtx)
6234         return "inc{w}\t%0";
6235       else if (operands[2] == constm1_rtx)
6236         return "dec{w}\t%0";
6237       abort();
6238
6239     default:
6240       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6242       if (GET_CODE (operands[2]) == CONST_INT
6243           && (INTVAL (operands[2]) == 128
6244               || (INTVAL (operands[2]) < 0
6245                   && INTVAL (operands[2]) != -128)))
6246         {
6247           operands[2] = GEN_INT (-INTVAL (operands[2]));
6248           return "sub{w}\t{%2, %0|%0, %2}";
6249         }
6250       return "add{w}\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" "HI")])
6258
6259 (define_expand "addqi3"
6260   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6261                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6262                             (match_operand:QI 2 "general_operand" "")))
6263               (clobber (reg:CC FLAGS_REG))])]
6264   "TARGET_QIMODE_MATH"
6265   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6266
6267 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6268 (define_insn "*addqi_1_lea"
6269   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6270         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6271                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "!TARGET_PARTIAL_REG_STALL
6274    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6275 {
6276   int widen = (which_alternative == 2);
6277   switch (get_attr_type (insn))
6278     {
6279     case TYPE_LEA:
6280       return "#";
6281     case TYPE_INCDEC:
6282       if (operands[2] == const1_rtx)
6283         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6284       else if (operands[2] == constm1_rtx)
6285         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6286       abort();
6287
6288     default:
6289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6290          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6291       if (GET_CODE (operands[2]) == CONST_INT
6292           && (INTVAL (operands[2]) == 128
6293               || (INTVAL (operands[2]) < 0
6294                   && INTVAL (operands[2]) != -128)))
6295         {
6296           operands[2] = GEN_INT (-INTVAL (operands[2]));
6297           if (widen)
6298             return "sub{l}\t{%2, %k0|%k0, %2}";
6299           else
6300             return "sub{b}\t{%2, %0|%0, %2}";
6301         }
6302       if (widen)
6303         return "add{l}\t{%k2, %k0|%k0, %k2}";
6304       else
6305         return "add{b}\t{%2, %0|%0, %2}";
6306     }
6307 }
6308   [(set (attr "type")
6309      (if_then_else (eq_attr "alternative" "3")
6310         (const_string "lea")
6311         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6312            (const_string "incdec")
6313            (const_string "alu"))))
6314    (set_attr "mode" "QI,QI,SI,SI")])
6315
6316 (define_insn "*addqi_1"
6317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6318         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6319                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6320    (clobber (reg:CC FLAGS_REG))]
6321   "TARGET_PARTIAL_REG_STALL
6322    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6323 {
6324   int widen = (which_alternative == 2);
6325   switch (get_attr_type (insn))
6326     {
6327     case TYPE_INCDEC:
6328       if (operands[2] == const1_rtx)
6329         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6330       else if (operands[2] == constm1_rtx)
6331         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6332       abort();
6333
6334     default:
6335       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6336          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6337       if (GET_CODE (operands[2]) == CONST_INT
6338           && (INTVAL (operands[2]) == 128
6339               || (INTVAL (operands[2]) < 0
6340                   && INTVAL (operands[2]) != -128)))
6341         {
6342           operands[2] = GEN_INT (-INTVAL (operands[2]));
6343           if (widen)
6344             return "sub{l}\t{%2, %k0|%k0, %2}";
6345           else
6346             return "sub{b}\t{%2, %0|%0, %2}";
6347         }
6348       if (widen)
6349         return "add{l}\t{%k2, %k0|%k0, %k2}";
6350       else
6351         return "add{b}\t{%2, %0|%0, %2}";
6352     }
6353 }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI,QI,SI")])
6359
6360 (define_insn "*addqi_1_slp"
6361   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6362         (plus:QI (match_dup 0)
6363                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6366    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6367 {
6368   switch (get_attr_type (insn))
6369     {
6370     case TYPE_INCDEC:
6371       if (operands[1] == const1_rtx)
6372         return "inc{b}\t%0";
6373       else if (operands[1] == constm1_rtx)
6374         return "dec{b}\t%0";
6375       abort();
6376
6377     default:
6378       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6379       if (GET_CODE (operands[1]) == CONST_INT
6380           && INTVAL (operands[1]) < 0)
6381         {
6382           operands[1] = GEN_INT (-INTVAL (operands[1]));
6383           return "sub{b}\t{%1, %0|%0, %1}";
6384         }
6385       return "add{b}\t{%1, %0|%0, %1}";
6386     }
6387 }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu1")))
6392    (set_attr "mode" "QI")])
6393
6394 (define_insn "*addqi_2"
6395   [(set (reg 17)
6396         (compare
6397           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6398                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6399           (const_int 0)))
6400    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6401         (plus:QI (match_dup 1) (match_dup 2)))]
6402   "ix86_match_ccmode (insn, CCGOCmode)
6403    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6404 {
6405   switch (get_attr_type (insn))
6406     {
6407     case TYPE_INCDEC:
6408       if (operands[2] == const1_rtx)
6409         return "inc{b}\t%0";
6410       else if (operands[2] == constm1_rtx
6411                || (GET_CODE (operands[2]) == CONST_INT
6412                    && INTVAL (operands[2]) == 255))
6413         return "dec{b}\t%0";
6414       abort();
6415
6416     default:
6417       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6418       if (GET_CODE (operands[2]) == CONST_INT
6419           && INTVAL (operands[2]) < 0)
6420         {
6421           operands[2] = GEN_INT (-INTVAL (operands[2]));
6422           return "sub{b}\t{%2, %0|%0, %2}";
6423         }
6424       return "add{b}\t{%2, %0|%0, %2}";
6425     }
6426 }
6427   [(set (attr "type")
6428      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429         (const_string "incdec")
6430         (const_string "alu")))
6431    (set_attr "mode" "QI")])
6432
6433 (define_insn "*addqi_3"
6434   [(set (reg 17)
6435         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6436                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6437    (clobber (match_scratch:QI 0 "=q"))]
6438   "ix86_match_ccmode (insn, CCZmode)
6439    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6440 {
6441   switch (get_attr_type (insn))
6442     {
6443     case TYPE_INCDEC:
6444       if (operands[2] == const1_rtx)
6445         return "inc{b}\t%0";
6446       else if (operands[2] == constm1_rtx
6447                || (GET_CODE (operands[2]) == CONST_INT
6448                    && INTVAL (operands[2]) == 255))
6449         return "dec{b}\t%0";
6450       abort();
6451
6452     default:
6453       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6454       if (GET_CODE (operands[2]) == CONST_INT
6455           && INTVAL (operands[2]) < 0)
6456         {
6457           operands[2] = GEN_INT (-INTVAL (operands[2]));
6458           return "sub{b}\t{%2, %0|%0, %2}";
6459         }
6460       return "add{b}\t{%2, %0|%0, %2}";
6461     }
6462 }
6463   [(set (attr "type")
6464      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465         (const_string "incdec")
6466         (const_string "alu")))
6467    (set_attr "mode" "QI")])
6468
6469 ; See comments above addsi_3_imm for details.
6470 (define_insn "*addqi_4"
6471   [(set (reg 17)
6472         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6473                  (match_operand:QI 2 "const_int_operand" "n")))
6474    (clobber (match_scratch:QI 0 "=qm"))]
6475   "ix86_match_ccmode (insn, CCGCmode)
6476    && (INTVAL (operands[2]) & 0xff) != 0x80"
6477 {
6478   switch (get_attr_type (insn))
6479     {
6480     case TYPE_INCDEC:
6481       if (operands[2] == constm1_rtx
6482           || (GET_CODE (operands[2]) == CONST_INT
6483               && INTVAL (operands[2]) == 255))
6484         return "inc{b}\t%0";
6485       else if (operands[2] == const1_rtx)
6486         return "dec{b}\t%0";
6487       else
6488         abort();
6489
6490     default:
6491       if (! rtx_equal_p (operands[0], operands[1]))
6492         abort ();
6493       if (INTVAL (operands[2]) < 0)
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "add{b}\t{%2, %0|%0, %2}";
6497         }
6498       return "sub{b}\t{%2, %0|%0, %2}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu")))
6505    (set_attr "mode" "QI")])
6506
6507
6508 (define_insn "*addqi_5"
6509   [(set (reg 17)
6510         (compare
6511           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6512                    (match_operand:QI 2 "general_operand" "qmni"))
6513           (const_int 0)))
6514    (clobber (match_scratch:QI 0 "=q"))]
6515   "ix86_match_ccmode (insn, CCGOCmode)
6516    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6517 {
6518   switch (get_attr_type (insn))
6519     {
6520     case TYPE_INCDEC:
6521       if (operands[2] == const1_rtx)
6522         return "inc{b}\t%0";
6523       else if (operands[2] == constm1_rtx
6524                || (GET_CODE (operands[2]) == CONST_INT
6525                    && INTVAL (operands[2]) == 255))
6526         return "dec{b}\t%0";
6527       abort();
6528
6529     default:
6530       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6531       if (GET_CODE (operands[2]) == CONST_INT
6532           && INTVAL (operands[2]) < 0)
6533         {
6534           operands[2] = GEN_INT (-INTVAL (operands[2]));
6535           return "sub{b}\t{%2, %0|%0, %2}";
6536         }
6537       return "add{b}\t{%2, %0|%0, %2}";
6538     }
6539 }
6540   [(set (attr "type")
6541      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6542         (const_string "incdec")
6543         (const_string "alu")))
6544    (set_attr "mode" "QI")])
6545
6546
6547 (define_insn "addqi_ext_1"
6548   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6549                          (const_int 8)
6550                          (const_int 8))
6551         (plus:SI
6552           (zero_extract:SI
6553             (match_operand 1 "ext_register_operand" "0")
6554             (const_int 8)
6555             (const_int 8))
6556           (match_operand:QI 2 "general_operand" "Qmn")))
6557    (clobber (reg:CC FLAGS_REG))]
6558   "!TARGET_64BIT"
6559 {
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{b}\t%h0";
6565       else if (operands[2] == constm1_rtx
6566                || (GET_CODE (operands[2]) == CONST_INT
6567                    && INTVAL (operands[2]) == 255))
6568         return "dec{b}\t%h0";
6569       abort();
6570
6571     default:
6572       return "add{b}\t{%2, %h0|%h0, %2}";
6573     }
6574 }
6575   [(set (attr "type")
6576      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6577         (const_string "incdec")
6578         (const_string "alu")))
6579    (set_attr "mode" "QI")])
6580
6581 (define_insn "*addqi_ext_1_rex64"
6582   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6583                          (const_int 8)
6584                          (const_int 8))
6585         (plus:SI
6586           (zero_extract:SI
6587             (match_operand 1 "ext_register_operand" "0")
6588             (const_int 8)
6589             (const_int 8))
6590           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6591    (clobber (reg:CC FLAGS_REG))]
6592   "TARGET_64BIT"
6593 {
6594   switch (get_attr_type (insn))
6595     {
6596     case TYPE_INCDEC:
6597       if (operands[2] == const1_rtx)
6598         return "inc{b}\t%h0";
6599       else if (operands[2] == constm1_rtx
6600                || (GET_CODE (operands[2]) == CONST_INT
6601                    && INTVAL (operands[2]) == 255))
6602         return "dec{b}\t%h0";
6603       abort();
6604
6605     default:
6606       return "add{b}\t{%2, %h0|%h0, %2}";
6607     }
6608 }
6609   [(set (attr "type")
6610      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611         (const_string "incdec")
6612         (const_string "alu")))
6613    (set_attr "mode" "QI")])
6614
6615 (define_insn "*addqi_ext_2"
6616   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6617                          (const_int 8)
6618                          (const_int 8))
6619         (plus:SI
6620           (zero_extract:SI
6621             (match_operand 1 "ext_register_operand" "%0")
6622             (const_int 8)
6623             (const_int 8))
6624           (zero_extract:SI
6625             (match_operand 2 "ext_register_operand" "Q")
6626             (const_int 8)
6627             (const_int 8))))
6628    (clobber (reg:CC FLAGS_REG))]
6629   ""
6630   "add{b}\t{%h2, %h0|%h0, %h2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "QI")])
6633
6634 ;; The patterns that match these are at the end of this file.
6635
6636 (define_expand "addxf3"
6637   [(set (match_operand:XF 0 "register_operand" "")
6638         (plus:XF (match_operand:XF 1 "register_operand" "")
6639                  (match_operand:XF 2 "register_operand" "")))]
6640   "TARGET_80387"
6641   "")
6642
6643 (define_expand "adddf3"
6644   [(set (match_operand:DF 0 "register_operand" "")
6645         (plus:DF (match_operand:DF 1 "register_operand" "")
6646                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6647   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6648   "")
6649
6650 (define_expand "addsf3"
6651   [(set (match_operand:SF 0 "register_operand" "")
6652         (plus:SF (match_operand:SF 1 "register_operand" "")
6653                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6654   "TARGET_80387 || TARGET_SSE_MATH"
6655   "")
6656 \f
6657 ;; Subtract instructions
6658
6659 ;; %%% splits for subsidi3
6660
6661 (define_expand "subdi3"
6662   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6663                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6664                              (match_operand:DI 2 "x86_64_general_operand" "")))
6665               (clobber (reg:CC FLAGS_REG))])]
6666   ""
6667   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6668
6669 (define_insn "*subdi3_1"
6670   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6671         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6672                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6673    (clobber (reg:CC FLAGS_REG))]
6674   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6675   "#")
6676
6677 (define_split
6678   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6679         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6680                   (match_operand:DI 2 "general_operand" "")))
6681    (clobber (reg:CC FLAGS_REG))]
6682   "!TARGET_64BIT && reload_completed"
6683   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6684               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6685    (parallel [(set (match_dup 3)
6686                    (minus:SI (match_dup 4)
6687                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6688                                       (match_dup 5))))
6689               (clobber (reg:CC FLAGS_REG))])]
6690   "split_di (operands+0, 1, operands+0, operands+3);
6691    split_di (operands+1, 1, operands+1, operands+4);
6692    split_di (operands+2, 1, operands+2, operands+5);")
6693
6694 (define_insn "subdi3_carry_rex64"
6695   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6696           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6697             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6698                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6699    (clobber (reg:CC FLAGS_REG))]
6700   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6701   "sbb{q}\t{%2, %0|%0, %2}"
6702   [(set_attr "type" "alu")
6703    (set_attr "pent_pair" "pu")
6704    (set_attr "mode" "DI")])
6705
6706 (define_insn "*subdi_1_rex64"
6707   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6708         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6709                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6710    (clobber (reg:CC FLAGS_REG))]
6711   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6712   "sub{q}\t{%2, %0|%0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "DI")])
6715
6716 (define_insn "*subdi_2_rex64"
6717   [(set (reg 17)
6718         (compare
6719           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6720                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6721           (const_int 0)))
6722    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6723         (minus:DI (match_dup 1) (match_dup 2)))]
6724   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6725    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6726   "sub{q}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "alu")
6728    (set_attr "mode" "DI")])
6729
6730 (define_insn "*subdi_3_rex63"
6731   [(set (reg 17)
6732         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6733                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6734    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6735         (minus:DI (match_dup 1) (match_dup 2)))]
6736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6737    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6738   "sub{q}\t{%2, %0|%0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "DI")])
6741
6742 (define_insn "subqi3_carry"
6743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6746                (match_operand:QI 2 "general_operand" "qi,qm"))))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6749   "sbb{b}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "pent_pair" "pu")
6752    (set_attr "mode" "QI")])
6753
6754 (define_insn "subhi3_carry"
6755   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6757             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6758                (match_operand:HI 2 "general_operand" "ri,rm"))))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6761   "sbb{w}\t{%2, %0|%0, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "pent_pair" "pu")
6764    (set_attr "mode" "HI")])
6765
6766 (define_insn "subsi3_carry"
6767   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6768           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6769             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6770                (match_operand:SI 2 "general_operand" "ri,rm"))))
6771    (clobber (reg:CC FLAGS_REG))]
6772   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6773   "sbb{l}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "pent_pair" "pu")
6776    (set_attr "mode" "SI")])
6777
6778 (define_insn "subsi3_carry_zext"
6779   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6780           (zero_extend:DI
6781             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6782               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6783                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6784    (clobber (reg:CC FLAGS_REG))]
6785   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6786   "sbb{l}\t{%2, %k0|%k0, %2}"
6787   [(set_attr "type" "alu")
6788    (set_attr "pent_pair" "pu")
6789    (set_attr "mode" "SI")])
6790
6791 (define_expand "subsi3"
6792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6793                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6794                              (match_operand:SI 2 "general_operand" "")))
6795               (clobber (reg:CC FLAGS_REG))])]
6796   ""
6797   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6798
6799 (define_insn "*subsi_1"
6800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6801         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802                   (match_operand:SI 2 "general_operand" "ri,rm")))
6803    (clobber (reg:CC FLAGS_REG))]
6804   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{l}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "SI")])
6808
6809 (define_insn "*subsi_1_zext"
6810   [(set (match_operand:DI 0 "register_operand" "=r")
6811         (zero_extend:DI
6812           (minus:SI (match_operand:SI 1 "register_operand" "0")
6813                     (match_operand:SI 2 "general_operand" "rim"))))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816   "sub{l}\t{%2, %k0|%k0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "SI")])
6819
6820 (define_insn "*subsi_2"
6821   [(set (reg 17)
6822         (compare
6823           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6824                     (match_operand:SI 2 "general_operand" "ri,rm"))
6825           (const_int 0)))
6826    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6827         (minus:SI (match_dup 1) (match_dup 2)))]
6828   "ix86_match_ccmode (insn, CCGOCmode)
6829    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6830   "sub{l}\t{%2, %0|%0, %2}"
6831   [(set_attr "type" "alu")
6832    (set_attr "mode" "SI")])
6833
6834 (define_insn "*subsi_2_zext"
6835   [(set (reg 17)
6836         (compare
6837           (minus:SI (match_operand:SI 1 "register_operand" "0")
6838                     (match_operand:SI 2 "general_operand" "rim"))
6839           (const_int 0)))
6840    (set (match_operand:DI 0 "register_operand" "=r")
6841         (zero_extend:DI
6842           (minus:SI (match_dup 1)
6843                     (match_dup 2))))]
6844   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6845    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6846   "sub{l}\t{%2, %k0|%k0, %2}"
6847   [(set_attr "type" "alu")
6848    (set_attr "mode" "SI")])
6849
6850 (define_insn "*subsi_3"
6851   [(set (reg 17)
6852         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6853                  (match_operand:SI 2 "general_operand" "ri,rm")))
6854    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6855         (minus:SI (match_dup 1) (match_dup 2)))]
6856   "ix86_match_ccmode (insn, CCmode)
6857    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6858   "sub{l}\t{%2, %0|%0, %2}"
6859   [(set_attr "type" "alu")
6860    (set_attr "mode" "SI")])
6861
6862 (define_insn "*subsi_3_zext"
6863   [(set (reg 17)
6864         (compare (match_operand:SI 1 "register_operand" "0")
6865                  (match_operand:SI 2 "general_operand" "rim")))
6866    (set (match_operand:DI 0 "register_operand" "=r")
6867         (zero_extend:DI
6868           (minus:SI (match_dup 1)
6869                     (match_dup 2))))]
6870   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6871    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6872   "sub{q}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "DI")])
6875
6876 (define_expand "subhi3"
6877   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6878                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6879                              (match_operand:HI 2 "general_operand" "")))
6880               (clobber (reg:CC FLAGS_REG))])]
6881   "TARGET_HIMODE_MATH"
6882   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6883
6884 (define_insn "*subhi_1"
6885   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6886         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6887                   (match_operand:HI 2 "general_operand" "ri,rm")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6890   "sub{w}\t{%2, %0|%0, %2}"
6891   [(set_attr "type" "alu")
6892    (set_attr "mode" "HI")])
6893
6894 (define_insn "*subhi_2"
6895   [(set (reg 17)
6896         (compare
6897           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6898                     (match_operand:HI 2 "general_operand" "ri,rm"))
6899           (const_int 0)))
6900    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6901         (minus:HI (match_dup 1) (match_dup 2)))]
6902   "ix86_match_ccmode (insn, CCGOCmode)
6903    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6904   "sub{w}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "alu")
6906    (set_attr "mode" "HI")])
6907
6908 (define_insn "*subhi_3"
6909   [(set (reg 17)
6910         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6911                  (match_operand:HI 2 "general_operand" "ri,rm")))
6912    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6913         (minus:HI (match_dup 1) (match_dup 2)))]
6914   "ix86_match_ccmode (insn, CCmode)
6915    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6916   "sub{w}\t{%2, %0|%0, %2}"
6917   [(set_attr "type" "alu")
6918    (set_attr "mode" "HI")])
6919
6920 (define_expand "subqi3"
6921   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6922                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6923                              (match_operand:QI 2 "general_operand" "")))
6924               (clobber (reg:CC FLAGS_REG))])]
6925   "TARGET_QIMODE_MATH"
6926   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6927
6928 (define_insn "*subqi_1"
6929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6930         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6931                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6934   "sub{b}\t{%2, %0|%0, %2}"
6935   [(set_attr "type" "alu")
6936    (set_attr "mode" "QI")])
6937
6938 (define_insn "*subqi_1_slp"
6939   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6940         (minus:QI (match_dup 0)
6941                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6944    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6945   "sub{b}\t{%1, %0|%0, %1}"
6946   [(set_attr "type" "alu1")
6947    (set_attr "mode" "QI")])
6948
6949 (define_insn "*subqi_2"
6950   [(set (reg 17)
6951         (compare
6952           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6953                     (match_operand:QI 2 "general_operand" "qi,qm"))
6954           (const_int 0)))
6955    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6956         (minus:HI (match_dup 1) (match_dup 2)))]
6957   "ix86_match_ccmode (insn, CCGOCmode)
6958    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6959   "sub{b}\t{%2, %0|%0, %2}"
6960   [(set_attr "type" "alu")
6961    (set_attr "mode" "QI")])
6962
6963 (define_insn "*subqi_3"
6964   [(set (reg 17)
6965         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6966                  (match_operand:QI 2 "general_operand" "qi,qm")))
6967    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6968         (minus:HI (match_dup 1) (match_dup 2)))]
6969   "ix86_match_ccmode (insn, CCmode)
6970    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6971   "sub{b}\t{%2, %0|%0, %2}"
6972   [(set_attr "type" "alu")
6973    (set_attr "mode" "QI")])
6974
6975 ;; The patterns that match these are at the end of this file.
6976
6977 (define_expand "subxf3"
6978   [(set (match_operand:XF 0 "register_operand" "")
6979         (minus:XF (match_operand:XF 1 "register_operand" "")
6980                   (match_operand:XF 2 "register_operand" "")))]
6981   "TARGET_80387"
6982   "")
6983
6984 (define_expand "subdf3"
6985   [(set (match_operand:DF 0 "register_operand" "")
6986         (minus:DF (match_operand:DF 1 "register_operand" "")
6987                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6988   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6989   "")
6990
6991 (define_expand "subsf3"
6992   [(set (match_operand:SF 0 "register_operand" "")
6993         (minus:SF (match_operand:SF 1 "register_operand" "")
6994                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6995   "TARGET_80387 || TARGET_SSE_MATH"
6996   "")
6997 \f
6998 ;; Multiply instructions
6999
7000 (define_expand "muldi3"
7001   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7002                    (mult:DI (match_operand:DI 1 "register_operand" "")
7003                             (match_operand:DI 2 "x86_64_general_operand" "")))
7004               (clobber (reg:CC FLAGS_REG))])]
7005   "TARGET_64BIT"
7006   "")
7007
7008 (define_insn "*muldi3_1_rex64"
7009   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7010         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7011                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "TARGET_64BIT
7014    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7015   "@
7016    imul{q}\t{%2, %1, %0|%0, %1, %2}
7017    imul{q}\t{%2, %1, %0|%0, %1, %2}
7018    imul{q}\t{%2, %0|%0, %2}"
7019   [(set_attr "type" "imul")
7020    (set_attr "prefix_0f" "0,0,1")
7021    (set (attr "athlon_decode")
7022         (cond [(eq_attr "cpu" "athlon")
7023                   (const_string "vector")
7024                (eq_attr "alternative" "1")
7025                   (const_string "vector")
7026                (and (eq_attr "alternative" "2")
7027                     (match_operand 1 "memory_operand" ""))
7028                   (const_string "vector")]
7029               (const_string "direct")))
7030    (set_attr "mode" "DI")])
7031
7032 (define_expand "mulsi3"
7033   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7034                    (mult:SI (match_operand:SI 1 "register_operand" "")
7035                             (match_operand:SI 2 "general_operand" "")))
7036               (clobber (reg:CC FLAGS_REG))])]
7037   ""
7038   "")
7039
7040 (define_insn "*mulsi3_1"
7041   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7042         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7043                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7044    (clobber (reg:CC FLAGS_REG))]
7045   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7046   "@
7047    imul{l}\t{%2, %1, %0|%0, %1, %2}
7048    imul{l}\t{%2, %1, %0|%0, %1, %2}
7049    imul{l}\t{%2, %0|%0, %2}"
7050   [(set_attr "type" "imul")
7051    (set_attr "prefix_0f" "0,0,1")
7052    (set (attr "athlon_decode")
7053         (cond [(eq_attr "cpu" "athlon")
7054                   (const_string "vector")
7055                (eq_attr "alternative" "1")
7056                   (const_string "vector")
7057                (and (eq_attr "alternative" "2")
7058                     (match_operand 1 "memory_operand" ""))
7059                   (const_string "vector")]
7060               (const_string "direct")))
7061    (set_attr "mode" "SI")])
7062
7063 (define_insn "*mulsi3_1_zext"
7064   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7065         (zero_extend:DI
7066           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7067                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "TARGET_64BIT
7070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071   "@
7072    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7073    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7074    imul{l}\t{%2, %k0|%k0, %2}"
7075   [(set_attr "type" "imul")
7076    (set_attr "prefix_0f" "0,0,1")
7077    (set (attr "athlon_decode")
7078         (cond [(eq_attr "cpu" "athlon")
7079                   (const_string "vector")
7080                (eq_attr "alternative" "1")
7081                   (const_string "vector")
7082                (and (eq_attr "alternative" "2")
7083                     (match_operand 1 "memory_operand" ""))
7084                   (const_string "vector")]
7085               (const_string "direct")))
7086    (set_attr "mode" "SI")])
7087
7088 (define_expand "mulhi3"
7089   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7090                    (mult:HI (match_operand:HI 1 "register_operand" "")
7091                             (match_operand:HI 2 "general_operand" "")))
7092               (clobber (reg:CC FLAGS_REG))])]
7093   "TARGET_HIMODE_MATH"
7094   "")
7095
7096 (define_insn "*mulhi3_1"
7097   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7098         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7099                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7102   "@
7103    imul{w}\t{%2, %1, %0|%0, %1, %2}
7104    imul{w}\t{%2, %1, %0|%0, %1, %2}
7105    imul{w}\t{%2, %0|%0, %2}"
7106   [(set_attr "type" "imul")
7107    (set_attr "prefix_0f" "0,0,1")
7108    (set (attr "athlon_decode")
7109         (cond [(eq_attr "cpu" "athlon")
7110                   (const_string "vector")
7111                (eq_attr "alternative" "1,2")
7112                   (const_string "vector")]
7113               (const_string "direct")))
7114    (set_attr "mode" "HI")])
7115
7116 (define_expand "mulqi3"
7117   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7118                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7119                             (match_operand:QI 2 "register_operand" "")))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   "TARGET_QIMODE_MATH"
7122   "")
7123
7124 (define_insn "*mulqi3_1"
7125   [(set (match_operand:QI 0 "register_operand" "=a")
7126         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7127                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7128    (clobber (reg:CC FLAGS_REG))]
7129   "TARGET_QIMODE_MATH
7130    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7131   "mul{b}\t%2"
7132   [(set_attr "type" "imul")
7133    (set_attr "length_immediate" "0")
7134    (set (attr "athlon_decode")
7135      (if_then_else (eq_attr "cpu" "athlon")
7136         (const_string "vector")
7137         (const_string "direct")))
7138    (set_attr "mode" "QI")])
7139
7140 (define_expand "umulqihi3"
7141   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7142                    (mult:HI (zero_extend:HI
7143                               (match_operand:QI 1 "nonimmediate_operand" ""))
7144                             (zero_extend:HI
7145                               (match_operand:QI 2 "register_operand" ""))))
7146               (clobber (reg:CC FLAGS_REG))])]
7147   "TARGET_QIMODE_MATH"
7148   "")
7149
7150 (define_insn "*umulqihi3_1"
7151   [(set (match_operand:HI 0 "register_operand" "=a")
7152         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7154    (clobber (reg:CC FLAGS_REG))]
7155   "TARGET_QIMODE_MATH
7156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7157   "mul{b}\t%2"
7158   [(set_attr "type" "imul")
7159    (set_attr "length_immediate" "0")
7160    (set (attr "athlon_decode")
7161      (if_then_else (eq_attr "cpu" "athlon")
7162         (const_string "vector")
7163         (const_string "direct")))
7164    (set_attr "mode" "QI")])
7165
7166 (define_expand "mulqihi3"
7167   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7168                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7169                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "TARGET_QIMODE_MATH"
7172   "")
7173
7174 (define_insn "*mulqihi3_insn"
7175   [(set (match_operand:HI 0 "register_operand" "=a")
7176         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7177                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "TARGET_QIMODE_MATH
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "imul{b}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "direct")))
7188    (set_attr "mode" "QI")])
7189
7190 (define_expand "umulditi3"
7191   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192                    (mult:TI (zero_extend:TI
7193                               (match_operand:DI 1 "nonimmediate_operand" ""))
7194                             (zero_extend:TI
7195                               (match_operand:DI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "TARGET_64BIT"
7198   "")
7199
7200 (define_insn "*umulditi3_insn"
7201   [(set (match_operand:TI 0 "register_operand" "=A")
7202         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "mul{q}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "DI")])
7215
7216 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7217 (define_expand "umulsidi3"
7218   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7219                    (mult:DI (zero_extend:DI
7220                               (match_operand:SI 1 "nonimmediate_operand" ""))
7221                             (zero_extend:DI
7222                               (match_operand:SI 2 "register_operand" ""))))
7223               (clobber (reg:CC FLAGS_REG))])]
7224   "!TARGET_64BIT"
7225   "")
7226
7227 (define_insn "*umulsidi3_insn"
7228   [(set (match_operand:DI 0 "register_operand" "=A")
7229         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7230                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "!TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{l}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
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 (define_expand "mulditi3"
7244   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7245                    (mult:TI (sign_extend:TI
7246                               (match_operand:DI 1 "nonimmediate_operand" ""))
7247                             (sign_extend:TI
7248                               (match_operand:DI 2 "register_operand" ""))))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   "TARGET_64BIT"
7251   "")
7252
7253 (define_insn "*mulditi3_insn"
7254   [(set (match_operand:TI 0 "register_operand" "=A")
7255         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7256                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "TARGET_64BIT
7259    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260   "imul{q}\t%2"
7261   [(set_attr "type" "imul")
7262    (set_attr "length_immediate" "0")
7263    (set (attr "athlon_decode")
7264      (if_then_else (eq_attr "cpu" "athlon")
7265         (const_string "vector")
7266         (const_string "double")))
7267    (set_attr "mode" "DI")])
7268
7269 (define_expand "mulsidi3"
7270   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7271                    (mult:DI (sign_extend:DI
7272                               (match_operand:SI 1 "nonimmediate_operand" ""))
7273                             (sign_extend:DI
7274                               (match_operand:SI 2 "register_operand" ""))))
7275               (clobber (reg:CC FLAGS_REG))])]
7276   "!TARGET_64BIT"
7277   "")
7278
7279 (define_insn "*mulsidi3_insn"
7280   [(set (match_operand:DI 0 "register_operand" "=A")
7281         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7282                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "!TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set_attr "length_immediate" "0")
7289    (set (attr "athlon_decode")
7290      (if_then_else (eq_attr "cpu" "athlon")
7291         (const_string "vector")
7292         (const_string "double")))
7293    (set_attr "mode" "SI")])
7294
7295 (define_expand "umuldi3_highpart"
7296   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7297                    (truncate:DI
7298                      (lshiftrt:TI
7299                        (mult:TI (zero_extend:TI
7300                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7301                                 (zero_extend:TI
7302                                   (match_operand:DI 2 "register_operand" "")))
7303                        (const_int 64))))
7304               (clobber (match_scratch:DI 3 ""))
7305               (clobber (reg:CC FLAGS_REG))])]
7306   "TARGET_64BIT"
7307   "")
7308
7309 (define_insn "*umuldi3_highpart_rex64"
7310   [(set (match_operand:DI 0 "register_operand" "=d")
7311         (truncate:DI
7312           (lshiftrt:TI
7313             (mult:TI (zero_extend:TI
7314                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7315                      (zero_extend:TI
7316                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7317             (const_int 64))))
7318    (clobber (match_scratch:DI 3 "=1"))
7319    (clobber (reg:CC FLAGS_REG))]
7320   "TARGET_64BIT
7321    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7322   "mul{q}\t%2"
7323   [(set_attr "type" "imul")
7324    (set_attr "length_immediate" "0")
7325    (set (attr "athlon_decode")
7326      (if_then_else (eq_attr "cpu" "athlon")
7327         (const_string "vector")
7328         (const_string "double")))
7329    (set_attr "mode" "DI")])
7330
7331 (define_expand "umulsi3_highpart"
7332   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7333                    (truncate:SI
7334                      (lshiftrt:DI
7335                        (mult:DI (zero_extend:DI
7336                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7337                                 (zero_extend:DI
7338                                   (match_operand:SI 2 "register_operand" "")))
7339                        (const_int 32))))
7340               (clobber (match_scratch:SI 3 ""))
7341               (clobber (reg:CC FLAGS_REG))])]
7342   ""
7343   "")
7344
7345 (define_insn "*umulsi3_highpart_insn"
7346   [(set (match_operand:SI 0 "register_operand" "=d")
7347         (truncate:SI
7348           (lshiftrt:DI
7349             (mult:DI (zero_extend:DI
7350                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7351                      (zero_extend:DI
7352                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7353             (const_int 32))))
7354    (clobber (match_scratch:SI 3 "=1"))
7355    (clobber (reg:CC FLAGS_REG))]
7356   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7357   "mul{l}\t%2"
7358   [(set_attr "type" "imul")
7359    (set_attr "length_immediate" "0")
7360    (set (attr "athlon_decode")
7361      (if_then_else (eq_attr "cpu" "athlon")
7362         (const_string "vector")
7363         (const_string "double")))
7364    (set_attr "mode" "SI")])
7365
7366 (define_insn "*umulsi3_highpart_zext"
7367   [(set (match_operand:DI 0 "register_operand" "=d")
7368         (zero_extend:DI (truncate:SI
7369           (lshiftrt:DI
7370             (mult:DI (zero_extend:DI
7371                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7372                      (zero_extend:DI
7373                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7374             (const_int 32)))))
7375    (clobber (match_scratch:SI 3 "=1"))
7376    (clobber (reg:CC FLAGS_REG))]
7377   "TARGET_64BIT
7378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7379   "mul{l}\t%2"
7380   [(set_attr "type" "imul")
7381    (set_attr "length_immediate" "0")
7382    (set (attr "athlon_decode")
7383      (if_then_else (eq_attr "cpu" "athlon")
7384         (const_string "vector")
7385         (const_string "double")))
7386    (set_attr "mode" "SI")])
7387
7388 (define_expand "smuldi3_highpart"
7389   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7390                    (truncate:DI
7391                      (lshiftrt:TI
7392                        (mult:TI (sign_extend:TI
7393                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7394                                 (sign_extend:TI
7395                                   (match_operand:DI 2 "register_operand" "")))
7396                        (const_int 64))))
7397               (clobber (match_scratch:DI 3 ""))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   "TARGET_64BIT"
7400   "")
7401
7402 (define_insn "*smuldi3_highpart_rex64"
7403   [(set (match_operand:DI 0 "register_operand" "=d")
7404         (truncate:DI
7405           (lshiftrt:TI
7406             (mult:TI (sign_extend:TI
7407                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7408                      (sign_extend:TI
7409                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7410             (const_int 64))))
7411    (clobber (match_scratch:DI 3 "=1"))
7412    (clobber (reg:CC FLAGS_REG))]
7413   "TARGET_64BIT
7414    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7415   "imul{q}\t%2"
7416   [(set_attr "type" "imul")
7417    (set (attr "athlon_decode")
7418      (if_then_else (eq_attr "cpu" "athlon")
7419         (const_string "vector")
7420         (const_string "double")))
7421    (set_attr "mode" "DI")])
7422
7423 (define_expand "smulsi3_highpart"
7424   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7425                    (truncate:SI
7426                      (lshiftrt:DI
7427                        (mult:DI (sign_extend:DI
7428                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7429                                 (sign_extend:DI
7430                                   (match_operand:SI 2 "register_operand" "")))
7431                        (const_int 32))))
7432               (clobber (match_scratch:SI 3 ""))
7433               (clobber (reg:CC FLAGS_REG))])]
7434   ""
7435   "")
7436
7437 (define_insn "*smulsi3_highpart_insn"
7438   [(set (match_operand:SI 0 "register_operand" "=d")
7439         (truncate:SI
7440           (lshiftrt:DI
7441             (mult:DI (sign_extend:DI
7442                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7443                      (sign_extend:DI
7444                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7445             (const_int 32))))
7446    (clobber (match_scratch:SI 3 "=1"))
7447    (clobber (reg:CC FLAGS_REG))]
7448   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7449   "imul{l}\t%2"
7450   [(set_attr "type" "imul")
7451    (set (attr "athlon_decode")
7452      (if_then_else (eq_attr "cpu" "athlon")
7453         (const_string "vector")
7454         (const_string "double")))
7455    (set_attr "mode" "SI")])
7456
7457 (define_insn "*smulsi3_highpart_zext"
7458   [(set (match_operand:DI 0 "register_operand" "=d")
7459         (zero_extend:DI (truncate:SI
7460           (lshiftrt:DI
7461             (mult:DI (sign_extend:DI
7462                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7463                      (sign_extend:DI
7464                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7465             (const_int 32)))))
7466    (clobber (match_scratch:SI 3 "=1"))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "TARGET_64BIT
7469    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7470   "imul{l}\t%2"
7471   [(set_attr "type" "imul")
7472    (set (attr "athlon_decode")
7473      (if_then_else (eq_attr "cpu" "athlon")
7474         (const_string "vector")
7475         (const_string "double")))
7476    (set_attr "mode" "SI")])
7477
7478 ;; The patterns that match these are at the end of this file.
7479
7480 (define_expand "mulxf3"
7481   [(set (match_operand:XF 0 "register_operand" "")
7482         (mult:XF (match_operand:XF 1 "register_operand" "")
7483                  (match_operand:XF 2 "register_operand" "")))]
7484   "TARGET_80387"
7485   "")
7486
7487 (define_expand "muldf3"
7488   [(set (match_operand:DF 0 "register_operand" "")
7489         (mult:DF (match_operand:DF 1 "register_operand" "")
7490                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7491   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7492   "")
7493
7494 (define_expand "mulsf3"
7495   [(set (match_operand:SF 0 "register_operand" "")
7496         (mult:SF (match_operand:SF 1 "register_operand" "")
7497                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7498   "TARGET_80387 || TARGET_SSE_MATH"
7499   "")
7500 \f
7501 ;; Divide instructions
7502
7503 (define_insn "divqi3"
7504   [(set (match_operand:QI 0 "register_operand" "=a")
7505         (div:QI (match_operand:HI 1 "register_operand" "0")
7506                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_QIMODE_MATH"
7509   "idiv{b}\t%2"
7510   [(set_attr "type" "idiv")
7511    (set_attr "mode" "QI")])
7512
7513 (define_insn "udivqi3"
7514   [(set (match_operand:QI 0 "register_operand" "=a")
7515         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7516                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "TARGET_QIMODE_MATH"
7519   "div{b}\t%2"
7520   [(set_attr "type" "idiv")
7521    (set_attr "mode" "QI")])
7522
7523 ;; The patterns that match these are at the end of this file.
7524
7525 (define_expand "divxf3"
7526   [(set (match_operand:XF 0 "register_operand" "")
7527         (div:XF (match_operand:XF 1 "register_operand" "")
7528                 (match_operand:XF 2 "register_operand" "")))]
7529   "TARGET_80387"
7530   "")
7531
7532 (define_expand "divdf3"
7533   [(set (match_operand:DF 0 "register_operand" "")
7534         (div:DF (match_operand:DF 1 "register_operand" "")
7535                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7536    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7537    "")
7538  
7539 (define_expand "divsf3"
7540   [(set (match_operand:SF 0 "register_operand" "")
7541         (div:SF (match_operand:SF 1 "register_operand" "")
7542                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7543   "TARGET_80387 || TARGET_SSE_MATH"
7544   "")
7545 \f
7546 ;; Remainder instructions.
7547
7548 (define_expand "divmoddi4"
7549   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7550                    (div:DI (match_operand:DI 1 "register_operand" "")
7551                            (match_operand:DI 2 "nonimmediate_operand" "")))
7552               (set (match_operand:DI 3 "register_operand" "")
7553                    (mod:DI (match_dup 1) (match_dup 2)))
7554               (clobber (reg:CC FLAGS_REG))])]
7555   "TARGET_64BIT"
7556   "")
7557
7558 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7559 ;; Penalize eax case slightly because it results in worse scheduling
7560 ;; of code.
7561 (define_insn "*divmoddi4_nocltd_rex64"
7562   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7563         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7564                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7565    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7566         (mod:DI (match_dup 2) (match_dup 3)))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7569   "#"
7570   [(set_attr "type" "multi")])
7571
7572 (define_insn "*divmoddi4_cltd_rex64"
7573   [(set (match_operand:DI 0 "register_operand" "=a")
7574         (div:DI (match_operand:DI 2 "register_operand" "a")
7575                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7576    (set (match_operand:DI 1 "register_operand" "=&d")
7577         (mod:DI (match_dup 2) (match_dup 3)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7580   "#"
7581   [(set_attr "type" "multi")])
7582
7583 (define_insn "*divmoddi_noext_rex64"
7584   [(set (match_operand:DI 0 "register_operand" "=a")
7585         (div:DI (match_operand:DI 1 "register_operand" "0")
7586                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7587    (set (match_operand:DI 3 "register_operand" "=d")
7588         (mod:DI (match_dup 1) (match_dup 2)))
7589    (use (match_operand:DI 4 "register_operand" "3"))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_64BIT"
7592   "idiv{q}\t%2"
7593   [(set_attr "type" "idiv")
7594    (set_attr "mode" "DI")])
7595
7596 (define_split
7597   [(set (match_operand:DI 0 "register_operand" "")
7598         (div:DI (match_operand:DI 1 "register_operand" "")
7599                 (match_operand:DI 2 "nonimmediate_operand" "")))
7600    (set (match_operand:DI 3 "register_operand" "")
7601         (mod:DI (match_dup 1) (match_dup 2)))
7602    (clobber (reg:CC FLAGS_REG))]
7603   "TARGET_64BIT && reload_completed"
7604   [(parallel [(set (match_dup 3)
7605                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7606               (clobber (reg:CC FLAGS_REG))])
7607    (parallel [(set (match_dup 0)
7608                    (div:DI (reg:DI 0) (match_dup 2)))
7609               (set (match_dup 3)
7610                    (mod:DI (reg:DI 0) (match_dup 2)))
7611               (use (match_dup 3))
7612               (clobber (reg:CC FLAGS_REG))])]
7613 {
7614   /* Avoid use of cltd in favor of a mov+shift.  */
7615   if (!TARGET_USE_CLTD && !optimize_size)
7616     {
7617       if (true_regnum (operands[1]))
7618         emit_move_insn (operands[0], operands[1]);
7619       else
7620         emit_move_insn (operands[3], operands[1]);
7621       operands[4] = operands[3];
7622     }
7623   else
7624     {
7625       if (true_regnum (operands[1]))
7626         abort();
7627       operands[4] = operands[1];
7628     }
7629 })
7630
7631
7632 (define_expand "divmodsi4"
7633   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7634                    (div:SI (match_operand:SI 1 "register_operand" "")
7635                            (match_operand:SI 2 "nonimmediate_operand" "")))
7636               (set (match_operand:SI 3 "register_operand" "")
7637                    (mod:SI (match_dup 1) (match_dup 2)))
7638               (clobber (reg:CC FLAGS_REG))])]
7639   ""
7640   "")
7641
7642 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7643 ;; Penalize eax case slightly because it results in worse scheduling
7644 ;; of code.
7645 (define_insn "*divmodsi4_nocltd"
7646   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7647         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7648                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7649    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7650         (mod:SI (match_dup 2) (match_dup 3)))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "!optimize_size && !TARGET_USE_CLTD"
7653   "#"
7654   [(set_attr "type" "multi")])
7655
7656 (define_insn "*divmodsi4_cltd"
7657   [(set (match_operand:SI 0 "register_operand" "=a")
7658         (div:SI (match_operand:SI 2 "register_operand" "a")
7659                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7660    (set (match_operand:SI 1 "register_operand" "=&d")
7661         (mod:SI (match_dup 2) (match_dup 3)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "optimize_size || TARGET_USE_CLTD"
7664   "#"
7665   [(set_attr "type" "multi")])
7666
7667 (define_insn "*divmodsi_noext"
7668   [(set (match_operand:SI 0 "register_operand" "=a")
7669         (div:SI (match_operand:SI 1 "register_operand" "0")
7670                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7671    (set (match_operand:SI 3 "register_operand" "=d")
7672         (mod:SI (match_dup 1) (match_dup 2)))
7673    (use (match_operand:SI 4 "register_operand" "3"))
7674    (clobber (reg:CC FLAGS_REG))]
7675   ""
7676   "idiv{l}\t%2"
7677   [(set_attr "type" "idiv")
7678    (set_attr "mode" "SI")])
7679
7680 (define_split
7681   [(set (match_operand:SI 0 "register_operand" "")
7682         (div:SI (match_operand:SI 1 "register_operand" "")
7683                 (match_operand:SI 2 "nonimmediate_operand" "")))
7684    (set (match_operand:SI 3 "register_operand" "")
7685         (mod:SI (match_dup 1) (match_dup 2)))
7686    (clobber (reg:CC FLAGS_REG))]
7687   "reload_completed"
7688   [(parallel [(set (match_dup 3)
7689                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7690               (clobber (reg:CC FLAGS_REG))])
7691    (parallel [(set (match_dup 0)
7692                    (div:SI (reg:SI 0) (match_dup 2)))
7693               (set (match_dup 3)
7694                    (mod:SI (reg:SI 0) (match_dup 2)))
7695               (use (match_dup 3))
7696               (clobber (reg:CC FLAGS_REG))])]
7697 {
7698   /* Avoid use of cltd in favor of a mov+shift.  */
7699   if (!TARGET_USE_CLTD && !optimize_size)
7700     {
7701       if (true_regnum (operands[1]))
7702         emit_move_insn (operands[0], operands[1]);
7703       else
7704         emit_move_insn (operands[3], operands[1]);
7705       operands[4] = operands[3];
7706     }
7707   else
7708     {
7709       if (true_regnum (operands[1]))
7710         abort();
7711       operands[4] = operands[1];
7712     }
7713 })
7714 ;; %%% Split me.
7715 (define_insn "divmodhi4"
7716   [(set (match_operand:HI 0 "register_operand" "=a")
7717         (div:HI (match_operand:HI 1 "register_operand" "0")
7718                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7719    (set (match_operand:HI 3 "register_operand" "=&d")
7720         (mod:HI (match_dup 1) (match_dup 2)))
7721    (clobber (reg:CC FLAGS_REG))]
7722   "TARGET_HIMODE_MATH"
7723   "cwtd\;idiv{w}\t%2"
7724   [(set_attr "type" "multi")
7725    (set_attr "length_immediate" "0")
7726    (set_attr "mode" "SI")])
7727
7728 (define_insn "udivmoddi4"
7729   [(set (match_operand:DI 0 "register_operand" "=a")
7730         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7731                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7732    (set (match_operand:DI 3 "register_operand" "=&d")
7733         (umod:DI (match_dup 1) (match_dup 2)))
7734    (clobber (reg:CC FLAGS_REG))]
7735   "TARGET_64BIT"
7736   "xor{q}\t%3, %3\;div{q}\t%2"
7737   [(set_attr "type" "multi")
7738    (set_attr "length_immediate" "0")
7739    (set_attr "mode" "DI")])
7740
7741 (define_insn "*udivmoddi4_noext"
7742   [(set (match_operand:DI 0 "register_operand" "=a")
7743         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7744                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7745    (set (match_operand:DI 3 "register_operand" "=d")
7746         (umod:DI (match_dup 1) (match_dup 2)))
7747    (use (match_dup 3))
7748    (clobber (reg:CC FLAGS_REG))]
7749   "TARGET_64BIT"
7750   "div{q}\t%2"
7751   [(set_attr "type" "idiv")
7752    (set_attr "mode" "DI")])
7753
7754 (define_split
7755   [(set (match_operand:DI 0 "register_operand" "")
7756         (udiv:DI (match_operand:DI 1 "register_operand" "")
7757                  (match_operand:DI 2 "nonimmediate_operand" "")))
7758    (set (match_operand:DI 3 "register_operand" "")
7759         (umod:DI (match_dup 1) (match_dup 2)))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_64BIT && reload_completed"
7762   [(set (match_dup 3) (const_int 0))
7763    (parallel [(set (match_dup 0)
7764                    (udiv:DI (match_dup 1) (match_dup 2)))
7765               (set (match_dup 3)
7766                    (umod:DI (match_dup 1) (match_dup 2)))
7767               (use (match_dup 3))
7768               (clobber (reg:CC FLAGS_REG))])]
7769   "")
7770
7771 (define_insn "udivmodsi4"
7772   [(set (match_operand:SI 0 "register_operand" "=a")
7773         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7774                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7775    (set (match_operand:SI 3 "register_operand" "=&d")
7776         (umod:SI (match_dup 1) (match_dup 2)))
7777    (clobber (reg:CC FLAGS_REG))]
7778   ""
7779   "xor{l}\t%3, %3\;div{l}\t%2"
7780   [(set_attr "type" "multi")
7781    (set_attr "length_immediate" "0")
7782    (set_attr "mode" "SI")])
7783
7784 (define_insn "*udivmodsi4_noext"
7785   [(set (match_operand:SI 0 "register_operand" "=a")
7786         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7787                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7788    (set (match_operand:SI 3 "register_operand" "=d")
7789         (umod:SI (match_dup 1) (match_dup 2)))
7790    (use (match_dup 3))
7791    (clobber (reg:CC FLAGS_REG))]
7792   ""
7793   "div{l}\t%2"
7794   [(set_attr "type" "idiv")
7795    (set_attr "mode" "SI")])
7796
7797 (define_split
7798   [(set (match_operand:SI 0 "register_operand" "")
7799         (udiv:SI (match_operand:SI 1 "register_operand" "")
7800                  (match_operand:SI 2 "nonimmediate_operand" "")))
7801    (set (match_operand:SI 3 "register_operand" "")
7802         (umod:SI (match_dup 1) (match_dup 2)))
7803    (clobber (reg:CC FLAGS_REG))]
7804   "reload_completed"
7805   [(set (match_dup 3) (const_int 0))
7806    (parallel [(set (match_dup 0)
7807                    (udiv:SI (match_dup 1) (match_dup 2)))
7808               (set (match_dup 3)
7809                    (umod:SI (match_dup 1) (match_dup 2)))
7810               (use (match_dup 3))
7811               (clobber (reg:CC FLAGS_REG))])]
7812   "")
7813
7814 (define_expand "udivmodhi4"
7815   [(set (match_dup 4) (const_int 0))
7816    (parallel [(set (match_operand:HI 0 "register_operand" "")
7817                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7818                             (match_operand:HI 2 "nonimmediate_operand" "")))
7819               (set (match_operand:HI 3 "register_operand" "")
7820                    (umod:HI (match_dup 1) (match_dup 2)))
7821               (use (match_dup 4))
7822               (clobber (reg:CC FLAGS_REG))])]
7823   "TARGET_HIMODE_MATH"
7824   "operands[4] = gen_reg_rtx (HImode);")
7825
7826 (define_insn "*udivmodhi_noext"
7827   [(set (match_operand:HI 0 "register_operand" "=a")
7828         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7829                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7830    (set (match_operand:HI 3 "register_operand" "=d")
7831         (umod:HI (match_dup 1) (match_dup 2)))
7832    (use (match_operand:HI 4 "register_operand" "3"))
7833    (clobber (reg:CC FLAGS_REG))]
7834   ""
7835   "div{w}\t%2"
7836   [(set_attr "type" "idiv")
7837    (set_attr "mode" "HI")])
7838
7839 ;; We cannot use div/idiv for double division, because it causes
7840 ;; "division by zero" on the overflow and that's not what we expect
7841 ;; from truncate.  Because true (non truncating) double division is
7842 ;; never generated, we can't create this insn anyway.
7843 ;
7844 ;(define_insn ""
7845 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7846 ;       (truncate:SI
7847 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7848 ;                  (zero_extend:DI
7849 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7850 ;   (set (match_operand:SI 3 "register_operand" "=d")
7851 ;       (truncate:SI
7852 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7853 ;   (clobber (reg:CC FLAGS_REG))]
7854 ;  ""
7855 ;  "div{l}\t{%2, %0|%0, %2}"
7856 ;  [(set_attr "type" "idiv")])
7857 \f
7858 ;;- Logical AND instructions
7859
7860 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7861 ;; Note that this excludes ah.
7862
7863 (define_insn "*testdi_1_rex64"
7864   [(set (reg 17)
7865         (compare
7866           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7867                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7868           (const_int 0)))]
7869   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871   "@
7872    test{l}\t{%k1, %k0|%k0, %k1}
7873    test{l}\t{%k1, %k0|%k0, %k1}
7874    test{q}\t{%1, %0|%0, %1}
7875    test{q}\t{%1, %0|%0, %1}
7876    test{q}\t{%1, %0|%0, %1}"
7877   [(set_attr "type" "test")
7878    (set_attr "modrm" "0,1,0,1,1")
7879    (set_attr "mode" "SI,SI,DI,DI,DI")
7880    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7881
7882 (define_insn "testsi_1"
7883   [(set (reg 17)
7884         (compare
7885           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7886                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7887           (const_int 0)))]
7888   "ix86_match_ccmode (insn, CCNOmode)
7889    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7890   "test{l}\t{%1, %0|%0, %1}"
7891   [(set_attr "type" "test")
7892    (set_attr "modrm" "0,1,1")
7893    (set_attr "mode" "SI")
7894    (set_attr "pent_pair" "uv,np,uv")])
7895
7896 (define_expand "testsi_ccno_1"
7897   [(set (reg:CCNO FLAGS_REG)
7898         (compare:CCNO
7899           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7900                   (match_operand:SI 1 "nonmemory_operand" ""))
7901           (const_int 0)))]
7902   ""
7903   "")
7904
7905 (define_insn "*testhi_1"
7906   [(set (reg 17)
7907         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7908                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7909                  (const_int 0)))]
7910   "ix86_match_ccmode (insn, CCNOmode)
7911    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7912   "test{w}\t{%1, %0|%0, %1}"
7913   [(set_attr "type" "test")
7914    (set_attr "modrm" "0,1,1")
7915    (set_attr "mode" "HI")
7916    (set_attr "pent_pair" "uv,np,uv")])
7917
7918 (define_expand "testqi_ccz_1"
7919   [(set (reg:CCZ FLAGS_REG)
7920         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7921                              (match_operand:QI 1 "nonmemory_operand" ""))
7922                  (const_int 0)))]
7923   ""
7924   "")
7925
7926 (define_insn "*testqi_1"
7927   [(set (reg 17)
7928         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7929                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7930                  (const_int 0)))]
7931   "ix86_match_ccmode (insn, CCNOmode)
7932    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7933 {
7934   if (which_alternative == 3)
7935     {
7936       if (GET_CODE (operands[1]) == CONST_INT
7937           && (INTVAL (operands[1]) & 0xffffff00))
7938         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7939       return "test{l}\t{%1, %k0|%k0, %1}";
7940     }
7941   return "test{b}\t{%1, %0|%0, %1}";
7942 }
7943   [(set_attr "type" "test")
7944    (set_attr "modrm" "0,1,1,1")
7945    (set_attr "mode" "QI,QI,QI,SI")
7946    (set_attr "pent_pair" "uv,np,uv,np")])
7947
7948 (define_expand "testqi_ext_ccno_0"
7949   [(set (reg:CCNO FLAGS_REG)
7950         (compare:CCNO
7951           (and:SI
7952             (zero_extract:SI
7953               (match_operand 0 "ext_register_operand" "")
7954               (const_int 8)
7955               (const_int 8))
7956             (match_operand 1 "const_int_operand" ""))
7957           (const_int 0)))]
7958   ""
7959   "")
7960
7961 (define_insn "*testqi_ext_0"
7962   [(set (reg 17)
7963         (compare
7964           (and:SI
7965             (zero_extract:SI
7966               (match_operand 0 "ext_register_operand" "Q")
7967               (const_int 8)
7968               (const_int 8))
7969             (match_operand 1 "const_int_operand" "n"))
7970           (const_int 0)))]
7971   "ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%1, %h0|%h0, %1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")
7975    (set_attr "length_immediate" "1")
7976    (set_attr "pent_pair" "np")])
7977
7978 (define_insn "*testqi_ext_1"
7979   [(set (reg 17)
7980         (compare
7981           (and:SI
7982             (zero_extract:SI
7983               (match_operand 0 "ext_register_operand" "Q")
7984               (const_int 8)
7985               (const_int 8))
7986             (zero_extend:SI
7987               (match_operand:QI 1 "general_operand" "Qm")))
7988           (const_int 0)))]
7989   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7990    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7991   "test{b}\t{%1, %h0|%h0, %1}"
7992   [(set_attr "type" "test")
7993    (set_attr "mode" "QI")])
7994
7995 (define_insn "*testqi_ext_1_rex64"
7996   [(set (reg 17)
7997         (compare
7998           (and:SI
7999             (zero_extract:SI
8000               (match_operand 0 "ext_register_operand" "Q")
8001               (const_int 8)
8002               (const_int 8))
8003             (zero_extend:SI
8004               (match_operand:QI 1 "register_operand" "Q")))
8005           (const_int 0)))]
8006   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8007   "test{b}\t{%1, %h0|%h0, %1}"
8008   [(set_attr "type" "test")
8009    (set_attr "mode" "QI")])
8010
8011 (define_insn "*testqi_ext_2"
8012   [(set (reg 17)
8013         (compare
8014           (and:SI
8015             (zero_extract:SI
8016               (match_operand 0 "ext_register_operand" "Q")
8017               (const_int 8)
8018               (const_int 8))
8019             (zero_extract:SI
8020               (match_operand 1 "ext_register_operand" "Q")
8021               (const_int 8)
8022               (const_int 8)))
8023           (const_int 0)))]
8024   "ix86_match_ccmode (insn, CCNOmode)"
8025   "test{b}\t{%h1, %h0|%h0, %h1}"
8026   [(set_attr "type" "test")
8027    (set_attr "mode" "QI")])
8028
8029 ;; Combine likes to form bit extractions for some tests.  Humor it.
8030 (define_insn "*testqi_ext_3"
8031   [(set (reg 17)
8032         (compare (zero_extract:SI
8033                    (match_operand 0 "nonimmediate_operand" "rm")
8034                    (match_operand:SI 1 "const_int_operand" "")
8035                    (match_operand:SI 2 "const_int_operand" ""))
8036                  (const_int 0)))]
8037   "ix86_match_ccmode (insn, CCNOmode)
8038    && (GET_MODE (operands[0]) == SImode
8039        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8040        || GET_MODE (operands[0]) == HImode
8041        || GET_MODE (operands[0]) == QImode)"
8042   "#")
8043
8044 (define_insn "*testqi_ext_3_rex64"
8045   [(set (reg 17)
8046         (compare (zero_extract:DI
8047                    (match_operand 0 "nonimmediate_operand" "rm")
8048                    (match_operand:DI 1 "const_int_operand" "")
8049                    (match_operand:DI 2 "const_int_operand" ""))
8050                  (const_int 0)))]
8051   "TARGET_64BIT
8052    && ix86_match_ccmode (insn, CCNOmode)
8053    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8054    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8055    /* Ensure that resulting mask is zero or sign extended operand.  */
8056    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8057        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8058            && INTVAL (operands[1]) > 32))
8059    && (GET_MODE (operands[0]) == SImode
8060        || GET_MODE (operands[0]) == DImode
8061        || GET_MODE (operands[0]) == HImode
8062        || GET_MODE (operands[0]) == QImode)"
8063   "#")
8064
8065 (define_split
8066   [(set (reg 17)
8067         (compare (zero_extract
8068                    (match_operand 0 "nonimmediate_operand" "")
8069                    (match_operand 1 "const_int_operand" "")
8070                    (match_operand 2 "const_int_operand" ""))
8071                  (const_int 0)))]
8072   "ix86_match_ccmode (insn, CCNOmode)"
8073   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8074 {
8075   HOST_WIDE_INT len = INTVAL (operands[1]);
8076   HOST_WIDE_INT pos = INTVAL (operands[2]);
8077   HOST_WIDE_INT mask;
8078   enum machine_mode mode, submode;
8079
8080   mode = GET_MODE (operands[0]);
8081   if (GET_CODE (operands[0]) == MEM)
8082     {
8083       /* ??? Combine likes to put non-volatile mem extractions in QImode
8084          no matter the size of the test.  So find a mode that works.  */
8085       if (! MEM_VOLATILE_P (operands[0]))
8086         {
8087           mode = smallest_mode_for_size (pos + len, MODE_INT);
8088           operands[0] = adjust_address (operands[0], mode, 0);
8089         }
8090     }
8091   else if (GET_CODE (operands[0]) == SUBREG
8092            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8093                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8094            && pos + len <= GET_MODE_BITSIZE (submode))
8095     {
8096       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8097       mode = submode;
8098       operands[0] = SUBREG_REG (operands[0]);
8099     }
8100   else if (mode == HImode && pos + len <= 8)
8101     {
8102       /* Small HImode tests can be converted to QImode.  */
8103       mode = QImode;
8104       operands[0] = gen_lowpart (QImode, operands[0]);
8105     }
8106
8107   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8108   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8109
8110   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8111 })
8112
8113 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8114 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8115 ;; this is relatively important trick.
8116 ;; Do the conversion only post-reload to avoid limiting of the register class
8117 ;; to QI regs.
8118 (define_split
8119   [(set (reg 17)
8120         (compare
8121           (and (match_operand 0 "register_operand" "")
8122                (match_operand 1 "const_int_operand" ""))
8123           (const_int 0)))]
8124    "reload_completed
8125     && QI_REG_P (operands[0])
8126     && ((ix86_match_ccmode (insn, CCZmode)
8127          && !(INTVAL (operands[1]) & ~(255 << 8)))
8128         || (ix86_match_ccmode (insn, CCNOmode)
8129             && !(INTVAL (operands[1]) & ~(127 << 8))))
8130     && GET_MODE (operands[0]) != QImode"
8131   [(set (reg:CCNO FLAGS_REG)
8132         (compare:CCNO
8133           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134                   (match_dup 1))
8135           (const_int 0)))]
8136   "operands[0] = gen_lowpart (SImode, operands[0]);
8137    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8138
8139 (define_split
8140   [(set (reg 17)
8141         (compare
8142           (and (match_operand 0 "nonimmediate_operand" "")
8143                (match_operand 1 "const_int_operand" ""))
8144           (const_int 0)))]
8145    "reload_completed
8146     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8147     && ((ix86_match_ccmode (insn, CCZmode)
8148          && !(INTVAL (operands[1]) & ~255))
8149         || (ix86_match_ccmode (insn, CCNOmode)
8150             && !(INTVAL (operands[1]) & ~127)))
8151     && GET_MODE (operands[0]) != QImode"
8152   [(set (reg:CCNO FLAGS_REG)
8153         (compare:CCNO
8154           (and:QI (match_dup 0)
8155                   (match_dup 1))
8156           (const_int 0)))]
8157   "operands[0] = gen_lowpart (QImode, operands[0]);
8158    operands[1] = gen_lowpart (QImode, operands[1]);")
8159
8160
8161 ;; %%% This used to optimize known byte-wide and operations to memory,
8162 ;; and sometimes to QImode registers.  If this is considered useful,
8163 ;; it should be done with splitters.
8164
8165 (define_expand "anddi3"
8166   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8167         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8168                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "TARGET_64BIT"
8171   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8172
8173 (define_insn "*anddi_1_rex64"
8174   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8175         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8176                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8177    (clobber (reg:CC FLAGS_REG))]
8178   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8179 {
8180   switch (get_attr_type (insn))
8181     {
8182     case TYPE_IMOVX:
8183       {
8184         enum machine_mode mode;
8185
8186         if (GET_CODE (operands[2]) != CONST_INT)
8187           abort ();
8188         if (INTVAL (operands[2]) == 0xff)
8189           mode = QImode;
8190         else if (INTVAL (operands[2]) == 0xffff)
8191           mode = HImode;
8192         else
8193           abort ();
8194         
8195         operands[1] = gen_lowpart (mode, operands[1]);
8196         if (mode == QImode)
8197           return "movz{bq|x}\t{%1,%0|%0, %1}";
8198         else
8199           return "movz{wq|x}\t{%1,%0|%0, %1}";
8200       }
8201
8202     default:
8203       if (! rtx_equal_p (operands[0], operands[1]))
8204         abort ();
8205       if (get_attr_mode (insn) == MODE_SI)
8206         return "and{l}\t{%k2, %k0|%k0, %k2}";
8207       else
8208         return "and{q}\t{%2, %0|%0, %2}";
8209     }
8210 }
8211   [(set_attr "type" "alu,alu,alu,imovx")
8212    (set_attr "length_immediate" "*,*,*,0")
8213    (set_attr "mode" "SI,DI,DI,DI")])
8214
8215 (define_insn "*anddi_2"
8216   [(set (reg 17)
8217         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8218                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8219                  (const_int 0)))
8220    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8221         (and:DI (match_dup 1) (match_dup 2)))]
8222   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8223    && ix86_binary_operator_ok (AND, DImode, operands)"
8224   "@
8225    and{l}\t{%k2, %k0|%k0, %k2}
8226    and{q}\t{%2, %0|%0, %2}
8227    and{q}\t{%2, %0|%0, %2}"
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "SI,DI,DI")])
8230
8231 (define_expand "andsi3"
8232   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8233         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8234                 (match_operand:SI 2 "general_operand" "")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   ""
8237   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8238
8239 (define_insn "*andsi_1"
8240   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8241         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8242                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8243    (clobber (reg:CC FLAGS_REG))]
8244   "ix86_binary_operator_ok (AND, SImode, operands)"
8245 {
8246   switch (get_attr_type (insn))
8247     {
8248     case TYPE_IMOVX:
8249       {
8250         enum machine_mode mode;
8251
8252         if (GET_CODE (operands[2]) != CONST_INT)
8253           abort ();
8254         if (INTVAL (operands[2]) == 0xff)
8255           mode = QImode;
8256         else if (INTVAL (operands[2]) == 0xffff)
8257           mode = HImode;
8258         else
8259           abort ();
8260         
8261         operands[1] = gen_lowpart (mode, operands[1]);
8262         if (mode == QImode)
8263           return "movz{bl|x}\t{%1,%0|%0, %1}";
8264         else
8265           return "movz{wl|x}\t{%1,%0|%0, %1}";
8266       }
8267
8268     default:
8269       if (! rtx_equal_p (operands[0], operands[1]))
8270         abort ();
8271       return "and{l}\t{%2, %0|%0, %2}";
8272     }
8273 }
8274   [(set_attr "type" "alu,alu,imovx")
8275    (set_attr "length_immediate" "*,*,0")
8276    (set_attr "mode" "SI")])
8277
8278 (define_split
8279   [(set (match_operand 0 "register_operand" "")
8280         (and (match_dup 0)
8281              (const_int -65536)))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8284   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8285   "operands[1] = gen_lowpart (HImode, operands[0]);")
8286
8287 (define_split
8288   [(set (match_operand 0 "ext_register_operand" "")
8289         (and (match_dup 0)
8290              (const_int -256)))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8293   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8294   "operands[1] = gen_lowpart (QImode, operands[0]);")
8295
8296 (define_split
8297   [(set (match_operand 0 "ext_register_operand" "")
8298         (and (match_dup 0)
8299              (const_int -65281)))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8302   [(parallel [(set (zero_extract:SI (match_dup 0)
8303                                     (const_int 8)
8304                                     (const_int 8))
8305                    (xor:SI 
8306                      (zero_extract:SI (match_dup 0)
8307                                       (const_int 8)
8308                                       (const_int 8))
8309                      (zero_extract:SI (match_dup 0)
8310                                       (const_int 8)
8311                                       (const_int 8))))
8312               (clobber (reg:CC FLAGS_REG))])]
8313   "operands[0] = gen_lowpart (SImode, operands[0]);")
8314
8315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8316 (define_insn "*andsi_1_zext"
8317   [(set (match_operand:DI 0 "register_operand" "=r")
8318         (zero_extend:DI
8319           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8320                   (match_operand:SI 2 "general_operand" "rim"))))
8321    (clobber (reg:CC FLAGS_REG))]
8322   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8323   "and{l}\t{%2, %k0|%k0, %2}"
8324   [(set_attr "type" "alu")
8325    (set_attr "mode" "SI")])
8326
8327 (define_insn "*andsi_2"
8328   [(set (reg 17)
8329         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8330                          (match_operand:SI 2 "general_operand" "rim,ri"))
8331                  (const_int 0)))
8332    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8333         (and:SI (match_dup 1) (match_dup 2)))]
8334   "ix86_match_ccmode (insn, CCNOmode)
8335    && ix86_binary_operator_ok (AND, SImode, operands)"
8336   "and{l}\t{%2, %0|%0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "SI")])
8339
8340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8341 (define_insn "*andsi_2_zext"
8342   [(set (reg 17)
8343         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8344                          (match_operand:SI 2 "general_operand" "rim"))
8345                  (const_int 0)))
8346    (set (match_operand:DI 0 "register_operand" "=r")
8347         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8348   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8349    && ix86_binary_operator_ok (AND, SImode, operands)"
8350   "and{l}\t{%2, %k0|%k0, %2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "SI")])
8353
8354 (define_expand "andhi3"
8355   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8356         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8357                 (match_operand:HI 2 "general_operand" "")))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "TARGET_HIMODE_MATH"
8360   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8361
8362 (define_insn "*andhi_1"
8363   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8364         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8365                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8366    (clobber (reg:CC FLAGS_REG))]
8367   "ix86_binary_operator_ok (AND, HImode, operands)"
8368 {
8369   switch (get_attr_type (insn))
8370     {
8371     case TYPE_IMOVX:
8372       if (GET_CODE (operands[2]) != CONST_INT)
8373         abort ();
8374       if (INTVAL (operands[2]) == 0xff)
8375         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8376       abort ();
8377
8378     default:
8379       if (! rtx_equal_p (operands[0], operands[1]))
8380         abort ();
8381
8382       return "and{w}\t{%2, %0|%0, %2}";
8383     }
8384 }
8385   [(set_attr "type" "alu,alu,imovx")
8386    (set_attr "length_immediate" "*,*,0")
8387    (set_attr "mode" "HI,HI,SI")])
8388
8389 (define_insn "*andhi_2"
8390   [(set (reg 17)
8391         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8392                          (match_operand:HI 2 "general_operand" "rim,ri"))
8393                  (const_int 0)))
8394    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8395         (and:HI (match_dup 1) (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)
8397    && ix86_binary_operator_ok (AND, HImode, operands)"
8398   "and{w}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "HI")])
8401
8402 (define_expand "andqi3"
8403   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8404         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8405                 (match_operand:QI 2 "general_operand" "")))
8406    (clobber (reg:CC FLAGS_REG))]
8407   "TARGET_QIMODE_MATH"
8408   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8409
8410 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8411 (define_insn "*andqi_1"
8412   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8413         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8414                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "ix86_binary_operator_ok (AND, QImode, operands)"
8417   "@
8418    and{b}\t{%2, %0|%0, %2}
8419    and{b}\t{%2, %0|%0, %2}
8420    and{l}\t{%k2, %k0|%k0, %k2}"
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "QI,QI,SI")])
8423
8424 (define_insn "*andqi_1_slp"
8425   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8426         (and:QI (match_dup 0)
8427                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8430    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8431   "and{b}\t{%1, %0|%0, %1}"
8432   [(set_attr "type" "alu1")
8433    (set_attr "mode" "QI")])
8434
8435 (define_insn "*andqi_2"
8436   [(set (reg 17)
8437         (compare (and:QI
8438                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8439                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8440                  (const_int 0)))
8441    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8442         (and:QI (match_dup 1) (match_dup 2)))]
8443   "ix86_match_ccmode (insn, CCNOmode)
8444    && ix86_binary_operator_ok (AND, QImode, operands)"
8445 {
8446   if (which_alternative == 2)
8447     {
8448       if (GET_CODE (operands[2]) == CONST_INT
8449           && (INTVAL (operands[2]) & 0xffffff00))
8450         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8451       return "and{l}\t{%2, %k0|%k0, %2}";
8452     }
8453   return "and{b}\t{%2, %0|%0, %2}";
8454 }
8455   [(set_attr "type" "alu")
8456    (set_attr "mode" "QI,QI,SI")])
8457
8458 (define_insn "*andqi_2_slp"
8459   [(set (reg 17)
8460         (compare (and:QI
8461                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8462                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8463                  (const_int 0)))
8464    (set (strict_low_part (match_dup 0))
8465         (and:QI (match_dup 0) (match_dup 1)))]
8466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8467    && ix86_match_ccmode (insn, CCNOmode)
8468    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8469   "and{b}\t{%1, %0|%0, %1}"
8470   [(set_attr "type" "alu1")
8471    (set_attr "mode" "QI")])
8472
8473 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8474 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8475 ;; for a QImode operand, which of course failed.
8476
8477 (define_insn "andqi_ext_0"
8478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479                          (const_int 8)
8480                          (const_int 8))
8481         (and:SI 
8482           (zero_extract:SI
8483             (match_operand 1 "ext_register_operand" "0")
8484             (const_int 8)
8485             (const_int 8))
8486           (match_operand 2 "const_int_operand" "n")))
8487    (clobber (reg:CC FLAGS_REG))]
8488   ""
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "1")
8492    (set_attr "mode" "QI")])
8493
8494 ;; Generated by peephole translating test to and.  This shows up
8495 ;; often in fp comparisons.
8496
8497 (define_insn "*andqi_ext_0_cc"
8498   [(set (reg 17)
8499         (compare
8500           (and:SI
8501             (zero_extract:SI
8502               (match_operand 1 "ext_register_operand" "0")
8503               (const_int 8)
8504               (const_int 8))
8505             (match_operand 2 "const_int_operand" "n"))
8506           (const_int 0)))
8507    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8508                          (const_int 8)
8509                          (const_int 8))
8510         (and:SI 
8511           (zero_extract:SI
8512             (match_dup 1)
8513             (const_int 8)
8514             (const_int 8))
8515           (match_dup 2)))]
8516   "ix86_match_ccmode (insn, CCNOmode)"
8517   "and{b}\t{%2, %h0|%h0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "length_immediate" "1")
8520    (set_attr "mode" "QI")])
8521
8522 (define_insn "*andqi_ext_1"
8523   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8524                          (const_int 8)
8525                          (const_int 8))
8526         (and:SI 
8527           (zero_extract:SI
8528             (match_operand 1 "ext_register_operand" "0")
8529             (const_int 8)
8530             (const_int 8))
8531           (zero_extend:SI
8532             (match_operand:QI 2 "general_operand" "Qm"))))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "!TARGET_64BIT"
8535   "and{b}\t{%2, %h0|%h0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "length_immediate" "0")
8538    (set_attr "mode" "QI")])
8539
8540 (define_insn "*andqi_ext_1_rex64"
8541   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8542                          (const_int 8)
8543                          (const_int 8))
8544         (and:SI 
8545           (zero_extract:SI
8546             (match_operand 1 "ext_register_operand" "0")
8547             (const_int 8)
8548             (const_int 8))
8549           (zero_extend:SI
8550             (match_operand 2 "ext_register_operand" "Q"))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT"
8553   "and{b}\t{%2, %h0|%h0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "length_immediate" "0")
8556    (set_attr "mode" "QI")])
8557
8558 (define_insn "*andqi_ext_2"
8559   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8560                          (const_int 8)
8561                          (const_int 8))
8562         (and:SI
8563           (zero_extract:SI
8564             (match_operand 1 "ext_register_operand" "%0")
8565             (const_int 8)
8566             (const_int 8))
8567           (zero_extract:SI
8568             (match_operand 2 "ext_register_operand" "Q")
8569             (const_int 8)
8570             (const_int 8))))
8571    (clobber (reg:CC FLAGS_REG))]
8572   ""
8573   "and{b}\t{%h2, %h0|%h0, %h2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "length_immediate" "0")
8576    (set_attr "mode" "QI")])
8577
8578 ;; Convert wide AND instructions with immediate operand to shorter QImode
8579 ;; equivalents when possible.
8580 ;; Don't do the splitting with memory operands, since it introduces risk
8581 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8582 ;; for size, but that can (should?) be handled by generic code instead.
8583 (define_split
8584   [(set (match_operand 0 "register_operand" "")
8585         (and (match_operand 1 "register_operand" "")
8586              (match_operand 2 "const_int_operand" "")))
8587    (clobber (reg:CC FLAGS_REG))]
8588    "reload_completed
8589     && QI_REG_P (operands[0])
8590     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8591     && !(~INTVAL (operands[2]) & ~(255 << 8))
8592     && GET_MODE (operands[0]) != QImode"
8593   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8594                    (and:SI (zero_extract:SI (match_dup 1)
8595                                             (const_int 8) (const_int 8))
8596                            (match_dup 2)))
8597               (clobber (reg:CC FLAGS_REG))])]
8598   "operands[0] = gen_lowpart (SImode, operands[0]);
8599    operands[1] = gen_lowpart (SImode, operands[1]);
8600    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8601
8602 ;; Since AND can be encoded with sign extended immediate, this is only
8603 ;; profitable when 7th bit is not set.
8604 (define_split
8605   [(set (match_operand 0 "register_operand" "")
8606         (and (match_operand 1 "general_operand" "")
8607              (match_operand 2 "const_int_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609    "reload_completed
8610     && ANY_QI_REG_P (operands[0])
8611     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8612     && !(~INTVAL (operands[2]) & ~255)
8613     && !(INTVAL (operands[2]) & 128)
8614     && GET_MODE (operands[0]) != QImode"
8615   [(parallel [(set (strict_low_part (match_dup 0))
8616                    (and:QI (match_dup 1)
8617                            (match_dup 2)))
8618               (clobber (reg:CC FLAGS_REG))])]
8619   "operands[0] = gen_lowpart (QImode, operands[0]);
8620    operands[1] = gen_lowpart (QImode, operands[1]);
8621    operands[2] = gen_lowpart (QImode, operands[2]);")
8622 \f
8623 ;; Logical inclusive OR instructions
8624
8625 ;; %%% This used to optimize known byte-wide and operations to memory.
8626 ;; If this is considered useful, it should be done with splitters.
8627
8628 (define_expand "iordi3"
8629   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8630         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8631                 (match_operand:DI 2 "x86_64_general_operand" "")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "TARGET_64BIT"
8634   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8635
8636 (define_insn "*iordi_1_rex64"
8637   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8638         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8639                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "TARGET_64BIT
8642    && ix86_binary_operator_ok (IOR, DImode, operands)"
8643   "or{q}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "DI")])
8646
8647 (define_insn "*iordi_2_rex64"
8648   [(set (reg 17)
8649         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8650                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8651                  (const_int 0)))
8652    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8653         (ior:DI (match_dup 1) (match_dup 2)))]
8654   "TARGET_64BIT
8655    && ix86_match_ccmode (insn, CCNOmode)
8656    && ix86_binary_operator_ok (IOR, DImode, operands)"
8657   "or{q}\t{%2, %0|%0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "mode" "DI")])
8660
8661 (define_insn "*iordi_3_rex64"
8662   [(set (reg 17)
8663         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8664                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8665                  (const_int 0)))
8666    (clobber (match_scratch:DI 0 "=r"))]
8667   "TARGET_64BIT
8668    && ix86_match_ccmode (insn, CCNOmode)
8669    && ix86_binary_operator_ok (IOR, DImode, operands)"
8670   "or{q}\t{%2, %0|%0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "DI")])
8673
8674
8675 (define_expand "iorsi3"
8676   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8677         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8678                 (match_operand:SI 2 "general_operand" "")))
8679    (clobber (reg:CC FLAGS_REG))]
8680   ""
8681   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8682
8683 (define_insn "*iorsi_1"
8684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8685         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8686                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8687    (clobber (reg:CC FLAGS_REG))]
8688   "ix86_binary_operator_ok (IOR, SImode, operands)"
8689   "or{l}\t{%2, %0|%0, %2}"
8690   [(set_attr "type" "alu")
8691    (set_attr "mode" "SI")])
8692
8693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8694 (define_insn "*iorsi_1_zext"
8695   [(set (match_operand:DI 0 "register_operand" "=rm")
8696         (zero_extend:DI
8697           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8698                   (match_operand:SI 2 "general_operand" "rim"))))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8701   "or{l}\t{%2, %k0|%k0, %2}"
8702   [(set_attr "type" "alu")
8703    (set_attr "mode" "SI")])
8704
8705 (define_insn "*iorsi_1_zext_imm"
8706   [(set (match_operand:DI 0 "register_operand" "=rm")
8707         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8708                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8709    (clobber (reg:CC FLAGS_REG))]
8710   "TARGET_64BIT"
8711   "or{l}\t{%2, %k0|%k0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "SI")])
8714
8715 (define_insn "*iorsi_2"
8716   [(set (reg 17)
8717         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8718                          (match_operand:SI 2 "general_operand" "rim,ri"))
8719                  (const_int 0)))
8720    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8721         (ior:SI (match_dup 1) (match_dup 2)))]
8722   "ix86_match_ccmode (insn, CCNOmode)
8723    && ix86_binary_operator_ok (IOR, SImode, operands)"
8724   "or{l}\t{%2, %0|%0, %2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "mode" "SI")])
8727
8728 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8729 ;; ??? Special case for immediate operand is missing - it is tricky.
8730 (define_insn "*iorsi_2_zext"
8731   [(set (reg 17)
8732         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8733                          (match_operand:SI 2 "general_operand" "rim"))
8734                  (const_int 0)))
8735    (set (match_operand:DI 0 "register_operand" "=r")
8736         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8737   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8738    && ix86_binary_operator_ok (IOR, SImode, operands)"
8739   "or{l}\t{%2, %k0|%k0, %2}"
8740   [(set_attr "type" "alu")
8741    (set_attr "mode" "SI")])
8742
8743 (define_insn "*iorsi_2_zext_imm"
8744   [(set (reg 17)
8745         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8746                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8747                  (const_int 0)))
8748    (set (match_operand:DI 0 "register_operand" "=r")
8749         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8750   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8751    && ix86_binary_operator_ok (IOR, SImode, operands)"
8752   "or{l}\t{%2, %k0|%k0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "SI")])
8755
8756 (define_insn "*iorsi_3"
8757   [(set (reg 17)
8758         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8759                          (match_operand:SI 2 "general_operand" "rim"))
8760                  (const_int 0)))
8761    (clobber (match_scratch:SI 0 "=r"))]
8762   "ix86_match_ccmode (insn, CCNOmode)
8763    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8764   "or{l}\t{%2, %0|%0, %2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "mode" "SI")])
8767
8768 (define_expand "iorhi3"
8769   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8770         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8771                 (match_operand:HI 2 "general_operand" "")))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_HIMODE_MATH"
8774   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8775
8776 (define_insn "*iorhi_1"
8777   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8778         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8779                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8780    (clobber (reg:CC FLAGS_REG))]
8781   "ix86_binary_operator_ok (IOR, HImode, operands)"
8782   "or{w}\t{%2, %0|%0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "HI")])
8785
8786 (define_insn "*iorhi_2"
8787   [(set (reg 17)
8788         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8789                          (match_operand:HI 2 "general_operand" "rim,ri"))
8790                  (const_int 0)))
8791    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8792         (ior:HI (match_dup 1) (match_dup 2)))]
8793   "ix86_match_ccmode (insn, CCNOmode)
8794    && ix86_binary_operator_ok (IOR, HImode, operands)"
8795   "or{w}\t{%2, %0|%0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "mode" "HI")])
8798
8799 (define_insn "*iorhi_3"
8800   [(set (reg 17)
8801         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8802                          (match_operand:HI 2 "general_operand" "rim"))
8803                  (const_int 0)))
8804    (clobber (match_scratch:HI 0 "=r"))]
8805   "ix86_match_ccmode (insn, CCNOmode)
8806    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8807   "or{w}\t{%2, %0|%0, %2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "HI")])
8810
8811 (define_expand "iorqi3"
8812   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8813         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8814                 (match_operand:QI 2 "general_operand" "")))
8815    (clobber (reg:CC FLAGS_REG))]
8816   "TARGET_QIMODE_MATH"
8817   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8818
8819 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8820 (define_insn "*iorqi_1"
8821   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8822         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8823                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "ix86_binary_operator_ok (IOR, QImode, operands)"
8826   "@
8827    or{b}\t{%2, %0|%0, %2}
8828    or{b}\t{%2, %0|%0, %2}
8829    or{l}\t{%k2, %k0|%k0, %k2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "QI,QI,SI")])
8832
8833 (define_insn "*iorqi_1_slp"
8834   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8835         (ior:QI (match_dup 0)
8836                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8839    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8840   "or{b}\t{%1, %0|%0, %1}"
8841   [(set_attr "type" "alu1")
8842    (set_attr "mode" "QI")])
8843
8844 (define_insn "*iorqi_2"
8845   [(set (reg 17)
8846         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8847                          (match_operand:QI 2 "general_operand" "qim,qi"))
8848                  (const_int 0)))
8849    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8850         (ior:QI (match_dup 1) (match_dup 2)))]
8851   "ix86_match_ccmode (insn, CCNOmode)
8852    && ix86_binary_operator_ok (IOR, QImode, operands)"
8853   "or{b}\t{%2, %0|%0, %2}"
8854   [(set_attr "type" "alu")
8855    (set_attr "mode" "QI")])
8856
8857 (define_insn "*iorqi_2_slp"
8858   [(set (reg 17)
8859         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8860                          (match_operand:QI 1 "general_operand" "qim,qi"))
8861                  (const_int 0)))
8862    (set (strict_low_part (match_dup 0))
8863         (ior:QI (match_dup 0) (match_dup 1)))]
8864   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8865    && ix86_match_ccmode (insn, CCNOmode)
8866    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8867   "or{b}\t{%1, %0|%0, %1}"
8868   [(set_attr "type" "alu1")
8869    (set_attr "mode" "QI")])
8870
8871 (define_insn "*iorqi_3"
8872   [(set (reg 17)
8873         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8874                          (match_operand:QI 2 "general_operand" "qim"))
8875                  (const_int 0)))
8876    (clobber (match_scratch:QI 0 "=q"))]
8877   "ix86_match_ccmode (insn, CCNOmode)
8878    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8879   "or{b}\t{%2, %0|%0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "mode" "QI")])
8882
8883 (define_insn "iorqi_ext_0"
8884   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885                          (const_int 8)
8886                          (const_int 8))
8887         (ior:SI 
8888           (zero_extract:SI
8889             (match_operand 1 "ext_register_operand" "0")
8890             (const_int 8)
8891             (const_int 8))
8892           (match_operand 2 "const_int_operand" "n")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8895   "or{b}\t{%2, %h0|%h0, %2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "length_immediate" "1")
8898    (set_attr "mode" "QI")])
8899
8900 (define_insn "*iorqi_ext_1"
8901   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8902                          (const_int 8)
8903                          (const_int 8))
8904         (ior:SI 
8905           (zero_extract:SI
8906             (match_operand 1 "ext_register_operand" "0")
8907             (const_int 8)
8908             (const_int 8))
8909           (zero_extend:SI
8910             (match_operand:QI 2 "general_operand" "Qm"))))
8911    (clobber (reg:CC FLAGS_REG))]
8912   "!TARGET_64BIT
8913    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8914   "or{b}\t{%2, %h0|%h0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "length_immediate" "0")
8917    (set_attr "mode" "QI")])
8918
8919 (define_insn "*iorqi_ext_1_rex64"
8920   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8921                          (const_int 8)
8922                          (const_int 8))
8923         (ior:SI 
8924           (zero_extract:SI
8925             (match_operand 1 "ext_register_operand" "0")
8926             (const_int 8)
8927             (const_int 8))
8928           (zero_extend:SI
8929             (match_operand 2 "ext_register_operand" "Q"))))
8930    (clobber (reg:CC FLAGS_REG))]
8931   "TARGET_64BIT
8932    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8933   "or{b}\t{%2, %h0|%h0, %2}"
8934   [(set_attr "type" "alu")
8935    (set_attr "length_immediate" "0")
8936    (set_attr "mode" "QI")])
8937
8938 (define_insn "*iorqi_ext_2"
8939   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8940                          (const_int 8)
8941                          (const_int 8))
8942         (ior:SI 
8943           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8944                            (const_int 8)
8945                            (const_int 8))
8946           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8947                            (const_int 8)
8948                            (const_int 8))))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8951   "ior{b}\t{%h2, %h0|%h0, %h2}"
8952   [(set_attr "type" "alu")
8953    (set_attr "length_immediate" "0")
8954    (set_attr "mode" "QI")])
8955
8956 (define_split
8957   [(set (match_operand 0 "register_operand" "")
8958         (ior (match_operand 1 "register_operand" "")
8959              (match_operand 2 "const_int_operand" "")))
8960    (clobber (reg:CC FLAGS_REG))]
8961    "reload_completed
8962     && QI_REG_P (operands[0])
8963     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8964     && !(INTVAL (operands[2]) & ~(255 << 8))
8965     && GET_MODE (operands[0]) != QImode"
8966   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8967                    (ior:SI (zero_extract:SI (match_dup 1)
8968                                             (const_int 8) (const_int 8))
8969                            (match_dup 2)))
8970               (clobber (reg:CC FLAGS_REG))])]
8971   "operands[0] = gen_lowpart (SImode, operands[0]);
8972    operands[1] = gen_lowpart (SImode, operands[1]);
8973    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8974
8975 ;; Since OR can be encoded with sign extended immediate, this is only
8976 ;; profitable when 7th bit is set.
8977 (define_split
8978   [(set (match_operand 0 "register_operand" "")
8979         (ior (match_operand 1 "general_operand" "")
8980              (match_operand 2 "const_int_operand" "")))
8981    (clobber (reg:CC FLAGS_REG))]
8982    "reload_completed
8983     && ANY_QI_REG_P (operands[0])
8984     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8985     && !(INTVAL (operands[2]) & ~255)
8986     && (INTVAL (operands[2]) & 128)
8987     && GET_MODE (operands[0]) != QImode"
8988   [(parallel [(set (strict_low_part (match_dup 0))
8989                    (ior:QI (match_dup 1)
8990                            (match_dup 2)))
8991               (clobber (reg:CC FLAGS_REG))])]
8992   "operands[0] = gen_lowpart (QImode, operands[0]);
8993    operands[1] = gen_lowpart (QImode, operands[1]);
8994    operands[2] = gen_lowpart (QImode, operands[2]);")
8995 \f
8996 ;; Logical XOR instructions
8997
8998 ;; %%% This used to optimize known byte-wide and operations to memory.
8999 ;; If this is considered useful, it should be done with splitters.
9000
9001 (define_expand "xordi3"
9002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9003         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9004                 (match_operand:DI 2 "x86_64_general_operand" "")))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "TARGET_64BIT"
9007   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9008
9009 (define_insn "*xordi_1_rex64"
9010   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9011         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9012                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9013    (clobber (reg:CC FLAGS_REG))]
9014   "TARGET_64BIT
9015    && ix86_binary_operator_ok (XOR, DImode, operands)"
9016   "@
9017    xor{q}\t{%2, %0|%0, %2}
9018    xor{q}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "DI,DI")])
9021
9022 (define_insn "*xordi_2_rex64"
9023   [(set (reg 17)
9024         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9025                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9026                  (const_int 0)))
9027    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9028         (xor:DI (match_dup 1) (match_dup 2)))]
9029   "TARGET_64BIT
9030    && ix86_match_ccmode (insn, CCNOmode)
9031    && ix86_binary_operator_ok (XOR, DImode, operands)"
9032   "@
9033    xor{q}\t{%2, %0|%0, %2}
9034    xor{q}\t{%2, %0|%0, %2}"
9035   [(set_attr "type" "alu")
9036    (set_attr "mode" "DI,DI")])
9037
9038 (define_insn "*xordi_3_rex64"
9039   [(set (reg 17)
9040         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9041                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9042                  (const_int 0)))
9043    (clobber (match_scratch:DI 0 "=r"))]
9044   "TARGET_64BIT
9045    && ix86_match_ccmode (insn, CCNOmode)
9046    && ix86_binary_operator_ok (XOR, DImode, operands)"
9047   "xor{q}\t{%2, %0|%0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "DI")])
9050
9051 (define_expand "xorsi3"
9052   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9053         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9054                 (match_operand:SI 2 "general_operand" "")))
9055    (clobber (reg:CC FLAGS_REG))]
9056   ""
9057   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9058
9059 (define_insn "*xorsi_1"
9060   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9061         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9062                 (match_operand:SI 2 "general_operand" "ri,rm")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %0|%0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9070 ;; Add speccase for immediates
9071 (define_insn "*xorsi_1_zext"
9072   [(set (match_operand:DI 0 "register_operand" "=r")
9073         (zero_extend:DI
9074           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9075                   (match_operand:SI 2 "general_operand" "rim"))))
9076    (clobber (reg:CC FLAGS_REG))]
9077   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9078   "xor{l}\t{%2, %k0|%k0, %2}"
9079   [(set_attr "type" "alu")
9080    (set_attr "mode" "SI")])
9081
9082 (define_insn "*xorsi_1_zext_imm"
9083   [(set (match_operand:DI 0 "register_operand" "=r")
9084         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9085                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9086    (clobber (reg:CC FLAGS_REG))]
9087   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9088   "xor{l}\t{%2, %k0|%k0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9091
9092 (define_insn "*xorsi_2"
9093   [(set (reg 17)
9094         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9095                          (match_operand:SI 2 "general_operand" "rim,ri"))
9096                  (const_int 0)))
9097    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9098         (xor:SI (match_dup 1) (match_dup 2)))]
9099   "ix86_match_ccmode (insn, CCNOmode)
9100    && ix86_binary_operator_ok (XOR, SImode, operands)"
9101   "xor{l}\t{%2, %0|%0, %2}"
9102   [(set_attr "type" "alu")
9103    (set_attr "mode" "SI")])
9104
9105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9106 ;; ??? Special case for immediate operand is missing - it is tricky.
9107 (define_insn "*xorsi_2_zext"
9108   [(set (reg 17)
9109         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9110                          (match_operand:SI 2 "general_operand" "rim"))
9111                  (const_int 0)))
9112    (set (match_operand:DI 0 "register_operand" "=r")
9113         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9115    && ix86_binary_operator_ok (XOR, SImode, operands)"
9116   "xor{l}\t{%2, %k0|%k0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "mode" "SI")])
9119
9120 (define_insn "*xorsi_2_zext_imm"
9121   [(set (reg 17)
9122         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9123                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9124                  (const_int 0)))
9125    (set (match_operand:DI 0 "register_operand" "=r")
9126         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9127   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9128    && ix86_binary_operator_ok (XOR, SImode, operands)"
9129   "xor{l}\t{%2, %k0|%k0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "SI")])
9132
9133 (define_insn "*xorsi_3"
9134   [(set (reg 17)
9135         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9136                          (match_operand:SI 2 "general_operand" "rim"))
9137                  (const_int 0)))
9138    (clobber (match_scratch:SI 0 "=r"))]
9139   "ix86_match_ccmode (insn, CCNOmode)
9140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9141   "xor{l}\t{%2, %0|%0, %2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "mode" "SI")])
9144
9145 (define_expand "xorhi3"
9146   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9147         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9148                 (match_operand:HI 2 "general_operand" "")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_HIMODE_MATH"
9151   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9152
9153 (define_insn "*xorhi_1"
9154   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9155         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9156                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9157    (clobber (reg:CC FLAGS_REG))]
9158   "ix86_binary_operator_ok (XOR, HImode, operands)"
9159   "xor{w}\t{%2, %0|%0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "mode" "HI")])
9162
9163 (define_insn "*xorhi_2"
9164   [(set (reg 17)
9165         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9166                          (match_operand:HI 2 "general_operand" "rim,ri"))
9167                  (const_int 0)))
9168    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9169         (xor:HI (match_dup 1) (match_dup 2)))]
9170   "ix86_match_ccmode (insn, CCNOmode)
9171    && ix86_binary_operator_ok (XOR, HImode, operands)"
9172   "xor{w}\t{%2, %0|%0, %2}"
9173   [(set_attr "type" "alu")
9174    (set_attr "mode" "HI")])
9175
9176 (define_insn "*xorhi_3"
9177   [(set (reg 17)
9178         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9179                          (match_operand:HI 2 "general_operand" "rim"))
9180                  (const_int 0)))
9181    (clobber (match_scratch:HI 0 "=r"))]
9182   "ix86_match_ccmode (insn, CCNOmode)
9183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9184   "xor{w}\t{%2, %0|%0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "HI")])
9187
9188 (define_expand "xorqi3"
9189   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9190         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9191                 (match_operand:QI 2 "general_operand" "")))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "TARGET_QIMODE_MATH"
9194   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9195
9196 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9197 (define_insn "*xorqi_1"
9198   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9199         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9200                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "ix86_binary_operator_ok (XOR, QImode, operands)"
9203   "@
9204    xor{b}\t{%2, %0|%0, %2}
9205    xor{b}\t{%2, %0|%0, %2}
9206    xor{l}\t{%k2, %k0|%k0, %k2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "mode" "QI,QI,SI")])
9209
9210 (define_insn "*xorqi_1_slp"
9211   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9212         (xor:QI (match_dup 0)
9213                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9214    (clobber (reg:CC FLAGS_REG))]
9215   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9216    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9217   "xor{b}\t{%1, %0|%0, %1}"
9218   [(set_attr "type" "alu1")
9219    (set_attr "mode" "QI")])
9220
9221 (define_insn "xorqi_ext_0"
9222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223                          (const_int 8)
9224                          (const_int 8))
9225         (xor:SI 
9226           (zero_extract:SI
9227             (match_operand 1 "ext_register_operand" "0")
9228             (const_int 8)
9229             (const_int 8))
9230           (match_operand 2 "const_int_operand" "n")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9233   "xor{b}\t{%2, %h0|%h0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "length_immediate" "1")
9236    (set_attr "mode" "QI")])
9237
9238 (define_insn "*xorqi_ext_1"
9239   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240                          (const_int 8)
9241                          (const_int 8))
9242         (xor:SI 
9243           (zero_extract:SI
9244             (match_operand 1 "ext_register_operand" "0")
9245             (const_int 8)
9246             (const_int 8))
9247           (zero_extend:SI
9248             (match_operand:QI 2 "general_operand" "Qm"))))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "!TARGET_64BIT
9251    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9252   "xor{b}\t{%2, %h0|%h0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "length_immediate" "0")
9255    (set_attr "mode" "QI")])
9256
9257 (define_insn "*xorqi_ext_1_rex64"
9258   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9259                          (const_int 8)
9260                          (const_int 8))
9261         (xor:SI 
9262           (zero_extract:SI
9263             (match_operand 1 "ext_register_operand" "0")
9264             (const_int 8)
9265             (const_int 8))
9266           (zero_extend:SI
9267             (match_operand 2 "ext_register_operand" "Q"))))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "TARGET_64BIT
9270    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9271   "xor{b}\t{%2, %h0|%h0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "length_immediate" "0")
9274    (set_attr "mode" "QI")])
9275
9276 (define_insn "*xorqi_ext_2"
9277   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9278                          (const_int 8)
9279                          (const_int 8))
9280         (xor:SI 
9281           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9282                            (const_int 8)
9283                            (const_int 8))
9284           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9285                            (const_int 8)
9286                            (const_int 8))))
9287    (clobber (reg:CC FLAGS_REG))]
9288   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9289   "xor{b}\t{%h2, %h0|%h0, %h2}"
9290   [(set_attr "type" "alu")
9291    (set_attr "length_immediate" "0")
9292    (set_attr "mode" "QI")])
9293
9294 (define_insn "*xorqi_cc_1"
9295   [(set (reg 17)
9296         (compare
9297           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9298                   (match_operand:QI 2 "general_operand" "qim,qi"))
9299           (const_int 0)))
9300    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9301         (xor:QI (match_dup 1) (match_dup 2)))]
9302   "ix86_match_ccmode (insn, CCNOmode)
9303    && ix86_binary_operator_ok (XOR, QImode, operands)"
9304   "xor{b}\t{%2, %0|%0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "QI")])
9307
9308 (define_insn "*xorqi_2_slp"
9309   [(set (reg 17)
9310         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9311                          (match_operand:QI 1 "general_operand" "qim,qi"))
9312                  (const_int 0)))
9313    (set (strict_low_part (match_dup 0))
9314         (xor:QI (match_dup 0) (match_dup 1)))]
9315   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9316    && ix86_match_ccmode (insn, CCNOmode)
9317    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9318   "xor{b}\t{%1, %0|%0, %1}"
9319   [(set_attr "type" "alu1")
9320    (set_attr "mode" "QI")])
9321
9322 (define_insn "*xorqi_cc_2"
9323   [(set (reg 17)
9324         (compare
9325           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9326                   (match_operand:QI 2 "general_operand" "qim"))
9327           (const_int 0)))
9328    (clobber (match_scratch:QI 0 "=q"))]
9329   "ix86_match_ccmode (insn, CCNOmode)
9330    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9331   "xor{b}\t{%2, %0|%0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "QI")])
9334
9335 (define_insn "*xorqi_cc_ext_1"
9336   [(set (reg 17)
9337         (compare
9338           (xor:SI
9339             (zero_extract:SI
9340               (match_operand 1 "ext_register_operand" "0")
9341               (const_int 8)
9342               (const_int 8))
9343             (match_operand:QI 2 "general_operand" "qmn"))
9344           (const_int 0)))
9345    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9346                          (const_int 8)
9347                          (const_int 8))
9348         (xor:SI 
9349           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9350           (match_dup 2)))]
9351   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9352   "xor{b}\t{%2, %h0|%h0, %2}"
9353   [(set_attr "type" "alu")
9354    (set_attr "mode" "QI")])
9355
9356 (define_insn "*xorqi_cc_ext_1_rex64"
9357   [(set (reg 17)
9358         (compare
9359           (xor:SI
9360             (zero_extract:SI
9361               (match_operand 1 "ext_register_operand" "0")
9362               (const_int 8)
9363               (const_int 8))
9364             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9365           (const_int 0)))
9366    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9367                          (const_int 8)
9368                          (const_int 8))
9369         (xor:SI 
9370           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9371           (match_dup 2)))]
9372   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9373   "xor{b}\t{%2, %h0|%h0, %2}"
9374   [(set_attr "type" "alu")
9375    (set_attr "mode" "QI")])
9376
9377 (define_expand "xorqi_cc_ext_1"
9378   [(parallel [
9379      (set (reg:CCNO FLAGS_REG)
9380           (compare:CCNO
9381             (xor:SI
9382               (zero_extract:SI
9383                 (match_operand 1 "ext_register_operand" "")
9384                 (const_int 8)
9385                 (const_int 8))
9386               (match_operand:QI 2 "general_operand" ""))
9387             (const_int 0)))
9388      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9389                            (const_int 8)
9390                            (const_int 8))
9391           (xor:SI 
9392             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9393             (match_dup 2)))])]
9394   ""
9395   "")
9396
9397 (define_split
9398   [(set (match_operand 0 "register_operand" "")
9399         (xor (match_operand 1 "register_operand" "")
9400              (match_operand 2 "const_int_operand" "")))
9401    (clobber (reg:CC FLAGS_REG))]
9402    "reload_completed
9403     && QI_REG_P (operands[0])
9404     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9405     && !(INTVAL (operands[2]) & ~(255 << 8))
9406     && GET_MODE (operands[0]) != QImode"
9407   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9408                    (xor:SI (zero_extract:SI (match_dup 1)
9409                                             (const_int 8) (const_int 8))
9410                            (match_dup 2)))
9411               (clobber (reg:CC FLAGS_REG))])]
9412   "operands[0] = gen_lowpart (SImode, operands[0]);
9413    operands[1] = gen_lowpart (SImode, operands[1]);
9414    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9415
9416 ;; Since XOR can be encoded with sign extended immediate, this is only
9417 ;; profitable when 7th bit is set.
9418 (define_split
9419   [(set (match_operand 0 "register_operand" "")
9420         (xor (match_operand 1 "general_operand" "")
9421              (match_operand 2 "const_int_operand" "")))
9422    (clobber (reg:CC FLAGS_REG))]
9423    "reload_completed
9424     && ANY_QI_REG_P (operands[0])
9425     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9426     && !(INTVAL (operands[2]) & ~255)
9427     && (INTVAL (operands[2]) & 128)
9428     && GET_MODE (operands[0]) != QImode"
9429   [(parallel [(set (strict_low_part (match_dup 0))
9430                    (xor:QI (match_dup 1)
9431                            (match_dup 2)))
9432               (clobber (reg:CC FLAGS_REG))])]
9433   "operands[0] = gen_lowpart (QImode, operands[0]);
9434    operands[1] = gen_lowpart (QImode, operands[1]);
9435    operands[2] = gen_lowpart (QImode, operands[2]);")
9436 \f
9437 ;; Negation instructions
9438
9439 (define_expand "negdi2"
9440   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9441                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9442               (clobber (reg:CC FLAGS_REG))])]
9443   ""
9444   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9445
9446 (define_insn "*negdi2_1"
9447   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9448         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9449    (clobber (reg:CC FLAGS_REG))]
9450   "!TARGET_64BIT
9451    && ix86_unary_operator_ok (NEG, DImode, operands)"
9452   "#")
9453
9454 (define_split
9455   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9456         (neg:DI (match_operand:DI 1 "general_operand" "")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "!TARGET_64BIT && reload_completed"
9459   [(parallel
9460     [(set (reg:CCZ FLAGS_REG)
9461           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9462      (set (match_dup 0) (neg:SI (match_dup 2)))])
9463    (parallel
9464     [(set (match_dup 1)
9465           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9466                             (match_dup 3))
9467                    (const_int 0)))
9468      (clobber (reg:CC FLAGS_REG))])
9469    (parallel
9470     [(set (match_dup 1)
9471           (neg:SI (match_dup 1)))
9472      (clobber (reg:CC FLAGS_REG))])]
9473   "split_di (operands+1, 1, operands+2, operands+3);
9474    split_di (operands+0, 1, operands+0, operands+1);")
9475
9476 (define_insn "*negdi2_1_rex64"
9477   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9478         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9481   "neg{q}\t%0"
9482   [(set_attr "type" "negnot")
9483    (set_attr "mode" "DI")])
9484
9485 ;; The problem with neg is that it does not perform (compare x 0),
9486 ;; it really performs (compare 0 x), which leaves us with the zero
9487 ;; flag being the only useful item.
9488
9489 (define_insn "*negdi2_cmpz_rex64"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9492                      (const_int 0)))
9493    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9494         (neg:DI (match_dup 1)))]
9495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9496   "neg{q}\t%0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "DI")])
9499
9500
9501 (define_expand "negsi2"
9502   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9503                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9504               (clobber (reg:CC FLAGS_REG))])]
9505   ""
9506   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9507
9508 (define_insn "*negsi2_1"
9509   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9510         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "ix86_unary_operator_ok (NEG, SImode, operands)"
9513   "neg{l}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "SI")])
9516
9517 ;; Combine is quite creative about this pattern.
9518 (define_insn "*negsi2_1_zext"
9519   [(set (match_operand:DI 0 "register_operand" "=r")
9520         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9521                                         (const_int 32)))
9522                      (const_int 32)))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9525   "neg{l}\t%k0"
9526   [(set_attr "type" "negnot")
9527    (set_attr "mode" "SI")])
9528
9529 ;; The problem with neg is that it does not perform (compare x 0),
9530 ;; it really performs (compare 0 x), which leaves us with the zero
9531 ;; flag being the only useful item.
9532
9533 (define_insn "*negsi2_cmpz"
9534   [(set (reg:CCZ FLAGS_REG)
9535         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9536                      (const_int 0)))
9537    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9538         (neg:SI (match_dup 1)))]
9539   "ix86_unary_operator_ok (NEG, SImode, operands)"
9540   "neg{l}\t%0"
9541   [(set_attr "type" "negnot")
9542    (set_attr "mode" "SI")])
9543
9544 (define_insn "*negsi2_cmpz_zext"
9545   [(set (reg:CCZ FLAGS_REG)
9546         (compare:CCZ (lshiftrt:DI
9547                        (neg:DI (ashift:DI
9548                                  (match_operand:DI 1 "register_operand" "0")
9549                                  (const_int 32)))
9550                        (const_int 32))
9551                      (const_int 0)))
9552    (set (match_operand:DI 0 "register_operand" "=r")
9553         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9554                                         (const_int 32)))
9555                      (const_int 32)))]
9556   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9557   "neg{l}\t%k0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "SI")])
9560
9561 (define_expand "neghi2"
9562   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9563                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_HIMODE_MATH"
9566   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9567
9568 (define_insn "*neghi2_1"
9569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9570         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "ix86_unary_operator_ok (NEG, HImode, operands)"
9573   "neg{w}\t%0"
9574   [(set_attr "type" "negnot")
9575    (set_attr "mode" "HI")])
9576
9577 (define_insn "*neghi2_cmpz"
9578   [(set (reg:CCZ FLAGS_REG)
9579         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9580                      (const_int 0)))
9581    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9582         (neg:HI (match_dup 1)))]
9583   "ix86_unary_operator_ok (NEG, HImode, operands)"
9584   "neg{w}\t%0"
9585   [(set_attr "type" "negnot")
9586    (set_attr "mode" "HI")])
9587
9588 (define_expand "negqi2"
9589   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9590                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9591               (clobber (reg:CC FLAGS_REG))])]
9592   "TARGET_QIMODE_MATH"
9593   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9594
9595 (define_insn "*negqi2_1"
9596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9597         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "ix86_unary_operator_ok (NEG, QImode, operands)"
9600   "neg{b}\t%0"
9601   [(set_attr "type" "negnot")
9602    (set_attr "mode" "QI")])
9603
9604 (define_insn "*negqi2_cmpz"
9605   [(set (reg:CCZ FLAGS_REG)
9606         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9607                      (const_int 0)))
9608    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9609         (neg:QI (match_dup 1)))]
9610   "ix86_unary_operator_ok (NEG, QImode, operands)"
9611   "neg{b}\t%0"
9612   [(set_attr "type" "negnot")
9613    (set_attr "mode" "QI")])
9614
9615 ;; Changing of sign for FP values is doable using integer unit too.
9616
9617 (define_expand "negsf2"
9618   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9619                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9620               (clobber (reg:CC FLAGS_REG))])]
9621   "TARGET_80387"
9622   "if (TARGET_SSE)
9623      {
9624        /* In case operand is in memory,  we will not use SSE.  */
9625        if (memory_operand (operands[0], VOIDmode)
9626            && rtx_equal_p (operands[0], operands[1]))
9627          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9628        else
9629         {
9630           /* Using SSE is tricky, since we need bitwise negation of -0
9631              in register.  */
9632           rtx reg = gen_reg_rtx (SFmode);
9633           rtx dest = operands[0];
9634           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9635
9636           operands[1] = force_reg (SFmode, operands[1]);
9637           operands[0] = force_reg (SFmode, operands[0]);
9638           reg = force_reg (V4SFmode,
9639                            gen_rtx_CONST_VECTOR (V4SFmode,
9640                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9641                                         CONST0_RTX (SFmode),
9642                                         CONST0_RTX (SFmode))));
9643           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9644           if (dest != operands[0])
9645             emit_move_insn (dest, operands[0]);
9646         }
9647        DONE;
9648      }
9649    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9650
9651 (define_insn "negsf2_memory"
9652   [(set (match_operand:SF 0 "memory_operand" "=m")
9653         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9654    (clobber (reg:CC FLAGS_REG))]
9655   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9656   "#")
9657
9658 (define_insn "negsf2_ifs"
9659   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9660         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9661    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "TARGET_SSE
9664    && (reload_in_progress || reload_completed
9665        || (register_operand (operands[0], VOIDmode)
9666            && register_operand (operands[1], VOIDmode)))"
9667   "#")
9668
9669 (define_split
9670   [(set (match_operand:SF 0 "memory_operand" "")
9671         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9672    (use (match_operand:SF 2 "" ""))
9673    (clobber (reg:CC FLAGS_REG))]
9674   ""
9675   [(parallel [(set (match_dup 0)
9676                    (neg:SF (match_dup 1)))
9677               (clobber (reg:CC FLAGS_REG))])])
9678
9679 (define_split
9680   [(set (match_operand:SF 0 "register_operand" "")
9681         (neg:SF (match_operand:SF 1 "register_operand" "")))
9682    (use (match_operand:V4SF 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed && !SSE_REG_P (operands[0])"
9685   [(parallel [(set (match_dup 0)
9686                    (neg:SF (match_dup 1)))
9687               (clobber (reg:CC FLAGS_REG))])])
9688
9689 (define_split
9690   [(set (match_operand:SF 0 "register_operand" "")
9691         (neg:SF (match_operand:SF 1 "register_operand" "")))
9692    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "reload_completed && SSE_REG_P (operands[0])"
9695   [(set (match_dup 0)
9696         (xor:V4SF (match_dup 1)
9697                   (match_dup 2)))]
9698 {
9699   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9700   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9701   if (operands_match_p (operands[0], operands[2]))
9702     {
9703       rtx tmp;
9704       tmp = operands[1];
9705       operands[1] = operands[2];
9706       operands[2] = tmp;
9707     }
9708 })
9709
9710
9711 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9712 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9713 ;; to itself.
9714 (define_insn "*negsf2_if"
9715   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9716         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "TARGET_80387 && !TARGET_SSE
9719    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9720   "#")
9721
9722 (define_split
9723   [(set (match_operand:SF 0 "fp_register_operand" "")
9724         (neg:SF (match_operand:SF 1 "register_operand" "")))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "TARGET_80387 && reload_completed"
9727   [(set (match_dup 0)
9728         (neg:SF (match_dup 1)))]
9729   "")
9730
9731 (define_split
9732   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9733         (neg:SF (match_operand:SF 1 "register_operand" "")))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "TARGET_80387 && reload_completed"
9736   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9737               (clobber (reg:CC FLAGS_REG))])]
9738   "operands[1] = gen_int_mode (0x80000000, SImode);
9739    operands[0] = gen_lowpart (SImode, operands[0]);")
9740
9741 (define_split
9742   [(set (match_operand 0 "memory_operand" "")
9743         (neg (match_operand 1 "memory_operand" "")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9746   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9747               (clobber (reg:CC FLAGS_REG))])]
9748 {
9749   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9750
9751   if (GET_MODE (operands[1]) == XFmode)
9752     size = 10;
9753   operands[0] = adjust_address (operands[0], QImode, size - 1);
9754   operands[1] = gen_int_mode (0x80, QImode);
9755 })
9756
9757 (define_expand "negdf2"
9758   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9759                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9760               (clobber (reg:CC FLAGS_REG))])]
9761   "TARGET_80387"
9762   "if (TARGET_SSE2)
9763      {
9764        /* In case operand is in memory,  we will not use SSE.  */
9765        if (memory_operand (operands[0], VOIDmode)
9766            && rtx_equal_p (operands[0], operands[1]))
9767          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9768        else
9769         {
9770           /* Using SSE is tricky, since we need bitwise negation of -0
9771              in register.  */
9772           rtx reg;
9773 #if HOST_BITS_PER_WIDE_INT >= 64
9774           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9775 #else
9776           rtx imm = immed_double_const (0, 0x80000000, DImode);
9777 #endif
9778           rtx dest = operands[0];
9779
9780           operands[1] = force_reg (DFmode, operands[1]);
9781           operands[0] = force_reg (DFmode, operands[0]);
9782           imm = gen_lowpart (DFmode, imm);
9783           reg = force_reg (V2DFmode,
9784                            gen_rtx_CONST_VECTOR (V2DFmode,
9785                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9786           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9787           if (dest != operands[0])
9788             emit_move_insn (dest, operands[0]);
9789         }
9790        DONE;
9791      }
9792    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9793
9794 (define_insn "negdf2_memory"
9795   [(set (match_operand:DF 0 "memory_operand" "=m")
9796         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9799   "#")
9800
9801 (define_insn "negdf2_ifs"
9802   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9803         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9804    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9805    (clobber (reg:CC FLAGS_REG))]
9806   "!TARGET_64BIT && TARGET_SSE2
9807    && (reload_in_progress || reload_completed
9808        || (register_operand (operands[0], VOIDmode)
9809            && register_operand (operands[1], VOIDmode)))"
9810   "#")
9811
9812 (define_insn "*negdf2_ifs_rex64"
9813   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9814         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9815    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9816    (clobber (reg:CC FLAGS_REG))]
9817   "TARGET_64BIT && TARGET_SSE2
9818    && (reload_in_progress || reload_completed
9819        || (register_operand (operands[0], VOIDmode)
9820            && register_operand (operands[1], VOIDmode)))"
9821   "#")
9822
9823 (define_split
9824   [(set (match_operand:DF 0 "memory_operand" "")
9825         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9826    (use (match_operand:V2DF 2 "" ""))
9827    (clobber (reg:CC FLAGS_REG))]
9828   ""
9829   [(parallel [(set (match_dup 0)
9830                    (neg:DF (match_dup 1)))
9831               (clobber (reg:CC FLAGS_REG))])])
9832
9833 (define_split
9834   [(set (match_operand:DF 0 "register_operand" "")
9835         (neg:DF (match_operand:DF 1 "register_operand" "")))
9836    (use (match_operand:V2DF 2 "" ""))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "reload_completed && !SSE_REG_P (operands[0])
9839    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9840   [(parallel [(set (match_dup 0)
9841                    (neg:DF (match_dup 1)))
9842               (clobber (reg:CC FLAGS_REG))])])
9843
9844 (define_split
9845   [(set (match_operand:DF 0 "register_operand" "")
9846         (neg:DF (match_operand:DF 1 "register_operand" "")))
9847    (use (match_operand:V2DF 2 "" ""))
9848    (clobber (reg:CC FLAGS_REG))]
9849   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9850   [(parallel [(set (match_dup 0)
9851                    (xor:DI (match_dup 1) (match_dup 2)))
9852               (clobber (reg:CC FLAGS_REG))])]
9853    "operands[0] = gen_lowpart (DImode, operands[0]);
9854     operands[1] = gen_lowpart (DImode, operands[1]);
9855     operands[2] = gen_lowpart (DImode, operands[2]);")
9856
9857 (define_split
9858   [(set (match_operand:DF 0 "register_operand" "")
9859         (neg:DF (match_operand:DF 1 "register_operand" "")))
9860    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "reload_completed && SSE_REG_P (operands[0])"
9863   [(set (match_dup 0)
9864         (xor:V2DF (match_dup 1)
9865                   (match_dup 2)))]
9866 {
9867   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9868   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9869   /* Avoid possible reformatting on the operands.  */
9870   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9871     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9872   if (operands_match_p (operands[0], operands[2]))
9873     {
9874       rtx tmp;
9875       tmp = operands[1];
9876       operands[1] = operands[2];
9877       operands[2] = tmp;
9878     }
9879 })
9880
9881 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9882 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9883 ;; to itself.
9884 (define_insn "*negdf2_if"
9885   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9886         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "!TARGET_64BIT && TARGET_80387
9889    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9890   "#")
9891
9892 ;; FIXME: We should to allow integer registers here.  Problem is that
9893 ;; we need another scratch register to get constant from.
9894 ;; Forcing constant to mem if no register available in peep2 should be
9895 ;; safe even for PIC mode, because of RIP relative addressing.
9896 (define_insn "*negdf2_if_rex64"
9897   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9898         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9899    (clobber (reg:CC FLAGS_REG))]
9900   "TARGET_64BIT && TARGET_80387
9901    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9902   "#")
9903
9904 (define_split
9905   [(set (match_operand:DF 0 "fp_register_operand" "")
9906         (neg:DF (match_operand:DF 1 "register_operand" "")))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_80387 && reload_completed"
9909   [(set (match_dup 0)
9910         (neg:DF (match_dup 1)))]
9911   "")
9912
9913 (define_split
9914   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9915         (neg:DF (match_operand:DF 1 "register_operand" "")))
9916    (clobber (reg:CC FLAGS_REG))]
9917   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9918   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9919               (clobber (reg:CC FLAGS_REG))])]
9920   "operands[4] = gen_int_mode (0x80000000, SImode);
9921    split_di (operands+0, 1, operands+2, operands+3);")
9922
9923 (define_expand "negxf2"
9924   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9925                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9926               (clobber (reg:CC FLAGS_REG))])]
9927   "TARGET_80387"
9928   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9929
9930 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9931 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9932 ;; to itself.
9933 (define_insn "*negxf2_if"
9934   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9935         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "TARGET_80387
9938    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9939   "#")
9940
9941 (define_split
9942   [(set (match_operand:XF 0 "fp_register_operand" "")
9943         (neg:XF (match_operand:XF 1 "register_operand" "")))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_80387 && reload_completed"
9946   [(set (match_dup 0)
9947         (neg:XF (match_dup 1)))]
9948   "")
9949
9950 (define_split
9951   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9952         (neg:XF (match_operand:XF 1 "register_operand" "")))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "TARGET_80387 && reload_completed"
9955   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9956               (clobber (reg:CC FLAGS_REG))])]
9957   "operands[1] = GEN_INT (0x8000);
9958    operands[0] = gen_rtx_REG (SImode,
9959                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9960
9961 ;; Conditionalize these after reload. If they matches before reload, we 
9962 ;; lose the clobber and ability to use integer instructions.
9963
9964 (define_insn "*negsf2_1"
9965   [(set (match_operand:SF 0 "register_operand" "=f")
9966         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9967   "TARGET_80387 && reload_completed"
9968   "fchs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "SF")])
9971
9972 (define_insn "*negdf2_1"
9973   [(set (match_operand:DF 0 "register_operand" "=f")
9974         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9975   "TARGET_80387 && reload_completed"
9976   "fchs"
9977   [(set_attr "type" "fsgn")
9978    (set_attr "mode" "DF")])
9979
9980 (define_insn "*negextendsfdf2"
9981   [(set (match_operand:DF 0 "register_operand" "=f")
9982         (neg:DF (float_extend:DF
9983                   (match_operand:SF 1 "register_operand" "0"))))]
9984   "TARGET_80387"
9985   "fchs"
9986   [(set_attr "type" "fsgn")
9987    (set_attr "mode" "DF")])
9988
9989 (define_insn "*negxf2_1"
9990   [(set (match_operand:XF 0 "register_operand" "=f")
9991         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9992   "TARGET_80387 && reload_completed"
9993   "fchs"
9994   [(set_attr "type" "fsgn")
9995    (set_attr "mode" "XF")])
9996
9997 (define_insn "*negextenddfxf2"
9998   [(set (match_operand:XF 0 "register_operand" "=f")
9999         (neg:XF (float_extend:XF
10000                   (match_operand:DF 1 "register_operand" "0"))))]
10001   "TARGET_80387"
10002   "fchs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "XF")])
10005
10006 (define_insn "*negextendsfxf2"
10007   [(set (match_operand:XF 0 "register_operand" "=f")
10008         (neg:XF (float_extend:XF
10009                   (match_operand:SF 1 "register_operand" "0"))))]
10010   "TARGET_80387"
10011   "fchs"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "XF")])
10014 \f
10015 ;; Absolute value instructions
10016
10017 (define_expand "abssf2"
10018   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10019                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10020               (clobber (reg:CC FLAGS_REG))])]
10021   "TARGET_80387"
10022   "if (TARGET_SSE)
10023      {
10024        /* In case operand is in memory,  we will not use SSE.  */
10025        if (memory_operand (operands[0], VOIDmode)
10026            && rtx_equal_p (operands[0], operands[1]))
10027          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10028        else
10029         {
10030           /* Using SSE is tricky, since we need bitwise negation of -0
10031              in register.  */
10032           rtx reg = gen_reg_rtx (V4SFmode);
10033           rtx dest = operands[0];
10034           rtx imm;
10035
10036           operands[1] = force_reg (SFmode, operands[1]);
10037           operands[0] = force_reg (SFmode, operands[0]);
10038           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10039           reg = force_reg (V4SFmode,
10040                            gen_rtx_CONST_VECTOR (V4SFmode,
10041                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10042                                       CONST0_RTX (SFmode),
10043                                       CONST0_RTX (SFmode))));
10044           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10045           if (dest != operands[0])
10046             emit_move_insn (dest, operands[0]);
10047         }
10048        DONE;
10049      }
10050    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10051
10052 (define_insn "abssf2_memory"
10053   [(set (match_operand:SF 0 "memory_operand" "=m")
10054         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10055    (clobber (reg:CC FLAGS_REG))]
10056   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10057   "#")
10058
10059 (define_insn "abssf2_ifs"
10060   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10061         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10062    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "TARGET_SSE
10065    && (reload_in_progress || reload_completed
10066        || (register_operand (operands[0], VOIDmode)
10067             && register_operand (operands[1], VOIDmode)))"
10068   "#")
10069
10070 (define_split
10071   [(set (match_operand:SF 0 "memory_operand" "")
10072         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10073    (use (match_operand:V4SF 2 "" ""))
10074    (clobber (reg:CC FLAGS_REG))]
10075   ""
10076   [(parallel [(set (match_dup 0)
10077                    (abs:SF (match_dup 1)))
10078               (clobber (reg:CC FLAGS_REG))])])
10079
10080 (define_split
10081   [(set (match_operand:SF 0 "register_operand" "")
10082         (abs:SF (match_operand:SF 1 "register_operand" "")))
10083    (use (match_operand:V4SF 2 "" ""))
10084    (clobber (reg:CC FLAGS_REG))]
10085   "reload_completed && !SSE_REG_P (operands[0])"
10086   [(parallel [(set (match_dup 0)
10087                    (abs:SF (match_dup 1)))
10088               (clobber (reg:CC FLAGS_REG))])])
10089
10090 (define_split
10091   [(set (match_operand:SF 0 "register_operand" "")
10092         (abs:SF (match_operand:SF 1 "register_operand" "")))
10093    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10094    (clobber (reg:CC FLAGS_REG))]
10095   "reload_completed && SSE_REG_P (operands[0])"
10096   [(set (match_dup 0)
10097         (and:V4SF (match_dup 1)
10098                   (match_dup 2)))]
10099 {
10100   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10101   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10102   if (operands_match_p (operands[0], operands[2]))
10103     {
10104       rtx tmp;
10105       tmp = operands[1];
10106       operands[1] = operands[2];
10107       operands[2] = tmp;
10108     }
10109 })
10110
10111 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10112 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10113 ;; to itself.
10114 (define_insn "*abssf2_if"
10115   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10116         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10117    (clobber (reg:CC FLAGS_REG))]
10118   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10119   "#")
10120
10121 (define_split
10122   [(set (match_operand:SF 0 "fp_register_operand" "")
10123         (abs:SF (match_operand:SF 1 "register_operand" "")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "TARGET_80387 && reload_completed"
10126   [(set (match_dup 0)
10127         (abs:SF (match_dup 1)))]
10128   "")
10129
10130 (define_split
10131   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10132         (abs:SF (match_operand:SF 1 "register_operand" "")))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "TARGET_80387 && reload_completed"
10135   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10136               (clobber (reg:CC FLAGS_REG))])]
10137   "operands[1] = gen_int_mode (~0x80000000, SImode);
10138    operands[0] = gen_lowpart (SImode, operands[0]);")
10139
10140 (define_split
10141   [(set (match_operand 0 "memory_operand" "")
10142         (abs (match_operand 1 "memory_operand" "")))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10145   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10146               (clobber (reg:CC FLAGS_REG))])]
10147 {
10148   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10149
10150   if (GET_MODE (operands[1]) == XFmode)
10151     size = 10;
10152   operands[0] = adjust_address (operands[0], QImode, size - 1);
10153   operands[1] = gen_int_mode (~0x80, QImode);
10154 })
10155
10156 (define_expand "absdf2"
10157   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10158                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10159               (clobber (reg:CC FLAGS_REG))])]
10160   "TARGET_80387"
10161   "if (TARGET_SSE2)
10162      {
10163        /* In case operand is in memory,  we will not use SSE.  */
10164        if (memory_operand (operands[0], VOIDmode)
10165            && rtx_equal_p (operands[0], operands[1]))
10166          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10167        else
10168         {
10169           /* Using SSE is tricky, since we need bitwise negation of -0
10170              in register.  */
10171           rtx reg = gen_reg_rtx (V2DFmode);
10172 #if HOST_BITS_PER_WIDE_INT >= 64
10173           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10174 #else
10175           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10176 #endif
10177           rtx dest = operands[0];
10178
10179           operands[1] = force_reg (DFmode, operands[1]);
10180           operands[0] = force_reg (DFmode, operands[0]);
10181
10182           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10183           imm = gen_lowpart (DFmode, imm);
10184           reg = force_reg (V2DFmode,
10185                            gen_rtx_CONST_VECTOR (V2DFmode,
10186                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10187           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10188           if (dest != operands[0])
10189             emit_move_insn (dest, operands[0]);
10190         }
10191        DONE;
10192      }
10193    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10194
10195 (define_insn "absdf2_memory"
10196   [(set (match_operand:DF 0 "memory_operand" "=m")
10197         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10200   "#")
10201
10202 (define_insn "absdf2_ifs"
10203   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10204         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10205    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10206    (clobber (reg:CC FLAGS_REG))]
10207   "!TARGET_64BIT && TARGET_SSE2
10208    && (reload_in_progress || reload_completed
10209        || (register_operand (operands[0], VOIDmode)
10210            && register_operand (operands[1], VOIDmode)))"
10211   "#")
10212
10213 (define_insn "*absdf2_ifs_rex64"
10214   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10215         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10216    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "TARGET_64BIT && TARGET_SSE2
10219    && (reload_in_progress || reload_completed
10220        || (register_operand (operands[0], VOIDmode)
10221            && register_operand (operands[1], VOIDmode)))"
10222   "#")
10223
10224 (define_split
10225   [(set (match_operand:DF 0 "memory_operand" "")
10226         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10227    (use (match_operand:V2DF 2 "" ""))
10228    (clobber (reg:CC FLAGS_REG))]
10229   ""
10230   [(parallel [(set (match_dup 0)
10231                    (abs:DF (match_dup 1)))
10232               (clobber (reg:CC FLAGS_REG))])])
10233
10234 (define_split
10235   [(set (match_operand:DF 0 "register_operand" "")
10236         (abs:DF (match_operand:DF 1 "register_operand" "")))
10237    (use (match_operand:V2DF 2 "" ""))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "reload_completed && !SSE_REG_P (operands[0])"
10240   [(parallel [(set (match_dup 0)
10241                    (abs:DF (match_dup 1)))
10242               (clobber (reg:CC FLAGS_REG))])])
10243
10244 (define_split
10245   [(set (match_operand:DF 0 "register_operand" "")
10246         (abs:DF (match_operand:DF 1 "register_operand" "")))
10247    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "reload_completed && SSE_REG_P (operands[0])"
10250   [(set (match_dup 0)
10251         (and:V2DF (match_dup 1)
10252                   (match_dup 2)))]
10253 {
10254   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10255   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10256   /* Avoid possible reformatting on the operands.  */
10257   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10258     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10259   if (operands_match_p (operands[0], operands[2]))
10260     {
10261       rtx tmp;
10262       tmp = operands[1];
10263       operands[1] = operands[2];
10264       operands[2] = tmp;
10265     }
10266 })
10267
10268
10269 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10270 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10271 ;; to itself.
10272 (define_insn "*absdf2_if"
10273   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10274         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "!TARGET_64BIT && TARGET_80387
10277    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10278   "#")
10279
10280 ;; FIXME: We should to allow integer registers here.  Problem is that
10281 ;; we need another scratch register to get constant from.
10282 ;; Forcing constant to mem if no register available in peep2 should be
10283 ;; safe even for PIC mode, because of RIP relative addressing.
10284 (define_insn "*absdf2_if_rex64"
10285   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10286         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10287    (clobber (reg:CC FLAGS_REG))]
10288   "TARGET_64BIT && TARGET_80387
10289    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10290   "#")
10291
10292 (define_split
10293   [(set (match_operand:DF 0 "fp_register_operand" "")
10294         (abs:DF (match_operand:DF 1 "register_operand" "")))
10295    (clobber (reg:CC FLAGS_REG))]
10296   "TARGET_80387 && reload_completed"
10297   [(set (match_dup 0)
10298         (abs:DF (match_dup 1)))]
10299   "")
10300
10301 (define_split
10302   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10303         (abs:DF (match_operand:DF 1 "register_operand" "")))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10306   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10307               (clobber (reg:CC FLAGS_REG))])]
10308   "operands[4] = gen_int_mode (~0x80000000, SImode);
10309    split_di (operands+0, 1, operands+2, operands+3);")
10310
10311 (define_expand "absxf2"
10312   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10313                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10314               (clobber (reg:CC FLAGS_REG))])]
10315   "TARGET_80387"
10316   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10317
10318 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10319 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10320 ;; to itself.
10321 (define_insn "*absxf2_if"
10322   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10323         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_80387
10326    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10327   "#")
10328
10329 (define_split
10330   [(set (match_operand:XF 0 "fp_register_operand" "")
10331         (abs:XF (match_operand:XF 1 "register_operand" "")))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "TARGET_80387 && reload_completed"
10334   [(set (match_dup 0)
10335         (abs:XF (match_dup 1)))]
10336   "")
10337
10338 (define_split
10339   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10340         (abs:XF (match_operand:XF 1 "register_operand" "")))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_80387 && reload_completed"
10343   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10344               (clobber (reg:CC FLAGS_REG))])]
10345   "operands[1] = GEN_INT (~0x8000);
10346    operands[0] = gen_rtx_REG (SImode,
10347                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10348
10349 (define_insn "*abssf2_1"
10350   [(set (match_operand:SF 0 "register_operand" "=f")
10351         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10352   "TARGET_80387 && reload_completed"
10353   "fabs"
10354   [(set_attr "type" "fsgn")
10355    (set_attr "mode" "SF")])
10356
10357 (define_insn "*absdf2_1"
10358   [(set (match_operand:DF 0 "register_operand" "=f")
10359         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10360   "TARGET_80387 && reload_completed"
10361   "fabs"
10362   [(set_attr "type" "fsgn")
10363    (set_attr "mode" "DF")])
10364
10365 (define_insn "*absextendsfdf2"
10366   [(set (match_operand:DF 0 "register_operand" "=f")
10367         (abs:DF (float_extend:DF
10368                   (match_operand:SF 1 "register_operand" "0"))))]
10369   "TARGET_80387"
10370   "fabs"
10371   [(set_attr "type" "fsgn")
10372    (set_attr "mode" "DF")])
10373
10374 (define_insn "*absxf2_1"
10375   [(set (match_operand:XF 0 "register_operand" "=f")
10376         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10377   "TARGET_80387 && reload_completed"
10378   "fabs"
10379   [(set_attr "type" "fsgn")
10380    (set_attr "mode" "DF")])
10381
10382 (define_insn "*absextenddfxf2"
10383   [(set (match_operand:XF 0 "register_operand" "=f")
10384         (abs:XF (float_extend:XF
10385           (match_operand:DF 1 "register_operand" "0"))))]
10386   "TARGET_80387"
10387   "fabs"
10388   [(set_attr "type" "fsgn")
10389    (set_attr "mode" "XF")])
10390
10391 (define_insn "*absextendsfxf2"
10392   [(set (match_operand:XF 0 "register_operand" "=f")
10393         (abs:XF (float_extend:XF
10394           (match_operand:SF 1 "register_operand" "0"))))]
10395   "TARGET_80387"
10396   "fabs"
10397   [(set_attr "type" "fsgn")
10398    (set_attr "mode" "XF")])
10399 \f
10400 ;; One complement instructions
10401
10402 (define_expand "one_cmpldi2"
10403   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10404         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10405   "TARGET_64BIT"
10406   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10407
10408 (define_insn "*one_cmpldi2_1_rex64"
10409   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10410         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10411   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10412   "not{q}\t%0"
10413   [(set_attr "type" "negnot")
10414    (set_attr "mode" "DI")])
10415
10416 (define_insn "*one_cmpldi2_2_rex64"
10417   [(set (reg 17)
10418         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10419                  (const_int 0)))
10420    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10421         (not:DI (match_dup 1)))]
10422   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10423    && ix86_unary_operator_ok (NOT, DImode, operands)"
10424   "#"
10425   [(set_attr "type" "alu1")
10426    (set_attr "mode" "DI")])
10427
10428 (define_split
10429   [(set (reg 17)
10430         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10431                  (const_int 0)))
10432    (set (match_operand:DI 0 "nonimmediate_operand" "")
10433         (not:DI (match_dup 1)))]
10434   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10435   [(parallel [(set (reg:CCNO FLAGS_REG)
10436                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10437                                  (const_int 0)))
10438               (set (match_dup 0)
10439                    (xor:DI (match_dup 1) (const_int -1)))])]
10440   "")
10441
10442 (define_expand "one_cmplsi2"
10443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445   ""
10446   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10447
10448 (define_insn "*one_cmplsi2_1"
10449   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10451   "ix86_unary_operator_ok (NOT, SImode, operands)"
10452   "not{l}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "SI")])
10455
10456 ;; ??? Currently never generated - xor is used instead.
10457 (define_insn "*one_cmplsi2_1_zext"
10458   [(set (match_operand:DI 0 "register_operand" "=r")
10459         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10460   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10461   "not{l}\t%k0"
10462   [(set_attr "type" "negnot")
10463    (set_attr "mode" "SI")])
10464
10465 (define_insn "*one_cmplsi2_2"
10466   [(set (reg 17)
10467         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10468                  (const_int 0)))
10469    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10470         (not:SI (match_dup 1)))]
10471   "ix86_match_ccmode (insn, CCNOmode)
10472    && ix86_unary_operator_ok (NOT, SImode, operands)"
10473   "#"
10474   [(set_attr "type" "alu1")
10475    (set_attr "mode" "SI")])
10476
10477 (define_split
10478   [(set (reg 17)
10479         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10480                  (const_int 0)))
10481    (set (match_operand:SI 0 "nonimmediate_operand" "")
10482         (not:SI (match_dup 1)))]
10483   "ix86_match_ccmode (insn, CCNOmode)"
10484   [(parallel [(set (reg:CCNO FLAGS_REG)
10485                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10486                                  (const_int 0)))
10487               (set (match_dup 0)
10488                    (xor:SI (match_dup 1) (const_int -1)))])]
10489   "")
10490
10491 ;; ??? Currently never generated - xor is used instead.
10492 (define_insn "*one_cmplsi2_2_zext"
10493   [(set (reg 17)
10494         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10495                  (const_int 0)))
10496    (set (match_operand:DI 0 "register_operand" "=r")
10497         (zero_extend:DI (not:SI (match_dup 1))))]
10498   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10499    && ix86_unary_operator_ok (NOT, SImode, operands)"
10500   "#"
10501   [(set_attr "type" "alu1")
10502    (set_attr "mode" "SI")])
10503
10504 (define_split
10505   [(set (reg 17)
10506         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10507                  (const_int 0)))
10508    (set (match_operand:DI 0 "register_operand" "")
10509         (zero_extend:DI (not:SI (match_dup 1))))]
10510   "ix86_match_ccmode (insn, CCNOmode)"
10511   [(parallel [(set (reg:CCNO FLAGS_REG)
10512                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10513                                  (const_int 0)))
10514               (set (match_dup 0)
10515                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10516   "")
10517
10518 (define_expand "one_cmplhi2"
10519   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10520         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10521   "TARGET_HIMODE_MATH"
10522   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10523
10524 (define_insn "*one_cmplhi2_1"
10525   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10526         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10527   "ix86_unary_operator_ok (NOT, HImode, operands)"
10528   "not{w}\t%0"
10529   [(set_attr "type" "negnot")
10530    (set_attr "mode" "HI")])
10531
10532 (define_insn "*one_cmplhi2_2"
10533   [(set (reg 17)
10534         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10535                  (const_int 0)))
10536    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10537         (not:HI (match_dup 1)))]
10538   "ix86_match_ccmode (insn, CCNOmode)
10539    && ix86_unary_operator_ok (NEG, HImode, operands)"
10540   "#"
10541   [(set_attr "type" "alu1")
10542    (set_attr "mode" "HI")])
10543
10544 (define_split
10545   [(set (reg 17)
10546         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10547                  (const_int 0)))
10548    (set (match_operand:HI 0 "nonimmediate_operand" "")
10549         (not:HI (match_dup 1)))]
10550   "ix86_match_ccmode (insn, CCNOmode)"
10551   [(parallel [(set (reg:CCNO FLAGS_REG)
10552                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10553                                  (const_int 0)))
10554               (set (match_dup 0)
10555                    (xor:HI (match_dup 1) (const_int -1)))])]
10556   "")
10557
10558 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10559 (define_expand "one_cmplqi2"
10560   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10561         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10562   "TARGET_QIMODE_MATH"
10563   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10564
10565 (define_insn "*one_cmplqi2_1"
10566   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10567         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10568   "ix86_unary_operator_ok (NOT, QImode, operands)"
10569   "@
10570    not{b}\t%0
10571    not{l}\t%k0"
10572   [(set_attr "type" "negnot")
10573    (set_attr "mode" "QI,SI")])
10574
10575 (define_insn "*one_cmplqi2_2"
10576   [(set (reg 17)
10577         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10578                  (const_int 0)))
10579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580         (not:QI (match_dup 1)))]
10581   "ix86_match_ccmode (insn, CCNOmode)
10582    && ix86_unary_operator_ok (NOT, QImode, operands)"
10583   "#"
10584   [(set_attr "type" "alu1")
10585    (set_attr "mode" "QI")])
10586
10587 (define_split
10588   [(set (reg 17)
10589         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10590                  (const_int 0)))
10591    (set (match_operand:QI 0 "nonimmediate_operand" "")
10592         (not:QI (match_dup 1)))]
10593   "ix86_match_ccmode (insn, CCNOmode)"
10594   [(parallel [(set (reg:CCNO FLAGS_REG)
10595                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10596                                  (const_int 0)))
10597               (set (match_dup 0)
10598                    (xor:QI (match_dup 1) (const_int -1)))])]
10599   "")
10600 \f
10601 ;; Arithmetic shift instructions
10602
10603 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10604 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10605 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10606 ;; from the assembler input.
10607 ;;
10608 ;; This instruction shifts the target reg/mem as usual, but instead of
10609 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10610 ;; is a left shift double, bits are taken from the high order bits of
10611 ;; reg, else if the insn is a shift right double, bits are taken from the
10612 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10613 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10614 ;;
10615 ;; Since sh[lr]d does not change the `reg' operand, that is done
10616 ;; separately, making all shifts emit pairs of shift double and normal
10617 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10618 ;; support a 63 bit shift, each shift where the count is in a reg expands
10619 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10620 ;;
10621 ;; If the shift count is a constant, we need never emit more than one
10622 ;; shift pair, instead using moves and sign extension for counts greater
10623 ;; than 31.
10624
10625 (define_expand "ashldi3"
10626   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10627                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10628                               (match_operand:QI 2 "nonmemory_operand" "")))
10629               (clobber (reg:CC FLAGS_REG))])]
10630   ""
10631 {
10632   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10633     {
10634       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10635       DONE;
10636     }
10637   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10638   DONE;
10639 })
10640
10641 (define_insn "*ashldi3_1_rex64"
10642   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10643         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10644                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10647 {
10648   switch (get_attr_type (insn))
10649     {
10650     case TYPE_ALU:
10651       if (operands[2] != const1_rtx)
10652         abort ();
10653       if (!rtx_equal_p (operands[0], operands[1]))
10654         abort ();
10655       return "add{q}\t{%0, %0|%0, %0}";
10656
10657     case TYPE_LEA:
10658       if (GET_CODE (operands[2]) != CONST_INT
10659           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10660         abort ();
10661       operands[1] = gen_rtx_MULT (DImode, operands[1],
10662                                   GEN_INT (1 << INTVAL (operands[2])));
10663       return "lea{q}\t{%a1, %0|%0, %a1}";
10664
10665     default:
10666       if (REG_P (operands[2]))
10667         return "sal{q}\t{%b2, %0|%0, %b2}";
10668       else if (operands[2] == const1_rtx
10669                && (TARGET_SHIFT1 || optimize_size))
10670         return "sal{q}\t%0";
10671       else
10672         return "sal{q}\t{%2, %0|%0, %2}";
10673     }
10674 }
10675   [(set (attr "type")
10676      (cond [(eq_attr "alternative" "1")
10677               (const_string "lea")
10678             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679                           (const_int 0))
10680                       (match_operand 0 "register_operand" ""))
10681                  (match_operand 2 "const1_operand" ""))
10682               (const_string "alu")
10683            ]
10684            (const_string "ishift")))
10685    (set_attr "mode" "DI")])
10686
10687 ;; Convert lea to the lea pattern to avoid flags dependency.
10688 (define_split
10689   [(set (match_operand:DI 0 "register_operand" "")
10690         (ashift:DI (match_operand:DI 1 "register_operand" "")
10691                    (match_operand:QI 2 "immediate_operand" "")))
10692    (clobber (reg:CC FLAGS_REG))]
10693   "TARGET_64BIT && reload_completed
10694    && true_regnum (operands[0]) != true_regnum (operands[1])"
10695   [(set (match_dup 0)
10696         (mult:DI (match_dup 1)
10697                  (match_dup 2)))]
10698   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10699
10700 ;; This pattern can't accept a variable shift count, since shifts by
10701 ;; zero don't affect the flags.  We assume that shifts by constant
10702 ;; zero are optimized away.
10703 (define_insn "*ashldi3_cmp_rex64"
10704   [(set (reg 17)
10705         (compare
10706           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10707                      (match_operand:QI 2 "immediate_operand" "e"))
10708           (const_int 0)))
10709    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10710         (ashift:DI (match_dup 1) (match_dup 2)))]
10711   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10712    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10713 {
10714   switch (get_attr_type (insn))
10715     {
10716     case TYPE_ALU:
10717       if (operands[2] != const1_rtx)
10718         abort ();
10719       return "add{q}\t{%0, %0|%0, %0}";
10720
10721     default:
10722       if (REG_P (operands[2]))
10723         return "sal{q}\t{%b2, %0|%0, %b2}";
10724       else if (operands[2] == const1_rtx
10725                && (TARGET_SHIFT1 || optimize_size))
10726         return "sal{q}\t%0";
10727       else
10728         return "sal{q}\t{%2, %0|%0, %2}";
10729     }
10730 }
10731   [(set (attr "type")
10732      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10733                           (const_int 0))
10734                       (match_operand 0 "register_operand" ""))
10735                  (match_operand 2 "const1_operand" ""))
10736               (const_string "alu")
10737            ]
10738            (const_string "ishift")))
10739    (set_attr "mode" "DI")])
10740
10741 (define_insn "ashldi3_1"
10742   [(set (match_operand:DI 0 "register_operand" "=r")
10743         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10744                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10745    (clobber (match_scratch:SI 3 "=&r"))
10746    (clobber (reg:CC FLAGS_REG))]
10747   "!TARGET_64BIT && TARGET_CMOVE"
10748   "#"
10749   [(set_attr "type" "multi")])
10750
10751 (define_insn "*ashldi3_2"
10752   [(set (match_operand:DI 0 "register_operand" "=r")
10753         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10754                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "!TARGET_64BIT"
10757   "#"
10758   [(set_attr "type" "multi")])
10759
10760 (define_split
10761   [(set (match_operand:DI 0 "register_operand" "")
10762         (ashift:DI (match_operand:DI 1 "register_operand" "")
10763                    (match_operand:QI 2 "nonmemory_operand" "")))
10764    (clobber (match_scratch:SI 3 ""))
10765    (clobber (reg:CC FLAGS_REG))]
10766   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10767   [(const_int 0)]
10768   "ix86_split_ashldi (operands, operands[3]); DONE;")
10769
10770 (define_split
10771   [(set (match_operand:DI 0 "register_operand" "")
10772         (ashift:DI (match_operand:DI 1 "register_operand" "")
10773                    (match_operand:QI 2 "nonmemory_operand" "")))
10774    (clobber (reg:CC FLAGS_REG))]
10775   "!TARGET_64BIT && reload_completed"
10776   [(const_int 0)]
10777   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10778
10779 (define_insn "x86_shld_1"
10780   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10781         (ior:SI (ashift:SI (match_dup 0)
10782                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10783                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10784                   (minus:QI (const_int 32) (match_dup 2)))))
10785    (clobber (reg:CC FLAGS_REG))]
10786   ""
10787   "@
10788    shld{l}\t{%2, %1, %0|%0, %1, %2}
10789    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10790   [(set_attr "type" "ishift")
10791    (set_attr "prefix_0f" "1")
10792    (set_attr "mode" "SI")
10793    (set_attr "pent_pair" "np")
10794    (set_attr "athlon_decode" "vector")])
10795
10796 (define_expand "x86_shift_adj_1"
10797   [(set (reg:CCZ FLAGS_REG)
10798         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10799                              (const_int 32))
10800                      (const_int 0)))
10801    (set (match_operand:SI 0 "register_operand" "")
10802         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10803                          (match_operand:SI 1 "register_operand" "")
10804                          (match_dup 0)))
10805    (set (match_dup 1)
10806         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10807                          (match_operand:SI 3 "register_operand" "r")
10808                          (match_dup 1)))]
10809   "TARGET_CMOVE"
10810   "")
10811
10812 (define_expand "x86_shift_adj_2"
10813   [(use (match_operand:SI 0 "register_operand" ""))
10814    (use (match_operand:SI 1 "register_operand" ""))
10815    (use (match_operand:QI 2 "register_operand" ""))]
10816   ""
10817 {
10818   rtx label = gen_label_rtx ();
10819   rtx tmp;
10820
10821   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10822
10823   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10824   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10825   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10826                               gen_rtx_LABEL_REF (VOIDmode, label),
10827                               pc_rtx);
10828   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10829   JUMP_LABEL (tmp) = label;
10830
10831   emit_move_insn (operands[0], operands[1]);
10832   emit_move_insn (operands[1], const0_rtx);
10833
10834   emit_label (label);
10835   LABEL_NUSES (label) = 1;
10836
10837   DONE;
10838 })
10839
10840 (define_expand "ashlsi3"
10841   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10842         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10843                    (match_operand:QI 2 "nonmemory_operand" "")))
10844    (clobber (reg:CC FLAGS_REG))]
10845   ""
10846   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10847
10848 (define_insn "*ashlsi3_1"
10849   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10850         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10851                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10852    (clobber (reg:CC FLAGS_REG))]
10853   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10854 {
10855   switch (get_attr_type (insn))
10856     {
10857     case TYPE_ALU:
10858       if (operands[2] != const1_rtx)
10859         abort ();
10860       if (!rtx_equal_p (operands[0], operands[1]))
10861         abort ();
10862       return "add{l}\t{%0, %0|%0, %0}";
10863
10864     case TYPE_LEA:
10865       return "#";
10866
10867     default:
10868       if (REG_P (operands[2]))
10869         return "sal{l}\t{%b2, %0|%0, %b2}";
10870       else if (operands[2] == const1_rtx
10871                && (TARGET_SHIFT1 || optimize_size))
10872         return "sal{l}\t%0";
10873       else
10874         return "sal{l}\t{%2, %0|%0, %2}";
10875     }
10876 }
10877   [(set (attr "type")
10878      (cond [(eq_attr "alternative" "1")
10879               (const_string "lea")
10880             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10881                           (const_int 0))
10882                       (match_operand 0 "register_operand" ""))
10883                  (match_operand 2 "const1_operand" ""))
10884               (const_string "alu")
10885            ]
10886            (const_string "ishift")))
10887    (set_attr "mode" "SI")])
10888
10889 ;; Convert lea to the lea pattern to avoid flags dependency.
10890 (define_split
10891   [(set (match_operand 0 "register_operand" "")
10892         (ashift (match_operand 1 "index_register_operand" "")
10893                 (match_operand:QI 2 "const_int_operand" "")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "reload_completed
10896    && true_regnum (operands[0]) != true_regnum (operands[1])"
10897   [(const_int 0)]
10898 {
10899   rtx pat;
10900   operands[0] = gen_lowpart (SImode, operands[0]);
10901   operands[1] = gen_lowpart (Pmode, operands[1]);
10902   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10903   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10904   if (Pmode != SImode)
10905     pat = gen_rtx_SUBREG (SImode, pat, 0);
10906   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10907   DONE;
10908 })
10909
10910 ;; Rare case of shifting RSP is handled by generating move and shift
10911 (define_split
10912   [(set (match_operand 0 "register_operand" "")
10913         (ashift (match_operand 1 "register_operand" "")
10914                 (match_operand:QI 2 "const_int_operand" "")))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "reload_completed
10917    && true_regnum (operands[0]) != true_regnum (operands[1])"
10918   [(const_int 0)]
10919 {
10920   rtx pat, clob;
10921   emit_move_insn (operands[1], operands[0]);
10922   pat = gen_rtx_SET (VOIDmode, operands[0],
10923                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10924                                      operands[0], operands[2]));
10925   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10926   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10927   DONE;
10928 })
10929
10930 (define_insn "*ashlsi3_1_zext"
10931   [(set (match_operand:DI 0 "register_operand" "=r,r")
10932         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10933                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10936 {
10937   switch (get_attr_type (insn))
10938     {
10939     case TYPE_ALU:
10940       if (operands[2] != const1_rtx)
10941         abort ();
10942       return "add{l}\t{%k0, %k0|%k0, %k0}";
10943
10944     case TYPE_LEA:
10945       return "#";
10946
10947     default:
10948       if (REG_P (operands[2]))
10949         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10950       else if (operands[2] == const1_rtx
10951                && (TARGET_SHIFT1 || optimize_size))
10952         return "sal{l}\t%k0";
10953       else
10954         return "sal{l}\t{%2, %k0|%k0, %2}";
10955     }
10956 }
10957   [(set (attr "type")
10958      (cond [(eq_attr "alternative" "1")
10959               (const_string "lea")
10960             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10961                      (const_int 0))
10962                  (match_operand 2 "const1_operand" ""))
10963               (const_string "alu")
10964            ]
10965            (const_string "ishift")))
10966    (set_attr "mode" "SI")])
10967
10968 ;; Convert lea to the lea pattern to avoid flags dependency.
10969 (define_split
10970   [(set (match_operand:DI 0 "register_operand" "")
10971         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10972                                 (match_operand:QI 2 "const_int_operand" ""))))
10973    (clobber (reg:CC FLAGS_REG))]
10974   "TARGET_64BIT && reload_completed
10975    && true_regnum (operands[0]) != true_regnum (operands[1])"
10976   [(set (match_dup 0) (zero_extend:DI
10977                         (subreg:SI (mult:SI (match_dup 1)
10978                                             (match_dup 2)) 0)))]
10979 {
10980   operands[1] = gen_lowpart (Pmode, operands[1]);
10981   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10982 })
10983
10984 ;; This pattern can't accept a variable shift count, since shifts by
10985 ;; zero don't affect the flags.  We assume that shifts by constant
10986 ;; zero are optimized away.
10987 (define_insn "*ashlsi3_cmp"
10988   [(set (reg 17)
10989         (compare
10990           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10991                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10992           (const_int 0)))
10993    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10994         (ashift:SI (match_dup 1) (match_dup 2)))]
10995   "ix86_match_ccmode (insn, CCGOCmode)
10996    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10997 {
10998   switch (get_attr_type (insn))
10999     {
11000     case TYPE_ALU:
11001       if (operands[2] != const1_rtx)
11002         abort ();
11003       return "add{l}\t{%0, %0|%0, %0}";
11004
11005     default:
11006       if (REG_P (operands[2]))
11007         return "sal{l}\t{%b2, %0|%0, %b2}";
11008       else if (operands[2] == const1_rtx
11009                && (TARGET_SHIFT1 || optimize_size))
11010         return "sal{l}\t%0";
11011       else
11012         return "sal{l}\t{%2, %0|%0, %2}";
11013     }
11014 }
11015   [(set (attr "type")
11016      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11017                           (const_int 0))
11018                       (match_operand 0 "register_operand" ""))
11019                  (match_operand 2 "const1_operand" ""))
11020               (const_string "alu")
11021            ]
11022            (const_string "ishift")))
11023    (set_attr "mode" "SI")])
11024
11025 (define_insn "*ashlsi3_cmp_zext"
11026   [(set (reg 17)
11027         (compare
11028           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11029                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11030           (const_int 0)))
11031    (set (match_operand:DI 0 "register_operand" "=r")
11032         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11033   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11034    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11035 {
11036   switch (get_attr_type (insn))
11037     {
11038     case TYPE_ALU:
11039       if (operands[2] != const1_rtx)
11040         abort ();
11041       return "add{l}\t{%k0, %k0|%k0, %k0}";
11042
11043     default:
11044       if (REG_P (operands[2]))
11045         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11046       else if (operands[2] == const1_rtx
11047                && (TARGET_SHIFT1 || optimize_size))
11048         return "sal{l}\t%k0";
11049       else
11050         return "sal{l}\t{%2, %k0|%k0, %2}";
11051     }
11052 }
11053   [(set (attr "type")
11054      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055                      (const_int 0))
11056                  (match_operand 2 "const1_operand" ""))
11057               (const_string "alu")
11058            ]
11059            (const_string "ishift")))
11060    (set_attr "mode" "SI")])
11061
11062 (define_expand "ashlhi3"
11063   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11064         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11065                    (match_operand:QI 2 "nonmemory_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_HIMODE_MATH"
11068   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11069
11070 (define_insn "*ashlhi3_1_lea"
11071   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11072         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11073                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "!TARGET_PARTIAL_REG_STALL
11076    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11077 {
11078   switch (get_attr_type (insn))
11079     {
11080     case TYPE_LEA:
11081       return "#";
11082     case TYPE_ALU:
11083       if (operands[2] != const1_rtx)
11084         abort ();
11085       return "add{w}\t{%0, %0|%0, %0}";
11086
11087     default:
11088       if (REG_P (operands[2]))
11089         return "sal{w}\t{%b2, %0|%0, %b2}";
11090       else if (operands[2] == const1_rtx
11091                && (TARGET_SHIFT1 || optimize_size))
11092         return "sal{w}\t%0";
11093       else
11094         return "sal{w}\t{%2, %0|%0, %2}";
11095     }
11096 }
11097   [(set (attr "type")
11098      (cond [(eq_attr "alternative" "1")
11099               (const_string "lea")
11100             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11101                           (const_int 0))
11102                       (match_operand 0 "register_operand" ""))
11103                  (match_operand 2 "const1_operand" ""))
11104               (const_string "alu")
11105            ]
11106            (const_string "ishift")))
11107    (set_attr "mode" "HI,SI")])
11108
11109 (define_insn "*ashlhi3_1"
11110   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11111         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11112                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11113    (clobber (reg:CC FLAGS_REG))]
11114   "TARGET_PARTIAL_REG_STALL
11115    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11116 {
11117   switch (get_attr_type (insn))
11118     {
11119     case TYPE_ALU:
11120       if (operands[2] != const1_rtx)
11121         abort ();
11122       return "add{w}\t{%0, %0|%0, %0}";
11123
11124     default:
11125       if (REG_P (operands[2]))
11126         return "sal{w}\t{%b2, %0|%0, %b2}";
11127       else if (operands[2] == const1_rtx
11128                && (TARGET_SHIFT1 || optimize_size))
11129         return "sal{w}\t%0";
11130       else
11131         return "sal{w}\t{%2, %0|%0, %2}";
11132     }
11133 }
11134   [(set (attr "type")
11135      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11136                           (const_int 0))
11137                       (match_operand 0 "register_operand" ""))
11138                  (match_operand 2 "const1_operand" ""))
11139               (const_string "alu")
11140            ]
11141            (const_string "ishift")))
11142    (set_attr "mode" "HI")])
11143
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags.  We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashlhi3_cmp"
11148   [(set (reg 17)
11149         (compare
11150           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11151                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11152           (const_int 0)))
11153    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11154         (ashift:HI (match_dup 1) (match_dup 2)))]
11155   "ix86_match_ccmode (insn, CCGOCmode)
11156    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11157 {
11158   switch (get_attr_type (insn))
11159     {
11160     case TYPE_ALU:
11161       if (operands[2] != const1_rtx)
11162         abort ();
11163       return "add{w}\t{%0, %0|%0, %0}";
11164
11165     default:
11166       if (REG_P (operands[2]))
11167         return "sal{w}\t{%b2, %0|%0, %b2}";
11168       else if (operands[2] == const1_rtx
11169                && (TARGET_SHIFT1 || optimize_size))
11170         return "sal{w}\t%0";
11171       else
11172         return "sal{w}\t{%2, %0|%0, %2}";
11173     }
11174 }
11175   [(set (attr "type")
11176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11177                           (const_int 0))
11178                       (match_operand 0 "register_operand" ""))
11179                  (match_operand 2 "const1_operand" ""))
11180               (const_string "alu")
11181            ]
11182            (const_string "ishift")))
11183    (set_attr "mode" "HI")])
11184
11185 (define_expand "ashlqi3"
11186   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11187         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11188                    (match_operand:QI 2 "nonmemory_operand" "")))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "TARGET_QIMODE_MATH"
11191   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11192
11193 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11194
11195 (define_insn "*ashlqi3_1_lea"
11196   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11197         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11198                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "!TARGET_PARTIAL_REG_STALL
11201    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11202 {
11203   switch (get_attr_type (insn))
11204     {
11205     case TYPE_LEA:
11206       return "#";
11207     case TYPE_ALU:
11208       if (operands[2] != const1_rtx)
11209         abort ();
11210       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11211         return "add{l}\t{%k0, %k0|%k0, %k0}";
11212       else
11213         return "add{b}\t{%0, %0|%0, %0}";
11214
11215     default:
11216       if (REG_P (operands[2]))
11217         {
11218           if (get_attr_mode (insn) == MODE_SI)
11219             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11220           else
11221             return "sal{b}\t{%b2, %0|%0, %b2}";
11222         }
11223       else if (operands[2] == const1_rtx
11224                && (TARGET_SHIFT1 || optimize_size))
11225         {
11226           if (get_attr_mode (insn) == MODE_SI)
11227             return "sal{l}\t%0";
11228           else
11229             return "sal{b}\t%0";
11230         }
11231       else
11232         {
11233           if (get_attr_mode (insn) == MODE_SI)
11234             return "sal{l}\t{%2, %k0|%k0, %2}";
11235           else
11236             return "sal{b}\t{%2, %0|%0, %2}";
11237         }
11238     }
11239 }
11240   [(set (attr "type")
11241      (cond [(eq_attr "alternative" "2")
11242               (const_string "lea")
11243             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244                           (const_int 0))
11245                       (match_operand 0 "register_operand" ""))
11246                  (match_operand 2 "const1_operand" ""))
11247               (const_string "alu")
11248            ]
11249            (const_string "ishift")))
11250    (set_attr "mode" "QI,SI,SI")])
11251
11252 (define_insn "*ashlqi3_1"
11253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11254         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11255                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11256    (clobber (reg:CC FLAGS_REG))]
11257   "TARGET_PARTIAL_REG_STALL
11258    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11259 {
11260   switch (get_attr_type (insn))
11261     {
11262     case TYPE_ALU:
11263       if (operands[2] != const1_rtx)
11264         abort ();
11265       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11266         return "add{l}\t{%k0, %k0|%k0, %k0}";
11267       else
11268         return "add{b}\t{%0, %0|%0, %0}";
11269
11270     default:
11271       if (REG_P (operands[2]))
11272         {
11273           if (get_attr_mode (insn) == MODE_SI)
11274             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11275           else
11276             return "sal{b}\t{%b2, %0|%0, %b2}";
11277         }
11278       else if (operands[2] == const1_rtx
11279                && (TARGET_SHIFT1 || optimize_size))
11280         {
11281           if (get_attr_mode (insn) == MODE_SI)
11282             return "sal{l}\t%0";
11283           else
11284             return "sal{b}\t%0";
11285         }
11286       else
11287         {
11288           if (get_attr_mode (insn) == MODE_SI)
11289             return "sal{l}\t{%2, %k0|%k0, %2}";
11290           else
11291             return "sal{b}\t{%2, %0|%0, %2}";
11292         }
11293     }
11294 }
11295   [(set (attr "type")
11296      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11297                           (const_int 0))
11298                       (match_operand 0 "register_operand" ""))
11299                  (match_operand 2 "const1_operand" ""))
11300               (const_string "alu")
11301            ]
11302            (const_string "ishift")))
11303    (set_attr "mode" "QI,SI")])
11304
11305 ;; This pattern can't accept a variable shift count, since shifts by
11306 ;; zero don't affect the flags.  We assume that shifts by constant
11307 ;; zero are optimized away.
11308 (define_insn "*ashlqi3_cmp"
11309   [(set (reg 17)
11310         (compare
11311           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11312                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11313           (const_int 0)))
11314    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11315         (ashift:QI (match_dup 1) (match_dup 2)))]
11316   "ix86_match_ccmode (insn, CCGOCmode)
11317    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11318 {
11319   switch (get_attr_type (insn))
11320     {
11321     case TYPE_ALU:
11322       if (operands[2] != const1_rtx)
11323         abort ();
11324       return "add{b}\t{%0, %0|%0, %0}";
11325
11326     default:
11327       if (REG_P (operands[2]))
11328         return "sal{b}\t{%b2, %0|%0, %b2}";
11329       else if (operands[2] == const1_rtx
11330                && (TARGET_SHIFT1 || optimize_size))
11331         return "sal{b}\t%0";
11332       else
11333         return "sal{b}\t{%2, %0|%0, %2}";
11334     }
11335 }
11336   [(set (attr "type")
11337      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11338                           (const_int 0))
11339                       (match_operand 0 "register_operand" ""))
11340                  (match_operand 2 "const1_operand" ""))
11341               (const_string "alu")
11342            ]
11343            (const_string "ishift")))
11344    (set_attr "mode" "QI")])
11345
11346 ;; See comment above `ashldi3' about how this works.
11347
11348 (define_expand "ashrdi3"
11349   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11350                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11351                                 (match_operand:QI 2 "nonmemory_operand" "")))
11352               (clobber (reg:CC FLAGS_REG))])]
11353   ""
11354 {
11355   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11356     {
11357       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11358       DONE;
11359     }
11360   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11361   DONE;
11362 })
11363
11364 (define_insn "ashrdi3_63_rex64"
11365   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11366         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11367                      (match_operand:DI 2 "const_int_operand" "i,i")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11370    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11371   "@
11372    {cqto|cqo}
11373    sar{q}\t{%2, %0|%0, %2}"
11374   [(set_attr "type" "imovx,ishift")
11375    (set_attr "prefix_0f" "0,*")
11376    (set_attr "length_immediate" "0,*")
11377    (set_attr "modrm" "0,1")
11378    (set_attr "mode" "DI")])
11379
11380 (define_insn "*ashrdi3_1_one_bit_rex64"
11381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11382         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11383                      (match_operand:QI 2 "const1_operand" "")))
11384    (clobber (reg:CC FLAGS_REG))]
11385   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11386    && (TARGET_SHIFT1 || optimize_size)"
11387   "sar{q}\t%0"
11388   [(set_attr "type" "ishift")
11389    (set (attr "length") 
11390      (if_then_else (match_operand:DI 0 "register_operand" "") 
11391         (const_string "2")
11392         (const_string "*")))])
11393
11394 (define_insn "*ashrdi3_1_rex64"
11395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11396         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11397                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11398    (clobber (reg:CC FLAGS_REG))]
11399   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400   "@
11401    sar{q}\t{%2, %0|%0, %2}
11402    sar{q}\t{%b2, %0|%0, %b2}"
11403   [(set_attr "type" "ishift")
11404    (set_attr "mode" "DI")])
11405
11406 ;; This pattern can't accept a variable shift count, since shifts by
11407 ;; zero don't affect the flags.  We assume that shifts by constant
11408 ;; zero are optimized away.
11409 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11410   [(set (reg 17)
11411         (compare
11412           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                        (match_operand:QI 2 "const1_operand" ""))
11414           (const_int 0)))
11415    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11416         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11417   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11418    && (TARGET_SHIFT1 || optimize_size)
11419    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11420   "sar{q}\t%0"
11421   [(set_attr "type" "ishift")
11422    (set (attr "length") 
11423      (if_then_else (match_operand:DI 0 "register_operand" "") 
11424         (const_string "2")
11425         (const_string "*")))])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrdi3_cmp_rex64"
11431   [(set (reg 17)
11432         (compare
11433           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const_int_operand" "n"))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11440   "sar{q}\t{%2, %0|%0, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "mode" "DI")])
11443
11444
11445 (define_insn "ashrdi3_1"
11446   [(set (match_operand:DI 0 "register_operand" "=r")
11447         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11448                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11449    (clobber (match_scratch:SI 3 "=&r"))
11450    (clobber (reg:CC FLAGS_REG))]
11451   "!TARGET_64BIT && TARGET_CMOVE"
11452   "#"
11453   [(set_attr "type" "multi")])
11454
11455 (define_insn "*ashrdi3_2"
11456   [(set (match_operand:DI 0 "register_operand" "=r")
11457         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11458                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "!TARGET_64BIT"
11461   "#"
11462   [(set_attr "type" "multi")])
11463
11464 (define_split
11465   [(set (match_operand:DI 0 "register_operand" "")
11466         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11467                      (match_operand:QI 2 "nonmemory_operand" "")))
11468    (clobber (match_scratch:SI 3 ""))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11471   [(const_int 0)]
11472   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11473
11474 (define_split
11475   [(set (match_operand:DI 0 "register_operand" "")
11476         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11477                      (match_operand:QI 2 "nonmemory_operand" "")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "!TARGET_64BIT && reload_completed"
11480   [(const_int 0)]
11481   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11482
11483 (define_insn "x86_shrd_1"
11484   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11485         (ior:SI (ashiftrt:SI (match_dup 0)
11486                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11487                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11488                   (minus:QI (const_int 32) (match_dup 2)))))
11489    (clobber (reg:CC FLAGS_REG))]
11490   ""
11491   "@
11492    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11493    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11494   [(set_attr "type" "ishift")
11495    (set_attr "prefix_0f" "1")
11496    (set_attr "pent_pair" "np")
11497    (set_attr "mode" "SI")])
11498
11499 (define_expand "x86_shift_adj_3"
11500   [(use (match_operand:SI 0 "register_operand" ""))
11501    (use (match_operand:SI 1 "register_operand" ""))
11502    (use (match_operand:QI 2 "register_operand" ""))]
11503   ""
11504 {
11505   rtx label = gen_label_rtx ();
11506   rtx tmp;
11507
11508   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11509
11510   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11511   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11512   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11513                               gen_rtx_LABEL_REF (VOIDmode, label),
11514                               pc_rtx);
11515   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11516   JUMP_LABEL (tmp) = label;
11517
11518   emit_move_insn (operands[0], operands[1]);
11519   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11520
11521   emit_label (label);
11522   LABEL_NUSES (label) = 1;
11523
11524   DONE;
11525 })
11526
11527 (define_insn "ashrsi3_31"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11530                      (match_operand:SI 2 "const_int_operand" "i,i")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11533    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11534   "@
11535    {cltd|cdq}
11536    sar{l}\t{%2, %0|%0, %2}"
11537   [(set_attr "type" "imovx,ishift")
11538    (set_attr "prefix_0f" "0,*")
11539    (set_attr "length_immediate" "0,*")
11540    (set_attr "modrm" "0,1")
11541    (set_attr "mode" "SI")])
11542
11543 (define_insn "*ashrsi3_31_zext"
11544   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11545         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11546                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11547    (clobber (reg:CC FLAGS_REG))]
11548   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11549    && INTVAL (operands[2]) == 31
11550    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551   "@
11552    {cltd|cdq}
11553    sar{l}\t{%2, %k0|%k0, %2}"
11554   [(set_attr "type" "imovx,ishift")
11555    (set_attr "prefix_0f" "0,*")
11556    (set_attr "length_immediate" "0,*")
11557    (set_attr "modrm" "0,1")
11558    (set_attr "mode" "SI")])
11559
11560 (define_expand "ashrsi3"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11563                      (match_operand:QI 2 "nonmemory_operand" "")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   ""
11566   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11567
11568 (define_insn "*ashrsi3_1_one_bit"
11569   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11570         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                      (match_operand:QI 2 "const1_operand" "")))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11574    && (TARGET_SHIFT1 || optimize_size)"
11575   "sar{l}\t%0"
11576   [(set_attr "type" "ishift")
11577    (set (attr "length") 
11578      (if_then_else (match_operand:SI 0 "register_operand" "") 
11579         (const_string "2")
11580         (const_string "*")))])
11581
11582 (define_insn "*ashrsi3_1_one_bit_zext"
11583   [(set (match_operand:DI 0 "register_operand" "=r")
11584         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11585                                      (match_operand:QI 2 "const1_operand" ""))))
11586    (clobber (reg:CC FLAGS_REG))]
11587   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11588    && (TARGET_SHIFT1 || optimize_size)"
11589   "sar{l}\t%k0"
11590   [(set_attr "type" "ishift")
11591    (set_attr "length" "2")])
11592
11593 (define_insn "*ashrsi3_1"
11594   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11595         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11596                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11599   "@
11600    sar{l}\t{%2, %0|%0, %2}
11601    sar{l}\t{%b2, %0|%0, %b2}"
11602   [(set_attr "type" "ishift")
11603    (set_attr "mode" "SI")])
11604
11605 (define_insn "*ashrsi3_1_zext"
11606   [(set (match_operand:DI 0 "register_operand" "=r,r")
11607         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11608                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11609    (clobber (reg:CC FLAGS_REG))]
11610   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11611   "@
11612    sar{l}\t{%2, %k0|%k0, %2}
11613    sar{l}\t{%b2, %k0|%k0, %b2}"
11614   [(set_attr "type" "ishift")
11615    (set_attr "mode" "SI")])
11616
11617 ;; This pattern can't accept a variable shift count, since shifts by
11618 ;; zero don't affect the flags.  We assume that shifts by constant
11619 ;; zero are optimized away.
11620 (define_insn "*ashrsi3_one_bit_cmp"
11621   [(set (reg 17)
11622         (compare
11623           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11624                        (match_operand:QI 2 "const1_operand" ""))
11625           (const_int 0)))
11626    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11627         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11628   "ix86_match_ccmode (insn, CCGOCmode)
11629    && (TARGET_SHIFT1 || optimize_size)
11630    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11631   "sar{l}\t%0"
11632   [(set_attr "type" "ishift")
11633    (set (attr "length") 
11634      (if_then_else (match_operand:SI 0 "register_operand" "") 
11635         (const_string "2")
11636         (const_string "*")))])
11637
11638 (define_insn "*ashrsi3_one_bit_cmp_zext"
11639   [(set (reg 17)
11640         (compare
11641           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11642                        (match_operand:QI 2 "const1_operand" ""))
11643           (const_int 0)))
11644    (set (match_operand:DI 0 "register_operand" "=r")
11645         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11646   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11647    && (TARGET_SHIFT1 || optimize_size)
11648    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11649   "sar{l}\t%k0"
11650   [(set_attr "type" "ishift")
11651    (set_attr "length" "2")])
11652
11653 ;; This pattern can't accept a variable shift count, since shifts by
11654 ;; zero don't affect the flags.  We assume that shifts by constant
11655 ;; zero are optimized away.
11656 (define_insn "*ashrsi3_cmp"
11657   [(set (reg 17)
11658         (compare
11659           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11660                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11661           (const_int 0)))
11662    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11663         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11664   "ix86_match_ccmode (insn, CCGOCmode)
11665    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11666   "sar{l}\t{%2, %0|%0, %2}"
11667   [(set_attr "type" "ishift")
11668    (set_attr "mode" "SI")])
11669
11670 (define_insn "*ashrsi3_cmp_zext"
11671   [(set (reg 17)
11672         (compare
11673           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11674                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11675           (const_int 0)))
11676    (set (match_operand:DI 0 "register_operand" "=r")
11677         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11679    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11680   "sar{l}\t{%2, %k0|%k0, %2}"
11681   [(set_attr "type" "ishift")
11682    (set_attr "mode" "SI")])
11683
11684 (define_expand "ashrhi3"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687                      (match_operand:QI 2 "nonmemory_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_HIMODE_MATH"
11690   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11691
11692 (define_insn "*ashrhi3_1_one_bit"
11693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const1_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698    && (TARGET_SHIFT1 || optimize_size)"
11699   "sar{w}\t%0"
11700   [(set_attr "type" "ishift")
11701    (set (attr "length") 
11702      (if_then_else (match_operand 0 "register_operand" "") 
11703         (const_string "2")
11704         (const_string "*")))])
11705
11706 (define_insn "*ashrhi3_1"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11712   "@
11713    sar{w}\t{%2, %0|%0, %2}
11714    sar{w}\t{%b2, %0|%0, %b2}"
11715   [(set_attr "type" "ishift")
11716    (set_attr "mode" "HI")])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*ashrhi3_one_bit_cmp"
11722   [(set (reg 17)
11723         (compare
11724           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11732   "sar{w}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 ;; This pattern can't accept a variable shift count, since shifts by
11740 ;; zero don't affect the flags.  We assume that shifts by constant
11741 ;; zero are optimized away.
11742 (define_insn "*ashrhi3_cmp"
11743   [(set (reg 17)
11744         (compare
11745           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11746                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11747           (const_int 0)))
11748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11749         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11750   "ix86_match_ccmode (insn, CCGOCmode)
11751    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752   "sar{w}\t{%2, %0|%0, %2}"
11753   [(set_attr "type" "ishift")
11754    (set_attr "mode" "HI")])
11755
11756 (define_expand "ashrqi3"
11757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11758         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11759                      (match_operand:QI 2 "nonmemory_operand" "")))
11760    (clobber (reg:CC FLAGS_REG))]
11761   "TARGET_QIMODE_MATH"
11762   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11763
11764 (define_insn "*ashrqi3_1_one_bit"
11765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11766         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11767                      (match_operand:QI 2 "const1_operand" "")))
11768    (clobber (reg:CC FLAGS_REG))]
11769   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11770    && (TARGET_SHIFT1 || optimize_size)"
11771   "sar{b}\t%0"
11772   [(set_attr "type" "ishift")
11773    (set (attr "length") 
11774      (if_then_else (match_operand 0 "register_operand" "") 
11775         (const_string "2")
11776         (const_string "*")))])
11777
11778 (define_insn "*ashrqi3_1_one_bit_slp"
11779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11780         (ashiftrt:QI (match_dup 0)
11781                      (match_operand:QI 1 "const1_operand" "")))
11782    (clobber (reg:CC FLAGS_REG))]
11783   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11784    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11785    && (TARGET_SHIFT1 || optimize_size)"
11786   "sar{b}\t%0"
11787   [(set_attr "type" "ishift1")
11788    (set (attr "length") 
11789      (if_then_else (match_operand 0 "register_operand" "") 
11790         (const_string "2")
11791         (const_string "*")))])
11792
11793 (define_insn "*ashrqi3_1"
11794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11795         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11796                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11799   "@
11800    sar{b}\t{%2, %0|%0, %2}
11801    sar{b}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "ishift")
11803    (set_attr "mode" "QI")])
11804
11805 (define_insn "*ashrqi3_1_slp"
11806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11807         (ashiftrt:QI (match_dup 0)
11808                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11812   "@
11813    sar{b}\t{%1, %0|%0, %1}
11814    sar{b}\t{%b1, %0|%0, %b1}"
11815   [(set_attr "type" "ishift1")
11816    (set_attr "mode" "QI")])
11817
11818 ;; This pattern can't accept a variable shift count, since shifts by
11819 ;; zero don't affect the flags.  We assume that shifts by constant
11820 ;; zero are optimized away.
11821 (define_insn "*ashrqi3_one_bit_cmp"
11822   [(set (reg 17)
11823         (compare
11824           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11825                        (match_operand:QI 2 "const1_operand" "I"))
11826           (const_int 0)))
11827    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11828         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11829   "ix86_match_ccmode (insn, CCGOCmode)
11830    && (TARGET_SHIFT1 || optimize_size)
11831    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11832   "sar{b}\t%0"
11833   [(set_attr "type" "ishift")
11834    (set (attr "length") 
11835      (if_then_else (match_operand 0 "register_operand" "") 
11836         (const_string "2")
11837         (const_string "*")))])
11838
11839 ;; This pattern can't accept a variable shift count, since shifts by
11840 ;; zero don't affect the flags.  We assume that shifts by constant
11841 ;; zero are optimized away.
11842 (define_insn "*ashrqi3_cmp"
11843   [(set (reg 17)
11844         (compare
11845           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11846                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11847           (const_int 0)))
11848    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11849         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11850   "ix86_match_ccmode (insn, CCGOCmode)
11851    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11852   "sar{b}\t{%2, %0|%0, %2}"
11853   [(set_attr "type" "ishift")
11854    (set_attr "mode" "QI")])
11855 \f
11856 ;; Logical shift instructions
11857
11858 ;; See comment above `ashldi3' about how this works.
11859
11860 (define_expand "lshrdi3"
11861   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11862                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11863                                 (match_operand:QI 2 "nonmemory_operand" "")))
11864               (clobber (reg:CC FLAGS_REG))])]
11865   ""
11866 {
11867   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11868     {
11869       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11870       DONE;
11871     }
11872   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11873   DONE;
11874 })
11875
11876 (define_insn "*lshrdi3_1_one_bit_rex64"
11877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11878         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11879                      (match_operand:QI 2 "const1_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "shr{q}\t%0"
11884   [(set_attr "type" "ishift")
11885    (set (attr "length") 
11886      (if_then_else (match_operand:DI 0 "register_operand" "") 
11887         (const_string "2")
11888         (const_string "*")))])
11889
11890 (define_insn "*lshrdi3_1_rex64"
11891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11892         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11893                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11896   "@
11897    shr{q}\t{%2, %0|%0, %2}
11898    shr{q}\t{%b2, %0|%0, %b2}"
11899   [(set_attr "type" "ishift")
11900    (set_attr "mode" "DI")])
11901
11902 ;; This pattern can't accept a variable shift count, since shifts by
11903 ;; zero don't affect the flags.  We assume that shifts by constant
11904 ;; zero are optimized away.
11905 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11906   [(set (reg 17)
11907         (compare
11908           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11909                        (match_operand:QI 2 "const1_operand" ""))
11910           (const_int 0)))
11911    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11912         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11913   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11914    && (TARGET_SHIFT1 || optimize_size)
11915    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11916   "shr{q}\t%0"
11917   [(set_attr "type" "ishift")
11918    (set (attr "length") 
11919      (if_then_else (match_operand:DI 0 "register_operand" "") 
11920         (const_string "2")
11921         (const_string "*")))])
11922
11923 ;; This pattern can't accept a variable shift count, since shifts by
11924 ;; zero don't affect the flags.  We assume that shifts by constant
11925 ;; zero are optimized away.
11926 (define_insn "*lshrdi3_cmp_rex64"
11927   [(set (reg 17)
11928         (compare
11929           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11930                        (match_operand:QI 2 "const_int_operand" "e"))
11931           (const_int 0)))
11932    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11933         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11934   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11935    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11936   "shr{q}\t{%2, %0|%0, %2}"
11937   [(set_attr "type" "ishift")
11938    (set_attr "mode" "DI")])
11939
11940 (define_insn "lshrdi3_1"
11941   [(set (match_operand:DI 0 "register_operand" "=r")
11942         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11943                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11944    (clobber (match_scratch:SI 3 "=&r"))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "!TARGET_64BIT && TARGET_CMOVE"
11947   "#"
11948   [(set_attr "type" "multi")])
11949
11950 (define_insn "*lshrdi3_2"
11951   [(set (match_operand:DI 0 "register_operand" "=r")
11952         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11953                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11954    (clobber (reg:CC FLAGS_REG))]
11955   "!TARGET_64BIT"
11956   "#"
11957   [(set_attr "type" "multi")])
11958
11959 (define_split 
11960   [(set (match_operand:DI 0 "register_operand" "")
11961         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11962                      (match_operand:QI 2 "nonmemory_operand" "")))
11963    (clobber (match_scratch:SI 3 ""))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11966   [(const_int 0)]
11967   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11968
11969 (define_split 
11970   [(set (match_operand:DI 0 "register_operand" "")
11971         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11972                      (match_operand:QI 2 "nonmemory_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "!TARGET_64BIT && reload_completed"
11975   [(const_int 0)]
11976   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11977
11978 (define_expand "lshrsi3"
11979   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11980         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11981                      (match_operand:QI 2 "nonmemory_operand" "")))
11982    (clobber (reg:CC FLAGS_REG))]
11983   ""
11984   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11985
11986 (define_insn "*lshrsi3_1_one_bit"
11987   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11988         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11989                      (match_operand:QI 2 "const1_operand" "")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11992    && (TARGET_SHIFT1 || optimize_size)"
11993   "shr{l}\t%0"
11994   [(set_attr "type" "ishift")
11995    (set (attr "length") 
11996      (if_then_else (match_operand:SI 0 "register_operand" "") 
11997         (const_string "2")
11998         (const_string "*")))])
11999
12000 (define_insn "*lshrsi3_1_one_bit_zext"
12001   [(set (match_operand:DI 0 "register_operand" "=r")
12002         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12003                      (match_operand:QI 2 "const1_operand" "")))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12006    && (TARGET_SHIFT1 || optimize_size)"
12007   "shr{l}\t%k0"
12008   [(set_attr "type" "ishift")
12009    (set_attr "length" "2")])
12010
12011 (define_insn "*lshrsi3_1"
12012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12013         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12014                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12015    (clobber (reg:CC FLAGS_REG))]
12016   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12017   "@
12018    shr{l}\t{%2, %0|%0, %2}
12019    shr{l}\t{%b2, %0|%0, %b2}"
12020   [(set_attr "type" "ishift")
12021    (set_attr "mode" "SI")])
12022
12023 (define_insn "*lshrsi3_1_zext"
12024   [(set (match_operand:DI 0 "register_operand" "=r,r")
12025         (zero_extend:DI
12026           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12027                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12030   "@
12031    shr{l}\t{%2, %k0|%k0, %2}
12032    shr{l}\t{%b2, %k0|%k0, %b2}"
12033   [(set_attr "type" "ishift")
12034    (set_attr "mode" "SI")])
12035
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags.  We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*lshrsi3_one_bit_cmp"
12040   [(set (reg 17)
12041         (compare
12042           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12043                        (match_operand:QI 2 "const1_operand" ""))
12044           (const_int 0)))
12045    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12046         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12047   "ix86_match_ccmode (insn, CCGOCmode)
12048    && (TARGET_SHIFT1 || optimize_size)
12049    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050   "shr{l}\t%0"
12051   [(set_attr "type" "ishift")
12052    (set (attr "length") 
12053      (if_then_else (match_operand:SI 0 "register_operand" "") 
12054         (const_string "2")
12055         (const_string "*")))])
12056
12057 (define_insn "*lshrsi3_cmp_one_bit_zext"
12058   [(set (reg 17)
12059         (compare
12060           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12061                        (match_operand:QI 2 "const1_operand" ""))
12062           (const_int 0)))
12063    (set (match_operand:DI 0 "register_operand" "=r")
12064         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12065   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12066    && (TARGET_SHIFT1 || optimize_size)
12067    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12068   "shr{l}\t%k0"
12069   [(set_attr "type" "ishift")
12070    (set_attr "length" "2")])
12071
12072 ;; This pattern can't accept a variable shift count, since shifts by
12073 ;; zero don't affect the flags.  We assume that shifts by constant
12074 ;; zero are optimized away.
12075 (define_insn "*lshrsi3_cmp"
12076   [(set (reg 17)
12077         (compare
12078           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12079                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12080           (const_int 0)))
12081    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12082         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12083   "ix86_match_ccmode (insn, CCGOCmode)
12084    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085   "shr{l}\t{%2, %0|%0, %2}"
12086   [(set_attr "type" "ishift")
12087    (set_attr "mode" "SI")])
12088
12089 (define_insn "*lshrsi3_cmp_zext"
12090   [(set (reg 17)
12091         (compare
12092           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12093                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12094           (const_int 0)))
12095    (set (match_operand:DI 0 "register_operand" "=r")
12096         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12097   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12098    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12099   "shr{l}\t{%2, %k0|%k0, %2}"
12100   [(set_attr "type" "ishift")
12101    (set_attr "mode" "SI")])
12102
12103 (define_expand "lshrhi3"
12104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12105         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12106                      (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_HIMODE_MATH"
12109   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12110
12111 (define_insn "*lshrhi3_1_one_bit"
12112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12113         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12114                      (match_operand:QI 2 "const1_operand" "")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117    && (TARGET_SHIFT1 || optimize_size)"
12118   "shr{w}\t%0"
12119   [(set_attr "type" "ishift")
12120    (set (attr "length") 
12121      (if_then_else (match_operand 0 "register_operand" "") 
12122         (const_string "2")
12123         (const_string "*")))])
12124
12125 (define_insn "*lshrhi3_1"
12126   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12127         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12128                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12131   "@
12132    shr{w}\t{%2, %0|%0, %2}
12133    shr{w}\t{%b2, %0|%0, %b2}"
12134   [(set_attr "type" "ishift")
12135    (set_attr "mode" "HI")])
12136
12137 ;; This pattern can't accept a variable shift count, since shifts by
12138 ;; zero don't affect the flags.  We assume that shifts by constant
12139 ;; zero are optimized away.
12140 (define_insn "*lshrhi3_one_bit_cmp"
12141   [(set (reg 17)
12142         (compare
12143           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12144                        (match_operand:QI 2 "const1_operand" ""))
12145           (const_int 0)))
12146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12147         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12148   "ix86_match_ccmode (insn, CCGOCmode)
12149    && (TARGET_SHIFT1 || optimize_size)
12150    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151   "shr{w}\t%0"
12152   [(set_attr "type" "ishift")
12153    (set (attr "length") 
12154      (if_then_else (match_operand:SI 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12157
12158 ;; This pattern can't accept a variable shift count, since shifts by
12159 ;; zero don't affect the flags.  We assume that shifts by constant
12160 ;; zero are optimized away.
12161 (define_insn "*lshrhi3_cmp"
12162   [(set (reg 17)
12163         (compare
12164           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12165                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12166           (const_int 0)))
12167    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12168         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12169   "ix86_match_ccmode (insn, CCGOCmode)
12170    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12171   "shr{w}\t{%2, %0|%0, %2}"
12172   [(set_attr "type" "ishift")
12173    (set_attr "mode" "HI")])
12174
12175 (define_expand "lshrqi3"
12176   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12177         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12178                      (match_operand:QI 2 "nonmemory_operand" "")))
12179    (clobber (reg:CC FLAGS_REG))]
12180   "TARGET_QIMODE_MATH"
12181   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12182
12183 (define_insn "*lshrqi3_1_one_bit"
12184   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12185         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12186                      (match_operand:QI 2 "const1_operand" "")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12189    && (TARGET_SHIFT1 || optimize_size)"
12190   "shr{b}\t%0"
12191   [(set_attr "type" "ishift")
12192    (set (attr "length") 
12193      (if_then_else (match_operand 0 "register_operand" "") 
12194         (const_string "2")
12195         (const_string "*")))])
12196
12197 (define_insn "*lshrqi3_1_one_bit_slp"
12198   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12199         (lshiftrt:QI (match_dup 0)
12200                      (match_operand:QI 1 "const1_operand" "")))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12203    && (TARGET_SHIFT1 || optimize_size)"
12204   "shr{b}\t%0"
12205   [(set_attr "type" "ishift1")
12206    (set (attr "length") 
12207      (if_then_else (match_operand 0 "register_operand" "") 
12208         (const_string "2")
12209         (const_string "*")))])
12210
12211 (define_insn "*lshrqi3_1"
12212   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12213         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12214                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12217   "@
12218    shr{b}\t{%2, %0|%0, %2}
12219    shr{b}\t{%b2, %0|%0, %b2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "QI")])
12222
12223 (define_insn "*lshrqi3_1_slp"
12224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12225         (lshiftrt:QI (match_dup 0)
12226                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12227    (clobber (reg:CC FLAGS_REG))]
12228   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12229    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12230   "@
12231    shr{b}\t{%1, %0|%0, %1}
12232    shr{b}\t{%b1, %0|%0, %b1}"
12233   [(set_attr "type" "ishift1")
12234    (set_attr "mode" "QI")])
12235
12236 ;; This pattern can't accept a variable shift count, since shifts by
12237 ;; zero don't affect the flags.  We assume that shifts by constant
12238 ;; zero are optimized away.
12239 (define_insn "*lshrqi2_one_bit_cmp"
12240   [(set (reg 17)
12241         (compare
12242           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12243                        (match_operand:QI 2 "const1_operand" ""))
12244           (const_int 0)))
12245    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12246         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12247   "ix86_match_ccmode (insn, CCGOCmode)
12248    && (TARGET_SHIFT1 || optimize_size)
12249    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12250   "shr{b}\t%0"
12251   [(set_attr "type" "ishift")
12252    (set (attr "length") 
12253      (if_then_else (match_operand:SI 0 "register_operand" "") 
12254         (const_string "2")
12255         (const_string "*")))])
12256
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags.  We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrqi2_cmp"
12261   [(set (reg 17)
12262         (compare
12263           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12264                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12265           (const_int 0)))
12266    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12267         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12268   "ix86_match_ccmode (insn, CCGOCmode)
12269    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12270   "shr{b}\t{%2, %0|%0, %2}"
12271   [(set_attr "type" "ishift")
12272    (set_attr "mode" "QI")])
12273 \f
12274 ;; Rotate instructions
12275
12276 (define_expand "rotldi3"
12277   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12278         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12279                    (match_operand:QI 2 "nonmemory_operand" "")))
12280    (clobber (reg:CC FLAGS_REG))]
12281   "TARGET_64BIT"
12282   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12283
12284 (define_insn "*rotlsi3_1_one_bit_rex64"
12285   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12286         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12287                    (match_operand:QI 2 "const1_operand" "")))
12288    (clobber (reg:CC FLAGS_REG))]
12289   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12290    && (TARGET_SHIFT1 || optimize_size)"
12291   "rol{q}\t%0"
12292   [(set_attr "type" "rotate")
12293    (set (attr "length") 
12294      (if_then_else (match_operand:DI 0 "register_operand" "") 
12295         (const_string "2")
12296         (const_string "*")))])
12297
12298 (define_insn "*rotldi3_1_rex64"
12299   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12300         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12301                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12304   "@
12305    rol{q}\t{%2, %0|%0, %2}
12306    rol{q}\t{%b2, %0|%0, %b2}"
12307   [(set_attr "type" "rotate")
12308    (set_attr "mode" "DI")])
12309
12310 (define_expand "rotlsi3"
12311   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12312         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12313                    (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   ""
12316   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12317
12318 (define_insn "*rotlsi3_1_one_bit"
12319   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12320         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12321                    (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "rol{l}\t%0"
12326   [(set_attr "type" "rotate")
12327    (set (attr "length") 
12328      (if_then_else (match_operand:SI 0 "register_operand" "") 
12329         (const_string "2")
12330         (const_string "*")))])
12331
12332 (define_insn "*rotlsi3_1_one_bit_zext"
12333   [(set (match_operand:DI 0 "register_operand" "=r")
12334         (zero_extend:DI
12335           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12336                      (match_operand:QI 2 "const1_operand" ""))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12339    && (TARGET_SHIFT1 || optimize_size)"
12340   "rol{l}\t%k0"
12341   [(set_attr "type" "rotate")
12342    (set_attr "length" "2")])
12343
12344 (define_insn "*rotlsi3_1"
12345   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12350   "@
12351    rol{l}\t{%2, %0|%0, %2}
12352    rol{l}\t{%b2, %0|%0, %b2}"
12353   [(set_attr "type" "rotate")
12354    (set_attr "mode" "SI")])
12355
12356 (define_insn "*rotlsi3_1_zext"
12357   [(set (match_operand:DI 0 "register_operand" "=r,r")
12358         (zero_extend:DI
12359           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12360                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12363   "@
12364    rol{l}\t{%2, %k0|%k0, %2}
12365    rol{l}\t{%b2, %k0|%k0, %b2}"
12366   [(set_attr "type" "rotate")
12367    (set_attr "mode" "SI")])
12368
12369 (define_expand "rotlhi3"
12370   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372                    (match_operand:QI 2 "nonmemory_operand" "")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_HIMODE_MATH"
12375   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12376
12377 (define_insn "*rotlhi3_1_one_bit"
12378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380                    (match_operand:QI 2 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12383    && (TARGET_SHIFT1 || optimize_size)"
12384   "rol{w}\t%0"
12385   [(set_attr "type" "rotate")
12386    (set (attr "length") 
12387      (if_then_else (match_operand 0 "register_operand" "") 
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*rotlhi3_1"
12392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12397   "@
12398    rol{w}\t{%2, %0|%0, %2}
12399    rol{w}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "HI")])
12402
12403 (define_expand "rotlqi3"
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406                    (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_QIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12410
12411 (define_insn "*rotlqi3_1_one_bit_slp"
12412   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12413         (rotate:QI (match_dup 0)
12414                    (match_operand:QI 1 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "rol{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 "*rotlqi3_1_one_bit"
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12428                    (match_operand:QI 2 "const1_operand" "")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12431    && (TARGET_SHIFT1 || optimize_size)"
12432   "rol{b}\t%0"
12433   [(set_attr "type" "rotate")
12434    (set (attr "length") 
12435      (if_then_else (match_operand 0 "register_operand" "") 
12436         (const_string "2")
12437         (const_string "*")))])
12438
12439 (define_insn "*rotlqi3_1_slp"
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12441         (rotate:QI (match_dup 0)
12442                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12445    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12446   "@
12447    rol{b}\t{%1, %0|%0, %1}
12448    rol{b}\t{%b1, %0|%0, %b1}"
12449   [(set_attr "type" "rotate1")
12450    (set_attr "mode" "QI")])
12451
12452 (define_insn "*rotlqi3_1"
12453   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12454         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12455                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12458   "@
12459    rol{b}\t{%2, %0|%0, %2}
12460    rol{b}\t{%b2, %0|%0, %b2}"
12461   [(set_attr "type" "rotate")
12462    (set_attr "mode" "QI")])
12463
12464 (define_expand "rotrdi3"
12465   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12466         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12467                      (match_operand:QI 2 "nonmemory_operand" "")))
12468    (clobber (reg:CC FLAGS_REG))]
12469   "TARGET_64BIT"
12470   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12471
12472 (define_insn "*rotrdi3_1_one_bit_rex64"
12473   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12474         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12475                      (match_operand:QI 2 "const1_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12478    && (TARGET_SHIFT1 || optimize_size)"
12479   "ror{q}\t%0"
12480   [(set_attr "type" "rotate")
12481    (set (attr "length") 
12482      (if_then_else (match_operand:DI 0 "register_operand" "") 
12483         (const_string "2")
12484         (const_string "*")))])
12485
12486 (define_insn "*rotrdi3_1_rex64"
12487   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12488         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12489                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12492   "@
12493    ror{q}\t{%2, %0|%0, %2}
12494    ror{q}\t{%b2, %0|%0, %b2}"
12495   [(set_attr "type" "rotate")
12496    (set_attr "mode" "DI")])
12497
12498 (define_expand "rotrsi3"
12499   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12500         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12501                      (match_operand:QI 2 "nonmemory_operand" "")))
12502    (clobber (reg:CC FLAGS_REG))]
12503   ""
12504   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12505
12506 (define_insn "*rotrsi3_1_one_bit"
12507   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12508         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509                      (match_operand:QI 2 "const1_operand" "")))
12510    (clobber (reg:CC FLAGS_REG))]
12511   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12512    && (TARGET_SHIFT1 || optimize_size)"
12513   "ror{l}\t%0"
12514   [(set_attr "type" "rotate")
12515    (set (attr "length") 
12516      (if_then_else (match_operand:SI 0 "register_operand" "") 
12517         (const_string "2")
12518         (const_string "*")))])
12519
12520 (define_insn "*rotrsi3_1_one_bit_zext"
12521   [(set (match_operand:DI 0 "register_operand" "=r")
12522         (zero_extend:DI
12523           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12524                        (match_operand:QI 2 "const1_operand" ""))))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12527    && (TARGET_SHIFT1 || optimize_size)"
12528   "ror{l}\t%k0"
12529   [(set_attr "type" "rotate")
12530    (set (attr "length") 
12531      (if_then_else (match_operand:SI 0 "register_operand" "") 
12532         (const_string "2")
12533         (const_string "*")))])
12534
12535 (define_insn "*rotrsi3_1"
12536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12537         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12538                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12541   "@
12542    ror{l}\t{%2, %0|%0, %2}
12543    ror{l}\t{%b2, %0|%0, %b2}"
12544   [(set_attr "type" "rotate")
12545    (set_attr "mode" "SI")])
12546
12547 (define_insn "*rotrsi3_1_zext"
12548   [(set (match_operand:DI 0 "register_operand" "=r,r")
12549         (zero_extend:DI
12550           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12551                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12554   "@
12555    ror{l}\t{%2, %k0|%k0, %2}
12556    ror{l}\t{%b2, %k0|%k0, %b2}"
12557   [(set_attr "type" "rotate")
12558    (set_attr "mode" "SI")])
12559
12560 (define_expand "rotrhi3"
12561   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12562         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12563                      (match_operand:QI 2 "nonmemory_operand" "")))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_HIMODE_MATH"
12566   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12567
12568 (define_insn "*rotrhi3_one_bit"
12569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12570         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12571                      (match_operand:QI 2 "const1_operand" "")))
12572    (clobber (reg:CC FLAGS_REG))]
12573   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12574    && (TARGET_SHIFT1 || optimize_size)"
12575   "ror{w}\t%0"
12576   [(set_attr "type" "rotate")
12577    (set (attr "length") 
12578      (if_then_else (match_operand 0 "register_operand" "") 
12579         (const_string "2")
12580         (const_string "*")))])
12581
12582 (define_insn "*rotrhi3"
12583   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12584         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12585                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12588   "@
12589    ror{w}\t{%2, %0|%0, %2}
12590    ror{w}\t{%b2, %0|%0, %b2}"
12591   [(set_attr "type" "rotate")
12592    (set_attr "mode" "HI")])
12593
12594 (define_expand "rotrqi3"
12595   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12596         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12597                      (match_operand:QI 2 "nonmemory_operand" "")))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "TARGET_QIMODE_MATH"
12600   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12601
12602 (define_insn "*rotrqi3_1_one_bit"
12603   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12604         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12605                      (match_operand:QI 2 "const1_operand" "")))
12606    (clobber (reg:CC FLAGS_REG))]
12607   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12608    && (TARGET_SHIFT1 || optimize_size)"
12609   "ror{b}\t%0"
12610   [(set_attr "type" "rotate")
12611    (set (attr "length") 
12612      (if_then_else (match_operand 0 "register_operand" "") 
12613         (const_string "2")
12614         (const_string "*")))])
12615
12616 (define_insn "*rotrqi3_1_one_bit_slp"
12617   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12618         (rotatert:QI (match_dup 0)
12619                      (match_operand:QI 1 "const1_operand" "")))
12620    (clobber (reg:CC FLAGS_REG))]
12621   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12622    && (TARGET_SHIFT1 || optimize_size)"
12623   "ror{b}\t%0"
12624   [(set_attr "type" "rotate1")
12625    (set (attr "length") 
12626      (if_then_else (match_operand 0 "register_operand" "") 
12627         (const_string "2")
12628         (const_string "*")))])
12629
12630 (define_insn "*rotrqi3_1"
12631   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12632         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12633                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12636   "@
12637    ror{b}\t{%2, %0|%0, %2}
12638    ror{b}\t{%b2, %0|%0, %b2}"
12639   [(set_attr "type" "rotate")
12640    (set_attr "mode" "QI")])
12641
12642 (define_insn "*rotrqi3_1_slp"
12643   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12644         (rotatert:QI (match_dup 0)
12645                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12646    (clobber (reg:CC FLAGS_REG))]
12647   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12649   "@
12650    ror{b}\t{%1, %0|%0, %1}
12651    ror{b}\t{%b1, %0|%0, %b1}"
12652   [(set_attr "type" "rotate1")
12653    (set_attr "mode" "QI")])
12654 \f
12655 ;; Bit set / bit test instructions
12656
12657 (define_expand "extv"
12658   [(set (match_operand:SI 0 "register_operand" "")
12659         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12660                          (match_operand:SI 2 "immediate_operand" "")
12661                          (match_operand:SI 3 "immediate_operand" "")))]
12662   ""
12663 {
12664   /* Handle extractions from %ah et al.  */
12665   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12666     FAIL;
12667
12668   /* From mips.md: extract_bit_field doesn't verify that our source
12669      matches the predicate, so check it again here.  */
12670   if (! register_operand (operands[1], VOIDmode))
12671     FAIL;
12672 })
12673
12674 (define_expand "extzv"
12675   [(set (match_operand:SI 0 "register_operand" "")
12676         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12677                          (match_operand:SI 2 "immediate_operand" "")
12678                          (match_operand:SI 3 "immediate_operand" "")))]
12679   ""
12680 {
12681   /* Handle extractions from %ah et al.  */
12682   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12683     FAIL;
12684
12685   /* From mips.md: extract_bit_field doesn't verify that our source
12686      matches the predicate, so check it again here.  */
12687   if (! register_operand (operands[1], VOIDmode))
12688     FAIL;
12689 })
12690
12691 (define_expand "insv"
12692   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12693                       (match_operand 1 "immediate_operand" "")
12694                       (match_operand 2 "immediate_operand" ""))
12695         (match_operand 3 "register_operand" ""))]
12696   ""
12697 {
12698   /* Handle extractions from %ah et al.  */
12699   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12700     FAIL;
12701
12702   /* From mips.md: insert_bit_field doesn't verify that our source
12703      matches the predicate, so check it again here.  */
12704   if (! register_operand (operands[0], VOIDmode))
12705     FAIL;
12706
12707   if (TARGET_64BIT)
12708     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12709   else
12710     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12711
12712   DONE;
12713 })
12714
12715 ;; %%% bts, btr, btc, bt.
12716 \f
12717 ;; Store-flag instructions.
12718
12719 ;; For all sCOND expanders, also expand the compare or test insn that
12720 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12721
12722 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12723 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12724 ;; way, which can later delete the movzx if only QImode is needed.
12725
12726 (define_expand "seq"
12727   [(set (match_operand:QI 0 "register_operand" "")
12728         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729   ""
12730   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12731
12732 (define_expand "sne"
12733   [(set (match_operand:QI 0 "register_operand" "")
12734         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735   ""
12736   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12737
12738 (define_expand "sgt"
12739   [(set (match_operand:QI 0 "register_operand" "")
12740         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12741   ""
12742   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12743
12744 (define_expand "sgtu"
12745   [(set (match_operand:QI 0 "register_operand" "")
12746         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747   ""
12748   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12749
12750 (define_expand "slt"
12751   [(set (match_operand:QI 0 "register_operand" "")
12752         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12753   ""
12754   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12755
12756 (define_expand "sltu"
12757   [(set (match_operand:QI 0 "register_operand" "")
12758         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12759   ""
12760   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12761
12762 (define_expand "sge"
12763   [(set (match_operand:QI 0 "register_operand" "")
12764         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12765   ""
12766   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12767
12768 (define_expand "sgeu"
12769   [(set (match_operand:QI 0 "register_operand" "")
12770         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12771   ""
12772   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12773
12774 (define_expand "sle"
12775   [(set (match_operand:QI 0 "register_operand" "")
12776         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12777   ""
12778   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12779
12780 (define_expand "sleu"
12781   [(set (match_operand:QI 0 "register_operand" "")
12782         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12783   ""
12784   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12785
12786 (define_expand "sunordered"
12787   [(set (match_operand:QI 0 "register_operand" "")
12788         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12789   "TARGET_80387 || TARGET_SSE"
12790   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12791
12792 (define_expand "sordered"
12793   [(set (match_operand:QI 0 "register_operand" "")
12794         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12795   "TARGET_80387"
12796   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12797
12798 (define_expand "suneq"
12799   [(set (match_operand:QI 0 "register_operand" "")
12800         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12801   "TARGET_80387 || TARGET_SSE"
12802   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12803
12804 (define_expand "sunge"
12805   [(set (match_operand:QI 0 "register_operand" "")
12806         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12807   "TARGET_80387 || TARGET_SSE"
12808   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12809
12810 (define_expand "sungt"
12811   [(set (match_operand:QI 0 "register_operand" "")
12812         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12813   "TARGET_80387 || TARGET_SSE"
12814   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12815
12816 (define_expand "sunle"
12817   [(set (match_operand:QI 0 "register_operand" "")
12818         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12819   "TARGET_80387 || TARGET_SSE"
12820   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12821
12822 (define_expand "sunlt"
12823   [(set (match_operand:QI 0 "register_operand" "")
12824         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12825   "TARGET_80387 || TARGET_SSE"
12826   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12827
12828 (define_expand "sltgt"
12829   [(set (match_operand:QI 0 "register_operand" "")
12830         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12831   "TARGET_80387 || TARGET_SSE"
12832   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12833
12834 (define_insn "*setcc_1"
12835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12836         (match_operator:QI 1 "ix86_comparison_operator"
12837           [(reg 17) (const_int 0)]))]
12838   ""
12839   "set%C1\t%0"
12840   [(set_attr "type" "setcc")
12841    (set_attr "mode" "QI")])
12842
12843 (define_insn "setcc_2"
12844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12845         (match_operator:QI 1 "ix86_comparison_operator"
12846           [(reg 17) (const_int 0)]))]
12847   ""
12848   "set%C1\t%0"
12849   [(set_attr "type" "setcc")
12850    (set_attr "mode" "QI")])
12851
12852 ;; In general it is not safe to assume too much about CCmode registers,
12853 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12854 ;; conditions this is safe on x86, so help combine not create
12855 ;;
12856 ;;      seta    %al
12857 ;;      testb   %al, %al
12858 ;;      sete    %al
12859
12860 (define_split 
12861   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12862         (ne:QI (match_operator 1 "ix86_comparison_operator"
12863                  [(reg 17) (const_int 0)])
12864             (const_int 0)))]
12865   ""
12866   [(set (match_dup 0) (match_dup 1))]
12867 {
12868   PUT_MODE (operands[1], QImode);
12869 })
12870
12871 (define_split 
12872   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12873         (ne:QI (match_operator 1 "ix86_comparison_operator"
12874                  [(reg 17) (const_int 0)])
12875             (const_int 0)))]
12876   ""
12877   [(set (match_dup 0) (match_dup 1))]
12878 {
12879   PUT_MODE (operands[1], QImode);
12880 })
12881
12882 (define_split 
12883   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12884         (eq:QI (match_operator 1 "ix86_comparison_operator"
12885                  [(reg 17) (const_int 0)])
12886             (const_int 0)))]
12887   ""
12888   [(set (match_dup 0) (match_dup 1))]
12889 {
12890   rtx new_op1 = copy_rtx (operands[1]);
12891   operands[1] = new_op1;
12892   PUT_MODE (new_op1, QImode);
12893   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12894                                              GET_MODE (XEXP (new_op1, 0))));
12895
12896   /* Make sure that (a) the CCmode we have for the flags is strong
12897      enough for the reversed compare or (b) we have a valid FP compare.  */
12898   if (! ix86_comparison_operator (new_op1, VOIDmode))
12899     FAIL;
12900 })
12901
12902 (define_split 
12903   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12904         (eq:QI (match_operator 1 "ix86_comparison_operator"
12905                  [(reg 17) (const_int 0)])
12906             (const_int 0)))]
12907   ""
12908   [(set (match_dup 0) (match_dup 1))]
12909 {
12910   rtx new_op1 = copy_rtx (operands[1]);
12911   operands[1] = new_op1;
12912   PUT_MODE (new_op1, QImode);
12913   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12914                                              GET_MODE (XEXP (new_op1, 0))));
12915
12916   /* Make sure that (a) the CCmode we have for the flags is strong
12917      enough for the reversed compare or (b) we have a valid FP compare.  */
12918   if (! ix86_comparison_operator (new_op1, VOIDmode))
12919     FAIL;
12920 })
12921
12922 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12923 ;; subsequent logical operations are used to imitate conditional moves.
12924 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12925 ;; it directly.  Further holding this value in pseudo register might bring
12926 ;; problem in implicit normalization in spill code.
12927 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12928 ;; instructions after reload by splitting the conditional move patterns.
12929
12930 (define_insn "*sse_setccsf"
12931   [(set (match_operand:SF 0 "register_operand" "=x")
12932         (match_operator:SF 1 "sse_comparison_operator"
12933           [(match_operand:SF 2 "register_operand" "0")
12934            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12935   "TARGET_SSE && reload_completed"
12936   "cmp%D1ss\t{%3, %0|%0, %3}"
12937   [(set_attr "type" "ssecmp")
12938    (set_attr "mode" "SF")])
12939
12940 (define_insn "*sse_setccdf"
12941   [(set (match_operand:DF 0 "register_operand" "=Y")
12942         (match_operator:DF 1 "sse_comparison_operator"
12943           [(match_operand:DF 2 "register_operand" "0")
12944            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12945   "TARGET_SSE2 && reload_completed"
12946   "cmp%D1sd\t{%3, %0|%0, %3}"
12947   [(set_attr "type" "ssecmp")
12948    (set_attr "mode" "DF")])
12949 \f
12950 ;; Basic conditional jump instructions.
12951 ;; We ignore the overflow flag for signed branch instructions.
12952
12953 ;; For all bCOND expanders, also expand the compare or test insn that
12954 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12955
12956 (define_expand "beq"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (EQ, operands[0]); DONE;")
12963
12964 (define_expand "bne"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (NE, operands[0]); DONE;")
12971
12972 (define_expand "bgt"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "ix86_expand_branch (GT, operands[0]); DONE;")
12979
12980 (define_expand "bgtu"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   ""
12986   "ix86_expand_branch (GTU, operands[0]); DONE;")
12987
12988 (define_expand "blt"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   ""
12994   "ix86_expand_branch (LT, operands[0]); DONE;")
12995
12996 (define_expand "bltu"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   ""
13002   "ix86_expand_branch (LTU, operands[0]); DONE;")
13003
13004 (define_expand "bge"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   ""
13010   "ix86_expand_branch (GE, operands[0]); DONE;")
13011
13012 (define_expand "bgeu"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   ""
13018   "ix86_expand_branch (GEU, operands[0]); DONE;")
13019
13020 (define_expand "ble"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   ""
13026   "ix86_expand_branch (LE, operands[0]); DONE;")
13027
13028 (define_expand "bleu"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   ""
13034   "ix86_expand_branch (LEU, operands[0]); DONE;")
13035
13036 (define_expand "bunordered"
13037   [(set (pc)
13038         (if_then_else (match_dup 1)
13039                       (label_ref (match_operand 0 "" ""))
13040                       (pc)))]
13041   "TARGET_80387 || TARGET_SSE"
13042   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13043
13044 (define_expand "bordered"
13045   [(set (pc)
13046         (if_then_else (match_dup 1)
13047                       (label_ref (match_operand 0 "" ""))
13048                       (pc)))]
13049   "TARGET_80387 || TARGET_SSE"
13050   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13051
13052 (define_expand "buneq"
13053   [(set (pc)
13054         (if_then_else (match_dup 1)
13055                       (label_ref (match_operand 0 "" ""))
13056                       (pc)))]
13057   "TARGET_80387 || TARGET_SSE"
13058   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13059
13060 (define_expand "bunge"
13061   [(set (pc)
13062         (if_then_else (match_dup 1)
13063                       (label_ref (match_operand 0 "" ""))
13064                       (pc)))]
13065   "TARGET_80387 || TARGET_SSE"
13066   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13067
13068 (define_expand "bungt"
13069   [(set (pc)
13070         (if_then_else (match_dup 1)
13071                       (label_ref (match_operand 0 "" ""))
13072                       (pc)))]
13073   "TARGET_80387 || TARGET_SSE"
13074   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13075
13076 (define_expand "bunle"
13077   [(set (pc)
13078         (if_then_else (match_dup 1)
13079                       (label_ref (match_operand 0 "" ""))
13080                       (pc)))]
13081   "TARGET_80387 || TARGET_SSE"
13082   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13083
13084 (define_expand "bunlt"
13085   [(set (pc)
13086         (if_then_else (match_dup 1)
13087                       (label_ref (match_operand 0 "" ""))
13088                       (pc)))]
13089   "TARGET_80387 || TARGET_SSE"
13090   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13091
13092 (define_expand "bltgt"
13093   [(set (pc)
13094         (if_then_else (match_dup 1)
13095                       (label_ref (match_operand 0 "" ""))
13096                       (pc)))]
13097   "TARGET_80387 || TARGET_SSE"
13098   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13099
13100 (define_insn "*jcc_1"
13101   [(set (pc)
13102         (if_then_else (match_operator 1 "ix86_comparison_operator"
13103                                       [(reg 17) (const_int 0)])
13104                       (label_ref (match_operand 0 "" ""))
13105                       (pc)))]
13106   ""
13107   "%+j%C1\t%l0"
13108   [(set_attr "type" "ibr")
13109    (set_attr "modrm" "0")
13110    (set (attr "length")
13111            (if_then_else (and (ge (minus (match_dup 0) (pc))
13112                                   (const_int -126))
13113                               (lt (minus (match_dup 0) (pc))
13114                                   (const_int 128)))
13115              (const_int 2)
13116              (const_int 6)))])
13117
13118 (define_insn "*jcc_2"
13119   [(set (pc)
13120         (if_then_else (match_operator 1 "ix86_comparison_operator"
13121                                       [(reg 17) (const_int 0)])
13122                       (pc)
13123                       (label_ref (match_operand 0 "" ""))))]
13124   ""
13125   "%+j%c1\t%l0"
13126   [(set_attr "type" "ibr")
13127    (set_attr "modrm" "0")
13128    (set (attr "length")
13129            (if_then_else (and (ge (minus (match_dup 0) (pc))
13130                                   (const_int -126))
13131                               (lt (minus (match_dup 0) (pc))
13132                                   (const_int 128)))
13133              (const_int 2)
13134              (const_int 6)))])
13135
13136 ;; In general it is not safe to assume too much about CCmode registers,
13137 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13138 ;; conditions this is safe on x86, so help combine not create
13139 ;;
13140 ;;      seta    %al
13141 ;;      testb   %al, %al
13142 ;;      je      Lfoo
13143
13144 (define_split 
13145   [(set (pc)
13146         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13147                                       [(reg 17) (const_int 0)])
13148                           (const_int 0))
13149                       (label_ref (match_operand 1 "" ""))
13150                       (pc)))]
13151   ""
13152   [(set (pc)
13153         (if_then_else (match_dup 0)
13154                       (label_ref (match_dup 1))
13155                       (pc)))]
13156 {
13157   PUT_MODE (operands[0], VOIDmode);
13158 })
13159   
13160 (define_split 
13161   [(set (pc)
13162         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13163                                       [(reg 17) (const_int 0)])
13164                           (const_int 0))
13165                       (label_ref (match_operand 1 "" ""))
13166                       (pc)))]
13167   ""
13168   [(set (pc)
13169         (if_then_else (match_dup 0)
13170                       (label_ref (match_dup 1))
13171                       (pc)))]
13172 {
13173   rtx new_op0 = copy_rtx (operands[0]);
13174   operands[0] = new_op0;
13175   PUT_MODE (new_op0, VOIDmode);
13176   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13177                                              GET_MODE (XEXP (new_op0, 0))));
13178
13179   /* Make sure that (a) the CCmode we have for the flags is strong
13180      enough for the reversed compare or (b) we have a valid FP compare.  */
13181   if (! ix86_comparison_operator (new_op0, VOIDmode))
13182     FAIL;
13183 })
13184
13185 ;; Define combination compare-and-branch fp compare instructions to use
13186 ;; during early optimization.  Splitting the operation apart early makes
13187 ;; for bad code when we want to reverse the operation.
13188
13189 (define_insn "*fp_jcc_1"
13190   [(set (pc)
13191         (if_then_else (match_operator 0 "comparison_operator"
13192                         [(match_operand 1 "register_operand" "f")
13193                          (match_operand 2 "register_operand" "f")])
13194           (label_ref (match_operand 3 "" ""))
13195           (pc)))
13196    (clobber (reg:CCFP FPSR_REG))
13197    (clobber (reg:CCFP FLAGS_REG))]
13198   "TARGET_CMOVE && TARGET_80387
13199    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13200    && FLOAT_MODE_P (GET_MODE (operands[1]))
13201    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13203   "#")
13204
13205 (define_insn "*fp_jcc_1_sse"
13206   [(set (pc)
13207         (if_then_else (match_operator 0 "comparison_operator"
13208                         [(match_operand 1 "register_operand" "f#x,x#f")
13209                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13210           (label_ref (match_operand 3 "" ""))
13211           (pc)))
13212    (clobber (reg:CCFP FPSR_REG))
13213    (clobber (reg:CCFP FLAGS_REG))]
13214   "TARGET_80387
13215    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13216    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13218   "#")
13219
13220 (define_insn "*fp_jcc_1_sse_only"
13221   [(set (pc)
13222         (if_then_else (match_operator 0 "comparison_operator"
13223                         [(match_operand 1 "register_operand" "x")
13224                          (match_operand 2 "nonimmediate_operand" "xm")])
13225           (label_ref (match_operand 3 "" ""))
13226           (pc)))
13227    (clobber (reg:CCFP FPSR_REG))
13228    (clobber (reg:CCFP FLAGS_REG))]
13229   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13230    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13231    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13232   "#")
13233
13234 (define_insn "*fp_jcc_2"
13235   [(set (pc)
13236         (if_then_else (match_operator 0 "comparison_operator"
13237                         [(match_operand 1 "register_operand" "f")
13238                          (match_operand 2 "register_operand" "f")])
13239           (pc)
13240           (label_ref (match_operand 3 "" ""))))
13241    (clobber (reg:CCFP FPSR_REG))
13242    (clobber (reg:CCFP FLAGS_REG))]
13243   "TARGET_CMOVE && TARGET_80387
13244    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13245    && FLOAT_MODE_P (GET_MODE (operands[1]))
13246    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248   "#")
13249
13250 (define_insn "*fp_jcc_2_sse"
13251   [(set (pc)
13252         (if_then_else (match_operator 0 "comparison_operator"
13253                         [(match_operand 1 "register_operand" "f#x,x#f")
13254                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13255           (pc)
13256           (label_ref (match_operand 3 "" ""))))
13257    (clobber (reg:CCFP FPSR_REG))
13258    (clobber (reg:CCFP FLAGS_REG))]
13259   "TARGET_80387
13260    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13261    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13262    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13263   "#")
13264
13265 (define_insn "*fp_jcc_2_sse_only"
13266   [(set (pc)
13267         (if_then_else (match_operator 0 "comparison_operator"
13268                         [(match_operand 1 "register_operand" "x")
13269                          (match_operand 2 "nonimmediate_operand" "xm")])
13270           (pc)
13271           (label_ref (match_operand 3 "" ""))))
13272    (clobber (reg:CCFP FPSR_REG))
13273    (clobber (reg:CCFP FLAGS_REG))]
13274   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13275    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13278
13279 (define_insn "*fp_jcc_3"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "nonimmediate_operand" "fm")])
13284           (label_ref (match_operand 3 "" ""))
13285           (pc)))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293    && SELECT_CC_MODE (GET_CODE (operands[0]),
13294                       operands[1], operands[2]) == CCFPmode
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13297
13298 (define_insn "*fp_jcc_4"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "nonimmediate_operand" "fm")])
13303           (pc)
13304           (label_ref (match_operand 3 "" ""))))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13312    && SELECT_CC_MODE (GET_CODE (operands[0]),
13313                       operands[1], operands[2]) == CCFPmode
13314    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13315   "#")
13316
13317 (define_insn "*fp_jcc_5"
13318   [(set (pc)
13319         (if_then_else (match_operator 0 "comparison_operator"
13320                         [(match_operand 1 "register_operand" "f")
13321                          (match_operand 2 "register_operand" "f")])
13322           (label_ref (match_operand 3 "" ""))
13323           (pc)))
13324    (clobber (reg:CCFP FPSR_REG))
13325    (clobber (reg:CCFP FLAGS_REG))
13326    (clobber (match_scratch:HI 4 "=a"))]
13327   "TARGET_80387
13328    && FLOAT_MODE_P (GET_MODE (operands[1]))
13329    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13330    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13331   "#")
13332
13333 (define_insn "*fp_jcc_6"
13334   [(set (pc)
13335         (if_then_else (match_operator 0 "comparison_operator"
13336                         [(match_operand 1 "register_operand" "f")
13337                          (match_operand 2 "register_operand" "f")])
13338           (pc)
13339           (label_ref (match_operand 3 "" ""))))
13340    (clobber (reg:CCFP FPSR_REG))
13341    (clobber (reg:CCFP FLAGS_REG))
13342    (clobber (match_scratch:HI 4 "=a"))]
13343   "TARGET_80387
13344    && FLOAT_MODE_P (GET_MODE (operands[1]))
13345    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347   "#")
13348
13349 (define_insn "*fp_jcc_7"
13350   [(set (pc)
13351         (if_then_else (match_operator 0 "comparison_operator"
13352                         [(match_operand 1 "register_operand" "f")
13353                          (match_operand 2 "const_double_operand" "C")])
13354           (label_ref (match_operand 3 "" ""))
13355           (pc)))
13356    (clobber (reg:CCFP FPSR_REG))
13357    (clobber (reg:CCFP FLAGS_REG))
13358    (clobber (match_scratch:HI 4 "=a"))]
13359   "TARGET_80387
13360    && FLOAT_MODE_P (GET_MODE (operands[1]))
13361    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13362    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13363    && SELECT_CC_MODE (GET_CODE (operands[0]),
13364                       operands[1], operands[2]) == CCFPmode
13365    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13366   "#")
13367
13368 (define_split
13369   [(set (pc)
13370         (if_then_else (match_operator 0 "comparison_operator"
13371                         [(match_operand 1 "register_operand" "")
13372                          (match_operand 2 "nonimmediate_operand" "")])
13373           (match_operand 3 "" "")
13374           (match_operand 4 "" "")))
13375    (clobber (reg:CCFP FPSR_REG))
13376    (clobber (reg:CCFP FLAGS_REG))]
13377   "reload_completed"
13378   [(const_int 0)]
13379 {
13380   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13381                         operands[3], operands[4], NULL_RTX);
13382   DONE;
13383 })
13384
13385 (define_split
13386   [(set (pc)
13387         (if_then_else (match_operator 0 "comparison_operator"
13388                         [(match_operand 1 "register_operand" "")
13389                          (match_operand 2 "general_operand" "")])
13390           (match_operand 3 "" "")
13391           (match_operand 4 "" "")))
13392    (clobber (reg:CCFP FPSR_REG))
13393    (clobber (reg:CCFP FLAGS_REG))
13394    (clobber (match_scratch:HI 5 "=a"))]
13395   "reload_completed"
13396   [(const_int 0)]
13397 {
13398   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13399                         operands[3], operands[4], operands[5]);
13400   DONE;
13401 })
13402 \f
13403 ;; Unconditional and other jump instructions
13404
13405 (define_insn "jump"
13406   [(set (pc)
13407         (label_ref (match_operand 0 "" "")))]
13408   ""
13409   "jmp\t%l0"
13410   [(set_attr "type" "ibr")
13411    (set (attr "length")
13412            (if_then_else (and (ge (minus (match_dup 0) (pc))
13413                                   (const_int -126))
13414                               (lt (minus (match_dup 0) (pc))
13415                                   (const_int 128)))
13416              (const_int 2)
13417              (const_int 5)))
13418    (set_attr "modrm" "0")])
13419
13420 (define_expand "indirect_jump"
13421   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13422   ""
13423   "")
13424
13425 (define_insn "*indirect_jump"
13426   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13427   "!TARGET_64BIT"
13428   "jmp\t%A0"
13429   [(set_attr "type" "ibr")
13430    (set_attr "length_immediate" "0")])
13431
13432 (define_insn "*indirect_jump_rtx64"
13433   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13434   "TARGET_64BIT"
13435   "jmp\t%A0"
13436   [(set_attr "type" "ibr")
13437    (set_attr "length_immediate" "0")])
13438
13439 (define_expand "tablejump"
13440   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13441               (use (label_ref (match_operand 1 "" "")))])]
13442   ""
13443 {
13444   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13445      relative.  Convert the relative address to an absolute address.  */
13446   if (flag_pic)
13447     {
13448       rtx op0, op1;
13449       enum rtx_code code;
13450
13451       if (TARGET_64BIT)
13452         {
13453           code = PLUS;
13454           op0 = operands[0];
13455           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13456         }
13457       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13458         {
13459           code = PLUS;
13460           op0 = operands[0];
13461           op1 = pic_offset_table_rtx;
13462         }
13463       else
13464         {
13465           code = MINUS;
13466           op0 = pic_offset_table_rtx;
13467           op1 = operands[0];
13468         }
13469
13470       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13471                                          OPTAB_DIRECT);
13472     }
13473 })
13474
13475 (define_insn "*tablejump_1"
13476   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13477    (use (label_ref (match_operand 1 "" "")))]
13478   "!TARGET_64BIT"
13479   "jmp\t%A0"
13480   [(set_attr "type" "ibr")
13481    (set_attr "length_immediate" "0")])
13482
13483 (define_insn "*tablejump_1_rtx64"
13484   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13485    (use (label_ref (match_operand 1 "" "")))]
13486   "TARGET_64BIT"
13487   "jmp\t%A0"
13488   [(set_attr "type" "ibr")
13489    (set_attr "length_immediate" "0")])
13490 \f
13491 ;; Loop instruction
13492 ;;
13493 ;; This is all complicated by the fact that since this is a jump insn
13494 ;; we must handle our own reloads.
13495
13496 (define_expand "doloop_end"
13497   [(use (match_operand 0 "" ""))        ; loop pseudo
13498    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13499    (use (match_operand 2 "" ""))        ; max iterations
13500    (use (match_operand 3 "" ""))        ; loop level 
13501    (use (match_operand 4 "" ""))]       ; label
13502   "!TARGET_64BIT && TARGET_USE_LOOP"
13503   "                                 
13504 {
13505   /* Only use cloop on innermost loops.  */
13506   if (INTVAL (operands[3]) > 1)
13507     FAIL;
13508   if (GET_MODE (operands[0]) != SImode)
13509     FAIL;
13510   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13511                                            operands[0]));
13512   DONE;
13513 }")
13514
13515 (define_insn "doloop_end_internal"
13516   [(set (pc)
13517         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13518                           (const_int 1))
13519                       (label_ref (match_operand 0 "" ""))
13520                       (pc)))
13521    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13522         (plus:SI (match_dup 1)
13523                  (const_int -1)))
13524    (clobber (match_scratch:SI 3 "=X,X,r"))
13525    (clobber (reg:CC FLAGS_REG))]
13526   "!TARGET_64BIT && TARGET_USE_LOOP
13527    && (reload_in_progress || reload_completed
13528        || register_operand (operands[2], VOIDmode))"
13529 {
13530   if (which_alternative != 0)
13531     return "#";
13532   if (get_attr_length (insn) == 2)
13533     return "%+loop\t%l0";
13534   else
13535     return "dec{l}\t%1\;%+jne\t%l0";
13536 }
13537   [(set (attr "length")
13538         (if_then_else (and (eq_attr "alternative" "0")
13539                            (and (ge (minus (match_dup 0) (pc))
13540                                     (const_int -126))
13541                                 (lt (minus (match_dup 0) (pc))
13542                                     (const_int 128))))
13543                       (const_int 2)
13544                       (const_int 16)))
13545    ;; We don't know the type before shorten branches.  Optimistically expect
13546    ;; the loop instruction to match.
13547    (set (attr "type") (const_string "ibr"))])
13548
13549 (define_split
13550   [(set (pc)
13551         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13552                           (const_int 1))
13553                       (match_operand 0 "" "")
13554                       (pc)))
13555    (set (match_dup 1)
13556         (plus:SI (match_dup 1)
13557                  (const_int -1)))
13558    (clobber (match_scratch:SI 2 ""))
13559    (clobber (reg:CC FLAGS_REG))]
13560   "!TARGET_64BIT && TARGET_USE_LOOP
13561    && reload_completed
13562    && REGNO (operands[1]) != 2"
13563   [(parallel [(set (reg:CCZ FLAGS_REG)
13564                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13565                                  (const_int 0)))
13566               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13567    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13568                            (match_dup 0)
13569                            (pc)))]
13570   "")
13571   
13572 (define_split
13573   [(set (pc)
13574         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13575                           (const_int 1))
13576                       (match_operand 0 "" "")
13577                       (pc)))
13578    (set (match_operand:SI 2 "nonimmediate_operand" "")
13579         (plus:SI (match_dup 1)
13580                  (const_int -1)))
13581    (clobber (match_scratch:SI 3 ""))
13582    (clobber (reg:CC FLAGS_REG))]
13583   "!TARGET_64BIT && TARGET_USE_LOOP
13584    && reload_completed
13585    && (! REG_P (operands[2])
13586        || ! rtx_equal_p (operands[1], operands[2]))"
13587   [(set (match_dup 3) (match_dup 1))
13588    (parallel [(set (reg:CCZ FLAGS_REG)
13589                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13590                                 (const_int 0)))
13591               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13592    (set (match_dup 2) (match_dup 3))
13593    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13594                            (match_dup 0)
13595                            (pc)))]
13596   "")
13597
13598 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13599
13600 (define_peephole2
13601   [(set (reg 17) (match_operand 0 "" ""))
13602    (set (match_operand:QI 1 "register_operand" "")
13603         (match_operator:QI 2 "ix86_comparison_operator"
13604           [(reg 17) (const_int 0)]))
13605    (set (match_operand 3 "q_regs_operand" "")
13606         (zero_extend (match_dup 1)))]
13607   "(peep2_reg_dead_p (3, operands[1])
13608     || operands_match_p (operands[1], operands[3]))
13609    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13610   [(set (match_dup 4) (match_dup 0))
13611    (set (strict_low_part (match_dup 5))
13612         (match_dup 2))]
13613 {
13614   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13615   operands[5] = gen_lowpart (QImode, operands[3]);
13616   ix86_expand_clear (operands[3]);
13617 })
13618
13619 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13620
13621 (define_peephole2
13622   [(set (reg 17) (match_operand 0 "" ""))
13623    (set (match_operand:QI 1 "register_operand" "")
13624         (match_operator:QI 2 "ix86_comparison_operator"
13625           [(reg 17) (const_int 0)]))
13626    (parallel [(set (match_operand 3 "q_regs_operand" "")
13627                    (zero_extend (match_dup 1)))
13628               (clobber (reg:CC FLAGS_REG))])]
13629   "(peep2_reg_dead_p (3, operands[1])
13630     || operands_match_p (operands[1], operands[3]))
13631    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13632   [(set (match_dup 4) (match_dup 0))
13633    (set (strict_low_part (match_dup 5))
13634         (match_dup 2))]
13635 {
13636   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13637   operands[5] = gen_lowpart (QImode, operands[3]);
13638   ix86_expand_clear (operands[3]);
13639 })
13640 \f
13641 ;; Call instructions.
13642
13643 ;; The predicates normally associated with named expanders are not properly
13644 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13645 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13646
13647 ;; Call subroutine returning no value.
13648
13649 (define_expand "call_pop"
13650   [(parallel [(call (match_operand:QI 0 "" "")
13651                     (match_operand:SI 1 "" ""))
13652               (set (reg:SI SP_REG)
13653                    (plus:SI (reg:SI SP_REG)
13654                             (match_operand:SI 3 "" "")))])]
13655   "!TARGET_64BIT"
13656 {
13657   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13658   DONE;
13659 })
13660
13661 (define_insn "*call_pop_0"
13662   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13663          (match_operand:SI 1 "" ""))
13664    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13665                             (match_operand:SI 2 "immediate_operand" "")))]
13666   "!TARGET_64BIT"
13667 {
13668   if (SIBLING_CALL_P (insn))
13669     return "jmp\t%P0";
13670   else
13671     return "call\t%P0";
13672 }
13673   [(set_attr "type" "call")])
13674   
13675 (define_insn "*call_pop_1"
13676   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13677          (match_operand:SI 1 "" ""))
13678    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13679                             (match_operand:SI 2 "immediate_operand" "i")))]
13680   "!TARGET_64BIT"
13681 {
13682   if (constant_call_address_operand (operands[0], Pmode))
13683     {
13684       if (SIBLING_CALL_P (insn))
13685         return "jmp\t%P0";
13686       else
13687         return "call\t%P0";
13688     }
13689   if (SIBLING_CALL_P (insn))
13690     return "jmp\t%A0";
13691   else
13692     return "call\t%A0";
13693 }
13694   [(set_attr "type" "call")])
13695
13696 (define_expand "call"
13697   [(call (match_operand:QI 0 "" "")
13698          (match_operand 1 "" ""))
13699    (use (match_operand 2 "" ""))]
13700   ""
13701 {
13702   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13703   DONE;
13704 })
13705
13706 (define_expand "sibcall"
13707   [(call (match_operand:QI 0 "" "")
13708          (match_operand 1 "" ""))
13709    (use (match_operand 2 "" ""))]
13710   ""
13711 {
13712   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13713   DONE;
13714 })
13715
13716 (define_insn "*call_0"
13717   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13718          (match_operand 1 "" ""))]
13719   ""
13720 {
13721   if (SIBLING_CALL_P (insn))
13722     return "jmp\t%P0";
13723   else
13724     return "call\t%P0";
13725 }
13726   [(set_attr "type" "call")])
13727
13728 (define_insn "*call_1"
13729   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13730          (match_operand 1 "" ""))]
13731   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13732 {
13733   if (constant_call_address_operand (operands[0], Pmode))
13734     return "call\t%P0";
13735   return "call\t%A0";
13736 }
13737   [(set_attr "type" "call")])
13738
13739 (define_insn "*sibcall_1"
13740   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13741          (match_operand 1 "" ""))]
13742   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13743 {
13744   if (constant_call_address_operand (operands[0], Pmode))
13745     return "jmp\t%P0";
13746   return "jmp\t%A0";
13747 }
13748   [(set_attr "type" "call")])
13749
13750 (define_insn "*call_1_rex64"
13751   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13752          (match_operand 1 "" ""))]
13753   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13754 {
13755   if (constant_call_address_operand (operands[0], Pmode))
13756     return "call\t%P0";
13757   return "call\t%A0";
13758 }
13759   [(set_attr "type" "call")])
13760
13761 (define_insn "*sibcall_1_rex64"
13762   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13763          (match_operand 1 "" ""))]
13764   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13765   "jmp\t%P0"
13766   [(set_attr "type" "call")])
13767
13768 (define_insn "*sibcall_1_rex64_v"
13769   [(call (mem:QI (reg:DI 40))
13770          (match_operand 0 "" ""))]
13771   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13772   "jmp\t*%%r11"
13773   [(set_attr "type" "call")])
13774
13775
13776 ;; Call subroutine, returning value in operand 0
13777
13778 (define_expand "call_value_pop"
13779   [(parallel [(set (match_operand 0 "" "")
13780                    (call (match_operand:QI 1 "" "")
13781                          (match_operand:SI 2 "" "")))
13782               (set (reg:SI SP_REG)
13783                    (plus:SI (reg:SI SP_REG)
13784                             (match_operand:SI 4 "" "")))])]
13785   "!TARGET_64BIT"
13786 {
13787   ix86_expand_call (operands[0], operands[1], operands[2],
13788                     operands[3], operands[4], 0);
13789   DONE;
13790 })
13791
13792 (define_expand "call_value"
13793   [(set (match_operand 0 "" "")
13794         (call (match_operand:QI 1 "" "")
13795               (match_operand:SI 2 "" "")))
13796    (use (match_operand:SI 3 "" ""))]
13797   ;; Operand 2 not used on the i386.
13798   ""
13799 {
13800   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13801   DONE;
13802 })
13803
13804 (define_expand "sibcall_value"
13805   [(set (match_operand 0 "" "")
13806         (call (match_operand:QI 1 "" "")
13807               (match_operand:SI 2 "" "")))
13808    (use (match_operand:SI 3 "" ""))]
13809   ;; Operand 2 not used on the i386.
13810   ""
13811 {
13812   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13813   DONE;
13814 })
13815
13816 ;; Call subroutine returning any type.
13817
13818 (define_expand "untyped_call"
13819   [(parallel [(call (match_operand 0 "" "")
13820                     (const_int 0))
13821               (match_operand 1 "" "")
13822               (match_operand 2 "" "")])]
13823   ""
13824 {
13825   int i;
13826
13827   /* In order to give reg-stack an easier job in validating two
13828      coprocessor registers as containing a possible return value,
13829      simply pretend the untyped call returns a complex long double
13830      value.  */
13831
13832   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13833                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13834                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13835                     NULL, 0);
13836
13837   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13838     {
13839       rtx set = XVECEXP (operands[2], 0, i);
13840       emit_move_insn (SET_DEST (set), SET_SRC (set));
13841     }
13842
13843   /* The optimizer does not know that the call sets the function value
13844      registers we stored in the result block.  We avoid problems by
13845      claiming that all hard registers are used and clobbered at this
13846      point.  */
13847   emit_insn (gen_blockage (const0_rtx));
13848
13849   DONE;
13850 })
13851 \f
13852 ;; Prologue and epilogue instructions
13853
13854 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13855 ;; all of memory.  This blocks insns from being moved across this point.
13856
13857 (define_insn "blockage"
13858   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13859   ""
13860   ""
13861   [(set_attr "length" "0")])
13862
13863 ;; Insn emitted into the body of a function to return from a function.
13864 ;; This is only done if the function's epilogue is known to be simple.
13865 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13866
13867 (define_expand "return"
13868   [(return)]
13869   "ix86_can_use_return_insn_p ()"
13870 {
13871   if (current_function_pops_args)
13872     {
13873       rtx popc = GEN_INT (current_function_pops_args);
13874       emit_jump_insn (gen_return_pop_internal (popc));
13875       DONE;
13876     }
13877 })
13878
13879 (define_insn "return_internal"
13880   [(return)]
13881   "reload_completed"
13882   "ret"
13883   [(set_attr "length" "1")
13884    (set_attr "length_immediate" "0")
13885    (set_attr "modrm" "0")])
13886
13887 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13888 ;; instruction Athlon and K8 have.
13889
13890 (define_insn "return_internal_long"
13891   [(return)
13892    (unspec [(const_int 0)] UNSPEC_REP)]
13893   "reload_completed"
13894   "rep {;} ret"
13895   [(set_attr "length" "1")
13896    (set_attr "length_immediate" "0")
13897    (set_attr "prefix_rep" "1")
13898    (set_attr "modrm" "0")])
13899
13900 (define_insn "return_pop_internal"
13901   [(return)
13902    (use (match_operand:SI 0 "const_int_operand" ""))]
13903   "reload_completed"
13904   "ret\t%0"
13905   [(set_attr "length" "3")
13906    (set_attr "length_immediate" "2")
13907    (set_attr "modrm" "0")])
13908
13909 (define_insn "return_indirect_internal"
13910   [(return)
13911    (use (match_operand:SI 0 "register_operand" "r"))]
13912   "reload_completed"
13913   "jmp\t%A0"
13914   [(set_attr "type" "ibr")
13915    (set_attr "length_immediate" "0")])
13916
13917 (define_insn "nop"
13918   [(const_int 0)]
13919   ""
13920   "nop"
13921   [(set_attr "length" "1")
13922    (set_attr "length_immediate" "0")
13923    (set_attr "modrm" "0")])
13924
13925 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13926 ;; branch prediction penalty for the third jump in a 16-byte
13927 ;; block on K8.
13928
13929 (define_insn "align"
13930   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13931   ""
13932 {
13933 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13934   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13935 #else
13936   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13937      The align insn is used to avoid 3 jump instructions in the row to improve
13938      branch prediction and the benefits hardly outweight the cost of extra 8
13939      nops on the average inserted by full alignment pseudo operation.  */
13940 #endif
13941   return "";
13942 }
13943   [(set_attr "length" "16")])
13944
13945 (define_expand "prologue"
13946   [(const_int 1)]
13947   ""
13948   "ix86_expand_prologue (); DONE;")
13949
13950 (define_insn "set_got"
13951   [(set (match_operand:SI 0 "register_operand" "=r")
13952         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13953    (clobber (reg:CC FLAGS_REG))]
13954   "!TARGET_64BIT"
13955   { return output_set_got (operands[0]); }
13956   [(set_attr "type" "multi")
13957    (set_attr "length" "12")])
13958
13959 (define_expand "epilogue"
13960   [(const_int 1)]
13961   ""
13962   "ix86_expand_epilogue (1); DONE;")
13963
13964 (define_expand "sibcall_epilogue"
13965   [(const_int 1)]
13966   ""
13967   "ix86_expand_epilogue (0); DONE;")
13968
13969 (define_expand "eh_return"
13970   [(use (match_operand 0 "register_operand" ""))]
13971   ""
13972 {
13973   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13974
13975   /* Tricky bit: we write the address of the handler to which we will
13976      be returning into someone else's stack frame, one word below the
13977      stack address we wish to restore.  */
13978   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13979   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13980   tmp = gen_rtx_MEM (Pmode, tmp);
13981   emit_move_insn (tmp, ra);
13982
13983   if (Pmode == SImode)
13984     emit_jump_insn (gen_eh_return_si (sa));
13985   else
13986     emit_jump_insn (gen_eh_return_di (sa));
13987   emit_barrier ();
13988   DONE;
13989 })
13990
13991 (define_insn_and_split "eh_return_si"
13992   [(set (pc) 
13993         (unspec [(match_operand:SI 0 "register_operand" "c")]
13994                  UNSPEC_EH_RETURN))]
13995   "!TARGET_64BIT"
13996   "#"
13997   "reload_completed"
13998   [(const_int 1)]
13999   "ix86_expand_epilogue (2); DONE;")
14000
14001 (define_insn_and_split "eh_return_di"
14002   [(set (pc) 
14003         (unspec [(match_operand:DI 0 "register_operand" "c")]
14004                  UNSPEC_EH_RETURN))]
14005   "TARGET_64BIT"
14006   "#"
14007   "reload_completed"
14008   [(const_int 1)]
14009   "ix86_expand_epilogue (2); DONE;")
14010
14011 (define_insn "leave"
14012   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14013    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14014    (clobber (mem:BLK (scratch)))]
14015   "!TARGET_64BIT"
14016   "leave"
14017   [(set_attr "type" "leave")])
14018
14019 (define_insn "leave_rex64"
14020   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14021    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14022    (clobber (mem:BLK (scratch)))]
14023   "TARGET_64BIT"
14024   "leave"
14025   [(set_attr "type" "leave")])
14026 \f
14027 (define_expand "ffssi2"
14028   [(parallel
14029      [(set (match_operand:SI 0 "register_operand" "") 
14030            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14031       (clobber (match_scratch:SI 2 ""))
14032       (clobber (reg:CC FLAGS_REG))])]
14033   ""
14034   "")
14035
14036 (define_insn_and_split "*ffs_cmove"
14037   [(set (match_operand:SI 0 "register_operand" "=r") 
14038         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14039    (clobber (match_scratch:SI 2 "=&r"))
14040    (clobber (reg:CC FLAGS_REG))]
14041   "TARGET_CMOVE"
14042   "#"
14043   "&& reload_completed"
14044   [(set (match_dup 2) (const_int -1))
14045    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14046               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14047    (set (match_dup 0) (if_then_else:SI
14048                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14049                         (match_dup 2)
14050                         (match_dup 0)))
14051    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14052               (clobber (reg:CC FLAGS_REG))])]
14053   "")
14054
14055 (define_insn_and_split "*ffs_no_cmove"
14056   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14057         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14058    (clobber (match_scratch:SI 2 "=&q"))
14059    (clobber (reg:CC FLAGS_REG))]
14060   ""
14061   "#"
14062   "reload_completed"
14063   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14064               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14065    (set (strict_low_part (match_dup 3))
14066         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14067    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14068               (clobber (reg:CC FLAGS_REG))])
14069    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14070               (clobber (reg:CC FLAGS_REG))])
14071    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14072               (clobber (reg:CC FLAGS_REG))])]
14073 {
14074   operands[3] = gen_lowpart (QImode, operands[2]);
14075   ix86_expand_clear (operands[2]);
14076 })
14077
14078 (define_insn "*ffssi_1"
14079   [(set (reg:CCZ FLAGS_REG)
14080         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14081                      (const_int 0)))
14082    (set (match_operand:SI 0 "register_operand" "=r")
14083         (ctz:SI (match_dup 1)))]
14084   ""
14085   "bsf{l}\t{%1, %0|%0, %1}"
14086   [(set_attr "prefix_0f" "1")])
14087
14088 (define_expand "ffsdi2"
14089   [(parallel
14090      [(set (match_operand:DI 0 "register_operand" "") 
14091            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14092       (clobber (match_scratch:DI 2 ""))
14093       (clobber (reg:CC 17))])]
14094   "TARGET_64BIT && TARGET_CMOVE"
14095   "")
14096
14097 (define_insn_and_split "*ffs_rex64"
14098   [(set (match_operand:DI 0 "register_operand" "=r") 
14099         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14100    (clobber (match_scratch:DI 2 "=&r"))
14101    (clobber (reg:CC 17))]
14102   "TARGET_64BIT && TARGET_CMOVE"
14103   "#"
14104   "&& reload_completed"
14105   [(set (match_dup 2) (const_int -1))
14106    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14107               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14108    (set (match_dup 0) (if_then_else:DI
14109                         (eq (reg:CCZ 17) (const_int 0))
14110                         (match_dup 2)
14111                         (match_dup 0)))
14112    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14113               (clobber (reg:CC 17))])]
14114   "")
14115
14116 (define_insn "*ffsdi_1"
14117   [(set (reg:CCZ 17)
14118         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14119                      (const_int 0)))
14120    (set (match_operand:DI 0 "register_operand" "=r")
14121         (ctz:DI (match_dup 1)))]
14122   "TARGET_64BIT"
14123   "bsf{q}\t{%1, %0|%0, %1}"
14124   [(set_attr "prefix_0f" "1")])
14125
14126 (define_insn "ctzsi2"
14127   [(set (match_operand:SI 0 "register_operand" "=r")
14128         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14129    (clobber (reg:CC FLAGS_REG))]
14130   ""
14131   "bsf{l}\t{%1, %0|%0, %1}"
14132   [(set_attr "prefix_0f" "1")])
14133
14134 (define_insn "ctzdi2"
14135   [(set (match_operand:DI 0 "register_operand" "=r")
14136         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14137    (clobber (reg:CC 17))]
14138   "TARGET_64BIT"
14139   "bsf{q}\t{%1, %0|%0, %1}"
14140   [(set_attr "prefix_0f" "1")])
14141
14142 (define_expand "clzsi2"
14143   [(parallel
14144      [(set (match_operand:SI 0 "register_operand" "")
14145            (minus:SI (const_int 31)
14146                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14147       (clobber (reg:CC FLAGS_REG))])
14148    (parallel
14149      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14150       (clobber (reg:CC FLAGS_REG))])]
14151   ""
14152   "")
14153
14154 (define_insn "*bsr"
14155   [(set (match_operand:SI 0 "register_operand" "=r")
14156         (minus:SI (const_int 31)
14157                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14158    (clobber (reg:CC FLAGS_REG))]
14159   ""
14160   "bsr{l}\t{%1, %0|%0, %1}"
14161   [(set_attr "prefix_0f" "1")])
14162
14163 (define_expand "clzdi2"
14164   [(parallel
14165      [(set (match_operand:DI 0 "register_operand" "")
14166            (minus:DI (const_int 63)
14167                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14168       (clobber (reg:CC 17))])
14169    (parallel
14170      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14171       (clobber (reg:CC 17))])]
14172   "TARGET_64BIT"
14173   "")
14174
14175 (define_insn "*bsr_rex64"
14176   [(set (match_operand:DI 0 "register_operand" "=r")
14177         (minus:DI (const_int 63)
14178                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14179    (clobber (reg:CC 17))]
14180   "TARGET_64BIT"
14181   "bsr{q}\t{%1, %0|%0, %1}"
14182   [(set_attr "prefix_0f" "1")])
14183 \f
14184 ;; Thread-local storage patterns for ELF.
14185 ;;
14186 ;; Note that these code sequences must appear exactly as shown
14187 ;; in order to allow linker relaxation.
14188
14189 (define_insn "*tls_global_dynamic_32_gnu"
14190   [(set (match_operand:SI 0 "register_operand" "=a")
14191         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14192                     (match_operand:SI 2 "tls_symbolic_operand" "")
14193                     (match_operand:SI 3 "call_insn_operand" "")]
14194                     UNSPEC_TLS_GD))
14195    (clobber (match_scratch:SI 4 "=d"))
14196    (clobber (match_scratch:SI 5 "=c"))
14197    (clobber (reg:CC FLAGS_REG))]
14198   "!TARGET_64BIT && TARGET_GNU_TLS"
14199   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14200   [(set_attr "type" "multi")
14201    (set_attr "length" "12")])
14202
14203 (define_insn "*tls_global_dynamic_32_sun"
14204   [(set (match_operand:SI 0 "register_operand" "=a")
14205         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14206                     (match_operand:SI 2 "tls_symbolic_operand" "")
14207                     (match_operand:SI 3 "call_insn_operand" "")]
14208                     UNSPEC_TLS_GD))
14209    (clobber (match_scratch:SI 4 "=d"))
14210    (clobber (match_scratch:SI 5 "=c"))
14211    (clobber (reg:CC FLAGS_REG))]
14212   "!TARGET_64BIT && TARGET_SUN_TLS"
14213   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14214         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14215   [(set_attr "type" "multi")
14216    (set_attr "length" "14")])
14217
14218 (define_expand "tls_global_dynamic_32"
14219   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14220                    (unspec:SI
14221                     [(match_dup 2)
14222                      (match_operand:SI 1 "tls_symbolic_operand" "")
14223                      (match_dup 3)]
14224                     UNSPEC_TLS_GD))
14225               (clobber (match_scratch:SI 4 ""))
14226               (clobber (match_scratch:SI 5 ""))
14227               (clobber (reg:CC FLAGS_REG))])]
14228   ""
14229 {
14230   if (flag_pic)
14231     operands[2] = pic_offset_table_rtx;
14232   else
14233     {
14234       operands[2] = gen_reg_rtx (Pmode);
14235       emit_insn (gen_set_got (operands[2]));
14236     }
14237   operands[3] = ix86_tls_get_addr ();
14238 })
14239
14240 (define_insn "*tls_global_dynamic_64"
14241   [(set (match_operand:DI 0 "register_operand" "=a")
14242         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14243                       (match_operand:DI 3 "" "")))
14244    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14245               UNSPEC_TLS_GD)]
14246   "TARGET_64BIT"
14247   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14248   [(set_attr "type" "multi")
14249    (set_attr "length" "16")])
14250
14251 (define_expand "tls_global_dynamic_64"
14252   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14253                    (call (mem:QI (match_dup 2)) (const_int 0)))
14254               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14255                          UNSPEC_TLS_GD)])]
14256   ""
14257 {
14258   operands[2] = ix86_tls_get_addr ();
14259 })
14260
14261 (define_insn "*tls_local_dynamic_base_32_gnu"
14262   [(set (match_operand:SI 0 "register_operand" "=a")
14263         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14264                     (match_operand:SI 2 "call_insn_operand" "")]
14265                    UNSPEC_TLS_LD_BASE))
14266    (clobber (match_scratch:SI 3 "=d"))
14267    (clobber (match_scratch:SI 4 "=c"))
14268    (clobber (reg:CC FLAGS_REG))]
14269   "!TARGET_64BIT && TARGET_GNU_TLS"
14270   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14271   [(set_attr "type" "multi")
14272    (set_attr "length" "11")])
14273
14274 (define_insn "*tls_local_dynamic_base_32_sun"
14275   [(set (match_operand:SI 0 "register_operand" "=a")
14276         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14277                     (match_operand:SI 2 "call_insn_operand" "")]
14278                    UNSPEC_TLS_LD_BASE))
14279    (clobber (match_scratch:SI 3 "=d"))
14280    (clobber (match_scratch:SI 4 "=c"))
14281    (clobber (reg:CC FLAGS_REG))]
14282   "!TARGET_64BIT && TARGET_SUN_TLS"
14283   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14284         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14285   [(set_attr "type" "multi")
14286    (set_attr "length" "13")])
14287
14288 (define_expand "tls_local_dynamic_base_32"
14289   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14290                    (unspec:SI [(match_dup 1) (match_dup 2)]
14291                               UNSPEC_TLS_LD_BASE))
14292               (clobber (match_scratch:SI 3 ""))
14293               (clobber (match_scratch:SI 4 ""))
14294               (clobber (reg:CC FLAGS_REG))])]
14295   ""
14296 {
14297   if (flag_pic)
14298     operands[1] = pic_offset_table_rtx;
14299   else
14300     {
14301       operands[1] = gen_reg_rtx (Pmode);
14302       emit_insn (gen_set_got (operands[1]));
14303     }
14304   operands[2] = ix86_tls_get_addr ();
14305 })
14306
14307 (define_insn "*tls_local_dynamic_base_64"
14308   [(set (match_operand:DI 0 "register_operand" "=a")
14309         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14310                       (match_operand:DI 2 "" "")))
14311    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14312   "TARGET_64BIT"
14313   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14314   [(set_attr "type" "multi")
14315    (set_attr "length" "12")])
14316
14317 (define_expand "tls_local_dynamic_base_64"
14318   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14319                    (call (mem:QI (match_dup 1)) (const_int 0)))
14320               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14321   ""
14322 {
14323   operands[1] = ix86_tls_get_addr ();
14324 })
14325
14326 ;; Local dynamic of a single variable is a lose.  Show combine how
14327 ;; to convert that back to global dynamic.
14328
14329 (define_insn_and_split "*tls_local_dynamic_32_once"
14330   [(set (match_operand:SI 0 "register_operand" "=a")
14331         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14332                              (match_operand:SI 2 "call_insn_operand" "")]
14333                             UNSPEC_TLS_LD_BASE)
14334                  (const:SI (unspec:SI
14335                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14336                             UNSPEC_DTPOFF))))
14337    (clobber (match_scratch:SI 4 "=d"))
14338    (clobber (match_scratch:SI 5 "=c"))
14339    (clobber (reg:CC FLAGS_REG))]
14340   ""
14341   "#"
14342   ""
14343   [(parallel [(set (match_dup 0)
14344                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14345                               UNSPEC_TLS_GD))
14346               (clobber (match_dup 4))
14347               (clobber (match_dup 5))
14348               (clobber (reg:CC FLAGS_REG))])]
14349   "")
14350
14351 ;; Load and add the thread base pointer from %gs:0.
14352
14353 (define_insn "*load_tp_si"
14354   [(set (match_operand:SI 0 "register_operand" "=r")
14355         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14356   "!TARGET_64BIT"
14357   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14358   [(set_attr "type" "imov")
14359    (set_attr "modrm" "0")
14360    (set_attr "length" "7")
14361    (set_attr "memory" "load")
14362    (set_attr "imm_disp" "false")])
14363
14364 (define_insn "*add_tp_si"
14365   [(set (match_operand:SI 0 "register_operand" "=r")
14366         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14367                  (match_operand:SI 1 "register_operand" "0")))
14368    (clobber (reg:CC FLAGS_REG))]
14369   "!TARGET_64BIT"
14370   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14371   [(set_attr "type" "alu")
14372    (set_attr "modrm" "0")
14373    (set_attr "length" "7")
14374    (set_attr "memory" "load")
14375    (set_attr "imm_disp" "false")])
14376
14377 (define_insn "*load_tp_di"
14378   [(set (match_operand:DI 0 "register_operand" "=r")
14379         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14380   "TARGET_64BIT"
14381   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14382   [(set_attr "type" "imov")
14383    (set_attr "modrm" "0")
14384    (set_attr "length" "7")
14385    (set_attr "memory" "load")
14386    (set_attr "imm_disp" "false")])
14387
14388 (define_insn "*add_tp_di"
14389   [(set (match_operand:DI 0 "register_operand" "=r")
14390         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14391                  (match_operand:DI 1 "register_operand" "0")))
14392    (clobber (reg:CC FLAGS_REG))]
14393   "TARGET_64BIT"
14394   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14395   [(set_attr "type" "alu")
14396    (set_attr "modrm" "0")
14397    (set_attr "length" "7")
14398    (set_attr "memory" "load")
14399    (set_attr "imm_disp" "false")])
14400 \f
14401 ;; These patterns match the binary 387 instructions for addM3, subM3,
14402 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14403 ;; SFmode.  The first is the normal insn, the second the same insn but
14404 ;; with one operand a conversion, and the third the same insn but with
14405 ;; the other operand a conversion.  The conversion may be SFmode or
14406 ;; SImode if the target mode DFmode, but only SImode if the target mode
14407 ;; is SFmode.
14408
14409 ;; Gcc is slightly more smart about handling normal two address instructions
14410 ;; so use special patterns for add and mull.
14411 (define_insn "*fop_sf_comm_nosse"
14412   [(set (match_operand:SF 0 "register_operand" "=f")
14413         (match_operator:SF 3 "binary_fp_operator"
14414                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14415                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14416   "TARGET_80387 && !TARGET_SSE_MATH
14417    && COMMUTATIVE_ARITH_P (operands[3])
14418    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14419   "* return output_387_binary_op (insn, operands);"
14420   [(set (attr "type") 
14421         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14422            (const_string "fmul")
14423            (const_string "fop")))
14424    (set_attr "mode" "SF")])
14425
14426 (define_insn "*fop_sf_comm"
14427   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14428         (match_operator:SF 3 "binary_fp_operator"
14429                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14430                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14431   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14432    && COMMUTATIVE_ARITH_P (operands[3])
14433    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434   "* return output_387_binary_op (insn, operands);"
14435   [(set (attr "type") 
14436         (if_then_else (eq_attr "alternative" "1")
14437            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14438               (const_string "ssemul")
14439               (const_string "sseadd"))
14440            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14441               (const_string "fmul")
14442               (const_string "fop"))))
14443    (set_attr "mode" "SF")])
14444
14445 (define_insn "*fop_sf_comm_sse"
14446   [(set (match_operand:SF 0 "register_operand" "=x")
14447         (match_operator:SF 3 "binary_fp_operator"
14448                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14449                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14450   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14455            (const_string "ssemul")
14456            (const_string "sseadd")))
14457    (set_attr "mode" "SF")])
14458
14459 (define_insn "*fop_df_comm_nosse"
14460   [(set (match_operand:DF 0 "register_operand" "=f")
14461         (match_operator:DF 3 "binary_fp_operator"
14462                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14463                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14464   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14465    && COMMUTATIVE_ARITH_P (operands[3])
14466    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14470            (const_string "fmul")
14471            (const_string "fop")))
14472    (set_attr "mode" "DF")])
14473
14474 (define_insn "*fop_df_comm"
14475   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14480    && COMMUTATIVE_ARITH_P (operands[3])
14481    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (if_then_else (eq_attr "alternative" "1")
14485            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14486               (const_string "ssemul")
14487               (const_string "sseadd"))
14488            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14489               (const_string "fmul")
14490               (const_string "fop"))))
14491    (set_attr "mode" "DF")])
14492
14493 (define_insn "*fop_df_comm_sse"
14494   [(set (match_operand:DF 0 "register_operand" "=Y")
14495         (match_operator:DF 3 "binary_fp_operator"
14496                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498   "TARGET_SSE2 && TARGET_SSE_MATH
14499    && COMMUTATIVE_ARITH_P (operands[3])
14500    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501   "* return output_387_binary_op (insn, operands);"
14502   [(set (attr "type") 
14503         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14504            (const_string "ssemul")
14505            (const_string "sseadd")))
14506    (set_attr "mode" "DF")])
14507
14508 (define_insn "*fop_xf_comm"
14509   [(set (match_operand:XF 0 "register_operand" "=f")
14510         (match_operator:XF 3 "binary_fp_operator"
14511                         [(match_operand:XF 1 "register_operand" "%0")
14512                          (match_operand:XF 2 "register_operand" "f")]))]
14513   "TARGET_80387
14514    && COMMUTATIVE_ARITH_P (operands[3])"
14515   "* return output_387_binary_op (insn, operands);"
14516   [(set (attr "type") 
14517         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14518            (const_string "fmul")
14519            (const_string "fop")))
14520    (set_attr "mode" "XF")])
14521
14522 (define_insn "*fop_sf_1_nosse"
14523   [(set (match_operand:SF 0 "register_operand" "=f,f")
14524         (match_operator:SF 3 "binary_fp_operator"
14525                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14526                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14527   "TARGET_80387 && !TARGET_SSE_MATH
14528    && !COMMUTATIVE_ARITH_P (operands[3])
14529    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14530   "* return output_387_binary_op (insn, operands);"
14531   [(set (attr "type") 
14532         (cond [(match_operand:SF 3 "mult_operator" "") 
14533                  (const_string "fmul")
14534                (match_operand:SF 3 "div_operator" "") 
14535                  (const_string "fdiv")
14536               ]
14537               (const_string "fop")))
14538    (set_attr "mode" "SF")])
14539
14540 (define_insn "*fop_sf_1"
14541   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14542         (match_operator:SF 3 "binary_fp_operator"
14543                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14544                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14545   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14546    && !COMMUTATIVE_ARITH_P (operands[3])
14547    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14548   "* return output_387_binary_op (insn, operands);"
14549   [(set (attr "type") 
14550         (cond [(and (eq_attr "alternative" "2")
14551                     (match_operand:SF 3 "mult_operator" ""))
14552                  (const_string "ssemul")
14553                (and (eq_attr "alternative" "2")
14554                     (match_operand:SF 3 "div_operator" ""))
14555                  (const_string "ssediv")
14556                (eq_attr "alternative" "2")
14557                  (const_string "sseadd")
14558                (match_operand:SF 3 "mult_operator" "") 
14559                  (const_string "fmul")
14560                (match_operand:SF 3 "div_operator" "") 
14561                  (const_string "fdiv")
14562               ]
14563               (const_string "fop")))
14564    (set_attr "mode" "SF")])
14565
14566 (define_insn "*fop_sf_1_sse"
14567   [(set (match_operand:SF 0 "register_operand" "=x")
14568         (match_operator:SF 3 "binary_fp_operator"
14569                         [(match_operand:SF 1 "register_operand" "0")
14570                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14571   "TARGET_SSE_MATH
14572    && !COMMUTATIVE_ARITH_P (operands[3])"
14573   "* return output_387_binary_op (insn, operands);"
14574   [(set (attr "type") 
14575         (cond [(match_operand:SF 3 "mult_operator" "")
14576                  (const_string "ssemul")
14577                (match_operand:SF 3 "div_operator" "")
14578                  (const_string "ssediv")
14579               ]
14580               (const_string "sseadd")))
14581    (set_attr "mode" "SF")])
14582
14583 ;; ??? Add SSE splitters for these!
14584 (define_insn "*fop_sf_2"
14585   [(set (match_operand:SF 0 "register_operand" "=f,f")
14586         (match_operator:SF 3 "binary_fp_operator"
14587           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14588            (match_operand:SF 2 "register_operand" "0,0")]))]
14589   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14590   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14591   [(set (attr "type") 
14592         (cond [(match_operand:SF 3 "mult_operator" "") 
14593                  (const_string "fmul")
14594                (match_operand:SF 3 "div_operator" "") 
14595                  (const_string "fdiv")
14596               ]
14597               (const_string "fop")))
14598    (set_attr "fp_int_src" "true")
14599    (set_attr "mode" "SI")])
14600
14601 (define_insn "*fop_sf_3"
14602   [(set (match_operand:SF 0 "register_operand" "=f,f")
14603         (match_operator:SF 3 "binary_fp_operator"
14604           [(match_operand:SF 1 "register_operand" "0,0")
14605            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14606   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14607   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14608   [(set (attr "type") 
14609         (cond [(match_operand:SF 3 "mult_operator" "") 
14610                  (const_string "fmul")
14611                (match_operand:SF 3 "div_operator" "") 
14612                  (const_string "fdiv")
14613               ]
14614               (const_string "fop")))
14615    (set_attr "fp_int_src" "true")
14616    (set_attr "mode" "SI")])
14617
14618 (define_insn "*fop_df_1_nosse"
14619   [(set (match_operand:DF 0 "register_operand" "=f,f")
14620         (match_operator:DF 3 "binary_fp_operator"
14621                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14622                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14623   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14624    && !COMMUTATIVE_ARITH_P (operands[3])
14625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14626   "* return output_387_binary_op (insn, operands);"
14627   [(set (attr "type") 
14628         (cond [(match_operand:DF 3 "mult_operator" "") 
14629                  (const_string "fmul")
14630                (match_operand:DF 3 "div_operator" "")
14631                  (const_string "fdiv")
14632               ]
14633               (const_string "fop")))
14634    (set_attr "mode" "DF")])
14635
14636
14637 (define_insn "*fop_df_1"
14638   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14639         (match_operator:DF 3 "binary_fp_operator"
14640                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14641                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14642   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14643    && !COMMUTATIVE_ARITH_P (operands[3])
14644    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14645   "* return output_387_binary_op (insn, operands);"
14646   [(set (attr "type") 
14647         (cond [(and (eq_attr "alternative" "2")
14648                     (match_operand:SF 3 "mult_operator" ""))
14649                  (const_string "ssemul")
14650                (and (eq_attr "alternative" "2")
14651                     (match_operand:SF 3 "div_operator" ""))
14652                  (const_string "ssediv")
14653                (eq_attr "alternative" "2")
14654                  (const_string "sseadd")
14655                (match_operand:DF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:DF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "mode" "DF")])
14662
14663 (define_insn "*fop_df_1_sse"
14664   [(set (match_operand:DF 0 "register_operand" "=Y")
14665         (match_operator:DF 3 "binary_fp_operator"
14666                         [(match_operand:DF 1 "register_operand" "0")
14667                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14668   "TARGET_SSE2 && TARGET_SSE_MATH
14669    && !COMMUTATIVE_ARITH_P (operands[3])"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set_attr "mode" "DF")
14672    (set (attr "type") 
14673         (cond [(match_operand:SF 3 "mult_operator" "")
14674                  (const_string "ssemul")
14675                (match_operand:SF 3 "div_operator" "")
14676                  (const_string "ssediv")
14677               ]
14678               (const_string "sseadd")))])
14679
14680 ;; ??? Add SSE splitters for these!
14681 (define_insn "*fop_df_2"
14682   [(set (match_operand:DF 0 "register_operand" "=f,f")
14683         (match_operator:DF 3 "binary_fp_operator"
14684            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14685             (match_operand:DF 2 "register_operand" "0,0")]))]
14686   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14687   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14688   [(set (attr "type") 
14689         (cond [(match_operand:DF 3 "mult_operator" "") 
14690                  (const_string "fmul")
14691                (match_operand:DF 3 "div_operator" "") 
14692                  (const_string "fdiv")
14693               ]
14694               (const_string "fop")))
14695    (set_attr "fp_int_src" "true")
14696    (set_attr "mode" "SI")])
14697
14698 (define_insn "*fop_df_3"
14699   [(set (match_operand:DF 0 "register_operand" "=f,f")
14700         (match_operator:DF 3 "binary_fp_operator"
14701            [(match_operand:DF 1 "register_operand" "0,0")
14702             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14703   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14704   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14705   [(set (attr "type") 
14706         (cond [(match_operand:DF 3 "mult_operator" "") 
14707                  (const_string "fmul")
14708                (match_operand:DF 3 "div_operator" "") 
14709                  (const_string "fdiv")
14710               ]
14711               (const_string "fop")))
14712    (set_attr "fp_int_src" "true")
14713    (set_attr "mode" "SI")])
14714
14715 (define_insn "*fop_df_4"
14716   [(set (match_operand:DF 0 "register_operand" "=f,f")
14717         (match_operator:DF 3 "binary_fp_operator"
14718            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14719             (match_operand:DF 2 "register_operand" "0,f")]))]
14720   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14721    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14722   "* return output_387_binary_op (insn, operands);"
14723   [(set (attr "type") 
14724         (cond [(match_operand:DF 3 "mult_operator" "") 
14725                  (const_string "fmul")
14726                (match_operand:DF 3 "div_operator" "") 
14727                  (const_string "fdiv")
14728               ]
14729               (const_string "fop")))
14730    (set_attr "mode" "SF")])
14731
14732 (define_insn "*fop_df_5"
14733   [(set (match_operand:DF 0 "register_operand" "=f,f")
14734         (match_operator:DF 3 "binary_fp_operator"
14735           [(match_operand:DF 1 "register_operand" "0,f")
14736            (float_extend:DF
14737             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14738   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14739   "* return output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(match_operand:DF 3 "mult_operator" "") 
14742                  (const_string "fmul")
14743                (match_operand:DF 3 "div_operator" "") 
14744                  (const_string "fdiv")
14745               ]
14746               (const_string "fop")))
14747    (set_attr "mode" "SF")])
14748
14749 (define_insn "*fop_df_6"
14750   [(set (match_operand:DF 0 "register_operand" "=f,f")
14751         (match_operator:DF 3 "binary_fp_operator"
14752           [(float_extend:DF
14753             (match_operand:SF 1 "register_operand" "0,f"))
14754            (float_extend:DF
14755             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14756   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14757   "* return output_387_binary_op (insn, operands);"
14758   [(set (attr "type") 
14759         (cond [(match_operand:DF 3 "mult_operator" "") 
14760                  (const_string "fmul")
14761                (match_operand:DF 3 "div_operator" "") 
14762                  (const_string "fdiv")
14763               ]
14764               (const_string "fop")))
14765    (set_attr "mode" "SF")])
14766
14767 (define_insn "*fop_xf_1"
14768   [(set (match_operand:XF 0 "register_operand" "=f,f")
14769         (match_operator:XF 3 "binary_fp_operator"
14770                         [(match_operand:XF 1 "register_operand" "0,f")
14771                          (match_operand:XF 2 "register_operand" "f,0")]))]
14772   "TARGET_80387
14773    && !COMMUTATIVE_ARITH_P (operands[3])"
14774   "* return output_387_binary_op (insn, operands);"
14775   [(set (attr "type") 
14776         (cond [(match_operand:XF 3 "mult_operator" "") 
14777                  (const_string "fmul")
14778                (match_operand:XF 3 "div_operator" "") 
14779                  (const_string "fdiv")
14780               ]
14781               (const_string "fop")))
14782    (set_attr "mode" "XF")])
14783
14784 (define_insn "*fop_xf_2"
14785   [(set (match_operand:XF 0 "register_operand" "=f,f")
14786         (match_operator:XF 3 "binary_fp_operator"
14787            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14788             (match_operand:XF 2 "register_operand" "0,0")]))]
14789   "TARGET_80387 && TARGET_USE_FIOP"
14790   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14791   [(set (attr "type") 
14792         (cond [(match_operand:XF 3 "mult_operator" "") 
14793                  (const_string "fmul")
14794                (match_operand:XF 3 "div_operator" "") 
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "fp_int_src" "true")
14799    (set_attr "mode" "SI")])
14800
14801 (define_insn "*fop_xf_3"
14802   [(set (match_operand:XF 0 "register_operand" "=f,f")
14803         (match_operator:XF 3 "binary_fp_operator"
14804           [(match_operand:XF 1 "register_operand" "0,0")
14805            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14806   "TARGET_80387 && TARGET_USE_FIOP"
14807   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14808   [(set (attr "type") 
14809         (cond [(match_operand:XF 3 "mult_operator" "") 
14810                  (const_string "fmul")
14811                (match_operand:XF 3 "div_operator" "") 
14812                  (const_string "fdiv")
14813               ]
14814               (const_string "fop")))
14815    (set_attr "fp_int_src" "true")
14816    (set_attr "mode" "SI")])
14817
14818 (define_insn "*fop_xf_4"
14819   [(set (match_operand:XF 0 "register_operand" "=f,f")
14820         (match_operator:XF 3 "binary_fp_operator"
14821            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14822             (match_operand:XF 2 "register_operand" "0,f")]))]
14823   "TARGET_80387"
14824   "* return output_387_binary_op (insn, operands);"
14825   [(set (attr "type") 
14826         (cond [(match_operand:XF 3 "mult_operator" "") 
14827                  (const_string "fmul")
14828                (match_operand:XF 3 "div_operator" "") 
14829                  (const_string "fdiv")
14830               ]
14831               (const_string "fop")))
14832    (set_attr "mode" "SF")])
14833
14834 (define_insn "*fop_xf_5"
14835   [(set (match_operand:XF 0 "register_operand" "=f,f")
14836         (match_operator:XF 3 "binary_fp_operator"
14837           [(match_operand:XF 1 "register_operand" "0,f")
14838            (float_extend:XF
14839             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14840   "TARGET_80387"
14841   "* return output_387_binary_op (insn, operands);"
14842   [(set (attr "type") 
14843         (cond [(match_operand:XF 3 "mult_operator" "") 
14844                  (const_string "fmul")
14845                (match_operand:XF 3 "div_operator" "") 
14846                  (const_string "fdiv")
14847               ]
14848               (const_string "fop")))
14849    (set_attr "mode" "SF")])
14850
14851 (define_insn "*fop_xf_6"
14852   [(set (match_operand:XF 0 "register_operand" "=f,f")
14853         (match_operator:XF 3 "binary_fp_operator"
14854           [(float_extend:XF
14855             (match_operand 1 "register_operand" "0,f"))
14856            (float_extend:XF
14857             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14858   "TARGET_80387"
14859   "* return output_387_binary_op (insn, operands);"
14860   [(set (attr "type") 
14861         (cond [(match_operand:XF 3 "mult_operator" "") 
14862                  (const_string "fmul")
14863                (match_operand:XF 3 "div_operator" "") 
14864                  (const_string "fdiv")
14865               ]
14866               (const_string "fop")))
14867    (set_attr "mode" "SF")])
14868
14869 (define_split
14870   [(set (match_operand 0 "register_operand" "")
14871         (match_operator 3 "binary_fp_operator"
14872            [(float (match_operand:SI 1 "register_operand" ""))
14873             (match_operand 2 "register_operand" "")]))]
14874   "TARGET_80387 && reload_completed
14875    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14876   [(const_int 0)]
14877
14878   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14879   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14880   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14881                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14882                                           GET_MODE (operands[3]),
14883                                           operands[4],
14884                                           operands[2])));
14885   ix86_free_from_memory (GET_MODE (operands[1]));
14886   DONE;
14887 })
14888
14889 (define_split
14890   [(set (match_operand 0 "register_operand" "")
14891         (match_operator 3 "binary_fp_operator"
14892            [(match_operand 1 "register_operand" "")
14893             (float (match_operand:SI 2 "register_operand" ""))]))]
14894   "TARGET_80387 && reload_completed
14895    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14896   [(const_int 0)]
14897 {
14898   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14899   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14900   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14901                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14902                                           GET_MODE (operands[3]),
14903                                           operands[1],
14904                                           operands[4])));
14905   ix86_free_from_memory (GET_MODE (operands[2]));
14906   DONE;
14907 })
14908 \f
14909 ;; FPU special functions.
14910
14911 (define_expand "sqrtsf2"
14912   [(set (match_operand:SF 0 "register_operand" "")
14913         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14914   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14915 {
14916   if (!TARGET_SSE_MATH)
14917     operands[1] = force_reg (SFmode, operands[1]);
14918 })
14919
14920 (define_insn "sqrtsf2_1"
14921   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14922         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14923   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14924    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14925   "@
14926    fsqrt
14927    sqrtss\t{%1, %0|%0, %1}"
14928   [(set_attr "type" "fpspc,sse")
14929    (set_attr "mode" "SF,SF")
14930    (set_attr "athlon_decode" "direct,*")])
14931
14932 (define_insn "sqrtsf2_1_sse_only"
14933   [(set (match_operand:SF 0 "register_operand" "=x")
14934         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14935   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14936   "sqrtss\t{%1, %0|%0, %1}"
14937   [(set_attr "type" "sse")
14938    (set_attr "mode" "SF")
14939    (set_attr "athlon_decode" "*")])
14940
14941 (define_insn "sqrtsf2_i387"
14942   [(set (match_operand:SF 0 "register_operand" "=f")
14943         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14944   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14945    && !TARGET_SSE_MATH"
14946   "fsqrt"
14947   [(set_attr "type" "fpspc")
14948    (set_attr "mode" "SF")
14949    (set_attr "athlon_decode" "direct")])
14950
14951 (define_expand "sqrtdf2"
14952   [(set (match_operand:DF 0 "register_operand" "")
14953         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14954   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14955    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14956 {
14957   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14958     operands[1] = force_reg (DFmode, operands[1]);
14959 })
14960
14961 (define_insn "sqrtdf2_1"
14962   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14963         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14964   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14965    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14966   "@
14967    fsqrt
14968    sqrtsd\t{%1, %0|%0, %1}"
14969   [(set_attr "type" "fpspc,sse")
14970    (set_attr "mode" "DF,DF")
14971    (set_attr "athlon_decode" "direct,*")])
14972
14973 (define_insn "sqrtdf2_1_sse_only"
14974   [(set (match_operand:DF 0 "register_operand" "=Y")
14975         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14976   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14977   "sqrtsd\t{%1, %0|%0, %1}"
14978   [(set_attr "type" "sse")
14979    (set_attr "mode" "DF")
14980    (set_attr "athlon_decode" "*")])
14981
14982 (define_insn "sqrtdf2_i387"
14983   [(set (match_operand:DF 0 "register_operand" "=f")
14984         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14985   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14986    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14987   "fsqrt"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "DF")
14990    (set_attr "athlon_decode" "direct")])
14991
14992 (define_insn "*sqrtextendsfdf2"
14993   [(set (match_operand:DF 0 "register_operand" "=f")
14994         (sqrt:DF (float_extend:DF
14995                   (match_operand:SF 1 "register_operand" "0"))))]
14996   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14997    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14998   "fsqrt"
14999   [(set_attr "type" "fpspc")
15000    (set_attr "mode" "DF")
15001    (set_attr "athlon_decode" "direct")])
15002
15003 (define_insn "sqrtxf2"
15004   [(set (match_operand:XF 0 "register_operand" "=f")
15005         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15006   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
15007    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15008   "fsqrt"
15009   [(set_attr "type" "fpspc")
15010    (set_attr "mode" "XF")
15011    (set_attr "athlon_decode" "direct")])
15012
15013 (define_insn "*sqrtextenddfxf2"
15014   [(set (match_operand:XF 0 "register_operand" "=f")
15015         (sqrt:XF (float_extend:XF
15016                   (match_operand:DF 1 "register_operand" "0"))))]
15017   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15018   "fsqrt"
15019   [(set_attr "type" "fpspc")
15020    (set_attr "mode" "XF")
15021    (set_attr "athlon_decode" "direct")])
15022
15023 (define_insn "*sqrtextendsfxf2"
15024   [(set (match_operand:XF 0 "register_operand" "=f")
15025         (sqrt:XF (float_extend:XF
15026                   (match_operand:SF 1 "register_operand" "0"))))]
15027   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15028   "fsqrt"
15029   [(set_attr "type" "fpspc")
15030    (set_attr "mode" "XF")
15031    (set_attr "athlon_decode" "direct")])
15032
15033 (define_insn "fpremxf4"
15034   [(set (match_operand:XF 0 "register_operand" "=f")
15035         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15036                     (match_operand:XF 3 "register_operand" "1")]
15037                    UNSPEC_FPREM_F))
15038    (set (match_operand:XF 1 "register_operand" "=u")
15039         (unspec:XF [(match_dup 2) (match_dup 3)]
15040                    UNSPEC_FPREM_U))
15041    (set (reg:CCFP FPSR_REG)
15042         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15043   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15044    && flag_unsafe_math_optimizations"
15045   "fprem"
15046   [(set_attr "type" "fpspc")
15047    (set_attr "mode" "XF")])
15048
15049 (define_expand "fmodsf3"
15050   [(use (match_operand:SF 0 "register_operand" ""))
15051    (use (match_operand:SF 1 "register_operand" ""))
15052    (use (match_operand:SF 2 "register_operand" ""))]
15053   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15054    && flag_unsafe_math_optimizations"
15055 {
15056   rtx label = gen_label_rtx ();
15057
15058   rtx op1 = gen_reg_rtx (XFmode);
15059   rtx op2 = gen_reg_rtx (XFmode);
15060
15061   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15062   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15063
15064   emit_label (label);
15065
15066   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15067   ix86_emit_fp_unordered_jump (label);
15068
15069   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15070   DONE;
15071 })
15072
15073 (define_expand "fmoddf3"
15074   [(use (match_operand:DF 0 "register_operand" ""))
15075    (use (match_operand:DF 1 "register_operand" ""))
15076    (use (match_operand:DF 2 "register_operand" ""))]
15077   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15078    && flag_unsafe_math_optimizations"
15079 {
15080   rtx label = gen_label_rtx ();
15081
15082   rtx op1 = gen_reg_rtx (XFmode);
15083   rtx op2 = gen_reg_rtx (XFmode);
15084
15085   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15086   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15087
15088   emit_label (label);
15089
15090   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15091   ix86_emit_fp_unordered_jump (label);
15092
15093   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15094   DONE;
15095 })
15096
15097 (define_expand "fmodxf3"
15098   [(use (match_operand:XF 0 "register_operand" ""))
15099    (use (match_operand:XF 1 "register_operand" ""))
15100    (use (match_operand:XF 2 "register_operand" ""))]
15101   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15102    && flag_unsafe_math_optimizations"
15103 {
15104   rtx label = gen_label_rtx ();
15105
15106   emit_label (label);
15107
15108   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15109                            operands[1], operands[2]));
15110   ix86_emit_fp_unordered_jump (label);
15111
15112   emit_move_insn (operands[0], operands[1]);
15113   DONE;
15114 })
15115
15116 (define_insn "fprem1xf4"
15117   [(set (match_operand:XF 0 "register_operand" "=f")
15118         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15119                     (match_operand:XF 3 "register_operand" "1")]
15120                    UNSPEC_FPREM1_F))
15121    (set (match_operand:XF 1 "register_operand" "=u")
15122         (unspec:XF [(match_dup 2) (match_dup 3)]
15123                    UNSPEC_FPREM1_U))
15124    (set (reg:CCFP FPSR_REG)
15125         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15126   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15127    && flag_unsafe_math_optimizations"
15128   "fprem1"
15129   [(set_attr "type" "fpspc")
15130    (set_attr "mode" "XF")])
15131
15132 (define_expand "dremsf3"
15133   [(use (match_operand:SF 0 "register_operand" ""))
15134    (use (match_operand:SF 1 "register_operand" ""))
15135    (use (match_operand:SF 2 "register_operand" ""))]
15136   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137    && flag_unsafe_math_optimizations"
15138 {
15139   rtx label = gen_label_rtx ();
15140
15141   rtx op1 = gen_reg_rtx (XFmode);
15142   rtx op2 = gen_reg_rtx (XFmode);
15143
15144   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15145   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15146
15147   emit_label (label);
15148
15149   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15150   ix86_emit_fp_unordered_jump (label);
15151
15152   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15153   DONE;
15154 })
15155
15156 (define_expand "dremdf3"
15157   [(use (match_operand:DF 0 "register_operand" ""))
15158    (use (match_operand:DF 1 "register_operand" ""))
15159    (use (match_operand:DF 2 "register_operand" ""))]
15160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161    && flag_unsafe_math_optimizations"
15162 {
15163   rtx label = gen_label_rtx ();
15164
15165   rtx op1 = gen_reg_rtx (XFmode);
15166   rtx op2 = gen_reg_rtx (XFmode);
15167
15168   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15169   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15170
15171   emit_label (label);
15172
15173   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15174   ix86_emit_fp_unordered_jump (label);
15175
15176   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15177   DONE;
15178 })
15179
15180 (define_expand "dremxf3"
15181   [(use (match_operand:XF 0 "register_operand" ""))
15182    (use (match_operand:XF 1 "register_operand" ""))
15183    (use (match_operand:XF 2 "register_operand" ""))]
15184   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15185    && flag_unsafe_math_optimizations"
15186 {
15187   rtx label = gen_label_rtx ();
15188
15189   emit_label (label);
15190
15191   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15192                             operands[1], operands[2]));
15193   ix86_emit_fp_unordered_jump (label);
15194
15195   emit_move_insn (operands[0], operands[1]);
15196   DONE;
15197 })
15198
15199 (define_insn "*sindf2"
15200   [(set (match_operand:DF 0 "register_operand" "=f")
15201         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15202   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15203    && flag_unsafe_math_optimizations"
15204   "fsin"
15205   [(set_attr "type" "fpspc")
15206    (set_attr "mode" "DF")])
15207
15208 (define_insn "*sinsf2"
15209   [(set (match_operand:SF 0 "register_operand" "=f")
15210         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15211   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15212    && flag_unsafe_math_optimizations"
15213   "fsin"
15214   [(set_attr "type" "fpspc")
15215    (set_attr "mode" "SF")])
15216
15217 (define_insn "*sinextendsfdf2"
15218   [(set (match_operand:DF 0 "register_operand" "=f")
15219         (unspec:DF [(float_extend:DF
15220                      (match_operand:SF 1 "register_operand" "0"))]
15221                    UNSPEC_SIN))]
15222   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15223    && flag_unsafe_math_optimizations"
15224   "fsin"
15225   [(set_attr "type" "fpspc")
15226    (set_attr "mode" "DF")])
15227
15228 (define_insn "*sinxf2"
15229   [(set (match_operand:XF 0 "register_operand" "=f")
15230         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15231   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15232    && flag_unsafe_math_optimizations"
15233   "fsin"
15234   [(set_attr "type" "fpspc")
15235    (set_attr "mode" "XF")])
15236
15237 (define_insn "*cosdf2"
15238   [(set (match_operand:DF 0 "register_operand" "=f")
15239         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15240   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15241    && flag_unsafe_math_optimizations"
15242   "fcos"
15243   [(set_attr "type" "fpspc")
15244    (set_attr "mode" "DF")])
15245
15246 (define_insn "*cossf2"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15249   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15250    && flag_unsafe_math_optimizations"
15251   "fcos"
15252   [(set_attr "type" "fpspc")
15253    (set_attr "mode" "SF")])
15254
15255 (define_insn "*cosextendsfdf2"
15256   [(set (match_operand:DF 0 "register_operand" "=f")
15257         (unspec:DF [(float_extend:DF
15258                      (match_operand:SF 1 "register_operand" "0"))]
15259                    UNSPEC_COS))]
15260   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15261    && flag_unsafe_math_optimizations"
15262   "fcos"
15263   [(set_attr "type" "fpspc")
15264    (set_attr "mode" "DF")])
15265
15266 (define_insn "*cosxf2"
15267   [(set (match_operand:XF 0 "register_operand" "=f")
15268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15269   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15270    && flag_unsafe_math_optimizations"
15271   "fcos"
15272   [(set_attr "type" "fpspc")
15273    (set_attr "mode" "XF")])
15274
15275 ;; With sincos pattern defined, sin and cos builtin function will be
15276 ;; expanded to sincos pattern with one of its outputs left unused. 
15277 ;; Cse pass  will detected, if two sincos patterns can be combined,
15278 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15279 ;; depending on the unused output.
15280
15281 (define_insn "sincosdf3"
15282   [(set (match_operand:DF 0 "register_operand" "=f")
15283         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15287   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15288    && flag_unsafe_math_optimizations"
15289   "fsincos"
15290   [(set_attr "type" "fpspc")
15291    (set_attr "mode" "DF")])
15292
15293 (define_split
15294   [(set (match_operand:DF 0 "register_operand" "")
15295         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15296                    UNSPEC_SINCOS_COS))
15297    (set (match_operand:DF 1 "register_operand" "")
15298         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15299   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15300    && !reload_completed && !reload_in_progress"
15301   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15302   "")
15303
15304 (define_split
15305   [(set (match_operand:DF 0 "register_operand" "")
15306         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15307                    UNSPEC_SINCOS_COS))
15308    (set (match_operand:DF 1 "register_operand" "")
15309         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15310   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15311    && !reload_completed && !reload_in_progress"
15312   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15313   "")
15314
15315 (define_insn "sincossf3"
15316   [(set (match_operand:SF 0 "register_operand" "=f")
15317         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15318                    UNSPEC_SINCOS_COS))
15319    (set (match_operand:SF 1 "register_operand" "=u")
15320         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15321   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15322    && flag_unsafe_math_optimizations"
15323   "fsincos"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "SF")])
15326
15327 (define_split
15328   [(set (match_operand:SF 0 "register_operand" "")
15329         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15330                    UNSPEC_SINCOS_COS))
15331    (set (match_operand:SF 1 "register_operand" "")
15332         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15333   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15334    && !reload_completed && !reload_in_progress"
15335   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15336   "")
15337
15338 (define_split
15339   [(set (match_operand:SF 0 "register_operand" "")
15340         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15341                    UNSPEC_SINCOS_COS))
15342    (set (match_operand:SF 1 "register_operand" "")
15343         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15344   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15345    && !reload_completed && !reload_in_progress"
15346   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15347   "")
15348
15349 (define_insn "*sincosextendsfdf3"
15350   [(set (match_operand:DF 0 "register_operand" "=f")
15351         (unspec:DF [(float_extend:DF
15352                      (match_operand:SF 2 "register_operand" "0"))]
15353                    UNSPEC_SINCOS_COS))
15354    (set (match_operand:DF 1 "register_operand" "=u")
15355         (unspec:DF [(float_extend:DF
15356                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15357   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15358    && flag_unsafe_math_optimizations"
15359   "fsincos"
15360   [(set_attr "type" "fpspc")
15361    (set_attr "mode" "DF")])
15362
15363 (define_split
15364   [(set (match_operand:DF 0 "register_operand" "")
15365         (unspec:DF [(float_extend:DF
15366                      (match_operand:SF 2 "register_operand" ""))]
15367                    UNSPEC_SINCOS_COS))
15368    (set (match_operand:DF 1 "register_operand" "")
15369         (unspec:DF [(float_extend:DF
15370                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15371   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15372    && !reload_completed && !reload_in_progress"
15373   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15374                                    (match_dup 2))] UNSPEC_SIN))]
15375   "")
15376
15377 (define_split
15378   [(set (match_operand:DF 0 "register_operand" "")
15379         (unspec:DF [(float_extend:DF
15380                      (match_operand:SF 2 "register_operand" ""))]
15381                    UNSPEC_SINCOS_COS))
15382    (set (match_operand:DF 1 "register_operand" "")
15383         (unspec:DF [(float_extend:DF
15384                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15385   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15386    && !reload_completed && !reload_in_progress"
15387   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15388                                    (match_dup 2))] UNSPEC_COS))]
15389   "")
15390
15391 (define_insn "sincosxf3"
15392   [(set (match_operand:XF 0 "register_operand" "=f")
15393         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15394                    UNSPEC_SINCOS_COS))
15395    (set (match_operand:XF 1 "register_operand" "=u")
15396         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15397   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15398    && flag_unsafe_math_optimizations"
15399   "fsincos"
15400   [(set_attr "type" "fpspc")
15401    (set_attr "mode" "XF")])
15402
15403 (define_split
15404   [(set (match_operand:XF 0 "register_operand" "")
15405         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15406                    UNSPEC_SINCOS_COS))
15407    (set (match_operand:XF 1 "register_operand" "")
15408         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15409   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15410    && !reload_completed && !reload_in_progress"
15411   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15412   "")
15413
15414 (define_split
15415   [(set (match_operand:XF 0 "register_operand" "")
15416         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15417                    UNSPEC_SINCOS_COS))
15418    (set (match_operand:XF 1 "register_operand" "")
15419         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15420   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15421    && !reload_completed && !reload_in_progress"
15422   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15423   "")
15424
15425 (define_insn "*tandf3_1"
15426   [(set (match_operand:DF 0 "register_operand" "=f")
15427         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15428                    UNSPEC_TAN_ONE))
15429    (set (match_operand:DF 1 "register_operand" "=u")
15430         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15431   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15432    && flag_unsafe_math_optimizations"
15433   "fptan"
15434   [(set_attr "type" "fpspc")
15435    (set_attr "mode" "DF")])
15436
15437 ;; optimize sequence: fptan
15438 ;;                    fstp    %st(0)
15439 ;;                    fld1
15440 ;; into fptan insn.
15441
15442 (define_peephole2
15443   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15444                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15445                              UNSPEC_TAN_ONE))
15446              (set (match_operand:DF 1 "register_operand" "")
15447                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15448    (set (match_dup 0)
15449         (match_operand:DF 3 "immediate_operand" ""))]
15450   "standard_80387_constant_p (operands[3]) == 2"
15451   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15452              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15453   "")
15454
15455 (define_expand "tandf2"
15456   [(parallel [(set (match_dup 2)
15457                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15458                               UNSPEC_TAN_ONE))
15459               (set (match_operand:DF 0 "register_operand" "")
15460                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15461   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15462    && flag_unsafe_math_optimizations"
15463 {
15464   operands[2] = gen_reg_rtx (DFmode);
15465 })
15466
15467 (define_insn "*tansf3_1"
15468   [(set (match_operand:SF 0 "register_operand" "=f")
15469         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15470                    UNSPEC_TAN_ONE))
15471    (set (match_operand:SF 1 "register_operand" "=u")
15472         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15473   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15474    && flag_unsafe_math_optimizations"
15475   "fptan"
15476   [(set_attr "type" "fpspc")
15477    (set_attr "mode" "SF")])
15478
15479 ;; optimize sequence: fptan
15480 ;;                    fstp    %st(0)
15481 ;;                    fld1
15482 ;; into fptan insn.
15483
15484 (define_peephole2
15485   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15486                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15487                              UNSPEC_TAN_ONE))
15488              (set (match_operand:SF 1 "register_operand" "")
15489                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15490    (set (match_dup 0)
15491         (match_operand:SF 3 "immediate_operand" ""))]
15492   "standard_80387_constant_p (operands[3]) == 2"
15493   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15494              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15495   "")
15496
15497 (define_expand "tansf2"
15498   [(parallel [(set (match_dup 2)
15499                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15500                               UNSPEC_TAN_ONE))
15501               (set (match_operand:SF 0 "register_operand" "")
15502                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15503   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15504    && flag_unsafe_math_optimizations"
15505 {
15506   operands[2] = gen_reg_rtx (SFmode);
15507 })
15508
15509 (define_insn "*tanxf3_1"
15510   [(set (match_operand:XF 0 "register_operand" "=f")
15511         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15512                    UNSPEC_TAN_ONE))
15513    (set (match_operand:XF 1 "register_operand" "=u")
15514         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15515   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15516    && flag_unsafe_math_optimizations"
15517   "fptan"
15518   [(set_attr "type" "fpspc")
15519    (set_attr "mode" "XF")])
15520
15521 ;; optimize sequence: fptan
15522 ;;                    fstp    %st(0)
15523 ;;                    fld1
15524 ;; into fptan insn.
15525
15526 (define_peephole2
15527   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15528                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15529                              UNSPEC_TAN_ONE))
15530              (set (match_operand:XF 1 "register_operand" "")
15531                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15532    (set (match_dup 0)
15533         (match_operand:XF 3 "immediate_operand" ""))]
15534   "standard_80387_constant_p (operands[3]) == 2"
15535   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15536              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15537   "")
15538
15539 (define_expand "tanxf2"
15540   [(parallel [(set (match_dup 2)
15541                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15542                               UNSPEC_TAN_ONE))
15543               (set (match_operand:XF 0 "register_operand" "")
15544                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15545   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15546    && flag_unsafe_math_optimizations"
15547 {
15548   operands[2] = gen_reg_rtx (XFmode);
15549 })
15550
15551 (define_insn "atan2df3_1"
15552   [(set (match_operand:DF 0 "register_operand" "=f")
15553         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15554                     (match_operand:DF 1 "register_operand" "u")]
15555                    UNSPEC_FPATAN))
15556    (clobber (match_scratch:DF 3 "=1"))]
15557   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15558    && flag_unsafe_math_optimizations"
15559   "fpatan"
15560   [(set_attr "type" "fpspc")
15561    (set_attr "mode" "DF")])
15562
15563 (define_expand "atan2df3"
15564   [(use (match_operand:DF 0 "register_operand" "=f"))
15565    (use (match_operand:DF 2 "register_operand" "0"))
15566    (use (match_operand:DF 1 "register_operand" "u"))]
15567   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15568    && flag_unsafe_math_optimizations"
15569 {
15570   rtx copy = gen_reg_rtx (DFmode);
15571   emit_move_insn (copy, operands[1]);
15572   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15573   DONE;
15574 })
15575
15576 (define_expand "atandf2"
15577   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15578                    (unspec:DF [(match_dup 2)
15579                                (match_operand:DF 1 "register_operand" "")]
15580                     UNSPEC_FPATAN))
15581               (clobber (match_scratch:DF 3 ""))])]
15582   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15583    && flag_unsafe_math_optimizations"
15584 {
15585   operands[2] = gen_reg_rtx (DFmode);
15586   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15587 })
15588
15589 (define_insn "atan2sf3_1"
15590   [(set (match_operand:SF 0 "register_operand" "=f")
15591         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15592                     (match_operand:SF 1 "register_operand" "u")]
15593                    UNSPEC_FPATAN))
15594    (clobber (match_scratch:SF 3 "=1"))]
15595   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15596    && flag_unsafe_math_optimizations"
15597   "fpatan"
15598   [(set_attr "type" "fpspc")
15599    (set_attr "mode" "SF")])
15600
15601 (define_expand "atan2sf3"
15602   [(use (match_operand:SF 0 "register_operand" "=f"))
15603    (use (match_operand:SF 2 "register_operand" "0"))
15604    (use (match_operand:SF 1 "register_operand" "u"))]
15605   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606    && flag_unsafe_math_optimizations"
15607 {
15608   rtx copy = gen_reg_rtx (SFmode);
15609   emit_move_insn (copy, operands[1]);
15610   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15611   DONE;
15612 })
15613
15614 (define_expand "atansf2"
15615   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15616                    (unspec:SF [(match_dup 2)
15617                                (match_operand:SF 1 "register_operand" "")]
15618                     UNSPEC_FPATAN))
15619               (clobber (match_scratch:SF 3 ""))])]
15620   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15621    && flag_unsafe_math_optimizations"
15622 {
15623   operands[2] = gen_reg_rtx (SFmode);
15624   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15625 })
15626
15627 (define_insn "atan2xf3_1"
15628   [(set (match_operand:XF 0 "register_operand" "=f")
15629         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15630                     (match_operand:XF 1 "register_operand" "u")]
15631                    UNSPEC_FPATAN))
15632    (clobber (match_scratch:XF 3 "=1"))]
15633   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15634    && flag_unsafe_math_optimizations"
15635   "fpatan"
15636   [(set_attr "type" "fpspc")
15637    (set_attr "mode" "XF")])
15638
15639 (define_expand "atan2xf3"
15640   [(use (match_operand:XF 0 "register_operand" "=f"))
15641    (use (match_operand:XF 2 "register_operand" "0"))
15642    (use (match_operand:XF 1 "register_operand" "u"))]
15643   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15644    && flag_unsafe_math_optimizations"
15645 {
15646   rtx copy = gen_reg_rtx (XFmode);
15647   emit_move_insn (copy, operands[1]);
15648   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15649   DONE;
15650 })
15651
15652 (define_expand "atanxf2"
15653   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15654                    (unspec:XF [(match_dup 2)
15655                                (match_operand:XF 1 "register_operand" "")]
15656                     UNSPEC_FPATAN))
15657               (clobber (match_scratch:XF 3 ""))])]
15658   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15659    && flag_unsafe_math_optimizations"
15660 {
15661   operands[2] = gen_reg_rtx (XFmode);
15662   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15663 })
15664
15665 (define_expand "asindf2"
15666   [(set (match_dup 2)
15667         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15668    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15669    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15670    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15671    (parallel [(set (match_dup 7)
15672                    (unspec:XF [(match_dup 6) (match_dup 2)]
15673                               UNSPEC_FPATAN))
15674               (clobber (match_scratch:XF 8 ""))])
15675    (set (match_operand:DF 0 "register_operand" "")
15676         (float_truncate:DF (match_dup 7)))]
15677   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678    && flag_unsafe_math_optimizations"
15679 {
15680   int i;
15681
15682   for (i=2; i<8; i++)
15683     operands[i] = gen_reg_rtx (XFmode);
15684
15685   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15686 })
15687
15688 (define_expand "asinsf2"
15689   [(set (match_dup 2)
15690         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15691    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15692    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15693    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15694    (parallel [(set (match_dup 7)
15695                    (unspec:XF [(match_dup 6) (match_dup 2)]
15696                               UNSPEC_FPATAN))
15697               (clobber (match_scratch:XF 8 ""))])
15698    (set (match_operand:SF 0 "register_operand" "")
15699         (float_truncate:SF (match_dup 7)))]
15700   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15701    && flag_unsafe_math_optimizations"
15702 {
15703   int i;
15704
15705   for (i=2; i<8; i++)
15706     operands[i] = gen_reg_rtx (XFmode);
15707
15708   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15709 })
15710
15711 (define_expand "asinxf2"
15712   [(set (match_dup 2)
15713         (mult:XF (match_operand:XF 1 "register_operand" "")
15714                  (match_dup 1)))
15715    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15716    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15717    (parallel [(set (match_operand:XF 0 "register_operand" "")
15718                    (unspec:XF [(match_dup 5) (match_dup 1)]
15719                               UNSPEC_FPATAN))
15720               (clobber (match_scratch:XF 6 ""))])]
15721   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15722    && flag_unsafe_math_optimizations"
15723 {
15724   int i;
15725
15726   for (i=2; i<6; i++)
15727     operands[i] = gen_reg_rtx (XFmode);
15728
15729   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15730 })
15731
15732 (define_expand "acosdf2"
15733   [(set (match_dup 2)
15734         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15735    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15736    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15737    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15738    (parallel [(set (match_dup 7)
15739                    (unspec:XF [(match_dup 2) (match_dup 6)]
15740                               UNSPEC_FPATAN))
15741               (clobber (match_scratch:XF 8 ""))])
15742    (set (match_operand:DF 0 "register_operand" "")
15743         (float_truncate:DF (match_dup 7)))]
15744   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15745    && flag_unsafe_math_optimizations"
15746 {
15747   int i;
15748
15749   for (i=2; i<8; i++)
15750     operands[i] = gen_reg_rtx (XFmode);
15751
15752   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15753 })
15754
15755 (define_expand "acossf2"
15756   [(set (match_dup 2)
15757         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15758    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15759    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15760    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15761    (parallel [(set (match_dup 7)
15762                    (unspec:XF [(match_dup 2) (match_dup 6)]
15763                               UNSPEC_FPATAN))
15764               (clobber (match_scratch:XF 8 ""))])
15765    (set (match_operand:SF 0 "register_operand" "")
15766         (float_truncate:SF (match_dup 7)))]
15767   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15768    && flag_unsafe_math_optimizations"
15769 {
15770   int i;
15771
15772   for (i=2; i<8; i++)
15773     operands[i] = gen_reg_rtx (XFmode);
15774
15775   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15776 })
15777
15778 (define_expand "acosxf2"
15779   [(set (match_dup 2)
15780         (mult:XF (match_operand:XF 1 "register_operand" "")
15781                  (match_dup 1)))
15782    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15783    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15784    (parallel [(set (match_operand:XF 0 "register_operand" "")
15785                    (unspec:XF [(match_dup 1) (match_dup 5)]
15786                               UNSPEC_FPATAN))
15787               (clobber (match_scratch:XF 6 ""))])]
15788   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15789    && flag_unsafe_math_optimizations"
15790 {
15791   int i;
15792
15793   for (i=2; i<6; i++)
15794     operands[i] = gen_reg_rtx (XFmode);
15795
15796   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15797 })
15798
15799 (define_insn "fyl2x_xf3"
15800   [(set (match_operand:XF 0 "register_operand" "=f")
15801         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15802                     (match_operand:XF 1 "register_operand" "u")]
15803                    UNSPEC_FYL2X))
15804    (clobber (match_scratch:XF 3 "=1"))]
15805   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15806    && flag_unsafe_math_optimizations"
15807   "fyl2x"
15808   [(set_attr "type" "fpspc")
15809    (set_attr "mode" "XF")])
15810
15811 (define_expand "logsf2"
15812   [(set (match_dup 2)
15813         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15814    (parallel [(set (match_dup 4)
15815                    (unspec:XF [(match_dup 2)
15816                                (match_dup 3)] UNSPEC_FYL2X))
15817               (clobber (match_scratch:XF 5 ""))])
15818    (set (match_operand:SF 0 "register_operand" "")
15819         (float_truncate:SF (match_dup 4)))]
15820   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15821    && flag_unsafe_math_optimizations"
15822 {
15823   rtx temp;
15824
15825   operands[2] = gen_reg_rtx (XFmode);
15826   operands[3] = gen_reg_rtx (XFmode);
15827   operands[4] = gen_reg_rtx (XFmode);
15828
15829   temp = standard_80387_constant_rtx (4); /* fldln2 */
15830   emit_move_insn (operands[3], temp);
15831 })
15832
15833 (define_expand "logdf2"
15834   [(set (match_dup 2)
15835         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15836    (parallel [(set (match_dup 4)
15837                    (unspec:XF [(match_dup 2)
15838                                (match_dup 3)] UNSPEC_FYL2X))
15839               (clobber (match_scratch:XF 5 ""))])
15840    (set (match_operand:DF 0 "register_operand" "")
15841         (float_truncate:DF (match_dup 4)))]
15842   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15843    && flag_unsafe_math_optimizations"
15844 {
15845   rtx temp;
15846
15847   operands[2] = gen_reg_rtx (XFmode);
15848   operands[3] = gen_reg_rtx (XFmode);
15849   operands[4] = gen_reg_rtx (XFmode);
15850
15851   temp = standard_80387_constant_rtx (4); /* fldln2 */
15852   emit_move_insn (operands[3], temp);
15853 })
15854
15855 (define_expand "logxf2"
15856   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15857                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15858                                (match_dup 2)] UNSPEC_FYL2X))
15859               (clobber (match_scratch:XF 3 ""))])]
15860   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15861    && flag_unsafe_math_optimizations"
15862 {
15863   rtx temp;
15864
15865   operands[2] = gen_reg_rtx (XFmode);
15866   temp = standard_80387_constant_rtx (4); /* fldln2 */
15867   emit_move_insn (operands[2], temp);
15868 })
15869
15870 (define_expand "log10sf2"
15871   [(set (match_dup 2)
15872         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15873    (parallel [(set (match_dup 4)
15874                    (unspec:XF [(match_dup 2)
15875                                (match_dup 3)] UNSPEC_FYL2X))
15876               (clobber (match_scratch:XF 5 ""))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 4)))]
15879   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15880    && flag_unsafe_math_optimizations"
15881 {
15882   rtx temp;
15883
15884   operands[2] = gen_reg_rtx (XFmode);
15885   operands[3] = gen_reg_rtx (XFmode);
15886   operands[4] = gen_reg_rtx (XFmode);
15887
15888   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15889   emit_move_insn (operands[3], temp);
15890 })
15891
15892 (define_expand "log10df2"
15893   [(set (match_dup 2)
15894         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15895    (parallel [(set (match_dup 4)
15896                    (unspec:XF [(match_dup 2)
15897                                (match_dup 3)] UNSPEC_FYL2X))
15898               (clobber (match_scratch:XF 5 ""))])
15899    (set (match_operand:DF 0 "register_operand" "")
15900         (float_truncate:DF (match_dup 4)))]
15901   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15902    && flag_unsafe_math_optimizations"
15903 {
15904   rtx temp;
15905
15906   operands[2] = gen_reg_rtx (XFmode);
15907   operands[3] = gen_reg_rtx (XFmode);
15908   operands[4] = gen_reg_rtx (XFmode);
15909
15910   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15911   emit_move_insn (operands[3], temp);
15912 })
15913
15914 (define_expand "log10xf2"
15915   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15916                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15917                                (match_dup 2)] UNSPEC_FYL2X))
15918               (clobber (match_scratch:XF 3 ""))])]
15919   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15920    && flag_unsafe_math_optimizations"
15921 {
15922   rtx temp;
15923
15924   operands[2] = gen_reg_rtx (XFmode);
15925   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15926   emit_move_insn (operands[2], temp);
15927 })
15928
15929 (define_expand "log2sf2"
15930   [(set (match_dup 2)
15931         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15932    (parallel [(set (match_dup 4)
15933                    (unspec:XF [(match_dup 2)
15934                                (match_dup 3)] UNSPEC_FYL2X))
15935               (clobber (match_scratch:XF 5 ""))])
15936    (set (match_operand:SF 0 "register_operand" "")
15937         (float_truncate:SF (match_dup 4)))]
15938   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15939    && flag_unsafe_math_optimizations"
15940 {
15941   operands[2] = gen_reg_rtx (XFmode);
15942   operands[3] = gen_reg_rtx (XFmode);
15943   operands[4] = gen_reg_rtx (XFmode);
15944
15945   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15946 })
15947
15948 (define_expand "log2df2"
15949   [(set (match_dup 2)
15950         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15951    (parallel [(set (match_dup 4)
15952                    (unspec:XF [(match_dup 2)
15953                                (match_dup 3)] UNSPEC_FYL2X))
15954               (clobber (match_scratch:XF 5 ""))])
15955    (set (match_operand:DF 0 "register_operand" "")
15956         (float_truncate:DF (match_dup 4)))]
15957   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15958    && flag_unsafe_math_optimizations"
15959 {
15960   operands[2] = gen_reg_rtx (XFmode);
15961   operands[3] = gen_reg_rtx (XFmode);
15962   operands[4] = gen_reg_rtx (XFmode);
15963
15964   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15965 })
15966
15967 (define_expand "log2xf2"
15968   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15969                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15970                                (match_dup 2)] UNSPEC_FYL2X))
15971               (clobber (match_scratch:XF 3 ""))])]
15972   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15973    && flag_unsafe_math_optimizations"
15974 {
15975   operands[2] = gen_reg_rtx (XFmode);
15976   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15977 })
15978
15979 (define_insn "fyl2xp1_xf3"
15980   [(set (match_operand:XF 0 "register_operand" "=f")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15982                     (match_operand:XF 1 "register_operand" "u")]
15983                    UNSPEC_FYL2XP1))
15984    (clobber (match_scratch:XF 3 "=1"))]
15985   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15986    && flag_unsafe_math_optimizations"
15987   "fyl2xp1"
15988   [(set_attr "type" "fpspc")
15989    (set_attr "mode" "XF")])
15990
15991 (define_expand "log1psf2"
15992   [(use (match_operand:XF 0 "register_operand" ""))
15993    (use (match_operand:XF 1 "register_operand" ""))]
15994   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15995    && flag_unsafe_math_optimizations"
15996 {
15997   rtx op0 = gen_reg_rtx (XFmode);
15998   rtx op1 = gen_reg_rtx (XFmode);
15999
16000   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16001   ix86_emit_i387_log1p (op0, op1);
16002   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16003   DONE;
16004 })
16005
16006 (define_expand "log1pdf2"
16007   [(use (match_operand:XF 0 "register_operand" ""))
16008    (use (match_operand:XF 1 "register_operand" ""))]
16009   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16010    && flag_unsafe_math_optimizations"
16011 {
16012   rtx op0 = gen_reg_rtx (XFmode);
16013   rtx op1 = gen_reg_rtx (XFmode);
16014
16015   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16016   ix86_emit_i387_log1p (op0, op1);
16017   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16018   DONE;
16019 })
16020
16021 (define_expand "log1pxf2"
16022   [(use (match_operand:XF 0 "register_operand" ""))
16023    (use (match_operand:XF 1 "register_operand" ""))]
16024   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16025    && flag_unsafe_math_optimizations"
16026 {
16027   ix86_emit_i387_log1p (operands[0], operands[1]);
16028   DONE;
16029 })
16030
16031 (define_insn "*fxtractxf3"
16032   [(set (match_operand:XF 0 "register_operand" "=f")
16033         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16034                    UNSPEC_XTRACT_FRACT))
16035    (set (match_operand:XF 1 "register_operand" "=u")
16036         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16037   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16038    && flag_unsafe_math_optimizations"
16039   "fxtract"
16040   [(set_attr "type" "fpspc")
16041    (set_attr "mode" "XF")])
16042
16043 (define_expand "logbsf2"
16044   [(set (match_dup 2)
16045         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16046    (parallel [(set (match_dup 3)
16047                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16048               (set (match_dup 4)
16049                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16050    (set (match_operand:SF 0 "register_operand" "")
16051         (float_truncate:SF (match_dup 4)))]
16052   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16053    && flag_unsafe_math_optimizations"
16054 {
16055   operands[2] = gen_reg_rtx (XFmode);
16056   operands[3] = gen_reg_rtx (XFmode);
16057   operands[4] = gen_reg_rtx (XFmode);
16058 })
16059
16060 (define_expand "logbdf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16063    (parallel [(set (match_dup 3)
16064                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16065               (set (match_dup 4)
16066                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16067    (set (match_operand:DF 0 "register_operand" "")
16068         (float_truncate:DF (match_dup 4)))]
16069   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16070    && flag_unsafe_math_optimizations"
16071 {
16072   operands[2] = gen_reg_rtx (XFmode);
16073   operands[3] = gen_reg_rtx (XFmode);
16074   operands[4] = gen_reg_rtx (XFmode);
16075 })
16076
16077 (define_expand "logbxf2"
16078   [(parallel [(set (match_dup 2)
16079                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16080                               UNSPEC_XTRACT_FRACT))
16081               (set (match_operand:XF 0 "register_operand" "")
16082                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16083   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16084    && flag_unsafe_math_optimizations"
16085 {
16086   operands[2] = gen_reg_rtx (XFmode);
16087 })
16088
16089 (define_expand "ilogbsi2"
16090   [(parallel [(set (match_dup 2)
16091                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16092                               UNSPEC_XTRACT_FRACT))
16093               (set (match_operand:XF 3 "register_operand" "")
16094                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16095    (parallel [(set (match_operand:SI 0 "register_operand" "")
16096                    (fix:SI (match_dup 3)))
16097               (clobber (reg:CC FLAGS_REG))])]
16098   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16099    && flag_unsafe_math_optimizations"
16100 {
16101   operands[2] = gen_reg_rtx (XFmode);
16102   operands[3] = gen_reg_rtx (XFmode);
16103 })
16104
16105 (define_insn "*f2xm1xf2"
16106   [(set (match_operand:XF 0 "register_operand" "=f")
16107         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16108          UNSPEC_F2XM1))]
16109   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16110    && flag_unsafe_math_optimizations"
16111   "f2xm1"
16112   [(set_attr "type" "fpspc")
16113    (set_attr "mode" "XF")])
16114
16115 (define_insn "*fscalexf4"
16116   [(set (match_operand:XF 0 "register_operand" "=f")
16117         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16118                     (match_operand:XF 3 "register_operand" "1")]
16119                    UNSPEC_FSCALE_FRACT))
16120    (set (match_operand:XF 1 "register_operand" "=u")
16121         (unspec:XF [(match_dup 2) (match_dup 3)]
16122                    UNSPEC_FSCALE_EXP))]
16123   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16124    && flag_unsafe_math_optimizations"
16125   "fscale"
16126   [(set_attr "type" "fpspc")
16127    (set_attr "mode" "XF")])
16128
16129 (define_expand "expsf2"
16130   [(set (match_dup 2)
16131         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16132    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16133    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16134    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16135    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16136    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16137    (parallel [(set (match_dup 10)
16138                    (unspec:XF [(match_dup 9) (match_dup 5)]
16139                               UNSPEC_FSCALE_FRACT))
16140               (set (match_dup 11)
16141                    (unspec:XF [(match_dup 9) (match_dup 5)]
16142                               UNSPEC_FSCALE_EXP))])
16143    (set (match_operand:SF 0 "register_operand" "")
16144         (float_truncate:SF (match_dup 10)))]
16145   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16146    && flag_unsafe_math_optimizations"
16147 {
16148   rtx temp;
16149   int i;
16150
16151   for (i=2; i<12; i++)
16152     operands[i] = gen_reg_rtx (XFmode);
16153   temp = standard_80387_constant_rtx (5); /* fldl2e */
16154   emit_move_insn (operands[3], temp);
16155   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16156 })
16157
16158 (define_expand "expdf2"
16159   [(set (match_dup 2)
16160         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16161    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16162    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16163    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16164    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16165    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16166    (parallel [(set (match_dup 10)
16167                    (unspec:XF [(match_dup 9) (match_dup 5)]
16168                               UNSPEC_FSCALE_FRACT))
16169               (set (match_dup 11)
16170                    (unspec:XF [(match_dup 9) (match_dup 5)]
16171                               UNSPEC_FSCALE_EXP))])
16172    (set (match_operand:DF 0 "register_operand" "")
16173         (float_truncate:DF (match_dup 10)))]
16174   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16175    && flag_unsafe_math_optimizations"
16176 {
16177   rtx temp;
16178   int i;
16179
16180   for (i=2; i<12; i++)
16181     operands[i] = gen_reg_rtx (XFmode);
16182   temp = standard_80387_constant_rtx (5); /* fldl2e */
16183   emit_move_insn (operands[3], temp);
16184   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16185 })
16186
16187 (define_expand "expxf2"
16188   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16189                                (match_dup 2)))
16190    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16191    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16192    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16193    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16194    (parallel [(set (match_operand:XF 0 "register_operand" "")
16195                    (unspec:XF [(match_dup 8) (match_dup 4)]
16196                               UNSPEC_FSCALE_FRACT))
16197               (set (match_dup 9)
16198                    (unspec:XF [(match_dup 8) (match_dup 4)]
16199                               UNSPEC_FSCALE_EXP))])]
16200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16201    && flag_unsafe_math_optimizations"
16202 {
16203   rtx temp;
16204   int i;
16205
16206   for (i=2; i<10; i++)
16207     operands[i] = gen_reg_rtx (XFmode);
16208   temp = standard_80387_constant_rtx (5); /* fldl2e */
16209   emit_move_insn (operands[2], temp);
16210   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16211 })
16212
16213 (define_expand "exp10sf2"
16214   [(set (match_dup 2)
16215         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16216    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16217    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16218    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16219    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16220    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16221    (parallel [(set (match_dup 10)
16222                    (unspec:XF [(match_dup 9) (match_dup 5)]
16223                               UNSPEC_FSCALE_FRACT))
16224               (set (match_dup 11)
16225                    (unspec:XF [(match_dup 9) (match_dup 5)]
16226                               UNSPEC_FSCALE_EXP))])
16227    (set (match_operand:SF 0 "register_operand" "")
16228         (float_truncate:SF (match_dup 10)))]
16229   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16230    && flag_unsafe_math_optimizations"
16231 {
16232   rtx temp;
16233   int i;
16234
16235   for (i=2; i<12; i++)
16236     operands[i] = gen_reg_rtx (XFmode);
16237   temp = standard_80387_constant_rtx (6); /* fldl2t */
16238   emit_move_insn (operands[3], temp);
16239   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16240 })
16241
16242 (define_expand "exp10df2"
16243   [(set (match_dup 2)
16244         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16245    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16246    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16247    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16248    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16249    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16250    (parallel [(set (match_dup 10)
16251                    (unspec:XF [(match_dup 9) (match_dup 5)]
16252                               UNSPEC_FSCALE_FRACT))
16253               (set (match_dup 11)
16254                    (unspec:XF [(match_dup 9) (match_dup 5)]
16255                               UNSPEC_FSCALE_EXP))])
16256    (set (match_operand:DF 0 "register_operand" "")
16257         (float_truncate:DF (match_dup 10)))]
16258   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16259    && flag_unsafe_math_optimizations"
16260 {
16261   rtx temp;
16262   int i;
16263
16264   for (i=2; i<12; i++)
16265     operands[i] = gen_reg_rtx (XFmode);
16266   temp = standard_80387_constant_rtx (6); /* fldl2t */
16267   emit_move_insn (operands[3], temp);
16268   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16269 })
16270
16271 (define_expand "exp10xf2"
16272   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16273                                (match_dup 2)))
16274    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16275    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16276    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16277    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16278    (parallel [(set (match_operand:XF 0 "register_operand" "")
16279                    (unspec:XF [(match_dup 8) (match_dup 4)]
16280                               UNSPEC_FSCALE_FRACT))
16281               (set (match_dup 9)
16282                    (unspec:XF [(match_dup 8) (match_dup 4)]
16283                               UNSPEC_FSCALE_EXP))])]
16284   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16285    && flag_unsafe_math_optimizations"
16286 {
16287   rtx temp;
16288   int i;
16289
16290   for (i=2; i<10; i++)
16291     operands[i] = gen_reg_rtx (XFmode);
16292   temp = standard_80387_constant_rtx (6); /* fldl2t */
16293   emit_move_insn (operands[2], temp);
16294   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16295 })
16296
16297 (define_expand "exp2sf2"
16298   [(set (match_dup 2)
16299         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16300    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16301    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16302    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16303    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16304    (parallel [(set (match_dup 8)
16305                    (unspec:XF [(match_dup 7) (match_dup 3)]
16306                               UNSPEC_FSCALE_FRACT))
16307               (set (match_dup 9)
16308                    (unspec:XF [(match_dup 7) (match_dup 3)]
16309                               UNSPEC_FSCALE_EXP))])
16310    (set (match_operand:SF 0 "register_operand" "")
16311         (float_truncate:SF (match_dup 8)))]
16312   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16313    && flag_unsafe_math_optimizations"
16314 {
16315   int i;
16316
16317   for (i=2; i<10; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16320 })
16321
16322 (define_expand "exp2df2"
16323   [(set (match_dup 2)
16324         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16326    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16327    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16328    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16329    (parallel [(set (match_dup 8)
16330                    (unspec:XF [(match_dup 7) (match_dup 3)]
16331                               UNSPEC_FSCALE_FRACT))
16332               (set (match_dup 9)
16333                    (unspec:XF [(match_dup 7) (match_dup 3)]
16334                               UNSPEC_FSCALE_EXP))])
16335    (set (match_operand:DF 0 "register_operand" "")
16336         (float_truncate:DF (match_dup 8)))]
16337   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16338    && flag_unsafe_math_optimizations"
16339 {
16340   int i;
16341
16342   for (i=2; i<10; i++)
16343     operands[i] = gen_reg_rtx (XFmode);
16344   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16345 })
16346
16347 (define_expand "exp2xf2"
16348   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16349    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16350    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16351    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16352    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16353    (parallel [(set (match_operand:XF 0 "register_operand" "")
16354                    (unspec:XF [(match_dup 7) (match_dup 3)]
16355                               UNSPEC_FSCALE_FRACT))
16356               (set (match_dup 8)
16357                    (unspec:XF [(match_dup 7) (match_dup 3)]
16358                               UNSPEC_FSCALE_EXP))])]
16359   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16360    && flag_unsafe_math_optimizations"
16361 {
16362   int i;
16363
16364   for (i=2; i<9; i++)
16365     operands[i] = gen_reg_rtx (XFmode);
16366   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16367 })
16368
16369 (define_expand "expm1df2"
16370   [(set (match_dup 2)
16371         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16372    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16373    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16374    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16375    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16376    (parallel [(set (match_dup 8)
16377                    (unspec:XF [(match_dup 7) (match_dup 5)]
16378                               UNSPEC_FSCALE_FRACT))
16379                    (set (match_dup 9)
16380                    (unspec:XF [(match_dup 7) (match_dup 5)]
16381                               UNSPEC_FSCALE_EXP))])
16382    (parallel [(set (match_dup 11)
16383                    (unspec:XF [(match_dup 10) (match_dup 9)]
16384                               UNSPEC_FSCALE_FRACT))
16385               (set (match_dup 12)
16386                    (unspec:XF [(match_dup 10) (match_dup 9)]
16387                               UNSPEC_FSCALE_EXP))])
16388    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16389    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16390    (set (match_operand:DF 0 "register_operand" "")
16391         (float_truncate:DF (match_dup 14)))]
16392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16393    && flag_unsafe_math_optimizations"
16394 {
16395   rtx temp;
16396   int i;
16397
16398   for (i=2; i<15; i++)
16399     operands[i] = gen_reg_rtx (XFmode);
16400   temp = standard_80387_constant_rtx (5); /* fldl2e */
16401   emit_move_insn (operands[3], temp);
16402   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16403 })
16404
16405 (define_expand "expm1sf2"
16406   [(set (match_dup 2)
16407         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16408    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16409    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16410    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16411    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16412    (parallel [(set (match_dup 8)
16413                    (unspec:XF [(match_dup 7) (match_dup 5)]
16414                               UNSPEC_FSCALE_FRACT))
16415                    (set (match_dup 9)
16416                    (unspec:XF [(match_dup 7) (match_dup 5)]
16417                               UNSPEC_FSCALE_EXP))])
16418    (parallel [(set (match_dup 11)
16419                    (unspec:XF [(match_dup 10) (match_dup 9)]
16420                               UNSPEC_FSCALE_FRACT))
16421               (set (match_dup 12)
16422                    (unspec:XF [(match_dup 10) (match_dup 9)]
16423                               UNSPEC_FSCALE_EXP))])
16424    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16425    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16426    (set (match_operand:SF 0 "register_operand" "")
16427         (float_truncate:SF (match_dup 14)))]
16428   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16429    && flag_unsafe_math_optimizations"
16430 {
16431   rtx temp;
16432   int i;
16433
16434   for (i=2; i<15; i++)
16435     operands[i] = gen_reg_rtx (XFmode);
16436   temp = standard_80387_constant_rtx (5); /* fldl2e */
16437   emit_move_insn (operands[3], temp);
16438   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16439 })
16440
16441 (define_expand "expm1xf2"
16442   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16443                                (match_dup 2)))
16444    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16445    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16446    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16447    (parallel [(set (match_dup 7)
16448                    (unspec:XF [(match_dup 6) (match_dup 4)]
16449                               UNSPEC_FSCALE_FRACT))
16450                    (set (match_dup 8)
16451                    (unspec:XF [(match_dup 6) (match_dup 4)]
16452                               UNSPEC_FSCALE_EXP))])
16453    (parallel [(set (match_dup 10)
16454                    (unspec:XF [(match_dup 9) (match_dup 8)]
16455                               UNSPEC_FSCALE_FRACT))
16456               (set (match_dup 11)
16457                    (unspec:XF [(match_dup 9) (match_dup 8)]
16458                               UNSPEC_FSCALE_EXP))])
16459    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16460    (set (match_operand:XF 0 "register_operand" "")
16461         (plus:XF (match_dup 12) (match_dup 7)))]
16462   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16463    && flag_unsafe_math_optimizations"
16464 {
16465   rtx temp;
16466   int i;
16467
16468   for (i=2; i<13; i++)
16469     operands[i] = gen_reg_rtx (XFmode);
16470   temp = standard_80387_constant_rtx (5); /* fldl2e */
16471   emit_move_insn (operands[2], temp);
16472   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16473 })
16474 \f
16475
16476 (define_insn "frndintxf2"
16477   [(set (match_operand:XF 0 "register_operand" "=f")
16478         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16479          UNSPEC_FRNDINT))]
16480   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16481    && flag_unsafe_math_optimizations"
16482   "frndint"
16483   [(set_attr "type" "fpspc")
16484    (set_attr "mode" "XF")])
16485
16486 (define_expand "rintdf2"
16487   [(use (match_operand:DF 0 "register_operand" ""))
16488    (use (match_operand:DF 1 "register_operand" ""))]
16489   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16490    && flag_unsafe_math_optimizations"
16491 {
16492   rtx op0 = gen_reg_rtx (XFmode);
16493   rtx op1 = gen_reg_rtx (XFmode);
16494
16495   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16496   emit_insn (gen_frndintxf2 (op0, op1));
16497
16498   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16499   DONE;
16500 })
16501
16502 (define_expand "rintsf2"
16503   [(use (match_operand:SF 0 "register_operand" ""))
16504    (use (match_operand:SF 1 "register_operand" ""))]
16505   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16506    && flag_unsafe_math_optimizations"
16507 {
16508   rtx op0 = gen_reg_rtx (XFmode);
16509   rtx op1 = gen_reg_rtx (XFmode);
16510
16511   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16512   emit_insn (gen_frndintxf2 (op0, op1));
16513
16514   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16515   DONE;
16516 })
16517
16518 (define_expand "rintxf2"
16519   [(use (match_operand:XF 0 "register_operand" ""))
16520    (use (match_operand:XF 1 "register_operand" ""))]
16521   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16522    && flag_unsafe_math_optimizations"
16523 {
16524   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16525   DONE;
16526 })
16527
16528 (define_insn "frndintxf2_floor"
16529   [(set (match_operand:XF 0 "register_operand" "=f")
16530         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16531          UNSPEC_FRNDINT_FLOOR))
16532    (use (match_operand:HI 2 "memory_operand" "m"))
16533    (use (match_operand:HI 3 "memory_operand" "m"))]
16534   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16535    && flag_unsafe_math_optimizations"
16536   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16537   [(set_attr "type" "frndint")
16538    (set_attr "i387_cw" "floor")
16539    (set_attr "mode" "XF")])
16540
16541 (define_expand "floordf2"
16542   [(use (match_operand:DF 0 "register_operand" ""))
16543    (use (match_operand:DF 1 "register_operand" ""))]
16544   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16545    && flag_unsafe_math_optimizations"
16546 {
16547   rtx op0 = gen_reg_rtx (XFmode);
16548   rtx op1 = gen_reg_rtx (XFmode);
16549   rtx op2 = assign_386_stack_local (HImode, 1);
16550   rtx op3 = assign_386_stack_local (HImode, 2);
16551         
16552   ix86_optimize_mode_switching = 1;
16553
16554   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16555   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16556
16557   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16558   DONE;
16559 })
16560
16561 (define_expand "floorsf2"
16562   [(use (match_operand:SF 0 "register_operand" ""))
16563    (use (match_operand:SF 1 "register_operand" ""))]
16564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16565    && flag_unsafe_math_optimizations"
16566 {
16567   rtx op0 = gen_reg_rtx (XFmode);
16568   rtx op1 = gen_reg_rtx (XFmode);
16569   rtx op2 = assign_386_stack_local (HImode, 1);
16570   rtx op3 = assign_386_stack_local (HImode, 2);
16571         
16572   ix86_optimize_mode_switching = 1;
16573
16574   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16575   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16576
16577   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16578   DONE;
16579 })
16580
16581 (define_expand "floorxf2"
16582   [(use (match_operand:XF 0 "register_operand" ""))
16583    (use (match_operand:XF 1 "register_operand" ""))]
16584   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16585    && flag_unsafe_math_optimizations"
16586 {
16587   rtx op2 = assign_386_stack_local (HImode, 1);
16588   rtx op3 = assign_386_stack_local (HImode, 2);
16589         
16590   ix86_optimize_mode_switching = 1;
16591
16592   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16593   DONE;
16594 })
16595
16596 (define_insn "frndintxf2_ceil"
16597   [(set (match_operand:XF 0 "register_operand" "=f")
16598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16599          UNSPEC_FRNDINT_CEIL))
16600    (use (match_operand:HI 2 "memory_operand" "m"))
16601    (use (match_operand:HI 3 "memory_operand" "m"))]
16602   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16603    && flag_unsafe_math_optimizations"
16604   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16605   [(set_attr "type" "frndint")
16606    (set_attr "i387_cw" "ceil")
16607    (set_attr "mode" "XF")])
16608
16609 (define_expand "ceildf2"
16610   [(use (match_operand:DF 0 "register_operand" ""))
16611    (use (match_operand:DF 1 "register_operand" ""))]
16612   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16613    && flag_unsafe_math_optimizations"
16614 {
16615   rtx op0 = gen_reg_rtx (XFmode);
16616   rtx op1 = gen_reg_rtx (XFmode);
16617   rtx op2 = assign_386_stack_local (HImode, 1);
16618   rtx op3 = assign_386_stack_local (HImode, 2);
16619         
16620   ix86_optimize_mode_switching = 1;
16621
16622   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16623   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16624
16625   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16626   DONE;
16627 })
16628
16629 (define_expand "ceilsf2"
16630   [(use (match_operand:SF 0 "register_operand" ""))
16631    (use (match_operand:SF 1 "register_operand" ""))]
16632   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16633    && flag_unsafe_math_optimizations"
16634 {
16635   rtx op0 = gen_reg_rtx (XFmode);
16636   rtx op1 = gen_reg_rtx (XFmode);
16637   rtx op2 = assign_386_stack_local (HImode, 1);
16638   rtx op3 = assign_386_stack_local (HImode, 2);
16639         
16640   ix86_optimize_mode_switching = 1;
16641
16642   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16643   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16644
16645   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16646   DONE;
16647 })
16648
16649 (define_expand "ceilxf2"
16650   [(use (match_operand:XF 0 "register_operand" ""))
16651    (use (match_operand:XF 1 "register_operand" ""))]
16652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16653    && flag_unsafe_math_optimizations"
16654 {
16655   rtx op2 = assign_386_stack_local (HImode, 1);
16656   rtx op3 = assign_386_stack_local (HImode, 2);
16657         
16658   ix86_optimize_mode_switching = 1;
16659
16660   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16661   DONE;
16662 })
16663
16664 (define_insn "frndintxf2_trunc"
16665   [(set (match_operand:XF 0 "register_operand" "=f")
16666         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16667          UNSPEC_FRNDINT_TRUNC))
16668    (use (match_operand:HI 2 "memory_operand" "m"))
16669    (use (match_operand:HI 3 "memory_operand" "m"))]
16670   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16671    && flag_unsafe_math_optimizations"
16672   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16673   [(set_attr "type" "frndint")
16674    (set_attr "i387_cw" "trunc")
16675    (set_attr "mode" "XF")])
16676
16677 (define_expand "btruncdf2"
16678   [(use (match_operand:DF 0 "register_operand" ""))
16679    (use (match_operand:DF 1 "register_operand" ""))]
16680   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16681    && flag_unsafe_math_optimizations"
16682 {
16683   rtx op0 = gen_reg_rtx (XFmode);
16684   rtx op1 = gen_reg_rtx (XFmode);
16685   rtx op2 = assign_386_stack_local (HImode, 1);
16686   rtx op3 = assign_386_stack_local (HImode, 2);
16687         
16688   ix86_optimize_mode_switching = 1;
16689
16690   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16691   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16692
16693   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16694   DONE;
16695 })
16696
16697 (define_expand "btruncsf2"
16698   [(use (match_operand:SF 0 "register_operand" ""))
16699    (use (match_operand:SF 1 "register_operand" ""))]
16700   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16701    && flag_unsafe_math_optimizations"
16702 {
16703   rtx op0 = gen_reg_rtx (XFmode);
16704   rtx op1 = gen_reg_rtx (XFmode);
16705   rtx op2 = assign_386_stack_local (HImode, 1);
16706   rtx op3 = assign_386_stack_local (HImode, 2);
16707         
16708   ix86_optimize_mode_switching = 1;
16709
16710   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16711   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16712
16713   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16714   DONE;
16715 })
16716
16717 (define_expand "btruncxf2"
16718   [(use (match_operand:XF 0 "register_operand" ""))
16719    (use (match_operand:XF 1 "register_operand" ""))]
16720   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16721    && flag_unsafe_math_optimizations"
16722 {
16723   rtx op2 = assign_386_stack_local (HImode, 1);
16724   rtx op3 = assign_386_stack_local (HImode, 2);
16725         
16726   ix86_optimize_mode_switching = 1;
16727
16728   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16729   DONE;
16730 })
16731
16732 (define_insn "frndintxf2_mask_pm"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16735          UNSPEC_FRNDINT_MASK_PM))
16736    (use (match_operand:HI 2 "memory_operand" "m"))
16737    (use (match_operand:HI 3 "memory_operand" "m"))]
16738   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16739    && flag_unsafe_math_optimizations"
16740   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16741   [(set_attr "type" "frndint")
16742    (set_attr "i387_cw" "mask_pm")
16743    (set_attr "mode" "XF")])
16744
16745 (define_expand "nearbyintdf2"
16746   [(use (match_operand:DF 0 "register_operand" ""))
16747    (use (match_operand:DF 1 "register_operand" ""))]
16748   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16749    && flag_unsafe_math_optimizations"
16750 {
16751   rtx op0 = gen_reg_rtx (XFmode);
16752   rtx op1 = gen_reg_rtx (XFmode);
16753   rtx op2 = assign_386_stack_local (HImode, 1);
16754   rtx op3 = assign_386_stack_local (HImode, 2);
16755         
16756   ix86_optimize_mode_switching = 1;
16757
16758   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16759   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16760
16761   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16762   DONE;
16763 })
16764
16765 (define_expand "nearbyintsf2"
16766   [(use (match_operand:SF 0 "register_operand" ""))
16767    (use (match_operand:SF 1 "register_operand" ""))]
16768   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16769    && flag_unsafe_math_optimizations"
16770 {
16771   rtx op0 = gen_reg_rtx (XFmode);
16772   rtx op1 = gen_reg_rtx (XFmode);
16773   rtx op2 = assign_386_stack_local (HImode, 1);
16774   rtx op3 = assign_386_stack_local (HImode, 2);
16775         
16776   ix86_optimize_mode_switching = 1;
16777
16778   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16779   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16780
16781   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16782   DONE;
16783 })
16784
16785 (define_expand "nearbyintxf2"
16786   [(use (match_operand:XF 0 "register_operand" ""))
16787    (use (match_operand:XF 1 "register_operand" ""))]
16788   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16789    && flag_unsafe_math_optimizations"
16790 {
16791   rtx op2 = assign_386_stack_local (HImode, 1);
16792   rtx op3 = assign_386_stack_local (HImode, 2);
16793         
16794   ix86_optimize_mode_switching = 1;
16795
16796   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16797                                      op2, op3));
16798   DONE;
16799 })
16800
16801 \f
16802 ;; Block operation instructions
16803
16804 (define_insn "cld"
16805  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16806  ""
16807  "cld"
16808   [(set_attr "type" "cld")])
16809
16810 (define_expand "movmemsi"
16811   [(use (match_operand:BLK 0 "memory_operand" ""))
16812    (use (match_operand:BLK 1 "memory_operand" ""))
16813    (use (match_operand:SI 2 "nonmemory_operand" ""))
16814    (use (match_operand:SI 3 "const_int_operand" ""))]
16815   "! optimize_size"
16816 {
16817  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16818    DONE;
16819  else
16820    FAIL;
16821 })
16822
16823 (define_expand "movmemdi"
16824   [(use (match_operand:BLK 0 "memory_operand" ""))
16825    (use (match_operand:BLK 1 "memory_operand" ""))
16826    (use (match_operand:DI 2 "nonmemory_operand" ""))
16827    (use (match_operand:DI 3 "const_int_operand" ""))]
16828   "TARGET_64BIT"
16829 {
16830  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16831    DONE;
16832  else
16833    FAIL;
16834 })
16835
16836 ;; Most CPUs don't like single string operations
16837 ;; Handle this case here to simplify previous expander.
16838
16839 (define_expand "strmov"
16840   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16841    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16842    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16843               (clobber (reg:CC FLAGS_REG))])
16844    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16845               (clobber (reg:CC FLAGS_REG))])]
16846   ""
16847 {
16848   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16849
16850   /* If .md ever supports :P for Pmode, these can be directly
16851      in the pattern above.  */
16852   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16853   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16854
16855   if (TARGET_SINGLE_STRINGOP || optimize_size)
16856     {
16857       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16858                                       operands[2], operands[3],
16859                                       operands[5], operands[6]));
16860       DONE;
16861     }
16862
16863   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16864 })
16865
16866 (define_expand "strmov_singleop"
16867   [(parallel [(set (match_operand 1 "memory_operand" "")
16868                    (match_operand 3 "memory_operand" ""))
16869               (set (match_operand 0 "register_operand" "")
16870                    (match_operand 4 "" ""))
16871               (set (match_operand 2 "register_operand" "")
16872                    (match_operand 5 "" ""))
16873               (use (reg:SI DIRFLAG_REG))])]
16874   "TARGET_SINGLE_STRINGOP || optimize_size"
16875   "")
16876
16877 (define_insn "*strmovdi_rex_1"
16878   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16879         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16880    (set (match_operand:DI 0 "register_operand" "=D")
16881         (plus:DI (match_dup 2)
16882                  (const_int 8)))
16883    (set (match_operand:DI 1 "register_operand" "=S")
16884         (plus:DI (match_dup 3)
16885                  (const_int 8)))
16886    (use (reg:SI DIRFLAG_REG))]
16887   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16888   "movsq"
16889   [(set_attr "type" "str")
16890    (set_attr "mode" "DI")
16891    (set_attr "memory" "both")])
16892
16893 (define_insn "*strmovsi_1"
16894   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16895         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16896    (set (match_operand:SI 0 "register_operand" "=D")
16897         (plus:SI (match_dup 2)
16898                  (const_int 4)))
16899    (set (match_operand:SI 1 "register_operand" "=S")
16900         (plus:SI (match_dup 3)
16901                  (const_int 4)))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16904   "{movsl|movsd}"
16905   [(set_attr "type" "str")
16906    (set_attr "mode" "SI")
16907    (set_attr "memory" "both")])
16908
16909 (define_insn "*strmovsi_rex_1"
16910   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16911         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16912    (set (match_operand:DI 0 "register_operand" "=D")
16913         (plus:DI (match_dup 2)
16914                  (const_int 4)))
16915    (set (match_operand:DI 1 "register_operand" "=S")
16916         (plus:DI (match_dup 3)
16917                  (const_int 4)))
16918    (use (reg:SI DIRFLAG_REG))]
16919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920   "{movsl|movsd}"
16921   [(set_attr "type" "str")
16922    (set_attr "mode" "SI")
16923    (set_attr "memory" "both")])
16924
16925 (define_insn "*strmovhi_1"
16926   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16927         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16928    (set (match_operand:SI 0 "register_operand" "=D")
16929         (plus:SI (match_dup 2)
16930                  (const_int 2)))
16931    (set (match_operand:SI 1 "register_operand" "=S")
16932         (plus:SI (match_dup 3)
16933                  (const_int 2)))
16934    (use (reg:SI DIRFLAG_REG))]
16935   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16936   "movsw"
16937   [(set_attr "type" "str")
16938    (set_attr "memory" "both")
16939    (set_attr "mode" "HI")])
16940
16941 (define_insn "*strmovhi_rex_1"
16942   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16943         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16944    (set (match_operand:DI 0 "register_operand" "=D")
16945         (plus:DI (match_dup 2)
16946                  (const_int 2)))
16947    (set (match_operand:DI 1 "register_operand" "=S")
16948         (plus:DI (match_dup 3)
16949                  (const_int 2)))
16950    (use (reg:SI DIRFLAG_REG))]
16951   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16952   "movsw"
16953   [(set_attr "type" "str")
16954    (set_attr "memory" "both")
16955    (set_attr "mode" "HI")])
16956
16957 (define_insn "*strmovqi_1"
16958   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16959         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16960    (set (match_operand:SI 0 "register_operand" "=D")
16961         (plus:SI (match_dup 2)
16962                  (const_int 1)))
16963    (set (match_operand:SI 1 "register_operand" "=S")
16964         (plus:SI (match_dup 3)
16965                  (const_int 1)))
16966    (use (reg:SI DIRFLAG_REG))]
16967   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16968   "movsb"
16969   [(set_attr "type" "str")
16970    (set_attr "memory" "both")
16971    (set_attr "mode" "QI")])
16972
16973 (define_insn "*strmovqi_rex_1"
16974   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16975         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16976    (set (match_operand:DI 0 "register_operand" "=D")
16977         (plus:DI (match_dup 2)
16978                  (const_int 1)))
16979    (set (match_operand:DI 1 "register_operand" "=S")
16980         (plus:DI (match_dup 3)
16981                  (const_int 1)))
16982    (use (reg:SI DIRFLAG_REG))]
16983   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16984   "movsb"
16985   [(set_attr "type" "str")
16986    (set_attr "memory" "both")
16987    (set_attr "mode" "QI")])
16988
16989 (define_expand "rep_mov"
16990   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16991               (set (match_operand 0 "register_operand" "")
16992                    (match_operand 5 "" ""))
16993               (set (match_operand 2 "register_operand" "")
16994                    (match_operand 6 "" ""))
16995               (set (match_operand 1 "memory_operand" "")
16996                    (match_operand 3 "memory_operand" ""))
16997               (use (match_dup 4))
16998               (use (reg:SI DIRFLAG_REG))])]
16999   ""
17000   "")
17001
17002 (define_insn "*rep_movdi_rex64"
17003   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17004    (set (match_operand:DI 0 "register_operand" "=D") 
17005         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17006                             (const_int 3))
17007                  (match_operand:DI 3 "register_operand" "0")))
17008    (set (match_operand:DI 1 "register_operand" "=S") 
17009         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17010                  (match_operand:DI 4 "register_operand" "1")))
17011    (set (mem:BLK (match_dup 3))
17012         (mem:BLK (match_dup 4)))
17013    (use (match_dup 5))
17014    (use (reg:SI DIRFLAG_REG))]
17015   "TARGET_64BIT"
17016   "{rep\;movsq|rep movsq}"
17017   [(set_attr "type" "str")
17018    (set_attr "prefix_rep" "1")
17019    (set_attr "memory" "both")
17020    (set_attr "mode" "DI")])
17021
17022 (define_insn "*rep_movsi"
17023   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17024    (set (match_operand:SI 0 "register_operand" "=D") 
17025         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17026                             (const_int 2))
17027                  (match_operand:SI 3 "register_operand" "0")))
17028    (set (match_operand:SI 1 "register_operand" "=S") 
17029         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17030                  (match_operand:SI 4 "register_operand" "1")))
17031    (set (mem:BLK (match_dup 3))
17032         (mem:BLK (match_dup 4)))
17033    (use (match_dup 5))
17034    (use (reg:SI DIRFLAG_REG))]
17035   "!TARGET_64BIT"
17036   "{rep\;movsl|rep movsd}"
17037   [(set_attr "type" "str")
17038    (set_attr "prefix_rep" "1")
17039    (set_attr "memory" "both")
17040    (set_attr "mode" "SI")])
17041
17042 (define_insn "*rep_movsi_rex64"
17043   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17044    (set (match_operand:DI 0 "register_operand" "=D") 
17045         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17046                             (const_int 2))
17047                  (match_operand:DI 3 "register_operand" "0")))
17048    (set (match_operand:DI 1 "register_operand" "=S") 
17049         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17050                  (match_operand:DI 4 "register_operand" "1")))
17051    (set (mem:BLK (match_dup 3))
17052         (mem:BLK (match_dup 4)))
17053    (use (match_dup 5))
17054    (use (reg:SI DIRFLAG_REG))]
17055   "TARGET_64BIT"
17056   "{rep\;movsl|rep movsd}"
17057   [(set_attr "type" "str")
17058    (set_attr "prefix_rep" "1")
17059    (set_attr "memory" "both")
17060    (set_attr "mode" "SI")])
17061
17062 (define_insn "*rep_movqi"
17063   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17064    (set (match_operand:SI 0 "register_operand" "=D") 
17065         (plus:SI (match_operand:SI 3 "register_operand" "0")
17066                  (match_operand:SI 5 "register_operand" "2")))
17067    (set (match_operand:SI 1 "register_operand" "=S") 
17068         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17069    (set (mem:BLK (match_dup 3))
17070         (mem:BLK (match_dup 4)))
17071    (use (match_dup 5))
17072    (use (reg:SI DIRFLAG_REG))]
17073   "!TARGET_64BIT"
17074   "{rep\;movsb|rep movsb}"
17075   [(set_attr "type" "str")
17076    (set_attr "prefix_rep" "1")
17077    (set_attr "memory" "both")
17078    (set_attr "mode" "SI")])
17079
17080 (define_insn "*rep_movqi_rex64"
17081   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17082    (set (match_operand:DI 0 "register_operand" "=D") 
17083         (plus:DI (match_operand:DI 3 "register_operand" "0")
17084                  (match_operand:DI 5 "register_operand" "2")))
17085    (set (match_operand:DI 1 "register_operand" "=S") 
17086         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17087    (set (mem:BLK (match_dup 3))
17088         (mem:BLK (match_dup 4)))
17089    (use (match_dup 5))
17090    (use (reg:SI DIRFLAG_REG))]
17091   "TARGET_64BIT"
17092   "{rep\;movsb|rep movsb}"
17093   [(set_attr "type" "str")
17094    (set_attr "prefix_rep" "1")
17095    (set_attr "memory" "both")
17096    (set_attr "mode" "SI")])
17097
17098 (define_expand "clrmemsi"
17099    [(use (match_operand:BLK 0 "memory_operand" ""))
17100     (use (match_operand:SI 1 "nonmemory_operand" ""))
17101     (use (match_operand 2 "const_int_operand" ""))]
17102   ""
17103 {
17104  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17105    DONE;
17106  else
17107    FAIL;
17108 })
17109
17110 (define_expand "clrmemdi"
17111    [(use (match_operand:BLK 0 "memory_operand" ""))
17112     (use (match_operand:DI 1 "nonmemory_operand" ""))
17113     (use (match_operand 2 "const_int_operand" ""))]
17114   "TARGET_64BIT"
17115 {
17116  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17117    DONE;
17118  else
17119    FAIL;
17120 })
17121
17122 ;; Most CPUs don't like single string operations
17123 ;; Handle this case here to simplify previous expander.
17124
17125 (define_expand "strset"
17126   [(set (match_operand 1 "memory_operand" "")
17127         (match_operand 2 "register_operand" ""))
17128    (parallel [(set (match_operand 0 "register_operand" "")
17129                    (match_dup 3))
17130               (clobber (reg:CC FLAGS_REG))])]
17131   ""
17132 {
17133   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17134     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17135
17136   /* If .md ever supports :P for Pmode, this can be directly
17137      in the pattern above.  */
17138   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17139                               GEN_INT (GET_MODE_SIZE (GET_MODE
17140                                                       (operands[2]))));
17141   if (TARGET_SINGLE_STRINGOP || optimize_size)
17142     {
17143       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17144                                       operands[3]));
17145       DONE;
17146     }
17147 })
17148
17149 (define_expand "strset_singleop"
17150   [(parallel [(set (match_operand 1 "memory_operand" "")
17151                    (match_operand 2 "register_operand" ""))
17152               (set (match_operand 0 "register_operand" "")
17153                    (match_operand 3 "" ""))
17154               (use (reg:SI DIRFLAG_REG))])]
17155   "TARGET_SINGLE_STRINGOP || optimize_size"
17156   "")
17157
17158 (define_insn "*strsetdi_rex_1"
17159   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17160         (match_operand:DI 2 "register_operand" "a"))
17161    (set (match_operand:DI 0 "register_operand" "=D")
17162         (plus:DI (match_dup 1)
17163                  (const_int 8)))
17164    (use (reg:SI DIRFLAG_REG))]
17165   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17166   "stosq"
17167   [(set_attr "type" "str")
17168    (set_attr "memory" "store")
17169    (set_attr "mode" "DI")])
17170
17171 (define_insn "*strsetsi_1"
17172   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17173         (match_operand:SI 2 "register_operand" "a"))
17174    (set (match_operand:SI 0 "register_operand" "=D")
17175         (plus:SI (match_dup 1)
17176                  (const_int 4)))
17177    (use (reg:SI DIRFLAG_REG))]
17178   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17179   "{stosl|stosd}"
17180   [(set_attr "type" "str")
17181    (set_attr "memory" "store")
17182    (set_attr "mode" "SI")])
17183
17184 (define_insn "*strsetsi_rex_1"
17185   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17186         (match_operand:SI 2 "register_operand" "a"))
17187    (set (match_operand:DI 0 "register_operand" "=D")
17188         (plus:DI (match_dup 1)
17189                  (const_int 4)))
17190    (use (reg:SI DIRFLAG_REG))]
17191   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17192   "{stosl|stosd}"
17193   [(set_attr "type" "str")
17194    (set_attr "memory" "store")
17195    (set_attr "mode" "SI")])
17196
17197 (define_insn "*strsethi_1"
17198   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17199         (match_operand:HI 2 "register_operand" "a"))
17200    (set (match_operand:SI 0 "register_operand" "=D")
17201         (plus:SI (match_dup 1)
17202                  (const_int 2)))
17203    (use (reg:SI DIRFLAG_REG))]
17204   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17205   "stosw"
17206   [(set_attr "type" "str")
17207    (set_attr "memory" "store")
17208    (set_attr "mode" "HI")])
17209
17210 (define_insn "*strsethi_rex_1"
17211   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17212         (match_operand:HI 2 "register_operand" "a"))
17213    (set (match_operand:DI 0 "register_operand" "=D")
17214         (plus:DI (match_dup 1)
17215                  (const_int 2)))
17216    (use (reg:SI DIRFLAG_REG))]
17217   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17218   "stosw"
17219   [(set_attr "type" "str")
17220    (set_attr "memory" "store")
17221    (set_attr "mode" "HI")])
17222
17223 (define_insn "*strsetqi_1"
17224   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17225         (match_operand:QI 2 "register_operand" "a"))
17226    (set (match_operand:SI 0 "register_operand" "=D")
17227         (plus:SI (match_dup 1)
17228                  (const_int 1)))
17229    (use (reg:SI DIRFLAG_REG))]
17230   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17231   "stosb"
17232   [(set_attr "type" "str")
17233    (set_attr "memory" "store")
17234    (set_attr "mode" "QI")])
17235
17236 (define_insn "*strsetqi_rex_1"
17237   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17238         (match_operand:QI 2 "register_operand" "a"))
17239    (set (match_operand:DI 0 "register_operand" "=D")
17240         (plus:DI (match_dup 1)
17241                  (const_int 1)))
17242    (use (reg:SI DIRFLAG_REG))]
17243   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17244   "stosb"
17245   [(set_attr "type" "str")
17246    (set_attr "memory" "store")
17247    (set_attr "mode" "QI")])
17248
17249 (define_expand "rep_stos"
17250   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17251               (set (match_operand 0 "register_operand" "")
17252                    (match_operand 4 "" ""))
17253               (set (match_operand 2 "memory_operand" "") (const_int 0))
17254               (use (match_operand 3 "register_operand" ""))
17255               (use (match_dup 1))
17256               (use (reg:SI DIRFLAG_REG))])]
17257   ""
17258   "")
17259
17260 (define_insn "*rep_stosdi_rex64"
17261   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17262    (set (match_operand:DI 0 "register_operand" "=D") 
17263         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17264                             (const_int 3))
17265                  (match_operand:DI 3 "register_operand" "0")))
17266    (set (mem:BLK (match_dup 3))
17267         (const_int 0))
17268    (use (match_operand:DI 2 "register_operand" "a"))
17269    (use (match_dup 4))
17270    (use (reg:SI DIRFLAG_REG))]
17271   "TARGET_64BIT"
17272   "{rep\;stosq|rep stosq}"
17273   [(set_attr "type" "str")
17274    (set_attr "prefix_rep" "1")
17275    (set_attr "memory" "store")
17276    (set_attr "mode" "DI")])
17277
17278 (define_insn "*rep_stossi"
17279   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17280    (set (match_operand:SI 0 "register_operand" "=D") 
17281         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17282                             (const_int 2))
17283                  (match_operand:SI 3 "register_operand" "0")))
17284    (set (mem:BLK (match_dup 3))
17285         (const_int 0))
17286    (use (match_operand:SI 2 "register_operand" "a"))
17287    (use (match_dup 4))
17288    (use (reg:SI DIRFLAG_REG))]
17289   "!TARGET_64BIT"
17290   "{rep\;stosl|rep stosd}"
17291   [(set_attr "type" "str")
17292    (set_attr "prefix_rep" "1")
17293    (set_attr "memory" "store")
17294    (set_attr "mode" "SI")])
17295
17296 (define_insn "*rep_stossi_rex64"
17297   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17298    (set (match_operand:DI 0 "register_operand" "=D") 
17299         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17300                             (const_int 2))
17301                  (match_operand:DI 3 "register_operand" "0")))
17302    (set (mem:BLK (match_dup 3))
17303         (const_int 0))
17304    (use (match_operand:SI 2 "register_operand" "a"))
17305    (use (match_dup 4))
17306    (use (reg:SI DIRFLAG_REG))]
17307   "TARGET_64BIT"
17308   "{rep\;stosl|rep stosd}"
17309   [(set_attr "type" "str")
17310    (set_attr "prefix_rep" "1")
17311    (set_attr "memory" "store")
17312    (set_attr "mode" "SI")])
17313
17314 (define_insn "*rep_stosqi"
17315   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17316    (set (match_operand:SI 0 "register_operand" "=D") 
17317         (plus:SI (match_operand:SI 3 "register_operand" "0")
17318                  (match_operand:SI 4 "register_operand" "1")))
17319    (set (mem:BLK (match_dup 3))
17320         (const_int 0))
17321    (use (match_operand:QI 2 "register_operand" "a"))
17322    (use (match_dup 4))
17323    (use (reg:SI DIRFLAG_REG))]
17324   "!TARGET_64BIT"
17325   "{rep\;stosb|rep stosb}"
17326   [(set_attr "type" "str")
17327    (set_attr "prefix_rep" "1")
17328    (set_attr "memory" "store")
17329    (set_attr "mode" "QI")])
17330
17331 (define_insn "*rep_stosqi_rex64"
17332   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17333    (set (match_operand:DI 0 "register_operand" "=D") 
17334         (plus:DI (match_operand:DI 3 "register_operand" "0")
17335                  (match_operand:DI 4 "register_operand" "1")))
17336    (set (mem:BLK (match_dup 3))
17337         (const_int 0))
17338    (use (match_operand:QI 2 "register_operand" "a"))
17339    (use (match_dup 4))
17340    (use (reg:SI DIRFLAG_REG))]
17341   "TARGET_64BIT"
17342   "{rep\;stosb|rep stosb}"
17343   [(set_attr "type" "str")
17344    (set_attr "prefix_rep" "1")
17345    (set_attr "memory" "store")
17346    (set_attr "mode" "QI")])
17347
17348 (define_expand "cmpstrsi"
17349   [(set (match_operand:SI 0 "register_operand" "")
17350         (compare:SI (match_operand:BLK 1 "general_operand" "")
17351                     (match_operand:BLK 2 "general_operand" "")))
17352    (use (match_operand 3 "general_operand" ""))
17353    (use (match_operand 4 "immediate_operand" ""))]
17354   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17355 {
17356   rtx addr1, addr2, out, outlow, count, countreg, align;
17357
17358   /* Can't use this if the user has appropriated esi or edi.  */
17359   if (global_regs[4] || global_regs[5])
17360     FAIL;
17361
17362   out = operands[0];
17363   if (GET_CODE (out) != REG)
17364     out = gen_reg_rtx (SImode);
17365
17366   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17367   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17368   if (addr1 != XEXP (operands[1], 0))
17369     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17370   if (addr2 != XEXP (operands[2], 0))
17371     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17372
17373   count = operands[3];
17374   countreg = ix86_zero_extend_to_Pmode (count);
17375
17376   /* %%% Iff we are testing strict equality, we can use known alignment
17377      to good advantage.  This may be possible with combine, particularly
17378      once cc0 is dead.  */
17379   align = operands[4];
17380
17381   emit_insn (gen_cld ());
17382   if (GET_CODE (count) == CONST_INT)
17383     {
17384       if (INTVAL (count) == 0)
17385         {
17386           emit_move_insn (operands[0], const0_rtx);
17387           DONE;
17388         }
17389       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17390                                     operands[1], operands[2]));
17391     }
17392   else
17393     {
17394       if (TARGET_64BIT)
17395         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17396       else
17397         emit_insn (gen_cmpsi_1 (countreg, countreg));
17398       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17399                                  operands[1], operands[2]));
17400     }
17401
17402   outlow = gen_lowpart (QImode, out);
17403   emit_insn (gen_cmpintqi (outlow));
17404   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17405
17406   if (operands[0] != out)
17407     emit_move_insn (operands[0], out);
17408
17409   DONE;
17410 })
17411
17412 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17413
17414 (define_expand "cmpintqi"
17415   [(set (match_dup 1)
17416         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17417    (set (match_dup 2)
17418         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17419    (parallel [(set (match_operand:QI 0 "register_operand" "")
17420                    (minus:QI (match_dup 1)
17421                              (match_dup 2)))
17422               (clobber (reg:CC FLAGS_REG))])]
17423   ""
17424   "operands[1] = gen_reg_rtx (QImode);
17425    operands[2] = gen_reg_rtx (QImode);")
17426
17427 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17428 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17429
17430 (define_expand "cmpstrqi_nz_1"
17431   [(parallel [(set (reg:CC FLAGS_REG)
17432                    (compare:CC (match_operand 4 "memory_operand" "")
17433                                (match_operand 5 "memory_operand" "")))
17434               (use (match_operand 2 "register_operand" ""))
17435               (use (match_operand:SI 3 "immediate_operand" ""))
17436               (use (reg:SI DIRFLAG_REG))
17437               (clobber (match_operand 0 "register_operand" ""))
17438               (clobber (match_operand 1 "register_operand" ""))
17439               (clobber (match_dup 2))])]
17440   ""
17441   "")
17442
17443 (define_insn "*cmpstrqi_nz_1"
17444   [(set (reg:CC FLAGS_REG)
17445         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17446                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17447    (use (match_operand:SI 6 "register_operand" "2"))
17448    (use (match_operand:SI 3 "immediate_operand" "i"))
17449    (use (reg:SI DIRFLAG_REG))
17450    (clobber (match_operand:SI 0 "register_operand" "=S"))
17451    (clobber (match_operand:SI 1 "register_operand" "=D"))
17452    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17453   "!TARGET_64BIT"
17454   "repz{\;| }cmpsb"
17455   [(set_attr "type" "str")
17456    (set_attr "mode" "QI")
17457    (set_attr "prefix_rep" "1")])
17458
17459 (define_insn "*cmpstrqi_nz_rex_1"
17460   [(set (reg:CC FLAGS_REG)
17461         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17462                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17463    (use (match_operand:DI 6 "register_operand" "2"))
17464    (use (match_operand:SI 3 "immediate_operand" "i"))
17465    (use (reg:SI DIRFLAG_REG))
17466    (clobber (match_operand:DI 0 "register_operand" "=S"))
17467    (clobber (match_operand:DI 1 "register_operand" "=D"))
17468    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17469   "TARGET_64BIT"
17470   "repz{\;| }cmpsb"
17471   [(set_attr "type" "str")
17472    (set_attr "mode" "QI")
17473    (set_attr "prefix_rep" "1")])
17474
17475 ;; The same, but the count is not known to not be zero.
17476
17477 (define_expand "cmpstrqi_1"
17478   [(parallel [(set (reg:CC FLAGS_REG)
17479                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17480                                      (const_int 0))
17481                   (compare:CC (match_operand 4 "memory_operand" "")
17482                               (match_operand 5 "memory_operand" ""))
17483                   (const_int 0)))
17484               (use (match_operand:SI 3 "immediate_operand" ""))
17485               (use (reg:CC FLAGS_REG))
17486               (use (reg:SI DIRFLAG_REG))
17487               (clobber (match_operand 0 "register_operand" ""))
17488               (clobber (match_operand 1 "register_operand" ""))
17489               (clobber (match_dup 2))])]
17490   ""
17491   "")
17492
17493 (define_insn "*cmpstrqi_1"
17494   [(set (reg:CC FLAGS_REG)
17495         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17496                              (const_int 0))
17497           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17498                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17499           (const_int 0)))
17500    (use (match_operand:SI 3 "immediate_operand" "i"))
17501    (use (reg:CC FLAGS_REG))
17502    (use (reg:SI DIRFLAG_REG))
17503    (clobber (match_operand:SI 0 "register_operand" "=S"))
17504    (clobber (match_operand:SI 1 "register_operand" "=D"))
17505    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17506   "!TARGET_64BIT"
17507   "repz{\;| }cmpsb"
17508   [(set_attr "type" "str")
17509    (set_attr "mode" "QI")
17510    (set_attr "prefix_rep" "1")])
17511
17512 (define_insn "*cmpstrqi_rex_1"
17513   [(set (reg:CC FLAGS_REG)
17514         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17515                              (const_int 0))
17516           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17517                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17518           (const_int 0)))
17519    (use (match_operand:SI 3 "immediate_operand" "i"))
17520    (use (reg:CC FLAGS_REG))
17521    (use (reg:SI DIRFLAG_REG))
17522    (clobber (match_operand:DI 0 "register_operand" "=S"))
17523    (clobber (match_operand:DI 1 "register_operand" "=D"))
17524    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17525   "TARGET_64BIT"
17526   "repz{\;| }cmpsb"
17527   [(set_attr "type" "str")
17528    (set_attr "mode" "QI")
17529    (set_attr "prefix_rep" "1")])
17530
17531 (define_expand "strlensi"
17532   [(set (match_operand:SI 0 "register_operand" "")
17533         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17534                     (match_operand:QI 2 "immediate_operand" "")
17535                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17536   ""
17537 {
17538  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17539    DONE;
17540  else
17541    FAIL;
17542 })
17543
17544 (define_expand "strlendi"
17545   [(set (match_operand:DI 0 "register_operand" "")
17546         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17547                     (match_operand:QI 2 "immediate_operand" "")
17548                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17549   ""
17550 {
17551  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17552    DONE;
17553  else
17554    FAIL;
17555 })
17556
17557 (define_expand "strlenqi_1"
17558   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17559               (use (reg:SI DIRFLAG_REG))
17560               (clobber (match_operand 1 "register_operand" ""))
17561               (clobber (reg:CC FLAGS_REG))])]
17562   ""
17563   "")
17564
17565 (define_insn "*strlenqi_1"
17566   [(set (match_operand:SI 0 "register_operand" "=&c")
17567         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17568                     (match_operand:QI 2 "register_operand" "a")
17569                     (match_operand:SI 3 "immediate_operand" "i")
17570                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17571    (use (reg:SI DIRFLAG_REG))
17572    (clobber (match_operand:SI 1 "register_operand" "=D"))
17573    (clobber (reg:CC FLAGS_REG))]
17574   "!TARGET_64BIT"
17575   "repnz{\;| }scasb"
17576   [(set_attr "type" "str")
17577    (set_attr "mode" "QI")
17578    (set_attr "prefix_rep" "1")])
17579
17580 (define_insn "*strlenqi_rex_1"
17581   [(set (match_operand:DI 0 "register_operand" "=&c")
17582         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17583                     (match_operand:QI 2 "register_operand" "a")
17584                     (match_operand:DI 3 "immediate_operand" "i")
17585                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17586    (use (reg:SI DIRFLAG_REG))
17587    (clobber (match_operand:DI 1 "register_operand" "=D"))
17588    (clobber (reg:CC FLAGS_REG))]
17589   "TARGET_64BIT"
17590   "repnz{\;| }scasb"
17591   [(set_attr "type" "str")
17592    (set_attr "mode" "QI")
17593    (set_attr "prefix_rep" "1")])
17594
17595 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17596 ;; handled in combine, but it is not currently up to the task.
17597 ;; When used for their truth value, the cmpstr* expanders generate
17598 ;; code like this:
17599 ;;
17600 ;;   repz cmpsb
17601 ;;   seta       %al
17602 ;;   setb       %dl
17603 ;;   cmpb       %al, %dl
17604 ;;   jcc        label
17605 ;;
17606 ;; The intermediate three instructions are unnecessary.
17607
17608 ;; This one handles cmpstr*_nz_1...
17609 (define_peephole2
17610   [(parallel[
17611      (set (reg:CC FLAGS_REG)
17612           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17613                       (mem:BLK (match_operand 5 "register_operand" ""))))
17614      (use (match_operand 6 "register_operand" ""))
17615      (use (match_operand:SI 3 "immediate_operand" ""))
17616      (use (reg:SI DIRFLAG_REG))
17617      (clobber (match_operand 0 "register_operand" ""))
17618      (clobber (match_operand 1 "register_operand" ""))
17619      (clobber (match_operand 2 "register_operand" ""))])
17620    (set (match_operand:QI 7 "register_operand" "")
17621         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17622    (set (match_operand:QI 8 "register_operand" "")
17623         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17624    (set (reg 17)
17625         (compare (match_dup 7) (match_dup 8)))
17626   ]
17627   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17628   [(parallel[
17629      (set (reg:CC FLAGS_REG)
17630           (compare:CC (mem:BLK (match_dup 4))
17631                       (mem:BLK (match_dup 5))))
17632      (use (match_dup 6))
17633      (use (match_dup 3))
17634      (use (reg:SI DIRFLAG_REG))
17635      (clobber (match_dup 0))
17636      (clobber (match_dup 1))
17637      (clobber (match_dup 2))])]
17638   "")
17639
17640 ;; ...and this one handles cmpstr*_1.
17641 (define_peephole2
17642   [(parallel[
17643      (set (reg:CC FLAGS_REG)
17644           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17645                                (const_int 0))
17646             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17647                         (mem:BLK (match_operand 5 "register_operand" "")))
17648             (const_int 0)))
17649      (use (match_operand:SI 3 "immediate_operand" ""))
17650      (use (reg:CC FLAGS_REG))
17651      (use (reg:SI DIRFLAG_REG))
17652      (clobber (match_operand 0 "register_operand" ""))
17653      (clobber (match_operand 1 "register_operand" ""))
17654      (clobber (match_operand 2 "register_operand" ""))])
17655    (set (match_operand:QI 7 "register_operand" "")
17656         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17657    (set (match_operand:QI 8 "register_operand" "")
17658         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17659    (set (reg 17)
17660         (compare (match_dup 7) (match_dup 8)))
17661   ]
17662   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17663   [(parallel[
17664      (set (reg:CC FLAGS_REG)
17665           (if_then_else:CC (ne (match_dup 6)
17666                                (const_int 0))
17667             (compare:CC (mem:BLK (match_dup 4))
17668                         (mem:BLK (match_dup 5)))
17669             (const_int 0)))
17670      (use (match_dup 3))
17671      (use (reg:CC FLAGS_REG))
17672      (use (reg:SI DIRFLAG_REG))
17673      (clobber (match_dup 0))
17674      (clobber (match_dup 1))
17675      (clobber (match_dup 2))])]
17676   "")
17677
17678
17679 \f
17680 ;; Conditional move instructions.
17681
17682 (define_expand "movdicc"
17683   [(set (match_operand:DI 0 "register_operand" "")
17684         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17685                          (match_operand:DI 2 "general_operand" "")
17686                          (match_operand:DI 3 "general_operand" "")))]
17687   "TARGET_64BIT"
17688   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17689
17690 (define_insn "x86_movdicc_0_m1_rex64"
17691   [(set (match_operand:DI 0 "register_operand" "=r")
17692         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17693           (const_int -1)
17694           (const_int 0)))
17695    (clobber (reg:CC FLAGS_REG))]
17696   "TARGET_64BIT"
17697   "sbb{q}\t%0, %0"
17698   ; Since we don't have the proper number of operands for an alu insn,
17699   ; fill in all the blanks.
17700   [(set_attr "type" "alu")
17701    (set_attr "pent_pair" "pu")
17702    (set_attr "memory" "none")
17703    (set_attr "imm_disp" "false")
17704    (set_attr "mode" "DI")
17705    (set_attr "length_immediate" "0")])
17706
17707 (define_insn "movdicc_c_rex64"
17708   [(set (match_operand:DI 0 "register_operand" "=r,r")
17709         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17710                                 [(reg 17) (const_int 0)])
17711                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17712                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17713   "TARGET_64BIT && TARGET_CMOVE
17714    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17715   "@
17716    cmov%O2%C1\t{%2, %0|%0, %2}
17717    cmov%O2%c1\t{%3, %0|%0, %3}"
17718   [(set_attr "type" "icmov")
17719    (set_attr "mode" "DI")])
17720
17721 (define_expand "movsicc"
17722   [(set (match_operand:SI 0 "register_operand" "")
17723         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17724                          (match_operand:SI 2 "general_operand" "")
17725                          (match_operand:SI 3 "general_operand" "")))]
17726   ""
17727   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17728
17729 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17730 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17731 ;; So just document what we're doing explicitly.
17732
17733 (define_insn "x86_movsicc_0_m1"
17734   [(set (match_operand:SI 0 "register_operand" "=r")
17735         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17736           (const_int -1)
17737           (const_int 0)))
17738    (clobber (reg:CC FLAGS_REG))]
17739   ""
17740   "sbb{l}\t%0, %0"
17741   ; Since we don't have the proper number of operands for an alu insn,
17742   ; fill in all the blanks.
17743   [(set_attr "type" "alu")
17744    (set_attr "pent_pair" "pu")
17745    (set_attr "memory" "none")
17746    (set_attr "imm_disp" "false")
17747    (set_attr "mode" "SI")
17748    (set_attr "length_immediate" "0")])
17749
17750 (define_insn "*movsicc_noc"
17751   [(set (match_operand:SI 0 "register_operand" "=r,r")
17752         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17753                                 [(reg 17) (const_int 0)])
17754                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17755                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17756   "TARGET_CMOVE
17757    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17758   "@
17759    cmov%O2%C1\t{%2, %0|%0, %2}
17760    cmov%O2%c1\t{%3, %0|%0, %3}"
17761   [(set_attr "type" "icmov")
17762    (set_attr "mode" "SI")])
17763
17764 (define_expand "movhicc"
17765   [(set (match_operand:HI 0 "register_operand" "")
17766         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17767                          (match_operand:HI 2 "general_operand" "")
17768                          (match_operand:HI 3 "general_operand" "")))]
17769   "TARGET_HIMODE_MATH"
17770   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17771
17772 (define_insn "*movhicc_noc"
17773   [(set (match_operand:HI 0 "register_operand" "=r,r")
17774         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17775                                 [(reg 17) (const_int 0)])
17776                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17777                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17778   "TARGET_CMOVE
17779    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17780   "@
17781    cmov%O2%C1\t{%2, %0|%0, %2}
17782    cmov%O2%c1\t{%3, %0|%0, %3}"
17783   [(set_attr "type" "icmov")
17784    (set_attr "mode" "HI")])
17785
17786 (define_expand "movqicc"
17787   [(set (match_operand:QI 0 "register_operand" "")
17788         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17789                          (match_operand:QI 2 "general_operand" "")
17790                          (match_operand:QI 3 "general_operand" "")))]
17791   "TARGET_QIMODE_MATH"
17792   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17793
17794 (define_insn_and_split "*movqicc_noc"
17795   [(set (match_operand:QI 0 "register_operand" "=r,r")
17796         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17797                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17798                       (match_operand:QI 2 "register_operand" "r,0")
17799                       (match_operand:QI 3 "register_operand" "0,r")))]
17800   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17801   "#"
17802   "&& reload_completed"
17803   [(set (match_dup 0)
17804         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17805                       (match_dup 2)
17806                       (match_dup 3)))]
17807   "operands[0] = gen_lowpart (SImode, operands[0]);
17808    operands[2] = gen_lowpart (SImode, operands[2]);
17809    operands[3] = gen_lowpart (SImode, operands[3]);"
17810   [(set_attr "type" "icmov")
17811    (set_attr "mode" "SI")])
17812
17813 (define_expand "movsfcc"
17814   [(set (match_operand:SF 0 "register_operand" "")
17815         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17816                          (match_operand:SF 2 "register_operand" "")
17817                          (match_operand:SF 3 "register_operand" "")))]
17818   "TARGET_CMOVE"
17819   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17820
17821 (define_insn "*movsfcc_1"
17822   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17823         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17824                                 [(reg 17) (const_int 0)])
17825                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17826                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17827   "TARGET_CMOVE
17828    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17829   "@
17830    fcmov%F1\t{%2, %0|%0, %2}
17831    fcmov%f1\t{%3, %0|%0, %3}
17832    cmov%O2%C1\t{%2, %0|%0, %2}
17833    cmov%O2%c1\t{%3, %0|%0, %3}"
17834   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17835    (set_attr "mode" "SF,SF,SI,SI")])
17836
17837 (define_expand "movdfcc"
17838   [(set (match_operand:DF 0 "register_operand" "")
17839         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17840                          (match_operand:DF 2 "register_operand" "")
17841                          (match_operand:DF 3 "register_operand" "")))]
17842   "TARGET_CMOVE"
17843   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17844
17845 (define_insn "*movdfcc_1"
17846   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17847         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17848                                 [(reg 17) (const_int 0)])
17849                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17850                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17851   "!TARGET_64BIT && TARGET_CMOVE
17852    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17853   "@
17854    fcmov%F1\t{%2, %0|%0, %2}
17855    fcmov%f1\t{%3, %0|%0, %3}
17856    #
17857    #"
17858   [(set_attr "type" "fcmov,fcmov,multi,multi")
17859    (set_attr "mode" "DF")])
17860
17861 (define_insn "*movdfcc_1_rex64"
17862   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17863         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17864                                 [(reg 17) (const_int 0)])
17865                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17866                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17867   "TARGET_64BIT && TARGET_CMOVE
17868    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17869   "@
17870    fcmov%F1\t{%2, %0|%0, %2}
17871    fcmov%f1\t{%3, %0|%0, %3}
17872    cmov%O2%C1\t{%2, %0|%0, %2}
17873    cmov%O2%c1\t{%3, %0|%0, %3}"
17874   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17875    (set_attr "mode" "DF")])
17876
17877 (define_split
17878   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17879         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17880                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17881                       (match_operand:DF 2 "nonimmediate_operand" "")
17882                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17883   "!TARGET_64BIT && reload_completed"
17884   [(set (match_dup 2)
17885         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17886                       (match_dup 5)
17887                       (match_dup 7)))
17888    (set (match_dup 3)
17889         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17890                       (match_dup 6)
17891                       (match_dup 8)))]
17892   "split_di (operands+2, 1, operands+5, operands+6);
17893    split_di (operands+3, 1, operands+7, operands+8);
17894    split_di (operands, 1, operands+2, operands+3);")
17895
17896 (define_expand "movxfcc"
17897   [(set (match_operand:XF 0 "register_operand" "")
17898         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17899                          (match_operand:XF 2 "register_operand" "")
17900                          (match_operand:XF 3 "register_operand" "")))]
17901   "TARGET_CMOVE"
17902   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17903
17904 (define_insn "*movxfcc_1"
17905   [(set (match_operand:XF 0 "register_operand" "=f,f")
17906         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17907                                 [(reg 17) (const_int 0)])
17908                       (match_operand:XF 2 "register_operand" "f,0")
17909                       (match_operand:XF 3 "register_operand" "0,f")))]
17910   "TARGET_CMOVE"
17911   "@
17912    fcmov%F1\t{%2, %0|%0, %2}
17913    fcmov%f1\t{%3, %0|%0, %3}"
17914   [(set_attr "type" "fcmov")
17915    (set_attr "mode" "XF")])
17916
17917 (define_expand "minsf3"
17918   [(parallel [
17919      (set (match_operand:SF 0 "register_operand" "")
17920           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17921                                (match_operand:SF 2 "nonimmediate_operand" ""))
17922                            (match_dup 1)
17923                            (match_dup 2)))
17924      (clobber (reg:CC FLAGS_REG))])]
17925   "TARGET_SSE"
17926   "")
17927
17928 (define_insn "*minsf"
17929   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17930         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17931                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17932                          (match_dup 1)
17933                          (match_dup 2)))
17934    (clobber (reg:CC FLAGS_REG))]
17935   "TARGET_SSE && TARGET_IEEE_FP"
17936   "#")
17937
17938 (define_insn "*minsf_nonieee"
17939   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17940         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17941                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17942                          (match_dup 1)
17943                          (match_dup 2)))
17944    (clobber (reg:CC FLAGS_REG))]
17945   "TARGET_SSE && !TARGET_IEEE_FP
17946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17947   "#")
17948
17949 (define_split
17950   [(set (match_operand:SF 0 "register_operand" "")
17951         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17952                              (match_operand:SF 2 "nonimmediate_operand" ""))
17953                          (match_operand:SF 3 "register_operand" "")
17954                          (match_operand:SF 4 "nonimmediate_operand" "")))
17955    (clobber (reg:CC FLAGS_REG))]
17956   "SSE_REG_P (operands[0]) && reload_completed
17957    && ((operands_match_p (operands[1], operands[3])
17958         && operands_match_p (operands[2], operands[4]))
17959        || (operands_match_p (operands[1], operands[4])
17960            && operands_match_p (operands[2], operands[3])))"
17961   [(set (match_dup 0)
17962         (if_then_else:SF (lt (match_dup 1)
17963                              (match_dup 2))
17964                          (match_dup 1)
17965                          (match_dup 2)))])
17966
17967 ;; Conditional addition patterns
17968 (define_expand "addqicc"
17969   [(match_operand:QI 0 "register_operand" "")
17970    (match_operand 1 "comparison_operator" "")
17971    (match_operand:QI 2 "register_operand" "")
17972    (match_operand:QI 3 "const_int_operand" "")]
17973   ""
17974   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17975
17976 (define_expand "addhicc"
17977   [(match_operand:HI 0 "register_operand" "")
17978    (match_operand 1 "comparison_operator" "")
17979    (match_operand:HI 2 "register_operand" "")
17980    (match_operand:HI 3 "const_int_operand" "")]
17981   ""
17982   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17983
17984 (define_expand "addsicc"
17985   [(match_operand:SI 0 "register_operand" "")
17986    (match_operand 1 "comparison_operator" "")
17987    (match_operand:SI 2 "register_operand" "")
17988    (match_operand:SI 3 "const_int_operand" "")]
17989   ""
17990   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17991
17992 (define_expand "adddicc"
17993   [(match_operand:DI 0 "register_operand" "")
17994    (match_operand 1 "comparison_operator" "")
17995    (match_operand:DI 2 "register_operand" "")
17996    (match_operand:DI 3 "const_int_operand" "")]
17997   "TARGET_64BIT"
17998   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17999
18000 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18001
18002 (define_split
18003   [(set (match_operand:SF 0 "fp_register_operand" "")
18004         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
18005                              (match_operand:SF 2 "register_operand" ""))
18006                          (match_operand:SF 3 "register_operand" "")
18007                          (match_operand:SF 4 "register_operand" "")))
18008    (clobber (reg:CC FLAGS_REG))]
18009   "reload_completed
18010    && ((operands_match_p (operands[1], operands[3])
18011         && operands_match_p (operands[2], operands[4]))
18012        || (operands_match_p (operands[1], operands[4])
18013            && operands_match_p (operands[2], operands[3])))"
18014   [(set (reg:CCFP FLAGS_REG)
18015         (compare:CCFP (match_dup 2)
18016                       (match_dup 1)))
18017    (set (match_dup 0)
18018         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18019                          (match_dup 1)
18020                          (match_dup 2)))])
18021
18022 (define_insn "*minsf_sse"
18023   [(set (match_operand:SF 0 "register_operand" "=x")
18024         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
18025                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18026                          (match_dup 1)
18027                          (match_dup 2)))]
18028   "TARGET_SSE && reload_completed"
18029   "minss\t{%2, %0|%0, %2}"
18030   [(set_attr "type" "sse")
18031    (set_attr "mode" "SF")])
18032
18033 (define_expand "mindf3"
18034   [(parallel [
18035      (set (match_operand:DF 0 "register_operand" "")
18036           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18037                                (match_operand:DF 2 "nonimmediate_operand" ""))
18038                            (match_dup 1)
18039                            (match_dup 2)))
18040      (clobber (reg:CC FLAGS_REG))])]
18041   "TARGET_SSE2 && TARGET_SSE_MATH"
18042   "#")
18043
18044 (define_insn "*mindf"
18045   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18046         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18047                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18048                          (match_dup 1)
18049                          (match_dup 2)))
18050    (clobber (reg:CC FLAGS_REG))]
18051   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18052   "#")
18053
18054 (define_insn "*mindf_nonieee"
18055   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18056         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18057                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18058                          (match_dup 1)
18059                          (match_dup 2)))
18060    (clobber (reg:CC FLAGS_REG))]
18061   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18063   "#")
18064
18065 (define_split
18066   [(set (match_operand:DF 0 "register_operand" "")
18067         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18068                              (match_operand:DF 2 "nonimmediate_operand" ""))
18069                          (match_operand:DF 3 "register_operand" "")
18070                          (match_operand:DF 4 "nonimmediate_operand" "")))
18071    (clobber (reg:CC FLAGS_REG))]
18072   "SSE_REG_P (operands[0]) && reload_completed
18073    && ((operands_match_p (operands[1], operands[3])
18074         && operands_match_p (operands[2], operands[4]))
18075        || (operands_match_p (operands[1], operands[4])
18076            && operands_match_p (operands[2], operands[3])))"
18077   [(set (match_dup 0)
18078         (if_then_else:DF (lt (match_dup 1)
18079                              (match_dup 2))
18080                          (match_dup 1)
18081                          (match_dup 2)))])
18082
18083 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18084 (define_split
18085   [(set (match_operand:DF 0 "fp_register_operand" "")
18086         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18087                              (match_operand:DF 2 "register_operand" ""))
18088                          (match_operand:DF 3 "register_operand" "")
18089                          (match_operand:DF 4 "register_operand" "")))
18090    (clobber (reg:CC FLAGS_REG))]
18091   "reload_completed
18092    && ((operands_match_p (operands[1], operands[3])
18093         && operands_match_p (operands[2], operands[4]))
18094        || (operands_match_p (operands[1], operands[4])
18095            && operands_match_p (operands[2], operands[3])))"
18096   [(set (reg:CCFP FLAGS_REG)
18097         (compare:CCFP (match_dup 2)
18098                       (match_dup 1)))
18099    (set (match_dup 0)
18100         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18101                          (match_dup 1)
18102                          (match_dup 2)))])
18103
18104 (define_insn "*mindf_sse"
18105   [(set (match_operand:DF 0 "register_operand" "=Y")
18106         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18107                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18108                          (match_dup 1)
18109                          (match_dup 2)))]
18110   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18111   "minsd\t{%2, %0|%0, %2}"
18112   [(set_attr "type" "sse")
18113    (set_attr "mode" "DF")])
18114
18115 (define_expand "maxsf3"
18116   [(parallel [
18117      (set (match_operand:SF 0 "register_operand" "")
18118           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18119                                (match_operand:SF 2 "nonimmediate_operand" ""))
18120                            (match_dup 1)
18121                            (match_dup 2)))
18122      (clobber (reg:CC FLAGS_REG))])]
18123   "TARGET_SSE"
18124   "#")
18125
18126 (define_insn "*maxsf"
18127   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18128         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18129                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18130                          (match_dup 1)
18131                          (match_dup 2)))
18132    (clobber (reg:CC FLAGS_REG))]
18133   "TARGET_SSE && TARGET_IEEE_FP"
18134   "#")
18135
18136 (define_insn "*maxsf_nonieee"
18137   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18138         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18139                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18140                          (match_dup 1)
18141                          (match_dup 2)))
18142    (clobber (reg:CC FLAGS_REG))]
18143   "TARGET_SSE && !TARGET_IEEE_FP
18144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18145   "#")
18146
18147 (define_split
18148   [(set (match_operand:SF 0 "register_operand" "")
18149         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18150                              (match_operand:SF 2 "nonimmediate_operand" ""))
18151                          (match_operand:SF 3 "register_operand" "")
18152                          (match_operand:SF 4 "nonimmediate_operand" "")))
18153    (clobber (reg:CC FLAGS_REG))]
18154   "SSE_REG_P (operands[0]) && reload_completed
18155    && ((operands_match_p (operands[1], operands[3])
18156         && operands_match_p (operands[2], operands[4]))
18157        || (operands_match_p (operands[1], operands[4])
18158            && operands_match_p (operands[2], operands[3])))"
18159   [(set (match_dup 0)
18160         (if_then_else:SF (gt (match_dup 1)
18161                              (match_dup 2))
18162                          (match_dup 1)
18163                          (match_dup 2)))])
18164
18165 (define_split
18166   [(set (match_operand:SF 0 "fp_register_operand" "")
18167         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18168                              (match_operand:SF 2 "register_operand" ""))
18169                          (match_operand:SF 3 "register_operand" "")
18170                          (match_operand:SF 4 "register_operand" "")))
18171    (clobber (reg:CC FLAGS_REG))]
18172   "reload_completed
18173    && ((operands_match_p (operands[1], operands[3])
18174         && operands_match_p (operands[2], operands[4]))
18175        || (operands_match_p (operands[1], operands[4])
18176            && operands_match_p (operands[2], operands[3])))"
18177   [(set (reg:CCFP FLAGS_REG)
18178         (compare:CCFP (match_dup 1)
18179                       (match_dup 2)))
18180    (set (match_dup 0)
18181         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18182                          (match_dup 1)
18183                          (match_dup 2)))])
18184
18185 (define_insn "*maxsf_sse"
18186   [(set (match_operand:SF 0 "register_operand" "=x")
18187         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18188                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18189                          (match_dup 1)
18190                          (match_dup 2)))]
18191   "TARGET_SSE && reload_completed"
18192   "maxss\t{%2, %0|%0, %2}"
18193   [(set_attr "type" "sse")
18194    (set_attr "mode" "SF")])
18195
18196 (define_expand "maxdf3"
18197   [(parallel [
18198      (set (match_operand:DF 0 "register_operand" "")
18199           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18200                                (match_operand:DF 2 "nonimmediate_operand" ""))
18201                            (match_dup 1)
18202                            (match_dup 2)))
18203      (clobber (reg:CC FLAGS_REG))])]
18204   "TARGET_SSE2 && TARGET_SSE_MATH"
18205   "#")
18206
18207 (define_insn "*maxdf"
18208   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18209         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18210                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18211                          (match_dup 1)
18212                          (match_dup 2)))
18213    (clobber (reg:CC FLAGS_REG))]
18214   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18215   "#")
18216
18217 (define_insn "*maxdf_nonieee"
18218   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18219         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18220                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18221                          (match_dup 1)
18222                          (match_dup 2)))
18223    (clobber (reg:CC FLAGS_REG))]
18224   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18226   "#")
18227
18228 (define_split
18229   [(set (match_operand:DF 0 "register_operand" "")
18230         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18231                              (match_operand:DF 2 "nonimmediate_operand" ""))
18232                          (match_operand:DF 3 "register_operand" "")
18233                          (match_operand:DF 4 "nonimmediate_operand" "")))
18234    (clobber (reg:CC FLAGS_REG))]
18235   "SSE_REG_P (operands[0]) && reload_completed
18236    && ((operands_match_p (operands[1], operands[3])
18237         && operands_match_p (operands[2], operands[4]))
18238        || (operands_match_p (operands[1], operands[4])
18239            && operands_match_p (operands[2], operands[3])))"
18240   [(set (match_dup 0)
18241         (if_then_else:DF (gt (match_dup 1)
18242                              (match_dup 2))
18243                          (match_dup 1)
18244                          (match_dup 2)))])
18245
18246 (define_split
18247   [(set (match_operand:DF 0 "fp_register_operand" "")
18248         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18249                              (match_operand:DF 2 "register_operand" ""))
18250                          (match_operand:DF 3 "register_operand" "")
18251                          (match_operand:DF 4 "register_operand" "")))
18252    (clobber (reg:CC FLAGS_REG))]
18253   "reload_completed
18254    && ((operands_match_p (operands[1], operands[3])
18255         && operands_match_p (operands[2], operands[4]))
18256        || (operands_match_p (operands[1], operands[4])
18257            && operands_match_p (operands[2], operands[3])))"
18258   [(set (reg:CCFP FLAGS_REG)
18259         (compare:CCFP (match_dup 1)
18260                       (match_dup 2)))
18261    (set (match_dup 0)
18262         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18263                          (match_dup 1)
18264                          (match_dup 2)))])
18265
18266 (define_insn "*maxdf_sse"
18267   [(set (match_operand:DF 0 "register_operand" "=Y")
18268         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18269                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18270                          (match_dup 1)
18271                          (match_dup 2)))]
18272   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18273   "maxsd\t{%2, %0|%0, %2}"
18274   [(set_attr "type" "sse")
18275    (set_attr "mode" "DF")])
18276 \f
18277 ;; Misc patterns (?)
18278
18279 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18280 ;; Otherwise there will be nothing to keep
18281 ;; 
18282 ;; [(set (reg ebp) (reg esp))]
18283 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18284 ;;  (clobber (eflags)]
18285 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18286 ;;
18287 ;; in proper program order.
18288 (define_insn "pro_epilogue_adjust_stack_1"
18289   [(set (match_operand:SI 0 "register_operand" "=r,r")
18290         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18291                  (match_operand:SI 2 "immediate_operand" "i,i")))
18292    (clobber (reg:CC FLAGS_REG))
18293    (clobber (mem:BLK (scratch)))]
18294   "!TARGET_64BIT"
18295 {
18296   switch (get_attr_type (insn))
18297     {
18298     case TYPE_IMOV:
18299       return "mov{l}\t{%1, %0|%0, %1}";
18300
18301     case TYPE_ALU:
18302       if (GET_CODE (operands[2]) == CONST_INT
18303           && (INTVAL (operands[2]) == 128
18304               || (INTVAL (operands[2]) < 0
18305                   && INTVAL (operands[2]) != -128)))
18306         {
18307           operands[2] = GEN_INT (-INTVAL (operands[2]));
18308           return "sub{l}\t{%2, %0|%0, %2}";
18309         }
18310       return "add{l}\t{%2, %0|%0, %2}";
18311
18312     case TYPE_LEA:
18313       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18314       return "lea{l}\t{%a2, %0|%0, %a2}";
18315
18316     default:
18317       abort ();
18318     }
18319 }
18320   [(set (attr "type")
18321         (cond [(eq_attr "alternative" "0")
18322                  (const_string "alu")
18323                (match_operand:SI 2 "const0_operand" "")
18324                  (const_string "imov")
18325               ]
18326               (const_string "lea")))
18327    (set_attr "mode" "SI")])
18328
18329 (define_insn "pro_epilogue_adjust_stack_rex64"
18330   [(set (match_operand:DI 0 "register_operand" "=r,r")
18331         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18332                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18333    (clobber (reg:CC FLAGS_REG))
18334    (clobber (mem:BLK (scratch)))]
18335   "TARGET_64BIT"
18336 {
18337   switch (get_attr_type (insn))
18338     {
18339     case TYPE_IMOV:
18340       return "mov{q}\t{%1, %0|%0, %1}";
18341
18342     case TYPE_ALU:
18343       if (GET_CODE (operands[2]) == CONST_INT
18344           /* Avoid overflows.  */
18345           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18346           && (INTVAL (operands[2]) == 128
18347               || (INTVAL (operands[2]) < 0
18348                   && INTVAL (operands[2]) != -128)))
18349         {
18350           operands[2] = GEN_INT (-INTVAL (operands[2]));
18351           return "sub{q}\t{%2, %0|%0, %2}";
18352         }
18353       return "add{q}\t{%2, %0|%0, %2}";
18354
18355     case TYPE_LEA:
18356       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18357       return "lea{q}\t{%a2, %0|%0, %a2}";
18358
18359     default:
18360       abort ();
18361     }
18362 }
18363   [(set (attr "type")
18364         (cond [(eq_attr "alternative" "0")
18365                  (const_string "alu")
18366                (match_operand:DI 2 "const0_operand" "")
18367                  (const_string "imov")
18368               ]
18369               (const_string "lea")))
18370    (set_attr "mode" "DI")])
18371
18372 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18373   [(set (match_operand:DI 0 "register_operand" "=r,r")
18374         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18375                  (match_operand:DI 3 "immediate_operand" "i,i")))
18376    (use (match_operand:DI 2 "register_operand" "r,r"))
18377    (clobber (reg:CC FLAGS_REG))
18378    (clobber (mem:BLK (scratch)))]
18379   "TARGET_64BIT"
18380 {
18381   switch (get_attr_type (insn))
18382     {
18383     case TYPE_ALU:
18384       return "add{q}\t{%2, %0|%0, %2}";
18385
18386     case TYPE_LEA:
18387       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18388       return "lea{q}\t{%a2, %0|%0, %a2}";
18389
18390     default:
18391       abort ();
18392     }
18393 }
18394   [(set_attr "type" "alu,lea")
18395    (set_attr "mode" "DI")])
18396
18397 ;; Placeholder for the conditional moves.  This one is split either to SSE
18398 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18399 ;; fact is that compares supported by the cmp??ss instructions are exactly
18400 ;; swapped of those supported by cmove sequence.
18401 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18402 ;; supported by i387 comparisons and we do need to emit two conditional moves
18403 ;; in tandem.
18404
18405 (define_insn "sse_movsfcc"
18406   [(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")
18407         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18408                         [(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")
18409                          (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")])
18410                       (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")
18411                       (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")))
18412    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18413    (clobber (reg:CC FLAGS_REG))]
18414   "TARGET_SSE
18415    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18416    /* Avoid combine from being smart and converting min/max
18417       instruction patterns into conditional moves.  */
18418    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18419         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18420        || !rtx_equal_p (operands[4], operands[2])
18421        || !rtx_equal_p (operands[5], operands[3]))
18422    && (!TARGET_IEEE_FP
18423        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18424   "#")
18425
18426 (define_insn "sse_movsfcc_eq"
18427   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18428         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18429                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18430                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18431                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18432    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18433    (clobber (reg:CC FLAGS_REG))]
18434   "TARGET_SSE
18435    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18436   "#")
18437
18438 (define_insn "sse_movdfcc"
18439   [(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")
18440         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18441                         [(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")
18442                          (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")])
18443                       (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")
18444                       (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")))
18445    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18446    (clobber (reg:CC FLAGS_REG))]
18447   "TARGET_SSE2
18448    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18449    /* Avoid combine from being smart and converting min/max
18450       instruction patterns into conditional moves.  */
18451    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18452         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18453        || !rtx_equal_p (operands[4], operands[2])
18454        || !rtx_equal_p (operands[5], operands[3]))
18455    && (!TARGET_IEEE_FP
18456        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18457   "#")
18458
18459 (define_insn "sse_movdfcc_eq"
18460   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18461         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18462                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18463                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18464                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18465    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18466    (clobber (reg:CC FLAGS_REG))]
18467   "TARGET_SSE
18468    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18469   "#")
18470
18471 ;; For non-sse moves just expand the usual cmove sequence.
18472 (define_split
18473   [(set (match_operand 0 "register_operand" "")
18474         (if_then_else (match_operator 1 "comparison_operator"
18475                         [(match_operand 4 "nonimmediate_operand" "")
18476                          (match_operand 5 "register_operand" "")])
18477                       (match_operand 2 "nonimmediate_operand" "")
18478                       (match_operand 3 "nonimmediate_operand" "")))
18479    (clobber (match_operand 6 "" ""))
18480    (clobber (reg:CC FLAGS_REG))]
18481   "!SSE_REG_P (operands[0]) && reload_completed
18482    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18483   [(const_int 0)]
18484 {
18485    ix86_compare_op0 = operands[5];
18486    ix86_compare_op1 = operands[4];
18487    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18488                                  VOIDmode, operands[5], operands[4]);
18489    ix86_expand_fp_movcc (operands);
18490    DONE;
18491 })
18492
18493 ;; Split SSE based conditional move into sequence:
18494 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18495 ;; and   op2, op0   -  zero op2 if comparison was false
18496 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18497 ;; or    op2, op0   -  get the nonzero one into the result.
18498 (define_split
18499   [(set (match_operand:SF 0 "register_operand" "")
18500         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18501                         [(match_operand:SF 4 "register_operand" "")
18502                          (match_operand:SF 5 "nonimmediate_operand" "")])
18503                       (match_operand:SF 2 "register_operand" "")
18504                       (match_operand:SF 3 "register_operand" "")))
18505    (clobber (match_operand 6 "" ""))
18506    (clobber (reg:CC FLAGS_REG))]
18507   "SSE_REG_P (operands[0]) && reload_completed"
18508   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18509    (set (match_dup 2) (and:V4SF (match_dup 2)
18510                                 (match_dup 8)))
18511    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18512                                           (match_dup 3)))
18513    (set (match_dup 0) (ior:V4SF (match_dup 6)
18514                                 (match_dup 7)))]
18515 {
18516   /* If op2 == op3, op3 would be clobbered before it is used.  */
18517   if (operands_match_p (operands[2], operands[3]))
18518     {
18519       emit_move_insn (operands[0], operands[2]);
18520       DONE;
18521     }
18522
18523   PUT_MODE (operands[1], GET_MODE (operands[0]));
18524   if (operands_match_p (operands[0], operands[4]))
18525     operands[6] = operands[4], operands[7] = operands[2];
18526   else
18527     operands[6] = operands[2], operands[7] = operands[4];
18528   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18529   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18530   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18531   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18532   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18533   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18534 })
18535
18536 (define_split
18537   [(set (match_operand:DF 0 "register_operand" "")
18538         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18539                         [(match_operand:DF 4 "register_operand" "")
18540                          (match_operand:DF 5 "nonimmediate_operand" "")])
18541                       (match_operand:DF 2 "register_operand" "")
18542                       (match_operand:DF 3 "register_operand" "")))
18543    (clobber (match_operand 6 "" ""))
18544    (clobber (reg:CC FLAGS_REG))]
18545   "SSE_REG_P (operands[0]) && reload_completed"
18546   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18547    (set (match_dup 2) (and:V2DF (match_dup 2)
18548                                 (match_dup 8)))
18549    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18550                                           (match_dup 3)))
18551    (set (match_dup 0) (ior:V2DF (match_dup 6)
18552                                 (match_dup 7)))]
18553 {
18554   if (GET_MODE (operands[2]) == DFmode
18555       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18556     {
18557       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18558       emit_insn (gen_sse2_unpcklpd (op, op, op));
18559       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18560       emit_insn (gen_sse2_unpcklpd (op, op, op));
18561     }
18562
18563   /* If op2 == op3, op3 would be clobbered before it is used.  */
18564   if (operands_match_p (operands[2], operands[3]))
18565     {
18566       emit_move_insn (operands[0], operands[2]);
18567       DONE;
18568     }
18569
18570   PUT_MODE (operands[1], GET_MODE (operands[0]));
18571   if (operands_match_p (operands[0], operands[4]))
18572     operands[6] = operands[4], operands[7] = operands[2];
18573   else
18574     operands[6] = operands[2], operands[7] = operands[4];
18575   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18576   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18577   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18578   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18579   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18580   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18581 })
18582
18583 ;; Special case of conditional move we can handle effectively.
18584 ;; Do not brother with the integer/floating point case, since these are
18585 ;; bot considerably slower, unlike in the generic case.
18586 (define_insn "*sse_movsfcc_const0_1"
18587   [(set (match_operand:SF 0 "register_operand" "=&x")
18588         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18589                         [(match_operand:SF 4 "register_operand" "0")
18590                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18591                       (match_operand:SF 2 "register_operand" "x")
18592                       (match_operand:SF 3 "const0_operand" "X")))]
18593   "TARGET_SSE"
18594   "#")
18595
18596 (define_insn "*sse_movsfcc_const0_2"
18597   [(set (match_operand:SF 0 "register_operand" "=&x")
18598         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18599                         [(match_operand:SF 4 "register_operand" "0")
18600                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18601                       (match_operand:SF 2 "const0_operand" "X")
18602                       (match_operand:SF 3 "register_operand" "x")))]
18603   "TARGET_SSE"
18604   "#")
18605
18606 (define_insn "*sse_movsfcc_const0_3"
18607   [(set (match_operand:SF 0 "register_operand" "=&x")
18608         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18609                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18610                          (match_operand:SF 5 "register_operand" "0")])
18611                       (match_operand:SF 2 "register_operand" "x")
18612                       (match_operand:SF 3 "const0_operand" "X")))]
18613   "TARGET_SSE"
18614   "#")
18615
18616 (define_insn "*sse_movsfcc_const0_4"
18617   [(set (match_operand:SF 0 "register_operand" "=&x")
18618         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18619                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18620                          (match_operand:SF 5 "register_operand" "0")])
18621                       (match_operand:SF 2 "const0_operand" "X")
18622                       (match_operand:SF 3 "register_operand" "x")))]
18623   "TARGET_SSE"
18624   "#")
18625
18626 (define_insn "*sse_movdfcc_const0_1"
18627   [(set (match_operand:DF 0 "register_operand" "=&Y")
18628         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18629                         [(match_operand:DF 4 "register_operand" "0")
18630                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18631                       (match_operand:DF 2 "register_operand" "Y")
18632                       (match_operand:DF 3 "const0_operand" "X")))]
18633   "TARGET_SSE2"
18634   "#")
18635
18636 (define_insn "*sse_movdfcc_const0_2"
18637   [(set (match_operand:DF 0 "register_operand" "=&Y")
18638         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18639                         [(match_operand:DF 4 "register_operand" "0")
18640                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18641                       (match_operand:DF 2 "const0_operand" "X")
18642                       (match_operand:DF 3 "register_operand" "Y")))]
18643   "TARGET_SSE2"
18644   "#")
18645
18646 (define_insn "*sse_movdfcc_const0_3"
18647   [(set (match_operand:DF 0 "register_operand" "=&Y")
18648         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18649                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18650                          (match_operand:DF 5 "register_operand" "0")])
18651                       (match_operand:DF 2 "register_operand" "Y")
18652                       (match_operand:DF 3 "const0_operand" "X")))]
18653   "TARGET_SSE2"
18654   "#")
18655
18656 (define_insn "*sse_movdfcc_const0_4"
18657   [(set (match_operand:DF 0 "register_operand" "=&Y")
18658         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18659                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18660                          (match_operand:DF 5 "register_operand" "0")])
18661                       (match_operand:DF 2 "const0_operand" "X")
18662                       (match_operand:DF 3 "register_operand" "Y")))]
18663   "TARGET_SSE2"
18664   "#")
18665
18666 (define_split
18667   [(set (match_operand:SF 0 "register_operand" "")
18668         (if_then_else (match_operator 1 "comparison_operator"
18669                         [(match_operand:SF 4 "nonimmediate_operand" "")
18670                          (match_operand:SF 5 "nonimmediate_operand" "")])
18671                       (match_operand:SF 2 "nonmemory_operand" "")
18672                       (match_operand:SF 3 "nonmemory_operand" "")))]
18673   "SSE_REG_P (operands[0]) && reload_completed
18674    && (const0_operand (operands[2], GET_MODE (operands[0]))
18675        || const0_operand (operands[3], GET_MODE (operands[0])))"
18676   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18677    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18678 {
18679   PUT_MODE (operands[1], GET_MODE (operands[0]));
18680   if (!sse_comparison_operator (operands[1], VOIDmode)
18681       || !rtx_equal_p (operands[0], operands[4]))
18682     {
18683       rtx tmp = operands[5];
18684       operands[5] = operands[4];
18685       operands[4] = tmp;
18686       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18687     }
18688   if (!rtx_equal_p (operands[0], operands[4]))
18689     abort ();
18690   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18691   if (const0_operand (operands[2], GET_MODE (operands[2])))
18692     {
18693       operands[7] = operands[3];
18694       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18695     }
18696   else
18697     {
18698       operands[7] = operands[2];
18699       operands[6] = operands[8];
18700     }
18701   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18702 })
18703
18704 (define_split
18705   [(set (match_operand:DF 0 "register_operand" "")
18706         (if_then_else (match_operator 1 "comparison_operator"
18707                         [(match_operand:DF 4 "nonimmediate_operand" "")
18708                          (match_operand:DF 5 "nonimmediate_operand" "")])
18709                       (match_operand:DF 2 "nonmemory_operand" "")
18710                       (match_operand:DF 3 "nonmemory_operand" "")))]
18711   "SSE_REG_P (operands[0]) && reload_completed
18712    && (const0_operand (operands[2], GET_MODE (operands[0]))
18713        || const0_operand (operands[3], GET_MODE (operands[0])))"
18714   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18715    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18716 {
18717   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18718       && GET_MODE (operands[2]) == DFmode)
18719     {
18720       if (REG_P (operands[2]))
18721         {
18722           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18723           emit_insn (gen_sse2_unpcklpd (op, op, op));
18724         }
18725       if (REG_P (operands[3]))
18726         {
18727           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18728           emit_insn (gen_sse2_unpcklpd (op, op, op));
18729         }
18730     }
18731   PUT_MODE (operands[1], GET_MODE (operands[0]));
18732   if (!sse_comparison_operator (operands[1], VOIDmode)
18733       || !rtx_equal_p (operands[0], operands[4]))
18734     {
18735       rtx tmp = operands[5];
18736       operands[5] = operands[4];
18737       operands[4] = tmp;
18738       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18739     }
18740   if (!rtx_equal_p (operands[0], operands[4]))
18741     abort ();
18742   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18743   if (const0_operand (operands[2], GET_MODE (operands[2])))
18744     {
18745       operands[7] = operands[3];
18746       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18747     }
18748   else
18749     {
18750       operands[7] = operands[2];
18751       operands[6] = operands[8];
18752     }
18753   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18754 })
18755
18756 (define_expand "allocate_stack_worker"
18757   [(match_operand:SI 0 "register_operand" "")]
18758   "TARGET_STACK_PROBE"
18759 {
18760   if (reload_completed)
18761     {
18762       if (TARGET_64BIT)
18763         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18764       else
18765         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18766     }
18767   else
18768     {
18769       if (TARGET_64BIT)
18770         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18771       else
18772         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18773     }
18774   DONE;
18775 })
18776
18777 (define_insn "allocate_stack_worker_1"
18778   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18779     UNSPECV_STACK_PROBE)
18780    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18781    (clobber (match_scratch:SI 1 "=0"))
18782    (clobber (reg:CC FLAGS_REG))]
18783   "!TARGET_64BIT && TARGET_STACK_PROBE"
18784   "call\t__alloca"
18785   [(set_attr "type" "multi")
18786    (set_attr "length" "5")])
18787
18788 (define_expand "allocate_stack_worker_postreload"
18789   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18790                                     UNSPECV_STACK_PROBE)
18791               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18792               (clobber (match_dup 0))
18793               (clobber (reg:CC FLAGS_REG))])]
18794   ""
18795   "")
18796
18797 (define_insn "allocate_stack_worker_rex64"
18798   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18799     UNSPECV_STACK_PROBE)
18800    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18801    (clobber (match_scratch:DI 1 "=0"))
18802    (clobber (reg:CC FLAGS_REG))]
18803   "TARGET_64BIT && TARGET_STACK_PROBE"
18804   "call\t__alloca"
18805   [(set_attr "type" "multi")
18806    (set_attr "length" "5")])
18807
18808 (define_expand "allocate_stack_worker_rex64_postreload"
18809   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18810                                     UNSPECV_STACK_PROBE)
18811               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18812               (clobber (match_dup 0))
18813               (clobber (reg:CC FLAGS_REG))])]
18814   ""
18815   "")
18816
18817 (define_expand "allocate_stack"
18818   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18819                    (minus:SI (reg:SI SP_REG)
18820                              (match_operand:SI 1 "general_operand" "")))
18821               (clobber (reg:CC FLAGS_REG))])
18822    (parallel [(set (reg:SI SP_REG)
18823                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18824               (clobber (reg:CC FLAGS_REG))])]
18825   "TARGET_STACK_PROBE"
18826 {
18827 #ifdef CHECK_STACK_LIMIT
18828   if (GET_CODE (operands[1]) == CONST_INT
18829       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18830     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18831                            operands[1]));
18832   else 
18833 #endif
18834     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18835                                                             operands[1])));
18836
18837   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18838   DONE;
18839 })
18840
18841 (define_expand "builtin_setjmp_receiver"
18842   [(label_ref (match_operand 0 "" ""))]
18843   "!TARGET_64BIT && flag_pic"
18844 {
18845   emit_insn (gen_set_got (pic_offset_table_rtx));
18846   DONE;
18847 })
18848 \f
18849 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18850
18851 (define_split
18852   [(set (match_operand 0 "register_operand" "")
18853         (match_operator 3 "promotable_binary_operator"
18854            [(match_operand 1 "register_operand" "")
18855             (match_operand 2 "aligned_operand" "")]))
18856    (clobber (reg:CC FLAGS_REG))]
18857   "! TARGET_PARTIAL_REG_STALL && reload_completed
18858    && ((GET_MODE (operands[0]) == HImode 
18859         && ((!optimize_size && !TARGET_FAST_PREFIX)
18860             || GET_CODE (operands[2]) != CONST_INT
18861             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18862        || (GET_MODE (operands[0]) == QImode 
18863            && (TARGET_PROMOTE_QImode || optimize_size)))"
18864   [(parallel [(set (match_dup 0)
18865                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   "operands[0] = gen_lowpart (SImode, operands[0]);
18868    operands[1] = gen_lowpart (SImode, operands[1]);
18869    if (GET_CODE (operands[3]) != ASHIFT)
18870      operands[2] = gen_lowpart (SImode, operands[2]);
18871    PUT_MODE (operands[3], SImode);")
18872
18873 ; Promote the QImode tests, as i386 has encoding of the AND
18874 ; instruction with 32-bit sign-extended immediate and thus the
18875 ; instruction size is unchanged, except in the %eax case for
18876 ; which it is increased by one byte, hence the ! optimize_size.
18877 (define_split
18878   [(set (reg 17)
18879         (compare (and (match_operand 1 "aligned_operand" "")
18880                       (match_operand 2 "const_int_operand" ""))
18881                  (const_int 0)))
18882    (set (match_operand 0 "register_operand" "")
18883         (and (match_dup 1) (match_dup 2)))]
18884   "! TARGET_PARTIAL_REG_STALL && reload_completed
18885    /* Ensure that the operand will remain sign-extended immediate.  */
18886    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18887    && ! optimize_size
18888    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18889        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18890   [(parallel [(set (reg:CCNO FLAGS_REG)
18891                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18892                                  (const_int 0)))
18893               (set (match_dup 0)
18894                    (and:SI (match_dup 1) (match_dup 2)))])]
18895   "operands[2]
18896      = gen_int_mode (INTVAL (operands[2])
18897                      & GET_MODE_MASK (GET_MODE (operands[0])),
18898                      SImode);
18899    operands[0] = gen_lowpart (SImode, operands[0]);
18900    operands[1] = gen_lowpart (SImode, operands[1]);")
18901
18902 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18903 ; the TEST instruction with 32-bit sign-extended immediate and thus
18904 ; the instruction size would at least double, which is not what we
18905 ; want even with ! optimize_size.
18906 (define_split
18907   [(set (reg 17)
18908         (compare (and (match_operand:HI 0 "aligned_operand" "")
18909                       (match_operand:HI 1 "const_int_operand" ""))
18910                  (const_int 0)))]
18911   "! TARGET_PARTIAL_REG_STALL && reload_completed
18912    /* Ensure that the operand will remain sign-extended immediate.  */
18913    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18914    && ! TARGET_FAST_PREFIX
18915    && ! optimize_size"
18916   [(set (reg:CCNO FLAGS_REG)
18917         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18918                       (const_int 0)))]
18919   "operands[1]
18920      = gen_int_mode (INTVAL (operands[1])
18921                      & GET_MODE_MASK (GET_MODE (operands[0])),
18922                      SImode);
18923    operands[0] = gen_lowpart (SImode, operands[0]);")
18924
18925 (define_split
18926   [(set (match_operand 0 "register_operand" "")
18927         (neg (match_operand 1 "register_operand" "")))
18928    (clobber (reg:CC FLAGS_REG))]
18929   "! TARGET_PARTIAL_REG_STALL && reload_completed
18930    && (GET_MODE (operands[0]) == HImode
18931        || (GET_MODE (operands[0]) == QImode 
18932            && (TARGET_PROMOTE_QImode || optimize_size)))"
18933   [(parallel [(set (match_dup 0)
18934                    (neg:SI (match_dup 1)))
18935               (clobber (reg:CC FLAGS_REG))])]
18936   "operands[0] = gen_lowpart (SImode, operands[0]);
18937    operands[1] = gen_lowpart (SImode, operands[1]);")
18938
18939 (define_split
18940   [(set (match_operand 0 "register_operand" "")
18941         (not (match_operand 1 "register_operand" "")))]
18942   "! TARGET_PARTIAL_REG_STALL && reload_completed
18943    && (GET_MODE (operands[0]) == HImode
18944        || (GET_MODE (operands[0]) == QImode 
18945            && (TARGET_PROMOTE_QImode || optimize_size)))"
18946   [(set (match_dup 0)
18947         (not:SI (match_dup 1)))]
18948   "operands[0] = gen_lowpart (SImode, operands[0]);
18949    operands[1] = gen_lowpart (SImode, operands[1]);")
18950
18951 (define_split 
18952   [(set (match_operand 0 "register_operand" "")
18953         (if_then_else (match_operator 1 "comparison_operator" 
18954                                 [(reg 17) (const_int 0)])
18955                       (match_operand 2 "register_operand" "")
18956                       (match_operand 3 "register_operand" "")))]
18957   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18958    && (GET_MODE (operands[0]) == HImode
18959        || (GET_MODE (operands[0]) == QImode 
18960            && (TARGET_PROMOTE_QImode || optimize_size)))"
18961   [(set (match_dup 0)
18962         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18963   "operands[0] = gen_lowpart (SImode, operands[0]);
18964    operands[2] = gen_lowpart (SImode, operands[2]);
18965    operands[3] = gen_lowpart (SImode, operands[3]);")
18966                         
18967 \f
18968 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18969 ;; transform a complex memory operation into two memory to register operations.
18970
18971 ;; Don't push memory operands
18972 (define_peephole2
18973   [(set (match_operand:SI 0 "push_operand" "")
18974         (match_operand:SI 1 "memory_operand" ""))
18975    (match_scratch:SI 2 "r")]
18976   "! optimize_size && ! TARGET_PUSH_MEMORY"
18977   [(set (match_dup 2) (match_dup 1))
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18980
18981 (define_peephole2
18982   [(set (match_operand:DI 0 "push_operand" "")
18983         (match_operand:DI 1 "memory_operand" ""))
18984    (match_scratch:DI 2 "r")]
18985   "! optimize_size && ! TARGET_PUSH_MEMORY"
18986   [(set (match_dup 2) (match_dup 1))
18987    (set (match_dup 0) (match_dup 2))]
18988   "")
18989
18990 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18991 ;; SImode pushes.
18992 (define_peephole2
18993   [(set (match_operand:SF 0 "push_operand" "")
18994         (match_operand:SF 1 "memory_operand" ""))
18995    (match_scratch:SF 2 "r")]
18996   "! optimize_size && ! TARGET_PUSH_MEMORY"
18997   [(set (match_dup 2) (match_dup 1))
18998    (set (match_dup 0) (match_dup 2))]
18999   "")
19000
19001 (define_peephole2
19002   [(set (match_operand:HI 0 "push_operand" "")
19003         (match_operand:HI 1 "memory_operand" ""))
19004    (match_scratch:HI 2 "r")]
19005   "! optimize_size && ! TARGET_PUSH_MEMORY"
19006   [(set (match_dup 2) (match_dup 1))
19007    (set (match_dup 0) (match_dup 2))]
19008   "")
19009
19010 (define_peephole2
19011   [(set (match_operand:QI 0 "push_operand" "")
19012         (match_operand:QI 1 "memory_operand" ""))
19013    (match_scratch:QI 2 "q")]
19014   "! optimize_size && ! TARGET_PUSH_MEMORY"
19015   [(set (match_dup 2) (match_dup 1))
19016    (set (match_dup 0) (match_dup 2))]
19017   "")
19018
19019 ;; Don't move an immediate directly to memory when the instruction
19020 ;; gets too big.
19021 (define_peephole2
19022   [(match_scratch:SI 1 "r")
19023    (set (match_operand:SI 0 "memory_operand" "")
19024         (const_int 0))]
19025   "! optimize_size
19026    && ! TARGET_USE_MOV0
19027    && TARGET_SPLIT_LONG_MOVES
19028    && get_attr_length (insn) >= ix86_cost->large_insn
19029    && peep2_regno_dead_p (0, FLAGS_REG)"
19030   [(parallel [(set (match_dup 1) (const_int 0))
19031               (clobber (reg:CC FLAGS_REG))])
19032    (set (match_dup 0) (match_dup 1))]
19033   "")
19034
19035 (define_peephole2
19036   [(match_scratch:HI 1 "r")
19037    (set (match_operand:HI 0 "memory_operand" "")
19038         (const_int 0))]
19039   "! optimize_size
19040    && ! TARGET_USE_MOV0
19041    && TARGET_SPLIT_LONG_MOVES
19042    && get_attr_length (insn) >= ix86_cost->large_insn
19043    && peep2_regno_dead_p (0, FLAGS_REG)"
19044   [(parallel [(set (match_dup 2) (const_int 0))
19045               (clobber (reg:CC FLAGS_REG))])
19046    (set (match_dup 0) (match_dup 1))]
19047   "operands[2] = gen_lowpart (SImode, operands[1]);")
19048
19049 (define_peephole2
19050   [(match_scratch:QI 1 "q")
19051    (set (match_operand:QI 0 "memory_operand" "")
19052         (const_int 0))]
19053   "! optimize_size
19054    && ! TARGET_USE_MOV0
19055    && TARGET_SPLIT_LONG_MOVES
19056    && get_attr_length (insn) >= ix86_cost->large_insn
19057    && peep2_regno_dead_p (0, FLAGS_REG)"
19058   [(parallel [(set (match_dup 2) (const_int 0))
19059               (clobber (reg:CC FLAGS_REG))])
19060    (set (match_dup 0) (match_dup 1))]
19061   "operands[2] = gen_lowpart (SImode, operands[1]);")
19062
19063 (define_peephole2
19064   [(match_scratch:SI 2 "r")
19065    (set (match_operand:SI 0 "memory_operand" "")
19066         (match_operand:SI 1 "immediate_operand" ""))]
19067   "! optimize_size
19068    && get_attr_length (insn) >= ix86_cost->large_insn
19069    && TARGET_SPLIT_LONG_MOVES"
19070   [(set (match_dup 2) (match_dup 1))
19071    (set (match_dup 0) (match_dup 2))]
19072   "")
19073
19074 (define_peephole2
19075   [(match_scratch:HI 2 "r")
19076    (set (match_operand:HI 0 "memory_operand" "")
19077         (match_operand:HI 1 "immediate_operand" ""))]
19078   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19079   && TARGET_SPLIT_LONG_MOVES"
19080   [(set (match_dup 2) (match_dup 1))
19081    (set (match_dup 0) (match_dup 2))]
19082   "")
19083
19084 (define_peephole2
19085   [(match_scratch:QI 2 "q")
19086    (set (match_operand:QI 0 "memory_operand" "")
19087         (match_operand:QI 1 "immediate_operand" ""))]
19088   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19089   && TARGET_SPLIT_LONG_MOVES"
19090   [(set (match_dup 2) (match_dup 1))
19091    (set (match_dup 0) (match_dup 2))]
19092   "")
19093
19094 ;; Don't compare memory with zero, load and use a test instead.
19095 (define_peephole2
19096   [(set (reg 17)
19097         (compare (match_operand:SI 0 "memory_operand" "")
19098                  (const_int 0)))
19099    (match_scratch:SI 3 "r")]
19100   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19101   [(set (match_dup 3) (match_dup 0))
19102    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19103   "")
19104
19105 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19106 ;; Don't split NOTs with a displacement operand, because resulting XOR
19107 ;; will not be pairable anyway.
19108 ;;
19109 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19110 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19111 ;; so this split helps here as well.
19112 ;;
19113 ;; Note: Can't do this as a regular split because we can't get proper
19114 ;; lifetime information then.
19115
19116 (define_peephole2
19117   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19118         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19119   "!optimize_size
19120    && peep2_regno_dead_p (0, FLAGS_REG)
19121    && ((TARGET_PENTIUM 
19122         && (GET_CODE (operands[0]) != MEM
19123             || !memory_displacement_operand (operands[0], SImode)))
19124        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19125   [(parallel [(set (match_dup 0)
19126                    (xor:SI (match_dup 1) (const_int -1)))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   "")
19129
19130 (define_peephole2
19131   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19132         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19133   "!optimize_size
19134    && peep2_regno_dead_p (0, FLAGS_REG)
19135    && ((TARGET_PENTIUM 
19136         && (GET_CODE (operands[0]) != MEM
19137             || !memory_displacement_operand (operands[0], HImode)))
19138        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19139   [(parallel [(set (match_dup 0)
19140                    (xor:HI (match_dup 1) (const_int -1)))
19141               (clobber (reg:CC FLAGS_REG))])]
19142   "")
19143
19144 (define_peephole2
19145   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19146         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19147   "!optimize_size
19148    && peep2_regno_dead_p (0, FLAGS_REG)
19149    && ((TARGET_PENTIUM 
19150         && (GET_CODE (operands[0]) != MEM
19151             || !memory_displacement_operand (operands[0], QImode)))
19152        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19153   [(parallel [(set (match_dup 0)
19154                    (xor:QI (match_dup 1) (const_int -1)))
19155               (clobber (reg:CC FLAGS_REG))])]
19156   "")
19157
19158 ;; Non pairable "test imm, reg" instructions can be translated to
19159 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19160 ;; byte opcode instead of two, have a short form for byte operands),
19161 ;; so do it for other CPUs as well.  Given that the value was dead,
19162 ;; this should not create any new dependencies.  Pass on the sub-word
19163 ;; versions if we're concerned about partial register stalls.
19164
19165 (define_peephole2
19166   [(set (reg 17)
19167         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19168                          (match_operand:SI 1 "immediate_operand" ""))
19169                  (const_int 0)))]
19170   "ix86_match_ccmode (insn, CCNOmode)
19171    && (true_regnum (operands[0]) != 0
19172        || (GET_CODE (operands[1]) == CONST_INT
19173            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19174    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19175   [(parallel
19176      [(set (reg:CCNO FLAGS_REG)
19177            (compare:CCNO (and:SI (match_dup 0)
19178                                  (match_dup 1))
19179                          (const_int 0)))
19180       (set (match_dup 0)
19181            (and:SI (match_dup 0) (match_dup 1)))])]
19182   "")
19183
19184 ;; We don't need to handle HImode case, because it will be promoted to SImode
19185 ;; on ! TARGET_PARTIAL_REG_STALL
19186
19187 (define_peephole2
19188   [(set (reg 17)
19189         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19190                          (match_operand:QI 1 "immediate_operand" ""))
19191                  (const_int 0)))]
19192   "! TARGET_PARTIAL_REG_STALL
19193    && ix86_match_ccmode (insn, CCNOmode)
19194    && true_regnum (operands[0]) != 0
19195    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19196   [(parallel
19197      [(set (reg:CCNO FLAGS_REG)
19198            (compare:CCNO (and:QI (match_dup 0)
19199                                  (match_dup 1))
19200                          (const_int 0)))
19201       (set (match_dup 0)
19202            (and:QI (match_dup 0) (match_dup 1)))])]
19203   "")
19204
19205 (define_peephole2
19206   [(set (reg 17)
19207         (compare
19208           (and:SI
19209             (zero_extract:SI
19210               (match_operand 0 "ext_register_operand" "")
19211               (const_int 8)
19212               (const_int 8))
19213             (match_operand 1 "const_int_operand" ""))
19214           (const_int 0)))]
19215   "! TARGET_PARTIAL_REG_STALL
19216    && ix86_match_ccmode (insn, CCNOmode)
19217    && true_regnum (operands[0]) != 0
19218    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19219   [(parallel [(set (reg:CCNO FLAGS_REG)
19220                    (compare:CCNO
19221                        (and:SI
19222                          (zero_extract:SI
19223                          (match_dup 0)
19224                          (const_int 8)
19225                          (const_int 8))
19226                         (match_dup 1))
19227                    (const_int 0)))
19228               (set (zero_extract:SI (match_dup 0)
19229                                     (const_int 8)
19230                                     (const_int 8))
19231                    (and:SI 
19232                      (zero_extract:SI
19233                        (match_dup 0)
19234                        (const_int 8)
19235                        (const_int 8))
19236                      (match_dup 1)))])]
19237   "")
19238
19239 ;; Don't do logical operations with memory inputs.
19240 (define_peephole2
19241   [(match_scratch:SI 2 "r")
19242    (parallel [(set (match_operand:SI 0 "register_operand" "")
19243                    (match_operator:SI 3 "arith_or_logical_operator"
19244                      [(match_dup 0)
19245                       (match_operand:SI 1 "memory_operand" "")]))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "! optimize_size && ! TARGET_READ_MODIFY"
19248   [(set (match_dup 2) (match_dup 1))
19249    (parallel [(set (match_dup 0)
19250                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19251               (clobber (reg:CC FLAGS_REG))])]
19252   "")
19253
19254 (define_peephole2
19255   [(match_scratch:SI 2 "r")
19256    (parallel [(set (match_operand:SI 0 "register_operand" "")
19257                    (match_operator:SI 3 "arith_or_logical_operator"
19258                      [(match_operand:SI 1 "memory_operand" "")
19259                       (match_dup 0)]))
19260               (clobber (reg:CC FLAGS_REG))])]
19261   "! optimize_size && ! TARGET_READ_MODIFY"
19262   [(set (match_dup 2) (match_dup 1))
19263    (parallel [(set (match_dup 0)
19264                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19265               (clobber (reg:CC FLAGS_REG))])]
19266   "")
19267
19268 ; Don't do logical operations with memory outputs
19269 ;
19270 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19271 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19272 ; the same decoder scheduling characteristics as the original.
19273
19274 (define_peephole2
19275   [(match_scratch:SI 2 "r")
19276    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19277                    (match_operator:SI 3 "arith_or_logical_operator"
19278                      [(match_dup 0)
19279                       (match_operand:SI 1 "nonmemory_operand" "")]))
19280               (clobber (reg:CC FLAGS_REG))])]
19281   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19282   [(set (match_dup 2) (match_dup 0))
19283    (parallel [(set (match_dup 2)
19284                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19285               (clobber (reg:CC FLAGS_REG))])
19286    (set (match_dup 0) (match_dup 2))]
19287   "")
19288
19289 (define_peephole2
19290   [(match_scratch:SI 2 "r")
19291    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19292                    (match_operator:SI 3 "arith_or_logical_operator"
19293                      [(match_operand:SI 1 "nonmemory_operand" "")
19294                       (match_dup 0)]))
19295               (clobber (reg:CC FLAGS_REG))])]
19296   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19297   [(set (match_dup 2) (match_dup 0))
19298    (parallel [(set (match_dup 2)
19299                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19300               (clobber (reg:CC FLAGS_REG))])
19301    (set (match_dup 0) (match_dup 2))]
19302   "")
19303
19304 ;; Attempt to always use XOR for zeroing registers.
19305 (define_peephole2
19306   [(set (match_operand 0 "register_operand" "")
19307         (const_int 0))]
19308   "(GET_MODE (operands[0]) == QImode
19309     || GET_MODE (operands[0]) == HImode
19310     || GET_MODE (operands[0]) == SImode
19311     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19312    && (! TARGET_USE_MOV0 || optimize_size)
19313    && peep2_regno_dead_p (0, FLAGS_REG)"
19314   [(parallel [(set (match_dup 0) (const_int 0))
19315               (clobber (reg:CC FLAGS_REG))])]
19316   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19317                               operands[0]);")
19318
19319 (define_peephole2
19320   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19321         (const_int 0))]
19322   "(GET_MODE (operands[0]) == QImode
19323     || GET_MODE (operands[0]) == HImode)
19324    && (! TARGET_USE_MOV0 || optimize_size)
19325    && peep2_regno_dead_p (0, FLAGS_REG)"
19326   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19327               (clobber (reg:CC FLAGS_REG))])])
19328
19329 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19330 (define_peephole2
19331   [(set (match_operand 0 "register_operand" "")
19332         (const_int -1))]
19333   "(GET_MODE (operands[0]) == HImode
19334     || GET_MODE (operands[0]) == SImode 
19335     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19336    && (optimize_size || TARGET_PENTIUM)
19337    && peep2_regno_dead_p (0, FLAGS_REG)"
19338   [(parallel [(set (match_dup 0) (const_int -1))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19341                               operands[0]);")
19342
19343 ;; Attempt to convert simple leas to adds. These can be created by
19344 ;; move expanders.
19345 (define_peephole2
19346   [(set (match_operand:SI 0 "register_operand" "")
19347         (plus:SI (match_dup 0)
19348                  (match_operand:SI 1 "nonmemory_operand" "")))]
19349   "peep2_regno_dead_p (0, FLAGS_REG)"
19350   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19351               (clobber (reg:CC FLAGS_REG))])]
19352   "")
19353
19354 (define_peephole2
19355   [(set (match_operand:SI 0 "register_operand" "")
19356         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19357                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19358   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19359   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19360               (clobber (reg:CC FLAGS_REG))])]
19361   "operands[2] = gen_lowpart (SImode, operands[2]);")
19362
19363 (define_peephole2
19364   [(set (match_operand:DI 0 "register_operand" "")
19365         (plus:DI (match_dup 0)
19366                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19367   "peep2_regno_dead_p (0, FLAGS_REG)"
19368   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19369               (clobber (reg:CC FLAGS_REG))])]
19370   "")
19371
19372 (define_peephole2
19373   [(set (match_operand:SI 0 "register_operand" "")
19374         (mult:SI (match_dup 0)
19375                  (match_operand:SI 1 "const_int_operand" "")))]
19376   "exact_log2 (INTVAL (operands[1])) >= 0
19377    && peep2_regno_dead_p (0, FLAGS_REG)"
19378   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19379               (clobber (reg:CC FLAGS_REG))])]
19380   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19381
19382 (define_peephole2
19383   [(set (match_operand:DI 0 "register_operand" "")
19384         (mult:DI (match_dup 0)
19385                  (match_operand:DI 1 "const_int_operand" "")))]
19386   "exact_log2 (INTVAL (operands[1])) >= 0
19387    && peep2_regno_dead_p (0, FLAGS_REG)"
19388   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19389               (clobber (reg:CC FLAGS_REG))])]
19390   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19391
19392 (define_peephole2
19393   [(set (match_operand:SI 0 "register_operand" "")
19394         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19395                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19396   "exact_log2 (INTVAL (operands[2])) >= 0
19397    && REGNO (operands[0]) == REGNO (operands[1])
19398    && peep2_regno_dead_p (0, FLAGS_REG)"
19399   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19400               (clobber (reg:CC FLAGS_REG))])]
19401   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19402
19403 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19404 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19405 ;; many CPUs it is also faster, since special hardware to avoid esp
19406 ;; dependencies is present.
19407
19408 ;; While some of these conversions may be done using splitters, we use peepholes
19409 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19410
19411 ;; Convert prologue esp subtractions to push.
19412 ;; We need register to push.  In order to keep verify_flow_info happy we have
19413 ;; two choices
19414 ;; - use scratch and clobber it in order to avoid dependencies
19415 ;; - use already live register
19416 ;; We can't use the second way right now, since there is no reliable way how to
19417 ;; verify that given register is live.  First choice will also most likely in
19418 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19419 ;; call clobbered registers are dead.  We may want to use base pointer as an
19420 ;; alternative when no register is available later.
19421
19422 (define_peephole2
19423   [(match_scratch:SI 0 "r")
19424    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19425               (clobber (reg:CC FLAGS_REG))
19426               (clobber (mem:BLK (scratch)))])]
19427   "optimize_size || !TARGET_SUB_ESP_4"
19428   [(clobber (match_dup 0))
19429    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19430               (clobber (mem:BLK (scratch)))])])
19431
19432 (define_peephole2
19433   [(match_scratch:SI 0 "r")
19434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19435               (clobber (reg:CC FLAGS_REG))
19436               (clobber (mem:BLK (scratch)))])]
19437   "optimize_size || !TARGET_SUB_ESP_8"
19438   [(clobber (match_dup 0))
19439    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19440    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19441               (clobber (mem:BLK (scratch)))])])
19442
19443 ;; Convert esp subtractions to push.
19444 (define_peephole2
19445   [(match_scratch:SI 0 "r")
19446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19447               (clobber (reg:CC FLAGS_REG))])]
19448   "optimize_size || !TARGET_SUB_ESP_4"
19449   [(clobber (match_dup 0))
19450    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19451
19452 (define_peephole2
19453   [(match_scratch:SI 0 "r")
19454    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "optimize_size || !TARGET_SUB_ESP_8"
19457   [(clobber (match_dup 0))
19458    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19459    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19460
19461 ;; Convert epilogue deallocator to pop.
19462 (define_peephole2
19463   [(match_scratch:SI 0 "r")
19464    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465               (clobber (reg:CC FLAGS_REG))
19466               (clobber (mem:BLK (scratch)))])]
19467   "optimize_size || !TARGET_ADD_ESP_4"
19468   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19469               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19470               (clobber (mem:BLK (scratch)))])]
19471   "")
19472
19473 ;; Two pops case is tricky, since pop causes dependency on destination register.
19474 ;; We use two registers if available.
19475 (define_peephole2
19476   [(match_scratch:SI 0 "r")
19477    (match_scratch:SI 1 "r")
19478    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19479               (clobber (reg:CC FLAGS_REG))
19480               (clobber (mem:BLK (scratch)))])]
19481   "optimize_size || !TARGET_ADD_ESP_8"
19482   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19483               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19484               (clobber (mem:BLK (scratch)))])
19485    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19486               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19487   "")
19488
19489 (define_peephole2
19490   [(match_scratch:SI 0 "r")
19491    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19492               (clobber (reg:CC FLAGS_REG))
19493               (clobber (mem:BLK (scratch)))])]
19494   "optimize_size"
19495   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19496               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19497               (clobber (mem:BLK (scratch)))])
19498    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19499               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19500   "")
19501
19502 ;; Convert esp additions to pop.
19503 (define_peephole2
19504   [(match_scratch:SI 0 "r")
19505    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19506               (clobber (reg:CC FLAGS_REG))])]
19507   ""
19508   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19509               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19510   "")
19511
19512 ;; Two pops case is tricky, since pop causes dependency on destination register.
19513 ;; We use two registers if available.
19514 (define_peephole2
19515   [(match_scratch:SI 0 "r")
19516    (match_scratch:SI 1 "r")
19517    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19518               (clobber (reg:CC FLAGS_REG))])]
19519   ""
19520   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19521               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19522    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19523               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19524   "")
19525
19526 (define_peephole2
19527   [(match_scratch:SI 0 "r")
19528    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19529               (clobber (reg:CC FLAGS_REG))])]
19530   "optimize_size"
19531   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19532               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19533    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19534               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19535   "")
19536 \f
19537 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19538 ;; required and register dies.
19539 (define_peephole2
19540   [(set (reg 17)
19541         (compare (match_operand:SI 0 "register_operand" "")
19542                  (match_operand:SI 1 "incdec_operand" "")))]
19543   "ix86_match_ccmode (insn, CCGCmode)
19544    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19545   [(parallel [(set (reg:CCGC FLAGS_REG)
19546                    (compare:CCGC (match_dup 0)
19547                                  (match_dup 1)))
19548               (clobber (match_dup 0))])]
19549   "")
19550
19551 (define_peephole2
19552   [(set (reg 17)
19553         (compare (match_operand:HI 0 "register_operand" "")
19554                  (match_operand:HI 1 "incdec_operand" "")))]
19555   "ix86_match_ccmode (insn, CCGCmode)
19556    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19557   [(parallel [(set (reg:CCGC FLAGS_REG)
19558                    (compare:CCGC (match_dup 0)
19559                                  (match_dup 1)))
19560               (clobber (match_dup 0))])]
19561   "")
19562
19563 (define_peephole2
19564   [(set (reg 17)
19565         (compare (match_operand:QI 0 "register_operand" "")
19566                  (match_operand:QI 1 "incdec_operand" "")))]
19567   "ix86_match_ccmode (insn, CCGCmode)
19568    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19569   [(parallel [(set (reg:CCGC FLAGS_REG)
19570                    (compare:CCGC (match_dup 0)
19571                                  (match_dup 1)))
19572               (clobber (match_dup 0))])]
19573   "")
19574
19575 ;; Convert compares with 128 to shorter add -128
19576 (define_peephole2
19577   [(set (reg 17)
19578         (compare (match_operand:SI 0 "register_operand" "")
19579                  (const_int 128)))]
19580   "ix86_match_ccmode (insn, CCGCmode)
19581    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19582   [(parallel [(set (reg:CCGC FLAGS_REG)
19583                    (compare:CCGC (match_dup 0)
19584                                  (const_int 128)))
19585               (clobber (match_dup 0))])]
19586   "")
19587
19588 (define_peephole2
19589   [(set (reg 17)
19590         (compare (match_operand:HI 0 "register_operand" "")
19591                  (const_int 128)))]
19592   "ix86_match_ccmode (insn, CCGCmode)
19593    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19594   [(parallel [(set (reg:CCGC FLAGS_REG)
19595                    (compare:CCGC (match_dup 0)
19596                                  (const_int 128)))
19597               (clobber (match_dup 0))])]
19598   "")
19599 \f
19600 (define_peephole2
19601   [(match_scratch:DI 0 "r")
19602    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19603               (clobber (reg:CC FLAGS_REG))
19604               (clobber (mem:BLK (scratch)))])]
19605   "optimize_size || !TARGET_SUB_ESP_4"
19606   [(clobber (match_dup 0))
19607    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19608               (clobber (mem:BLK (scratch)))])])
19609
19610 (define_peephole2
19611   [(match_scratch:DI 0 "r")
19612    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19613               (clobber (reg:CC FLAGS_REG))
19614               (clobber (mem:BLK (scratch)))])]
19615   "optimize_size || !TARGET_SUB_ESP_8"
19616   [(clobber (match_dup 0))
19617    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19618    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19619               (clobber (mem:BLK (scratch)))])])
19620
19621 ;; Convert esp subtractions to push.
19622 (define_peephole2
19623   [(match_scratch:DI 0 "r")
19624    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19625               (clobber (reg:CC FLAGS_REG))])]
19626   "optimize_size || !TARGET_SUB_ESP_4"
19627   [(clobber (match_dup 0))
19628    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19629
19630 (define_peephole2
19631   [(match_scratch:DI 0 "r")
19632    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19633               (clobber (reg:CC FLAGS_REG))])]
19634   "optimize_size || !TARGET_SUB_ESP_8"
19635   [(clobber (match_dup 0))
19636    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19637    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19638
19639 ;; Convert epilogue deallocator to pop.
19640 (define_peephole2
19641   [(match_scratch:DI 0 "r")
19642    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19643               (clobber (reg:CC FLAGS_REG))
19644               (clobber (mem:BLK (scratch)))])]
19645   "optimize_size || !TARGET_ADD_ESP_4"
19646   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19647               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19648               (clobber (mem:BLK (scratch)))])]
19649   "")
19650
19651 ;; Two pops case is tricky, since pop causes dependency on destination register.
19652 ;; We use two registers if available.
19653 (define_peephole2
19654   [(match_scratch:DI 0 "r")
19655    (match_scratch:DI 1 "r")
19656    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19657               (clobber (reg:CC FLAGS_REG))
19658               (clobber (mem:BLK (scratch)))])]
19659   "optimize_size || !TARGET_ADD_ESP_8"
19660   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19661               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19662               (clobber (mem:BLK (scratch)))])
19663    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19664               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19665   "")
19666
19667 (define_peephole2
19668   [(match_scratch:DI 0 "r")
19669    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19670               (clobber (reg:CC FLAGS_REG))
19671               (clobber (mem:BLK (scratch)))])]
19672   "optimize_size"
19673   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19674               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19675               (clobber (mem:BLK (scratch)))])
19676    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19678   "")
19679
19680 ;; Convert esp additions to pop.
19681 (define_peephole2
19682   [(match_scratch:DI 0 "r")
19683    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19684               (clobber (reg:CC FLAGS_REG))])]
19685   ""
19686   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19687               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19688   "")
19689
19690 ;; Two pops case is tricky, since pop causes dependency on destination register.
19691 ;; We use two registers if available.
19692 (define_peephole2
19693   [(match_scratch:DI 0 "r")
19694    (match_scratch:DI 1 "r")
19695    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19696               (clobber (reg:CC FLAGS_REG))])]
19697   ""
19698   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19699               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19700    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19701               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19702   "")
19703
19704 (define_peephole2
19705   [(match_scratch:DI 0 "r")
19706    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   "optimize_size"
19709   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19710               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19711    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19712               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19713   "")
19714 \f
19715 ;; Convert imul by three, five and nine into lea
19716 (define_peephole2
19717   [(parallel
19718     [(set (match_operand:SI 0 "register_operand" "")
19719           (mult:SI (match_operand:SI 1 "register_operand" "")
19720                    (match_operand:SI 2 "const_int_operand" "")))
19721      (clobber (reg:CC FLAGS_REG))])]
19722   "INTVAL (operands[2]) == 3
19723    || INTVAL (operands[2]) == 5
19724    || INTVAL (operands[2]) == 9"
19725   [(set (match_dup 0)
19726         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19727                  (match_dup 1)))]
19728   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19729
19730 (define_peephole2
19731   [(parallel
19732     [(set (match_operand:SI 0 "register_operand" "")
19733           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19734                    (match_operand:SI 2 "const_int_operand" "")))
19735      (clobber (reg:CC FLAGS_REG))])]
19736   "!optimize_size 
19737    && (INTVAL (operands[2]) == 3
19738        || INTVAL (operands[2]) == 5
19739        || INTVAL (operands[2]) == 9)"
19740   [(set (match_dup 0) (match_dup 1))
19741    (set (match_dup 0)
19742         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19743                  (match_dup 0)))]
19744   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19745
19746 (define_peephole2
19747   [(parallel
19748     [(set (match_operand:DI 0 "register_operand" "")
19749           (mult:DI (match_operand:DI 1 "register_operand" "")
19750                    (match_operand:DI 2 "const_int_operand" "")))
19751      (clobber (reg:CC FLAGS_REG))])]
19752   "TARGET_64BIT
19753    && (INTVAL (operands[2]) == 3
19754        || INTVAL (operands[2]) == 5
19755        || INTVAL (operands[2]) == 9)"
19756   [(set (match_dup 0)
19757         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19758                  (match_dup 1)))]
19759   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19760
19761 (define_peephole2
19762   [(parallel
19763     [(set (match_operand:DI 0 "register_operand" "")
19764           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19765                    (match_operand:DI 2 "const_int_operand" "")))
19766      (clobber (reg:CC FLAGS_REG))])]
19767   "TARGET_64BIT
19768    && !optimize_size 
19769    && (INTVAL (operands[2]) == 3
19770        || INTVAL (operands[2]) == 5
19771        || INTVAL (operands[2]) == 9)"
19772   [(set (match_dup 0) (match_dup 1))
19773    (set (match_dup 0)
19774         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19775                  (match_dup 0)))]
19776   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19777
19778 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19779 ;; imul $32bit_imm, reg, reg is direct decoded.
19780 (define_peephole2
19781   [(match_scratch:DI 3 "r")
19782    (parallel [(set (match_operand:DI 0 "register_operand" "")
19783                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19784                             (match_operand:DI 2 "immediate_operand" "")))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "TARGET_K8 && !optimize_size
19787    && (GET_CODE (operands[2]) != CONST_INT
19788        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19789   [(set (match_dup 3) (match_dup 1))
19790    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19791               (clobber (reg:CC FLAGS_REG))])]
19792 "")
19793
19794 (define_peephole2
19795   [(match_scratch:SI 3 "r")
19796    (parallel [(set (match_operand:SI 0 "register_operand" "")
19797                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19798                             (match_operand:SI 2 "immediate_operand" "")))
19799               (clobber (reg:CC FLAGS_REG))])]
19800   "TARGET_K8 && !optimize_size
19801    && (GET_CODE (operands[2]) != CONST_INT
19802        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19803   [(set (match_dup 3) (match_dup 1))
19804    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19805               (clobber (reg:CC FLAGS_REG))])]
19806 "")
19807
19808 (define_peephole2
19809   [(match_scratch:SI 3 "r")
19810    (parallel [(set (match_operand:DI 0 "register_operand" "")
19811                    (zero_extend:DI
19812                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19813                               (match_operand:SI 2 "immediate_operand" ""))))
19814               (clobber (reg:CC FLAGS_REG))])]
19815   "TARGET_K8 && !optimize_size
19816    && (GET_CODE (operands[2]) != CONST_INT
19817        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19818   [(set (match_dup 3) (match_dup 1))
19819    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19820               (clobber (reg:CC FLAGS_REG))])]
19821 "")
19822
19823 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19824 ;; Convert it into imul reg, reg
19825 ;; It would be better to force assembler to encode instruction using long
19826 ;; immediate, but there is apparently no way to do so.
19827 (define_peephole2
19828   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19829                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19830                             (match_operand:DI 2 "const_int_operand" "")))
19831               (clobber (reg:CC FLAGS_REG))])
19832    (match_scratch:DI 3 "r")]
19833   "TARGET_K8 && !optimize_size
19834    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19835   [(set (match_dup 3) (match_dup 2))
19836    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19837               (clobber (reg:CC FLAGS_REG))])]
19838 {
19839   if (!rtx_equal_p (operands[0], operands[1]))
19840     emit_move_insn (operands[0], operands[1]);
19841 })
19842
19843 (define_peephole2
19844   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19845                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19846                             (match_operand:SI 2 "const_int_operand" "")))
19847               (clobber (reg:CC FLAGS_REG))])
19848    (match_scratch:SI 3 "r")]
19849   "TARGET_K8 && !optimize_size
19850    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19851   [(set (match_dup 3) (match_dup 2))
19852    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19853               (clobber (reg:CC FLAGS_REG))])]
19854 {
19855   if (!rtx_equal_p (operands[0], operands[1]))
19856     emit_move_insn (operands[0], operands[1]);
19857 })
19858
19859 (define_peephole2
19860   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19861                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19862                             (match_operand:HI 2 "immediate_operand" "")))
19863               (clobber (reg:CC FLAGS_REG))])
19864    (match_scratch:HI 3 "r")]
19865   "TARGET_K8 && !optimize_size"
19866   [(set (match_dup 3) (match_dup 2))
19867    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19868               (clobber (reg:CC FLAGS_REG))])]
19869 {
19870   if (!rtx_equal_p (operands[0], operands[1]))
19871     emit_move_insn (operands[0], operands[1]);
19872 })
19873 \f
19874 ;; Call-value patterns last so that the wildcard operand does not
19875 ;; disrupt insn-recog's switch tables.
19876
19877 (define_insn "*call_value_pop_0"
19878   [(set (match_operand 0 "" "")
19879         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19880               (match_operand:SI 2 "" "")))
19881    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19882                             (match_operand:SI 3 "immediate_operand" "")))]
19883   "!TARGET_64BIT"
19884 {
19885   if (SIBLING_CALL_P (insn))
19886     return "jmp\t%P1";
19887   else
19888     return "call\t%P1";
19889 }
19890   [(set_attr "type" "callv")])
19891
19892 (define_insn "*call_value_pop_1"
19893   [(set (match_operand 0 "" "")
19894         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19895               (match_operand:SI 2 "" "")))
19896    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19897                             (match_operand:SI 3 "immediate_operand" "i")))]
19898   "!TARGET_64BIT"
19899 {
19900   if (constant_call_address_operand (operands[1], Pmode))
19901     {
19902       if (SIBLING_CALL_P (insn))
19903         return "jmp\t%P1";
19904       else
19905         return "call\t%P1";
19906     }
19907   if (SIBLING_CALL_P (insn))
19908     return "jmp\t%A1";
19909   else
19910     return "call\t%A1";
19911 }
19912   [(set_attr "type" "callv")])
19913
19914 (define_insn "*call_value_0"
19915   [(set (match_operand 0 "" "")
19916         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19917               (match_operand:SI 2 "" "")))]
19918   "!TARGET_64BIT"
19919 {
19920   if (SIBLING_CALL_P (insn))
19921     return "jmp\t%P1";
19922   else
19923     return "call\t%P1";
19924 }
19925   [(set_attr "type" "callv")])
19926
19927 (define_insn "*call_value_0_rex64"
19928   [(set (match_operand 0 "" "")
19929         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19930               (match_operand:DI 2 "const_int_operand" "")))]
19931   "TARGET_64BIT"
19932 {
19933   if (SIBLING_CALL_P (insn))
19934     return "jmp\t%P1";
19935   else
19936     return "call\t%P1";
19937 }
19938   [(set_attr "type" "callv")])
19939
19940 (define_insn "*call_value_1"
19941   [(set (match_operand 0 "" "")
19942         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19943               (match_operand:SI 2 "" "")))]
19944   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19945 {
19946   if (constant_call_address_operand (operands[1], Pmode))
19947     return "call\t%P1";
19948   return "call\t%*%1";
19949 }
19950   [(set_attr "type" "callv")])
19951
19952 (define_insn "*sibcall_value_1"
19953   [(set (match_operand 0 "" "")
19954         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19955               (match_operand:SI 2 "" "")))]
19956   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19957 {
19958   if (constant_call_address_operand (operands[1], Pmode))
19959     return "jmp\t%P1";
19960   return "jmp\t%*%1";
19961 }
19962   [(set_attr "type" "callv")])
19963
19964 (define_insn "*call_value_1_rex64"
19965   [(set (match_operand 0 "" "")
19966         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19967               (match_operand:DI 2 "" "")))]
19968   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19969 {
19970   if (constant_call_address_operand (operands[1], Pmode))
19971     return "call\t%P1";
19972   return "call\t%A1";
19973 }
19974   [(set_attr "type" "callv")])
19975
19976 (define_insn "*sibcall_value_1_rex64"
19977   [(set (match_operand 0 "" "")
19978         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19979               (match_operand:DI 2 "" "")))]
19980   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19981   "jmp\t%P1"
19982   [(set_attr "type" "callv")])
19983
19984 (define_insn "*sibcall_value_1_rex64_v"
19985   [(set (match_operand 0 "" "")
19986         (call (mem:QI (reg:DI 40))
19987               (match_operand:DI 1 "" "")))]
19988   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19989   "jmp\t*%%r11"
19990   [(set_attr "type" "callv")])
19991 \f
19992 (define_insn "trap"
19993   [(trap_if (const_int 1) (const_int 5))]
19994   ""
19995   "int\t$5")
19996
19997 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19998 ;;; for the sake of bounds checking.  By emitting bounds checks as
19999 ;;; conditional traps rather than as conditional jumps around
20000 ;;; unconditional traps we avoid introducing spurious basic-block
20001 ;;; boundaries and facilitate elimination of redundant checks.  In
20002 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
20003 ;;; interrupt 5.
20004 ;;; 
20005 ;;; FIXME: Static branch prediction rules for ix86 are such that
20006 ;;; forward conditional branches predict as untaken.  As implemented
20007 ;;; below, pseudo conditional traps violate that rule.  We should use
20008 ;;; .pushsection/.popsection to place all of the `int 5's in a special
20009 ;;; section loaded at the end of the text segment and branch forward
20010 ;;; there on bounds-failure, and then jump back immediately (in case
20011 ;;; the system chooses to ignore bounds violations, or to report
20012 ;;; violations and continue execution).
20013
20014 (define_expand "conditional_trap"
20015   [(trap_if (match_operator 0 "comparison_operator"
20016              [(match_dup 2) (const_int 0)])
20017             (match_operand 1 "const_int_operand" ""))]
20018   ""
20019 {
20020   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
20021                               ix86_expand_compare (GET_CODE (operands[0]),
20022                                                    NULL, NULL),
20023                               operands[1]));
20024   DONE;
20025 })
20026
20027 (define_insn "*conditional_trap_1"
20028   [(trap_if (match_operator 0 "comparison_operator"
20029              [(reg 17) (const_int 0)])
20030             (match_operand 1 "const_int_operand" ""))]
20031   ""
20032 {
20033   operands[2] = gen_label_rtx ();
20034   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
20035   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20036                              CODE_LABEL_NUMBER (operands[2]));
20037   RET;
20038 })
20039
20040         ;; Pentium III SIMD instructions.
20041
20042 ;; Moves for SSE/MMX regs.
20043
20044 (define_insn "movv4sf_internal"
20045   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20046         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
20047   "TARGET_SSE"
20048   "@
20049     xorps\t%0, %0
20050     movaps\t{%1, %0|%0, %1}
20051     movaps\t{%1, %0|%0, %1}"
20052   [(set_attr "type" "ssemov")
20053    (set_attr "mode" "V4SF")])
20054
20055 (define_split
20056   [(set (match_operand:V4SF 0 "register_operand" "")
20057         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
20058   "TARGET_SSE"
20059   [(set (match_dup 0)
20060         (vec_merge:V4SF
20061          (vec_duplicate:V4SF (match_dup 1))
20062          (match_dup 2)
20063          (const_int 1)))]
20064 {
20065   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20066   operands[2] = CONST0_RTX (V4SFmode);
20067 })
20068
20069 (define_insn "movv4si_internal"
20070   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20071         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20072   "TARGET_SSE"
20073 {
20074   switch (which_alternative)
20075     {
20076     case 0:
20077       if (get_attr_mode (insn) == MODE_V4SF)
20078         return "xorps\t%0, %0";
20079       else
20080         return "pxor\t%0, %0";
20081     case 1:
20082     case 2:
20083       if (get_attr_mode (insn) == MODE_V4SF)
20084         return "movaps\t{%1, %0|%0, %1}";
20085       else
20086         return "movdqa\t{%1, %0|%0, %1}";
20087     default:
20088       abort ();
20089     }
20090 }
20091   [(set_attr "type" "ssemov")
20092    (set (attr "mode")
20093         (cond [(eq_attr "alternative" "0,1")
20094                  (if_then_else
20095                    (ne (symbol_ref "optimize_size")
20096                        (const_int 0))
20097                    (const_string "V4SF")
20098                    (const_string "TI"))
20099                (eq_attr "alternative" "2")
20100                  (if_then_else
20101                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20102                             (const_int 0))
20103                         (ne (symbol_ref "optimize_size")
20104                             (const_int 0)))
20105                    (const_string "V4SF")
20106                    (const_string "TI"))]
20107                (const_string "TI")))])
20108
20109 (define_insn "movv2di_internal"
20110   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20111         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20112   "TARGET_SSE"
20113 {
20114   switch (which_alternative)
20115     {
20116     case 0:
20117       if (get_attr_mode (insn) == MODE_V4SF)
20118         return "xorps\t%0, %0";
20119       else
20120         return "pxor\t%0, %0";
20121     case 1:
20122     case 2:
20123       if (get_attr_mode (insn) == MODE_V4SF)
20124         return "movaps\t{%1, %0|%0, %1}";
20125       else
20126         return "movdqa\t{%1, %0|%0, %1}";
20127     default:
20128       abort ();
20129     }
20130 }
20131   [(set_attr "type" "ssemov")
20132    (set (attr "mode")
20133         (cond [(eq_attr "alternative" "0,1")
20134                  (if_then_else
20135                    (ne (symbol_ref "optimize_size")
20136                        (const_int 0))
20137                    (const_string "V4SF")
20138                    (const_string "TI"))
20139                (eq_attr "alternative" "2")
20140                  (if_then_else
20141                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20142                             (const_int 0))
20143                         (ne (symbol_ref "optimize_size")
20144                             (const_int 0)))
20145                    (const_string "V4SF")
20146                    (const_string "TI"))]
20147                (const_string "TI")))])
20148
20149 (define_split
20150   [(set (match_operand:V2DF 0 "register_operand" "")
20151         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20152   "TARGET_SSE2"
20153   [(set (match_dup 0)
20154         (vec_merge:V2DF
20155          (vec_duplicate:V2DF (match_dup 1))
20156          (match_dup 2)
20157          (const_int 1)))]
20158 {
20159   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20160   operands[2] = CONST0_RTX (V2DFmode);
20161 })
20162
20163 (define_insn "movv8qi_internal"
20164   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20165         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20166   "TARGET_MMX
20167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20168   "@
20169     pxor\t%0, %0
20170     movq\t{%1, %0|%0, %1}
20171     movq\t{%1, %0|%0, %1}
20172     movdq2q\t{%1, %0|%0, %1}
20173     movq2dq\t{%1, %0|%0, %1}
20174     movq\t{%1, %0|%0, %1}
20175     movq\t{%1, %0|%0, %1}"
20176   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20177    (set_attr "mode" "DI")])
20178
20179 (define_insn "movv4hi_internal"
20180   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20181         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20182   "TARGET_MMX
20183    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20184   "@
20185     pxor\t%0, %0
20186     movq\t{%1, %0|%0, %1}
20187     movq\t{%1, %0|%0, %1}
20188     movdq2q\t{%1, %0|%0, %1}
20189     movq2dq\t{%1, %0|%0, %1}
20190     movq\t{%1, %0|%0, %1}
20191     movq\t{%1, %0|%0, %1}"
20192   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20193    (set_attr "mode" "DI")])
20194
20195 (define_insn "*movv2si_internal"
20196   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20197         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20198   "TARGET_MMX
20199    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20200   "@
20201     pxor\t%0, %0
20202     movq\t{%1, %0|%0, %1}
20203     movq\t{%1, %0|%0, %1}
20204     movdq2q\t{%1, %0|%0, %1}
20205     movq2dq\t{%1, %0|%0, %1}
20206     movq\t{%1, %0|%0, %1}
20207     movq\t{%1, %0|%0, %1}"
20208   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20209    (set_attr "mode" "DI")])
20210
20211 (define_insn "movv2sf_internal"
20212   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20213         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20214   "TARGET_3DNOW
20215    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20216   "@
20217     pxor\t%0, %0
20218     movq\t{%1, %0|%0, %1}
20219     movq\t{%1, %0|%0, %1}
20220     movdq2q\t{%1, %0|%0, %1}
20221     movq2dq\t{%1, %0|%0, %1}
20222     movlps\t{%1, %0|%0, %1}
20223     movlps\t{%1, %0|%0, %1}"
20224   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20225    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20226
20227 (define_expand "movti"
20228   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20229         (match_operand:TI 1 "nonimmediate_operand" ""))]
20230   "TARGET_SSE || TARGET_64BIT"
20231 {
20232   if (TARGET_64BIT)
20233     ix86_expand_move (TImode, operands);
20234   else
20235     ix86_expand_vector_move (TImode, operands);
20236   DONE;
20237 })
20238
20239 (define_expand "movtf"
20240   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20241         (match_operand:TF 1 "nonimmediate_operand" ""))]
20242   "TARGET_64BIT"
20243 {
20244   if (TARGET_64BIT)
20245     ix86_expand_move (TFmode, operands);
20246   else
20247     ix86_expand_vector_move (TFmode, operands);
20248   DONE;
20249 })
20250
20251 (define_insn "movv2df_internal"
20252   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20253         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20254   "TARGET_SSE2
20255    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20256 {
20257   switch (which_alternative)
20258     {
20259     case 0:
20260       if (get_attr_mode (insn) == MODE_V4SF)
20261         return "xorps\t%0, %0";
20262       else
20263         return "xorpd\t%0, %0";
20264     case 1:
20265     case 2:
20266       if (get_attr_mode (insn) == MODE_V4SF)
20267         return "movaps\t{%1, %0|%0, %1}";
20268       else
20269         return "movapd\t{%1, %0|%0, %1}";
20270     default:
20271       abort ();
20272     }
20273 }
20274   [(set_attr "type" "ssemov")
20275    (set (attr "mode")
20276         (cond [(eq_attr "alternative" "0,1")
20277                  (if_then_else
20278                    (ne (symbol_ref "optimize_size")
20279                        (const_int 0))
20280                    (const_string "V4SF")
20281                    (const_string "V2DF"))
20282                (eq_attr "alternative" "2")
20283                  (if_then_else
20284                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20285                             (const_int 0))
20286                         (ne (symbol_ref "optimize_size")
20287                             (const_int 0)))
20288                    (const_string "V4SF")
20289                    (const_string "V2DF"))]
20290                (const_string "V2DF")))])
20291
20292 (define_insn "movv8hi_internal"
20293   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20294         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20295   "TARGET_SSE2
20296    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20297 {
20298   switch (which_alternative)
20299     {
20300     case 0:
20301       if (get_attr_mode (insn) == MODE_V4SF)
20302         return "xorps\t%0, %0";
20303       else
20304         return "pxor\t%0, %0";
20305     case 1:
20306     case 2:
20307       if (get_attr_mode (insn) == MODE_V4SF)
20308         return "movaps\t{%1, %0|%0, %1}";
20309       else
20310         return "movdqa\t{%1, %0|%0, %1}";
20311     default:
20312       abort ();
20313     }
20314 }
20315   [(set_attr "type" "ssemov")
20316    (set (attr "mode")
20317         (cond [(eq_attr "alternative" "0,1")
20318                  (if_then_else
20319                    (ne (symbol_ref "optimize_size")
20320                        (const_int 0))
20321                    (const_string "V4SF")
20322                    (const_string "TI"))
20323                (eq_attr "alternative" "2")
20324                  (if_then_else
20325                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20326                             (const_int 0))
20327                         (ne (symbol_ref "optimize_size")
20328                             (const_int 0)))
20329                    (const_string "V4SF")
20330                    (const_string "TI"))]
20331                (const_string "TI")))])
20332
20333 (define_insn "movv16qi_internal"
20334   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20335         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20336   "TARGET_SSE2
20337    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20338 {
20339   switch (which_alternative)
20340     {
20341     case 0:
20342       if (get_attr_mode (insn) == MODE_V4SF)
20343         return "xorps\t%0, %0";
20344       else
20345         return "pxor\t%0, %0";
20346     case 1:
20347     case 2:
20348       if (get_attr_mode (insn) == MODE_V4SF)
20349         return "movaps\t{%1, %0|%0, %1}";
20350       else
20351         return "movdqa\t{%1, %0|%0, %1}";
20352     default:
20353       abort ();
20354     }
20355 }
20356   [(set_attr "type" "ssemov")
20357    (set (attr "mode")
20358         (cond [(eq_attr "alternative" "0,1")
20359                  (if_then_else
20360                    (ne (symbol_ref "optimize_size")
20361                        (const_int 0))
20362                    (const_string "V4SF")
20363                    (const_string "TI"))
20364                (eq_attr "alternative" "2")
20365                  (if_then_else
20366                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20367                             (const_int 0))
20368                         (ne (symbol_ref "optimize_size")
20369                             (const_int 0)))
20370                    (const_string "V4SF")
20371                    (const_string "TI"))]
20372                (const_string "TI")))])
20373
20374 (define_expand "movv2df"
20375   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20376         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20377   "TARGET_SSE2"
20378 {
20379   ix86_expand_vector_move (V2DFmode, operands);
20380   DONE;
20381 })
20382
20383 (define_expand "movv8hi"
20384   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20385         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20386   "TARGET_SSE2"
20387 {
20388   ix86_expand_vector_move (V8HImode, operands);
20389   DONE;
20390 })
20391
20392 (define_expand "movv16qi"
20393   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20394         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20395   "TARGET_SSE2"
20396 {
20397   ix86_expand_vector_move (V16QImode, operands);
20398   DONE;
20399 })
20400
20401 (define_expand "movv4sf"
20402   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20403         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20404   "TARGET_SSE"
20405 {
20406   ix86_expand_vector_move (V4SFmode, operands);
20407   DONE;
20408 })
20409
20410 (define_expand "movv4si"
20411   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20412         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20413   "TARGET_SSE"
20414 {
20415   ix86_expand_vector_move (V4SImode, operands);
20416   DONE;
20417 })
20418
20419 (define_expand "movv2di"
20420   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20421         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20422   "TARGET_SSE"
20423 {
20424   ix86_expand_vector_move (V2DImode, operands);
20425   DONE;
20426 })
20427
20428 (define_expand "movv2si"
20429   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20430         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20431   "TARGET_MMX"
20432 {
20433   ix86_expand_vector_move (V2SImode, operands);
20434   DONE;
20435 })
20436
20437 (define_expand "movv4hi"
20438   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20439         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20440   "TARGET_MMX"
20441 {
20442   ix86_expand_vector_move (V4HImode, operands);
20443   DONE;
20444 })
20445
20446 (define_expand "movv8qi"
20447   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20448         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20449   "TARGET_MMX"
20450 {
20451   ix86_expand_vector_move (V8QImode, operands);
20452   DONE;
20453 })
20454
20455 (define_expand "movv2sf"
20456   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20457         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20458    "TARGET_3DNOW"
20459 {
20460   ix86_expand_vector_move (V2SFmode, operands);
20461   DONE;
20462 })
20463
20464 (define_insn "*pushti"
20465   [(set (match_operand:TI 0 "push_operand" "=<")
20466         (match_operand:TI 1 "register_operand" "x"))]
20467   "TARGET_SSE"
20468   "#")
20469
20470 (define_insn "*pushv2df"
20471   [(set (match_operand:V2DF 0 "push_operand" "=<")
20472         (match_operand:V2DF 1 "register_operand" "x"))]
20473   "TARGET_SSE"
20474   "#")
20475
20476 (define_insn "*pushv2di"
20477   [(set (match_operand:V2DI 0 "push_operand" "=<")
20478         (match_operand:V2DI 1 "register_operand" "x"))]
20479   "TARGET_SSE2"
20480   "#")
20481
20482 (define_insn "*pushv8hi"
20483   [(set (match_operand:V8HI 0 "push_operand" "=<")
20484         (match_operand:V8HI 1 "register_operand" "x"))]
20485   "TARGET_SSE2"
20486   "#")
20487
20488 (define_insn "*pushv16qi"
20489   [(set (match_operand:V16QI 0 "push_operand" "=<")
20490         (match_operand:V16QI 1 "register_operand" "x"))]
20491   "TARGET_SSE2"
20492   "#")
20493
20494 (define_insn "*pushv4sf"
20495   [(set (match_operand:V4SF 0 "push_operand" "=<")
20496         (match_operand:V4SF 1 "register_operand" "x"))]
20497   "TARGET_SSE"
20498   "#")
20499
20500 (define_insn "*pushv4si"
20501   [(set (match_operand:V4SI 0 "push_operand" "=<")
20502         (match_operand:V4SI 1 "register_operand" "x"))]
20503   "TARGET_SSE2"
20504   "#")
20505
20506 (define_insn "*pushv2si"
20507   [(set (match_operand:V2SI 0 "push_operand" "=<")
20508         (match_operand:V2SI 1 "register_operand" "y"))]
20509   "TARGET_MMX"
20510   "#")
20511
20512 (define_insn "*pushv4hi"
20513   [(set (match_operand:V4HI 0 "push_operand" "=<")
20514         (match_operand:V4HI 1 "register_operand" "y"))]
20515   "TARGET_MMX"
20516   "#")
20517
20518 (define_insn "*pushv8qi"
20519   [(set (match_operand:V8QI 0 "push_operand" "=<")
20520         (match_operand:V8QI 1 "register_operand" "y"))]
20521   "TARGET_MMX"
20522   "#")
20523
20524 (define_insn "*pushv2sf"
20525   [(set (match_operand:V2SF 0 "push_operand" "=<")
20526         (match_operand:V2SF 1 "register_operand" "y"))]
20527   "TARGET_3DNOW"
20528   "#")
20529
20530 (define_split
20531   [(set (match_operand 0 "push_operand" "")
20532         (match_operand 1 "register_operand" ""))]
20533   "!TARGET_64BIT && reload_completed
20534    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20535   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20536    (set (match_dup 2) (match_dup 1))]
20537   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20538                                  stack_pointer_rtx);
20539    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20540
20541 (define_split
20542   [(set (match_operand 0 "push_operand" "")
20543         (match_operand 1 "register_operand" ""))]
20544   "TARGET_64BIT && reload_completed
20545    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20546   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20547    (set (match_dup 2) (match_dup 1))]
20548   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20549                                  stack_pointer_rtx);
20550    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20551
20552
20553 (define_insn "movti_internal"
20554   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20555         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20556   "TARGET_SSE && !TARGET_64BIT
20557    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20558 {
20559   switch (which_alternative)
20560     {
20561     case 0:
20562       if (get_attr_mode (insn) == MODE_V4SF)
20563         return "xorps\t%0, %0";
20564       else
20565         return "pxor\t%0, %0";
20566     case 1:
20567     case 2:
20568       if (get_attr_mode (insn) == MODE_V4SF)
20569         return "movaps\t{%1, %0|%0, %1}";
20570       else
20571         return "movdqa\t{%1, %0|%0, %1}";
20572     default:
20573       abort ();
20574     }
20575 }
20576   [(set_attr "type" "ssemov,ssemov,ssemov")
20577    (set (attr "mode")
20578         (cond [(eq_attr "alternative" "0,1")
20579                  (if_then_else
20580                    (ne (symbol_ref "optimize_size")
20581                        (const_int 0))
20582                    (const_string "V4SF")
20583                    (const_string "TI"))
20584                (eq_attr "alternative" "2")
20585                  (if_then_else
20586                    (ne (symbol_ref "optimize_size")
20587                        (const_int 0))
20588                    (const_string "V4SF")
20589                    (const_string "TI"))]
20590                (const_string "TI")))])
20591
20592 (define_insn "*movti_rex64"
20593   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20594         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20595   "TARGET_64BIT
20596    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20597 {
20598   switch (which_alternative)
20599     {
20600     case 0:
20601     case 1:
20602       return "#";
20603     case 2:
20604       if (get_attr_mode (insn) == MODE_V4SF)
20605         return "xorps\t%0, %0";
20606       else
20607         return "pxor\t%0, %0";
20608     case 3:
20609     case 4:
20610       if (get_attr_mode (insn) == MODE_V4SF)
20611         return "movaps\t{%1, %0|%0, %1}";
20612       else
20613         return "movdqa\t{%1, %0|%0, %1}";
20614     default:
20615       abort ();
20616     }
20617 }
20618   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20619    (set (attr "mode")
20620         (cond [(eq_attr "alternative" "2,3")
20621                  (if_then_else
20622                    (ne (symbol_ref "optimize_size")
20623                        (const_int 0))
20624                    (const_string "V4SF")
20625                    (const_string "TI"))
20626                (eq_attr "alternative" "4")
20627                  (if_then_else
20628                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20629                             (const_int 0))
20630                         (ne (symbol_ref "optimize_size")
20631                             (const_int 0)))
20632                    (const_string "V4SF")
20633                    (const_string "TI"))]
20634                (const_string "DI")))])
20635
20636 (define_insn "*movtf_rex64"
20637   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20638         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20639   "TARGET_64BIT
20640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20641 {
20642   switch (which_alternative)
20643     {
20644     case 0:
20645     case 1:
20646       return "#";
20647     case 2:
20648       if (get_attr_mode (insn) == MODE_V4SF)
20649         return "xorps\t%0, %0";
20650       else
20651         return "pxor\t%0, %0";
20652     case 3:
20653     case 4:
20654       if (get_attr_mode (insn) == MODE_V4SF)
20655         return "movaps\t{%1, %0|%0, %1}";
20656       else
20657         return "movdqa\t{%1, %0|%0, %1}";
20658     default:
20659       abort ();
20660     }
20661 }
20662   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20663    (set (attr "mode")
20664         (cond [(eq_attr "alternative" "2,3")
20665                  (if_then_else
20666                    (ne (symbol_ref "optimize_size")
20667                        (const_int 0))
20668                    (const_string "V4SF")
20669                    (const_string "TI"))
20670                (eq_attr "alternative" "4")
20671                  (if_then_else
20672                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20673                             (const_int 0))
20674                         (ne (symbol_ref "optimize_size")
20675                             (const_int 0)))
20676                    (const_string "V4SF")
20677                    (const_string "TI"))]
20678                (const_string "DI")))])
20679
20680 (define_split
20681   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20682         (match_operand:TI 1 "general_operand" ""))]
20683   "reload_completed && !SSE_REG_P (operands[0])
20684    && !SSE_REG_P (operands[1])"
20685   [(const_int 0)]
20686   "ix86_split_long_move (operands); DONE;")
20687
20688 (define_split
20689   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20690         (match_operand:TF 1 "general_operand" ""))]
20691   "reload_completed && !SSE_REG_P (operands[0])
20692    && !SSE_REG_P (operands[1])"
20693   [(const_int 0)]
20694   "ix86_split_long_move (operands); DONE;")
20695
20696 ;; These two patterns are useful for specifying exactly whether to use
20697 ;; movaps or movups
20698 (define_expand "sse_movaps"
20699   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20700         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20701                      UNSPEC_MOVA))]
20702   "TARGET_SSE"
20703 {
20704   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20705     {
20706       rtx tmp = gen_reg_rtx (V4SFmode);
20707       emit_insn (gen_sse_movaps (tmp, operands[1]));
20708       emit_move_insn (operands[0], tmp);
20709       DONE;
20710     }
20711 })
20712
20713 (define_insn "*sse_movaps_1"
20714   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20715         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20716                      UNSPEC_MOVA))]
20717   "TARGET_SSE
20718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20719   "movaps\t{%1, %0|%0, %1}"
20720   [(set_attr "type" "ssemov,ssemov")
20721    (set_attr "mode" "V4SF")])
20722
20723 (define_expand "sse_movups"
20724   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20725         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20726                      UNSPEC_MOVU))]
20727   "TARGET_SSE"
20728 {
20729   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20730     {
20731       rtx tmp = gen_reg_rtx (V4SFmode);
20732       emit_insn (gen_sse_movups (tmp, operands[1]));
20733       emit_move_insn (operands[0], tmp);
20734       DONE;
20735     }
20736 })
20737
20738 (define_insn "*sse_movups_1"
20739   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20740         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20741                      UNSPEC_MOVU))]
20742   "TARGET_SSE
20743    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20744   "movups\t{%1, %0|%0, %1}"
20745   [(set_attr "type" "ssecvt,ssecvt")
20746    (set_attr "mode" "V4SF")])
20747
20748 ;; SSE Strange Moves.
20749
20750 (define_insn "sse_movmskps"
20751   [(set (match_operand:SI 0 "register_operand" "=r")
20752         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20753                    UNSPEC_MOVMSK))]
20754   "TARGET_SSE"
20755   "movmskps\t{%1, %0|%0, %1}"
20756   [(set_attr "type" "ssecvt")
20757    (set_attr "mode" "V4SF")])
20758
20759 (define_insn "mmx_pmovmskb"
20760   [(set (match_operand:SI 0 "register_operand" "=r")
20761         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20762                    UNSPEC_MOVMSK))]
20763   "TARGET_SSE || TARGET_3DNOW_A"
20764   "pmovmskb\t{%1, %0|%0, %1}"
20765   [(set_attr "type" "ssecvt")
20766    (set_attr "mode" "V4SF")])
20767
20768
20769 (define_insn "mmx_maskmovq"
20770   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20771         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20772                       (match_operand:V8QI 2 "register_operand" "y")]
20773                      UNSPEC_MASKMOV))]
20774   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20775   ;; @@@ check ordering of operands in intel/nonintel syntax
20776   "maskmovq\t{%2, %1|%1, %2}"
20777   [(set_attr "type" "mmxcvt")
20778    (set_attr "mode" "DI")])
20779
20780 (define_insn "mmx_maskmovq_rex"
20781   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20782         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20783                       (match_operand:V8QI 2 "register_operand" "y")]
20784                      UNSPEC_MASKMOV))]
20785   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20786   ;; @@@ check ordering of operands in intel/nonintel syntax
20787   "maskmovq\t{%2, %1|%1, %2}"
20788   [(set_attr "type" "mmxcvt")
20789    (set_attr "mode" "DI")])
20790
20791 (define_insn "sse_movntv4sf"
20792   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20793         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20794                      UNSPEC_MOVNT))]
20795   "TARGET_SSE"
20796   "movntps\t{%1, %0|%0, %1}"
20797   [(set_attr "type" "ssemov")
20798    (set_attr "mode" "V4SF")])
20799
20800 (define_insn "sse_movntdi"
20801   [(set (match_operand:DI 0 "memory_operand" "=m")
20802         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20803                    UNSPEC_MOVNT))]
20804   "TARGET_SSE || TARGET_3DNOW_A"
20805   "movntq\t{%1, %0|%0, %1}"
20806   [(set_attr "type" "mmxmov")
20807    (set_attr "mode" "DI")])
20808
20809 (define_insn "sse_movhlps"
20810   [(set (match_operand:V4SF 0 "register_operand" "=x")
20811         (vec_merge:V4SF
20812          (match_operand:V4SF 1 "register_operand" "0")
20813          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20814                           (parallel [(const_int 2)
20815                                      (const_int 3)
20816                                      (const_int 0)
20817                                      (const_int 1)]))
20818          (const_int 3)))]
20819   "TARGET_SSE"
20820   "movhlps\t{%2, %0|%0, %2}"
20821   [(set_attr "type" "ssecvt")
20822    (set_attr "mode" "V4SF")])
20823
20824 (define_insn "sse_movlhps"
20825   [(set (match_operand:V4SF 0 "register_operand" "=x")
20826         (vec_merge:V4SF
20827          (match_operand:V4SF 1 "register_operand" "0")
20828          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20829                           (parallel [(const_int 2)
20830                                      (const_int 3)
20831                                      (const_int 0)
20832                                      (const_int 1)]))
20833          (const_int 12)))]
20834   "TARGET_SSE"
20835   "movlhps\t{%2, %0|%0, %2}"
20836   [(set_attr "type" "ssecvt")
20837    (set_attr "mode" "V4SF")])
20838
20839 (define_insn "sse_movhps"
20840   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20841         (vec_merge:V4SF
20842          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20843          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20844          (const_int 12)))]
20845   "TARGET_SSE
20846    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20847   "movhps\t{%2, %0|%0, %2}"
20848   [(set_attr "type" "ssecvt")
20849    (set_attr "mode" "V4SF")])
20850
20851 (define_insn "sse_movlps"
20852   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20853         (vec_merge:V4SF
20854          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20855          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20856          (const_int 3)))]
20857   "TARGET_SSE
20858    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20859   "movlps\t{%2, %0|%0, %2}"
20860   [(set_attr "type" "ssecvt")
20861    (set_attr "mode" "V4SF")])
20862
20863 (define_expand "sse_loadss"
20864   [(match_operand:V4SF 0 "register_operand" "")
20865    (match_operand:SF 1 "memory_operand" "")]
20866   "TARGET_SSE"
20867 {
20868   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20869                                CONST0_RTX (V4SFmode)));
20870   DONE;
20871 })
20872
20873 (define_insn "sse_loadss_1"
20874   [(set (match_operand:V4SF 0 "register_operand" "=x")
20875         (vec_merge:V4SF
20876          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20877          (match_operand:V4SF 2 "const0_operand" "X")
20878          (const_int 1)))]
20879   "TARGET_SSE"
20880   "movss\t{%1, %0|%0, %1}"
20881   [(set_attr "type" "ssemov")
20882    (set_attr "mode" "SF")])
20883
20884 (define_insn "sse_movss"
20885   [(set (match_operand:V4SF 0 "register_operand" "=x")
20886         (vec_merge:V4SF
20887          (match_operand:V4SF 1 "register_operand" "0")
20888          (match_operand:V4SF 2 "register_operand" "x")
20889          (const_int 1)))]
20890   "TARGET_SSE"
20891   "movss\t{%2, %0|%0, %2}"
20892   [(set_attr "type" "ssemov")
20893    (set_attr "mode" "SF")])
20894
20895 (define_insn "sse_storess"
20896   [(set (match_operand:SF 0 "memory_operand" "=m")
20897         (vec_select:SF
20898          (match_operand:V4SF 1 "register_operand" "x")
20899          (parallel [(const_int 0)])))]
20900   "TARGET_SSE"
20901   "movss\t{%1, %0|%0, %1}"
20902   [(set_attr "type" "ssemov")
20903    (set_attr "mode" "SF")])
20904
20905 (define_insn "sse_shufps"
20906   [(set (match_operand:V4SF 0 "register_operand" "=x")
20907         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20908                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20909                       (match_operand:SI 3 "immediate_operand" "i")]
20910                      UNSPEC_SHUFFLE))]
20911   "TARGET_SSE"
20912   ;; @@@ check operand order for intel/nonintel syntax
20913   "shufps\t{%3, %2, %0|%0, %2, %3}"
20914   [(set_attr "type" "ssecvt")
20915    (set_attr "mode" "V4SF")])
20916
20917
20918 ;; SSE arithmetic
20919
20920 (define_insn "addv4sf3"
20921   [(set (match_operand:V4SF 0 "register_operand" "=x")
20922         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20923                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20924   "TARGET_SSE"
20925   "addps\t{%2, %0|%0, %2}"
20926   [(set_attr "type" "sseadd")
20927    (set_attr "mode" "V4SF")])
20928
20929 (define_insn "vmaddv4sf3"
20930   [(set (match_operand:V4SF 0 "register_operand" "=x")
20931         (vec_merge:V4SF
20932          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20933                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20934          (match_dup 1)
20935          (const_int 1)))]
20936   "TARGET_SSE"
20937   "addss\t{%2, %0|%0, %2}"
20938   [(set_attr "type" "sseadd")
20939    (set_attr "mode" "SF")])
20940
20941 (define_insn "subv4sf3"
20942   [(set (match_operand:V4SF 0 "register_operand" "=x")
20943         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20944                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20945   "TARGET_SSE"
20946   "subps\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "sseadd")
20948    (set_attr "mode" "V4SF")])
20949
20950 (define_insn "vmsubv4sf3"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (vec_merge:V4SF
20953          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20954                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20955          (match_dup 1)
20956          (const_int 1)))]
20957   "TARGET_SSE"
20958   "subss\t{%2, %0|%0, %2}"
20959   [(set_attr "type" "sseadd")
20960    (set_attr "mode" "SF")])
20961
20962 ;; ??? Should probably be done by generic code instead.
20963 (define_expand "negv4sf2"
20964   [(set (match_operand:V4SF 0 "register_operand" "")
20965         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20966                   (match_dup 2)))]
20967   "TARGET_SSE"
20968 {
20969   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20970   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20971   operands[2] = force_reg (V4SFmode, vm0);
20972 })
20973
20974 (define_insn "mulv4sf3"
20975   [(set (match_operand:V4SF 0 "register_operand" "=x")
20976         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20977                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20978   "TARGET_SSE"
20979   "mulps\t{%2, %0|%0, %2}"
20980   [(set_attr "type" "ssemul")
20981    (set_attr "mode" "V4SF")])
20982
20983 (define_insn "vmmulv4sf3"
20984   [(set (match_operand:V4SF 0 "register_operand" "=x")
20985         (vec_merge:V4SF
20986          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20987                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20988          (match_dup 1)
20989          (const_int 1)))]
20990   "TARGET_SSE"
20991   "mulss\t{%2, %0|%0, %2}"
20992   [(set_attr "type" "ssemul")
20993    (set_attr "mode" "SF")])
20994
20995 (define_insn "divv4sf3"
20996   [(set (match_operand:V4SF 0 "register_operand" "=x")
20997         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20998                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20999   "TARGET_SSE"
21000   "divps\t{%2, %0|%0, %2}"
21001   [(set_attr "type" "ssediv")
21002    (set_attr "mode" "V4SF")])
21003
21004 (define_insn "vmdivv4sf3"
21005   [(set (match_operand:V4SF 0 "register_operand" "=x")
21006         (vec_merge:V4SF
21007          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
21008                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21009          (match_dup 1)
21010          (const_int 1)))]
21011   "TARGET_SSE"
21012   "divss\t{%2, %0|%0, %2}"
21013   [(set_attr "type" "ssediv")
21014    (set_attr "mode" "SF")])
21015
21016
21017 ;; SSE square root/reciprocal
21018
21019 (define_insn "rcpv4sf2"
21020   [(set (match_operand:V4SF 0 "register_operand" "=x")
21021         (unspec:V4SF
21022          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
21023   "TARGET_SSE"
21024   "rcpps\t{%1, %0|%0, %1}"
21025   [(set_attr "type" "sse")
21026    (set_attr "mode" "V4SF")])
21027
21028 (define_insn "vmrcpv4sf2"
21029   [(set (match_operand:V4SF 0 "register_operand" "=x")
21030         (vec_merge:V4SF
21031          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21032                       UNSPEC_RCP)
21033          (match_operand:V4SF 2 "register_operand" "0")
21034          (const_int 1)))]
21035   "TARGET_SSE"
21036   "rcpss\t{%1, %0|%0, %1}"
21037   [(set_attr "type" "sse")
21038    (set_attr "mode" "SF")])
21039
21040 (define_insn "rsqrtv4sf2"
21041   [(set (match_operand:V4SF 0 "register_operand" "=x")
21042         (unspec:V4SF
21043          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
21044   "TARGET_SSE"
21045   "rsqrtps\t{%1, %0|%0, %1}"
21046   [(set_attr "type" "sse")
21047    (set_attr "mode" "V4SF")])
21048
21049 (define_insn "vmrsqrtv4sf2"
21050   [(set (match_operand:V4SF 0 "register_operand" "=x")
21051         (vec_merge:V4SF
21052          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21053                       UNSPEC_RSQRT)
21054          (match_operand:V4SF 2 "register_operand" "0")
21055          (const_int 1)))]
21056   "TARGET_SSE"
21057   "rsqrtss\t{%1, %0|%0, %1}"
21058   [(set_attr "type" "sse")
21059    (set_attr "mode" "SF")])
21060
21061 (define_insn "sqrtv4sf2"
21062   [(set (match_operand:V4SF 0 "register_operand" "=x")
21063         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21064   "TARGET_SSE"
21065   "sqrtps\t{%1, %0|%0, %1}"
21066   [(set_attr "type" "sse")
21067    (set_attr "mode" "V4SF")])
21068
21069 (define_insn "vmsqrtv4sf2"
21070   [(set (match_operand:V4SF 0 "register_operand" "=x")
21071         (vec_merge:V4SF
21072          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21073          (match_operand:V4SF 2 "register_operand" "0")
21074          (const_int 1)))]
21075   "TARGET_SSE"
21076   "sqrtss\t{%1, %0|%0, %1}"
21077   [(set_attr "type" "sse")
21078    (set_attr "mode" "SF")])
21079
21080 ;; SSE logical operations.
21081
21082 ;; SSE defines logical operations on floating point values.  This brings
21083 ;; interesting challenge to RTL representation where logicals are only valid
21084 ;; on integral types.  We deal with this by representing the floating point
21085 ;; logical as logical on arguments casted to TImode as this is what hardware
21086 ;; really does.  Unfortunately hardware requires the type information to be
21087 ;; present and thus we must avoid subregs from being simplified and eliminated
21088 ;; in later compilation phases.
21089 ;;
21090 ;; We have following variants from each instruction:
21091 ;; sse_andsf3 - the operation taking V4SF vector operands
21092 ;;              and doing TImode cast on them
21093 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21094 ;;                      TImode, since backend insist on eliminating casts
21095 ;;                      on memory operands
21096 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21097 ;;                   We cannot accept memory operand here as instruction reads
21098 ;;                   whole scalar.  This is generated only post reload by GCC
21099 ;;                   scalar float operations that expands to logicals (fabs)
21100 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21101 ;;                   memory operand.  Eventually combine can be able
21102 ;;                   to synthesize these using splitter.
21103 ;; sse2_anddf3, *sse2_anddf3_memory
21104 ;;              
21105 ;; 
21106 ;; These are not called andti3 etc. because we really really don't want
21107 ;; the compiler to widen DImode ands to TImode ands and then try to move
21108 ;; into DImode subregs of SSE registers, and them together, and move out
21109 ;; of DImode subregs again!
21110 ;; SSE1 single precision floating point logical operation
21111 (define_expand "sse_andv4sf3"
21112   [(set (match_operand:V4SF 0 "register_operand" "")
21113         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21114                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21115   "TARGET_SSE"
21116   "")
21117
21118 (define_insn "*sse_andv4sf3"
21119   [(set (match_operand:V4SF 0 "register_operand" "=x")
21120         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21121                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21122   "TARGET_SSE
21123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21124   "andps\t{%2, %0|%0, %2}"
21125   [(set_attr "type" "sselog")
21126    (set_attr "mode" "V4SF")])
21127
21128 (define_expand "sse_nandv4sf3"
21129   [(set (match_operand:V4SF 0 "register_operand" "")
21130         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21131                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21132   "TARGET_SSE"
21133   "")
21134
21135 (define_insn "*sse_nandv4sf3"
21136   [(set (match_operand:V4SF 0 "register_operand" "=x")
21137         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21138                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21139   "TARGET_SSE"
21140   "andnps\t{%2, %0|%0, %2}"
21141   [(set_attr "type" "sselog")
21142    (set_attr "mode" "V4SF")])
21143
21144 (define_expand "sse_iorv4sf3"
21145   [(set (match_operand:V4SF 0 "register_operand" "")
21146         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21147                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21148   "TARGET_SSE"
21149   "")
21150
21151 (define_insn "*sse_iorv4sf3"
21152   [(set (match_operand:V4SF 0 "register_operand" "=x")
21153         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21154                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21155   "TARGET_SSE
21156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21157   "orps\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "sselog")
21159    (set_attr "mode" "V4SF")])
21160
21161 (define_expand "sse_xorv4sf3"
21162   [(set (match_operand:V4SF 0 "register_operand" "")
21163         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21164                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21165   "TARGET_SSE"
21166   "")
21167
21168 (define_insn "*sse_xorv4sf3"
21169   [(set (match_operand:V4SF 0 "register_operand" "=x")
21170         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21171                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21172   "TARGET_SSE
21173    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21174   "xorps\t{%2, %0|%0, %2}"
21175   [(set_attr "type" "sselog")
21176    (set_attr "mode" "V4SF")])
21177
21178 ;; SSE2 double precision floating point logical operation
21179
21180 (define_expand "sse2_andv2df3"
21181   [(set (match_operand:V2DF 0 "register_operand" "")
21182         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21183                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21184   "TARGET_SSE2"
21185   "")
21186
21187 (define_insn "*sse2_andv2df3"
21188   [(set (match_operand:V2DF 0 "register_operand" "=x")
21189         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21190                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21191   "TARGET_SSE2
21192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21193   "andpd\t{%2, %0|%0, %2}"
21194   [(set_attr "type" "sselog")
21195    (set_attr "mode" "V2DF")])
21196
21197 (define_expand "sse2_nandv2df3"
21198   [(set (match_operand:V2DF 0 "register_operand" "")
21199         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21200                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21201   "TARGET_SSE2"
21202   "")
21203
21204 (define_insn "*sse2_nandv2df3"
21205   [(set (match_operand:V2DF 0 "register_operand" "=x")
21206         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21207                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21208   "TARGET_SSE2"
21209   "andnpd\t{%2, %0|%0, %2}"
21210   [(set_attr "type" "sselog")
21211    (set_attr "mode" "V2DF")])
21212
21213 (define_expand "sse2_iorv2df3"
21214   [(set (match_operand:V2DF 0 "register_operand" "")
21215         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21216                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21217   "TARGET_SSE2"
21218   "")
21219
21220 (define_insn "*sse2_iorv2df3"
21221   [(set (match_operand:V2DF 0 "register_operand" "=x")
21222         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21223                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21224   "TARGET_SSE2
21225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21226   "orpd\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "sselog")
21228    (set_attr "mode" "V2DF")])
21229
21230 (define_expand "sse2_xorv2df3"
21231   [(set (match_operand:V2DF 0 "register_operand" "")
21232         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21233                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21234   "TARGET_SSE2"
21235   "")
21236
21237 (define_insn "*sse2_xorv2df3"
21238   [(set (match_operand:V2DF 0 "register_operand" "=x")
21239         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21240                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21241   "TARGET_SSE2
21242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21243   "xorpd\t{%2, %0|%0, %2}"
21244   [(set_attr "type" "sselog")
21245    (set_attr "mode" "V2DF")])
21246
21247 ;; SSE2 integral logicals.  These patterns must always come after floating
21248 ;; point ones since we don't want compiler to use integer opcodes on floating
21249 ;; point SSE values to avoid matching of subregs in the match_operand.
21250 (define_insn "*sse2_andti3"
21251   [(set (match_operand:TI 0 "register_operand" "=x")
21252         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21253                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21254   "TARGET_SSE2
21255    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21256   "pand\t{%2, %0|%0, %2}"
21257   [(set_attr "type" "sselog")
21258    (set_attr "mode" "TI")])
21259
21260 (define_insn "sse2_andv2di3"
21261   [(set (match_operand:V2DI 0 "register_operand" "=x")
21262         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21263                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21264   "TARGET_SSE2
21265    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21266   "pand\t{%2, %0|%0, %2}"
21267   [(set_attr "type" "sselog")
21268    (set_attr "mode" "TI")])
21269
21270 (define_insn "*sse2_nandti3"
21271   [(set (match_operand:TI 0 "register_operand" "=x")
21272         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21273                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21274   "TARGET_SSE2"
21275   "pandn\t{%2, %0|%0, %2}"
21276   [(set_attr "type" "sselog")
21277    (set_attr "mode" "TI")])
21278
21279 (define_insn "sse2_nandv2di3"
21280   [(set (match_operand:V2DI 0 "register_operand" "=x")
21281         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21282                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21283   "TARGET_SSE2
21284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21285   "pandn\t{%2, %0|%0, %2}"
21286   [(set_attr "type" "sselog")
21287    (set_attr "mode" "TI")])
21288
21289 (define_insn "*sse2_iorti3"
21290   [(set (match_operand:TI 0 "register_operand" "=x")
21291         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21292                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21293   "TARGET_SSE2
21294    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21295   "por\t{%2, %0|%0, %2}"
21296   [(set_attr "type" "sselog")
21297    (set_attr "mode" "TI")])
21298
21299 (define_insn "sse2_iorv2di3"
21300   [(set (match_operand:V2DI 0 "register_operand" "=x")
21301         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21302                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21303   "TARGET_SSE2
21304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21305   "por\t{%2, %0|%0, %2}"
21306   [(set_attr "type" "sselog")
21307    (set_attr "mode" "TI")])
21308
21309 (define_insn "*sse2_xorti3"
21310   [(set (match_operand:TI 0 "register_operand" "=x")
21311         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21312                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21313   "TARGET_SSE2
21314    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21315   "pxor\t{%2, %0|%0, %2}"
21316   [(set_attr "type" "sselog")
21317    (set_attr "mode" "TI")])
21318
21319 (define_insn "sse2_xorv2di3"
21320   [(set (match_operand:V2DI 0 "register_operand" "=x")
21321         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21322                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21323   "TARGET_SSE2
21324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21325   "pxor\t{%2, %0|%0, %2}"
21326   [(set_attr "type" "sselog")
21327    (set_attr "mode" "TI")])
21328
21329 ;; Use xor, but don't show input operands so they aren't live before
21330 ;; this insn.
21331 (define_insn "sse_clrv4sf"
21332   [(set (match_operand:V4SF 0 "register_operand" "=x")
21333         (match_operand:V4SF 1 "const0_operand" "X"))]
21334   "TARGET_SSE"
21335 {
21336   if (get_attr_mode (insn) == MODE_TI)
21337     return "pxor\t{%0, %0|%0, %0}";
21338   else
21339     return "xorps\t{%0, %0|%0, %0}";
21340 }
21341   [(set_attr "type" "sselog")
21342    (set_attr "memory" "none")
21343    (set (attr "mode")
21344         (if_then_else
21345            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21346                          (const_int 0))
21347                      (ne (symbol_ref "TARGET_SSE2")
21348                          (const_int 0)))
21349                 (eq (symbol_ref "optimize_size")
21350                     (const_int 0)))
21351          (const_string "TI")
21352          (const_string "V4SF")))])
21353
21354 ;; Use xor, but don't show input operands so they aren't live before
21355 ;; this insn.
21356 (define_insn "sse_clrv2df"
21357   [(set (match_operand:V2DF 0 "register_operand" "=x")
21358         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21359   "TARGET_SSE2"
21360   "xorpd\t{%0, %0|%0, %0}"
21361   [(set_attr "type" "sselog")
21362    (set_attr "memory" "none")
21363    (set_attr "mode" "V4SF")])
21364
21365 ;; SSE mask-generating compares
21366
21367 (define_insn "maskcmpv4sf3"
21368   [(set (match_operand:V4SI 0 "register_operand" "=x")
21369         (match_operator:V4SI 3 "sse_comparison_operator"
21370                 [(match_operand:V4SF 1 "register_operand" "0")
21371                  (match_operand:V4SF 2 "register_operand" "x")]))]
21372   "TARGET_SSE"
21373   "cmp%D3ps\t{%2, %0|%0, %2}"
21374   [(set_attr "type" "ssecmp")
21375    (set_attr "mode" "V4SF")])
21376
21377 (define_insn "maskncmpv4sf3"
21378   [(set (match_operand:V4SI 0 "register_operand" "=x")
21379         (not:V4SI
21380          (match_operator:V4SI 3 "sse_comparison_operator"
21381                 [(match_operand:V4SF 1 "register_operand" "0")
21382                  (match_operand:V4SF 2 "register_operand" "x")])))]
21383   "TARGET_SSE"
21384 {
21385   if (GET_CODE (operands[3]) == UNORDERED)
21386     return "cmpordps\t{%2, %0|%0, %2}";
21387   else
21388     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21389 }
21390   [(set_attr "type" "ssecmp")
21391    (set_attr "mode" "V4SF")])
21392
21393 (define_insn "vmmaskcmpv4sf3"
21394   [(set (match_operand:V4SI 0 "register_operand" "=x")
21395         (vec_merge:V4SI
21396          (match_operator:V4SI 3 "sse_comparison_operator"
21397                 [(match_operand:V4SF 1 "register_operand" "0")
21398                  (match_operand:V4SF 2 "register_operand" "x")])
21399          (subreg:V4SI (match_dup 1) 0)
21400          (const_int 1)))]
21401   "TARGET_SSE"
21402   "cmp%D3ss\t{%2, %0|%0, %2}"
21403   [(set_attr "type" "ssecmp")
21404    (set_attr "mode" "SF")])
21405
21406 (define_insn "vmmaskncmpv4sf3"
21407   [(set (match_operand:V4SI 0 "register_operand" "=x")
21408         (vec_merge:V4SI
21409          (not:V4SI
21410           (match_operator:V4SI 3 "sse_comparison_operator"
21411                 [(match_operand:V4SF 1 "register_operand" "0")
21412                  (match_operand:V4SF 2 "register_operand" "x")]))
21413          (subreg:V4SI (match_dup 1) 0)
21414          (const_int 1)))]
21415   "TARGET_SSE"
21416 {
21417   if (GET_CODE (operands[3]) == UNORDERED)
21418     return "cmpordss\t{%2, %0|%0, %2}";
21419   else
21420     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21421 }
21422   [(set_attr "type" "ssecmp")
21423    (set_attr "mode" "SF")])
21424
21425 (define_insn "sse_comi"
21426   [(set (reg:CCFP FLAGS_REG)
21427         (compare:CCFP (vec_select:SF
21428                        (match_operand:V4SF 0 "register_operand" "x")
21429                        (parallel [(const_int 0)]))
21430                       (vec_select:SF
21431                        (match_operand:V4SF 1 "register_operand" "x")
21432                        (parallel [(const_int 0)]))))]
21433   "TARGET_SSE"
21434   "comiss\t{%1, %0|%0, %1}"
21435   [(set_attr "type" "ssecomi")
21436    (set_attr "mode" "SF")])
21437
21438 (define_insn "sse_ucomi"
21439   [(set (reg:CCFPU FLAGS_REG)
21440         (compare:CCFPU (vec_select:SF
21441                         (match_operand:V4SF 0 "register_operand" "x")
21442                         (parallel [(const_int 0)]))
21443                        (vec_select:SF
21444                         (match_operand:V4SF 1 "register_operand" "x")
21445                         (parallel [(const_int 0)]))))]
21446   "TARGET_SSE"
21447   "ucomiss\t{%1, %0|%0, %1}"
21448   [(set_attr "type" "ssecomi")
21449    (set_attr "mode" "SF")])
21450
21451
21452 ;; SSE unpack
21453
21454 (define_insn "sse_unpckhps"
21455   [(set (match_operand:V4SF 0 "register_operand" "=x")
21456         (vec_merge:V4SF
21457          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21458                           (parallel [(const_int 2)
21459                                      (const_int 0)
21460                                      (const_int 3)
21461                                      (const_int 1)]))
21462          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21463                           (parallel [(const_int 0)
21464                                      (const_int 2)
21465                                      (const_int 1)
21466                                      (const_int 3)]))
21467          (const_int 5)))]
21468   "TARGET_SSE"
21469   "unpckhps\t{%2, %0|%0, %2}"
21470   [(set_attr "type" "ssecvt")
21471    (set_attr "mode" "V4SF")])
21472
21473 (define_insn "sse_unpcklps"
21474   [(set (match_operand:V4SF 0 "register_operand" "=x")
21475         (vec_merge:V4SF
21476          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21477                           (parallel [(const_int 0)
21478                                      (const_int 2)
21479                                      (const_int 1)
21480                                      (const_int 3)]))
21481          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21482                           (parallel [(const_int 2)
21483                                      (const_int 0)
21484                                      (const_int 3)
21485                                      (const_int 1)]))
21486          (const_int 5)))]
21487   "TARGET_SSE"
21488   "unpcklps\t{%2, %0|%0, %2}"
21489   [(set_attr "type" "ssecvt")
21490    (set_attr "mode" "V4SF")])
21491
21492
21493 ;; SSE min/max
21494
21495 (define_insn "smaxv4sf3"
21496   [(set (match_operand:V4SF 0 "register_operand" "=x")
21497         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21498                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21499   "TARGET_SSE"
21500   "maxps\t{%2, %0|%0, %2}"
21501   [(set_attr "type" "sse")
21502    (set_attr "mode" "V4SF")])
21503
21504 (define_insn "vmsmaxv4sf3"
21505   [(set (match_operand:V4SF 0 "register_operand" "=x")
21506         (vec_merge:V4SF
21507          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21508                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21509          (match_dup 1)
21510          (const_int 1)))]
21511   "TARGET_SSE"
21512   "maxss\t{%2, %0|%0, %2}"
21513   [(set_attr "type" "sse")
21514    (set_attr "mode" "SF")])
21515
21516 (define_insn "sminv4sf3"
21517   [(set (match_operand:V4SF 0 "register_operand" "=x")
21518         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21519                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21520   "TARGET_SSE"
21521   "minps\t{%2, %0|%0, %2}"
21522   [(set_attr "type" "sse")
21523    (set_attr "mode" "V4SF")])
21524
21525 (define_insn "vmsminv4sf3"
21526   [(set (match_operand:V4SF 0 "register_operand" "=x")
21527         (vec_merge:V4SF
21528          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21529                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21530          (match_dup 1)
21531          (const_int 1)))]
21532   "TARGET_SSE"
21533   "minss\t{%2, %0|%0, %2}"
21534   [(set_attr "type" "sse")
21535    (set_attr "mode" "SF")])
21536
21537 ;; SSE <-> integer/MMX conversions
21538
21539 (define_insn "cvtpi2ps"
21540   [(set (match_operand:V4SF 0 "register_operand" "=x")
21541         (vec_merge:V4SF
21542          (match_operand:V4SF 1 "register_operand" "0")
21543          (vec_duplicate:V4SF
21544           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21545          (const_int 12)))]
21546   "TARGET_SSE"
21547   "cvtpi2ps\t{%2, %0|%0, %2}"
21548   [(set_attr "type" "ssecvt")
21549    (set_attr "mode" "V4SF")])
21550
21551 (define_insn "cvtps2pi"
21552   [(set (match_operand:V2SI 0 "register_operand" "=y")
21553         (vec_select:V2SI
21554          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21555          (parallel [(const_int 0) (const_int 1)])))]
21556   "TARGET_SSE"
21557   "cvtps2pi\t{%1, %0|%0, %1}"
21558   [(set_attr "type" "ssecvt")
21559    (set_attr "mode" "V4SF")])
21560
21561 (define_insn "cvttps2pi"
21562   [(set (match_operand:V2SI 0 "register_operand" "=y")
21563         (vec_select:V2SI
21564          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21565                       UNSPEC_FIX)
21566          (parallel [(const_int 0) (const_int 1)])))]
21567   "TARGET_SSE"
21568   "cvttps2pi\t{%1, %0|%0, %1}"
21569   [(set_attr "type" "ssecvt")
21570    (set_attr "mode" "SF")])
21571
21572 (define_insn "cvtsi2ss"
21573   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21574         (vec_merge:V4SF
21575          (match_operand:V4SF 1 "register_operand" "0,0")
21576          (vec_duplicate:V4SF
21577           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21578          (const_int 14)))]
21579   "TARGET_SSE"
21580   "cvtsi2ss\t{%2, %0|%0, %2}"
21581   [(set_attr "type" "sseicvt")
21582    (set_attr "athlon_decode" "vector,double")
21583    (set_attr "mode" "SF")])
21584
21585 (define_insn "cvtsi2ssq"
21586   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21587         (vec_merge:V4SF
21588          (match_operand:V4SF 1 "register_operand" "0,0")
21589          (vec_duplicate:V4SF
21590           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21591          (const_int 14)))]
21592   "TARGET_SSE && TARGET_64BIT"
21593   "cvtsi2ssq\t{%2, %0|%0, %2}"
21594   [(set_attr "type" "sseicvt")
21595    (set_attr "athlon_decode" "vector,double")
21596    (set_attr "mode" "SF")])
21597
21598 (define_insn "cvtss2si"
21599   [(set (match_operand:SI 0 "register_operand" "=r,r")
21600         (vec_select:SI
21601          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21602          (parallel [(const_int 0)])))]
21603   "TARGET_SSE"
21604   "cvtss2si\t{%1, %0|%0, %1}"
21605   [(set_attr "type" "sseicvt")
21606    (set_attr "athlon_decode" "double,vector")
21607    (set_attr "mode" "SI")])
21608
21609 (define_insn "cvtss2siq"
21610   [(set (match_operand:DI 0 "register_operand" "=r,r")
21611         (vec_select:DI
21612          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21613          (parallel [(const_int 0)])))]
21614   "TARGET_SSE"
21615   "cvtss2siq\t{%1, %0|%0, %1}"
21616   [(set_attr "type" "sseicvt")
21617    (set_attr "athlon_decode" "double,vector")
21618    (set_attr "mode" "DI")])
21619
21620 (define_insn "cvttss2si"
21621   [(set (match_operand:SI 0 "register_operand" "=r,r")
21622         (vec_select:SI
21623          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21624                       UNSPEC_FIX)
21625          (parallel [(const_int 0)])))]
21626   "TARGET_SSE"
21627   "cvttss2si\t{%1, %0|%0, %1}"
21628   [(set_attr "type" "sseicvt")
21629    (set_attr "mode" "SF")
21630    (set_attr "athlon_decode" "double,vector")])
21631
21632 (define_insn "cvttss2siq"
21633   [(set (match_operand:DI 0 "register_operand" "=r,r")
21634         (vec_select:DI
21635          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21636                       UNSPEC_FIX)
21637          (parallel [(const_int 0)])))]
21638   "TARGET_SSE && TARGET_64BIT"
21639   "cvttss2siq\t{%1, %0|%0, %1}"
21640   [(set_attr "type" "sseicvt")
21641    (set_attr "mode" "SF")
21642    (set_attr "athlon_decode" "double,vector")])
21643
21644
21645 ;; MMX insns
21646
21647 ;; MMX arithmetic
21648
21649 (define_insn "addv8qi3"
21650   [(set (match_operand:V8QI 0 "register_operand" "=y")
21651         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21652                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21653   "TARGET_MMX"
21654   "paddb\t{%2, %0|%0, %2}"
21655   [(set_attr "type" "mmxadd")
21656    (set_attr "mode" "DI")])
21657
21658 (define_insn "addv4hi3"
21659   [(set (match_operand:V4HI 0 "register_operand" "=y")
21660         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21661                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21662   "TARGET_MMX"
21663   "paddw\t{%2, %0|%0, %2}"
21664   [(set_attr "type" "mmxadd")
21665    (set_attr "mode" "DI")])
21666
21667 (define_insn "addv2si3"
21668   [(set (match_operand:V2SI 0 "register_operand" "=y")
21669         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21670                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21671   "TARGET_MMX"
21672   "paddd\t{%2, %0|%0, %2}"
21673   [(set_attr "type" "mmxadd")
21674    (set_attr "mode" "DI")])
21675
21676 (define_insn "mmx_adddi3"
21677   [(set (match_operand:DI 0 "register_operand" "=y")
21678         (unspec:DI
21679          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21680                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21681          UNSPEC_NOP))]
21682   "TARGET_MMX"
21683   "paddq\t{%2, %0|%0, %2}"
21684   [(set_attr "type" "mmxadd")
21685    (set_attr "mode" "DI")])
21686
21687 (define_insn "ssaddv8qi3"
21688   [(set (match_operand:V8QI 0 "register_operand" "=y")
21689         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21690                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21691   "TARGET_MMX"
21692   "paddsb\t{%2, %0|%0, %2}"
21693   [(set_attr "type" "mmxadd")
21694    (set_attr "mode" "DI")])
21695
21696 (define_insn "ssaddv4hi3"
21697   [(set (match_operand:V4HI 0 "register_operand" "=y")
21698         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21699                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21700   "TARGET_MMX"
21701   "paddsw\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxadd")
21703    (set_attr "mode" "DI")])
21704
21705 (define_insn "usaddv8qi3"
21706   [(set (match_operand:V8QI 0 "register_operand" "=y")
21707         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21708                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21709   "TARGET_MMX"
21710   "paddusb\t{%2, %0|%0, %2}"
21711   [(set_attr "type" "mmxadd")
21712    (set_attr "mode" "DI")])
21713
21714 (define_insn "usaddv4hi3"
21715   [(set (match_operand:V4HI 0 "register_operand" "=y")
21716         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21717                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21718   "TARGET_MMX"
21719   "paddusw\t{%2, %0|%0, %2}"
21720   [(set_attr "type" "mmxadd")
21721    (set_attr "mode" "DI")])
21722
21723 (define_insn "subv8qi3"
21724   [(set (match_operand:V8QI 0 "register_operand" "=y")
21725         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21726                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21727   "TARGET_MMX"
21728   "psubb\t{%2, %0|%0, %2}"
21729   [(set_attr "type" "mmxadd")
21730    (set_attr "mode" "DI")])
21731
21732 (define_insn "subv4hi3"
21733   [(set (match_operand:V4HI 0 "register_operand" "=y")
21734         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21735                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21736   "TARGET_MMX"
21737   "psubw\t{%2, %0|%0, %2}"
21738   [(set_attr "type" "mmxadd")
21739    (set_attr "mode" "DI")])
21740
21741 (define_insn "subv2si3"
21742   [(set (match_operand:V2SI 0 "register_operand" "=y")
21743         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21744                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21745   "TARGET_MMX"
21746   "psubd\t{%2, %0|%0, %2}"
21747   [(set_attr "type" "mmxadd")
21748    (set_attr "mode" "DI")])
21749
21750 (define_insn "mmx_subdi3"
21751   [(set (match_operand:DI 0 "register_operand" "=y")
21752         (unspec:DI
21753          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21754                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21755          UNSPEC_NOP))]
21756   "TARGET_MMX"
21757   "psubq\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxadd")
21759    (set_attr "mode" "DI")])
21760
21761 (define_insn "sssubv8qi3"
21762   [(set (match_operand:V8QI 0 "register_operand" "=y")
21763         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21764                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21765   "TARGET_MMX"
21766   "psubsb\t{%2, %0|%0, %2}"
21767   [(set_attr "type" "mmxadd")
21768    (set_attr "mode" "DI")])
21769
21770 (define_insn "sssubv4hi3"
21771   [(set (match_operand:V4HI 0 "register_operand" "=y")
21772         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21773                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21774   "TARGET_MMX"
21775   "psubsw\t{%2, %0|%0, %2}"
21776   [(set_attr "type" "mmxadd")
21777    (set_attr "mode" "DI")])
21778
21779 (define_insn "ussubv8qi3"
21780   [(set (match_operand:V8QI 0 "register_operand" "=y")
21781         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21782                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21783   "TARGET_MMX"
21784   "psubusb\t{%2, %0|%0, %2}"
21785   [(set_attr "type" "mmxadd")
21786    (set_attr "mode" "DI")])
21787
21788 (define_insn "ussubv4hi3"
21789   [(set (match_operand:V4HI 0 "register_operand" "=y")
21790         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21791                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21792   "TARGET_MMX"
21793   "psubusw\t{%2, %0|%0, %2}"
21794   [(set_attr "type" "mmxadd")
21795    (set_attr "mode" "DI")])
21796
21797 (define_insn "mulv4hi3"
21798   [(set (match_operand:V4HI 0 "register_operand" "=y")
21799         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21800                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21801   "TARGET_MMX"
21802   "pmullw\t{%2, %0|%0, %2}"
21803   [(set_attr "type" "mmxmul")
21804    (set_attr "mode" "DI")])
21805
21806 (define_insn "smulv4hi3_highpart"
21807   [(set (match_operand:V4HI 0 "register_operand" "=y")
21808         (truncate:V4HI
21809          (lshiftrt:V4SI
21810           (mult:V4SI (sign_extend:V4SI
21811                       (match_operand:V4HI 1 "register_operand" "0"))
21812                      (sign_extend:V4SI
21813                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21814           (const_int 16))))]
21815   "TARGET_MMX"
21816   "pmulhw\t{%2, %0|%0, %2}"
21817   [(set_attr "type" "mmxmul")
21818    (set_attr "mode" "DI")])
21819
21820 (define_insn "umulv4hi3_highpart"
21821   [(set (match_operand:V4HI 0 "register_operand" "=y")
21822         (truncate:V4HI
21823          (lshiftrt:V4SI
21824           (mult:V4SI (zero_extend:V4SI
21825                       (match_operand:V4HI 1 "register_operand" "0"))
21826                      (zero_extend:V4SI
21827                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21828           (const_int 16))))]
21829   "TARGET_SSE || TARGET_3DNOW_A"
21830   "pmulhuw\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "mmxmul")
21832    (set_attr "mode" "DI")])
21833
21834 (define_insn "mmx_pmaddwd"
21835   [(set (match_operand:V2SI 0 "register_operand" "=y")
21836         (plus:V2SI
21837          (mult:V2SI
21838           (sign_extend:V2SI
21839            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21840                             (parallel [(const_int 0) (const_int 2)])))
21841           (sign_extend:V2SI
21842            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21843                             (parallel [(const_int 0) (const_int 2)]))))
21844          (mult:V2SI
21845           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21846                                              (parallel [(const_int 1)
21847                                                         (const_int 3)])))
21848           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21849                                              (parallel [(const_int 1)
21850                                                         (const_int 3)]))))))]
21851   "TARGET_MMX"
21852   "pmaddwd\t{%2, %0|%0, %2}"
21853   [(set_attr "type" "mmxmul")
21854    (set_attr "mode" "DI")])
21855
21856
21857 ;; MMX logical operations
21858 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21859 ;; normal code that also wants to use the FPU from getting broken.
21860 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21861 (define_insn "mmx_iordi3"
21862   [(set (match_operand:DI 0 "register_operand" "=y")
21863         (unspec:DI
21864          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21865                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21866          UNSPEC_NOP))]
21867   "TARGET_MMX"
21868   "por\t{%2, %0|%0, %2}"
21869   [(set_attr "type" "mmxadd")
21870    (set_attr "mode" "DI")])
21871
21872 (define_insn "mmx_xordi3"
21873   [(set (match_operand:DI 0 "register_operand" "=y")
21874         (unspec:DI
21875          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21876                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21877          UNSPEC_NOP))]
21878   "TARGET_MMX"
21879   "pxor\t{%2, %0|%0, %2}"
21880   [(set_attr "type" "mmxadd")
21881    (set_attr "mode" "DI")
21882    (set_attr "memory" "none")])
21883
21884 ;; Same as pxor, but don't show input operands so that we don't think
21885 ;; they are live.
21886 (define_insn "mmx_clrdi"
21887   [(set (match_operand:DI 0 "register_operand" "=y")
21888         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21889   "TARGET_MMX"
21890   "pxor\t{%0, %0|%0, %0}"
21891   [(set_attr "type" "mmxadd")
21892    (set_attr "mode" "DI")
21893    (set_attr "memory" "none")])
21894
21895 (define_insn "mmx_anddi3"
21896   [(set (match_operand:DI 0 "register_operand" "=y")
21897         (unspec:DI
21898          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21899                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21900          UNSPEC_NOP))]
21901   "TARGET_MMX"
21902   "pand\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "mmxadd")
21904    (set_attr "mode" "DI")])
21905
21906 (define_insn "mmx_nanddi3"
21907   [(set (match_operand:DI 0 "register_operand" "=y")
21908         (unspec:DI
21909          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21910                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21911          UNSPEC_NOP))]
21912   "TARGET_MMX"
21913   "pandn\t{%2, %0|%0, %2}"
21914   [(set_attr "type" "mmxadd")
21915    (set_attr "mode" "DI")])
21916
21917
21918 ;; MMX unsigned averages/sum of absolute differences
21919
21920 (define_insn "mmx_uavgv8qi3"
21921   [(set (match_operand:V8QI 0 "register_operand" "=y")
21922         (ashiftrt:V8QI
21923          (plus:V8QI (plus:V8QI
21924                      (match_operand:V8QI 1 "register_operand" "0")
21925                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21926                     (const_vector:V8QI [(const_int 1)
21927                                         (const_int 1)
21928                                         (const_int 1)
21929                                         (const_int 1)
21930                                         (const_int 1)
21931                                         (const_int 1)
21932                                         (const_int 1)
21933                                         (const_int 1)]))
21934          (const_int 1)))]
21935   "TARGET_SSE || TARGET_3DNOW_A"
21936   "pavgb\t{%2, %0|%0, %2}"
21937   [(set_attr "type" "mmxshft")
21938    (set_attr "mode" "DI")])
21939
21940 (define_insn "mmx_uavgv4hi3"
21941   [(set (match_operand:V4HI 0 "register_operand" "=y")
21942         (ashiftrt:V4HI
21943          (plus:V4HI (plus:V4HI
21944                      (match_operand:V4HI 1 "register_operand" "0")
21945                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21946                     (const_vector:V4HI [(const_int 1)
21947                                         (const_int 1)
21948                                         (const_int 1)
21949                                         (const_int 1)]))
21950          (const_int 1)))]
21951   "TARGET_SSE || TARGET_3DNOW_A"
21952   "pavgw\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "mmxshft")
21954    (set_attr "mode" "DI")])
21955
21956 (define_insn "mmx_psadbw"
21957   [(set (match_operand:DI 0 "register_operand" "=y")
21958         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21959                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21960                    UNSPEC_PSADBW))]
21961   "TARGET_SSE || TARGET_3DNOW_A"
21962   "psadbw\t{%2, %0|%0, %2}"
21963   [(set_attr "type" "mmxshft")
21964    (set_attr "mode" "DI")])
21965
21966
21967 ;; MMX insert/extract/shuffle
21968
21969 (define_insn "mmx_pinsrw"
21970   [(set (match_operand:V4HI 0 "register_operand" "=y")
21971         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21972                         (vec_duplicate:V4HI
21973                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21974                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21975   "TARGET_SSE || TARGET_3DNOW_A"
21976   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21977   [(set_attr "type" "mmxcvt")
21978    (set_attr "mode" "DI")])
21979
21980 (define_insn "mmx_pextrw"
21981   [(set (match_operand:SI 0 "register_operand" "=r")
21982         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21983                                        (parallel
21984                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21985   "TARGET_SSE || TARGET_3DNOW_A"
21986   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21987   [(set_attr "type" "mmxcvt")
21988    (set_attr "mode" "DI")])
21989
21990 (define_insn "mmx_pshufw"
21991   [(set (match_operand:V4HI 0 "register_operand" "=y")
21992         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21993                       (match_operand:SI 2 "immediate_operand" "i")]
21994                      UNSPEC_SHUFFLE))]
21995   "TARGET_SSE || TARGET_3DNOW_A"
21996   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21997   [(set_attr "type" "mmxcvt")
21998    (set_attr "mode" "DI")])
21999
22000
22001 ;; MMX mask-generating comparisons
22002
22003 (define_insn "eqv8qi3"
22004   [(set (match_operand:V8QI 0 "register_operand" "=y")
22005         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
22006                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22007   "TARGET_MMX"
22008   "pcmpeqb\t{%2, %0|%0, %2}"
22009   [(set_attr "type" "mmxcmp")
22010    (set_attr "mode" "DI")])
22011
22012 (define_insn "eqv4hi3"
22013   [(set (match_operand:V4HI 0 "register_operand" "=y")
22014         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
22015                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22016   "TARGET_MMX"
22017   "pcmpeqw\t{%2, %0|%0, %2}"
22018   [(set_attr "type" "mmxcmp")
22019    (set_attr "mode" "DI")])
22020
22021 (define_insn "eqv2si3"
22022   [(set (match_operand:V2SI 0 "register_operand" "=y")
22023         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
22024                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22025   "TARGET_MMX"
22026   "pcmpeqd\t{%2, %0|%0, %2}"
22027   [(set_attr "type" "mmxcmp")
22028    (set_attr "mode" "DI")])
22029
22030 (define_insn "gtv8qi3"
22031   [(set (match_operand:V8QI 0 "register_operand" "=y")
22032         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
22033                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22034   "TARGET_MMX"
22035   "pcmpgtb\t{%2, %0|%0, %2}"
22036   [(set_attr "type" "mmxcmp")
22037    (set_attr "mode" "DI")])
22038
22039 (define_insn "gtv4hi3"
22040   [(set (match_operand:V4HI 0 "register_operand" "=y")
22041         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22042                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22043   "TARGET_MMX"
22044   "pcmpgtw\t{%2, %0|%0, %2}"
22045   [(set_attr "type" "mmxcmp")
22046    (set_attr "mode" "DI")])
22047
22048 (define_insn "gtv2si3"
22049   [(set (match_operand:V2SI 0 "register_operand" "=y")
22050         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22051                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22052   "TARGET_MMX"
22053   "pcmpgtd\t{%2, %0|%0, %2}"
22054   [(set_attr "type" "mmxcmp")
22055    (set_attr "mode" "DI")])
22056
22057
22058 ;; MMX max/min insns
22059
22060 (define_insn "umaxv8qi3"
22061   [(set (match_operand:V8QI 0 "register_operand" "=y")
22062         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22063                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22064   "TARGET_SSE || TARGET_3DNOW_A"
22065   "pmaxub\t{%2, %0|%0, %2}"
22066   [(set_attr "type" "mmxadd")
22067    (set_attr "mode" "DI")])
22068
22069 (define_insn "smaxv4hi3"
22070   [(set (match_operand:V4HI 0 "register_operand" "=y")
22071         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22072                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22073   "TARGET_SSE || TARGET_3DNOW_A"
22074   "pmaxsw\t{%2, %0|%0, %2}"
22075   [(set_attr "type" "mmxadd")
22076    (set_attr "mode" "DI")])
22077
22078 (define_insn "uminv8qi3"
22079   [(set (match_operand:V8QI 0 "register_operand" "=y")
22080         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22081                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22082   "TARGET_SSE || TARGET_3DNOW_A"
22083   "pminub\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxadd")
22085    (set_attr "mode" "DI")])
22086
22087 (define_insn "sminv4hi3"
22088   [(set (match_operand:V4HI 0 "register_operand" "=y")
22089         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22090                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22091   "TARGET_SSE || TARGET_3DNOW_A"
22092   "pminsw\t{%2, %0|%0, %2}"
22093   [(set_attr "type" "mmxadd")
22094    (set_attr "mode" "DI")])
22095
22096
22097 ;; MMX shifts
22098
22099 (define_insn "ashrv4hi3"
22100   [(set (match_operand:V4HI 0 "register_operand" "=y")
22101         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22102                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22103   "TARGET_MMX"
22104   "psraw\t{%2, %0|%0, %2}"
22105   [(set_attr "type" "mmxshft")
22106    (set_attr "mode" "DI")])
22107
22108 (define_insn "ashrv2si3"
22109   [(set (match_operand:V2SI 0 "register_operand" "=y")
22110         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22111                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22112   "TARGET_MMX"
22113   "psrad\t{%2, %0|%0, %2}"
22114   [(set_attr "type" "mmxshft")
22115    (set_attr "mode" "DI")])
22116
22117 (define_insn "lshrv4hi3"
22118   [(set (match_operand:V4HI 0 "register_operand" "=y")
22119         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22120                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22121   "TARGET_MMX"
22122   "psrlw\t{%2, %0|%0, %2}"
22123   [(set_attr "type" "mmxshft")
22124    (set_attr "mode" "DI")])
22125
22126 (define_insn "lshrv2si3"
22127   [(set (match_operand:V2SI 0 "register_operand" "=y")
22128         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22129                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22130   "TARGET_MMX"
22131   "psrld\t{%2, %0|%0, %2}"
22132   [(set_attr "type" "mmxshft")
22133    (set_attr "mode" "DI")])
22134
22135 ;; See logical MMX insns.
22136 (define_insn "mmx_lshrdi3"
22137   [(set (match_operand:DI 0 "register_operand" "=y")
22138         (unspec:DI
22139           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22140                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22141           UNSPEC_NOP))]
22142   "TARGET_MMX"
22143   "psrlq\t{%2, %0|%0, %2}"
22144   [(set_attr "type" "mmxshft")
22145    (set_attr "mode" "DI")])
22146
22147 (define_insn "ashlv4hi3"
22148   [(set (match_operand:V4HI 0 "register_operand" "=y")
22149         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22150                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22151   "TARGET_MMX"
22152   "psllw\t{%2, %0|%0, %2}"
22153   [(set_attr "type" "mmxshft")
22154    (set_attr "mode" "DI")])
22155
22156 (define_insn "ashlv2si3"
22157   [(set (match_operand:V2SI 0 "register_operand" "=y")
22158         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22159                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22160   "TARGET_MMX"
22161   "pslld\t{%2, %0|%0, %2}"
22162   [(set_attr "type" "mmxshft")
22163    (set_attr "mode" "DI")])
22164
22165 ;; See logical MMX insns.
22166 (define_insn "mmx_ashldi3"
22167   [(set (match_operand:DI 0 "register_operand" "=y")
22168         (unspec:DI
22169          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22170                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22171          UNSPEC_NOP))]
22172   "TARGET_MMX"
22173   "psllq\t{%2, %0|%0, %2}"
22174   [(set_attr "type" "mmxshft")
22175    (set_attr "mode" "DI")])
22176
22177
22178 ;; MMX pack/unpack insns.
22179
22180 (define_insn "mmx_packsswb"
22181   [(set (match_operand:V8QI 0 "register_operand" "=y")
22182         (vec_concat:V8QI
22183          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22184          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22185   "TARGET_MMX"
22186   "packsswb\t{%2, %0|%0, %2}"
22187   [(set_attr "type" "mmxshft")
22188    (set_attr "mode" "DI")])
22189
22190 (define_insn "mmx_packssdw"
22191   [(set (match_operand:V4HI 0 "register_operand" "=y")
22192         (vec_concat:V4HI
22193          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22194          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22195   "TARGET_MMX"
22196   "packssdw\t{%2, %0|%0, %2}"
22197   [(set_attr "type" "mmxshft")
22198    (set_attr "mode" "DI")])
22199
22200 (define_insn "mmx_packuswb"
22201   [(set (match_operand:V8QI 0 "register_operand" "=y")
22202         (vec_concat:V8QI
22203          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22204          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22205   "TARGET_MMX"
22206   "packuswb\t{%2, %0|%0, %2}"
22207   [(set_attr "type" "mmxshft")
22208    (set_attr "mode" "DI")])
22209
22210 (define_insn "mmx_punpckhbw"
22211   [(set (match_operand:V8QI 0 "register_operand" "=y")
22212         (vec_merge:V8QI
22213          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22214                           (parallel [(const_int 4)
22215                                      (const_int 0)
22216                                      (const_int 5)
22217                                      (const_int 1)
22218                                      (const_int 6)
22219                                      (const_int 2)
22220                                      (const_int 7)
22221                                      (const_int 3)]))
22222          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22223                           (parallel [(const_int 0)
22224                                      (const_int 4)
22225                                      (const_int 1)
22226                                      (const_int 5)
22227                                      (const_int 2)
22228                                      (const_int 6)
22229                                      (const_int 3)
22230                                      (const_int 7)]))
22231          (const_int 85)))]
22232   "TARGET_MMX"
22233   "punpckhbw\t{%2, %0|%0, %2}"
22234   [(set_attr "type" "mmxcvt")
22235    (set_attr "mode" "DI")])
22236
22237 (define_insn "mmx_punpckhwd"
22238   [(set (match_operand:V4HI 0 "register_operand" "=y")
22239         (vec_merge:V4HI
22240          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22241                           (parallel [(const_int 0)
22242                                      (const_int 2)
22243                                      (const_int 1)
22244                                      (const_int 3)]))
22245          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22246                           (parallel [(const_int 2)
22247                                      (const_int 0)
22248                                      (const_int 3)
22249                                      (const_int 1)]))
22250          (const_int 5)))]
22251   "TARGET_MMX"
22252   "punpckhwd\t{%2, %0|%0, %2}"
22253   [(set_attr "type" "mmxcvt")
22254    (set_attr "mode" "DI")])
22255
22256 (define_insn "mmx_punpckhdq"
22257   [(set (match_operand:V2SI 0 "register_operand" "=y")
22258         (vec_merge:V2SI
22259          (match_operand:V2SI 1 "register_operand" "0")
22260          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22261                           (parallel [(const_int 1)
22262                                      (const_int 0)]))
22263          (const_int 1)))]
22264   "TARGET_MMX"
22265   "punpckhdq\t{%2, %0|%0, %2}"
22266   [(set_attr "type" "mmxcvt")
22267    (set_attr "mode" "DI")])
22268
22269 (define_insn "mmx_punpcklbw"
22270   [(set (match_operand:V8QI 0 "register_operand" "=y")
22271         (vec_merge:V8QI
22272          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22273                           (parallel [(const_int 0)
22274                                      (const_int 4)
22275                                      (const_int 1)
22276                                      (const_int 5)
22277                                      (const_int 2)
22278                                      (const_int 6)
22279                                      (const_int 3)
22280                                      (const_int 7)]))
22281          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22282                           (parallel [(const_int 4)
22283                                      (const_int 0)
22284                                      (const_int 5)
22285                                      (const_int 1)
22286                                      (const_int 6)
22287                                      (const_int 2)
22288                                      (const_int 7)
22289                                      (const_int 3)]))
22290          (const_int 85)))]
22291   "TARGET_MMX"
22292   "punpcklbw\t{%2, %0|%0, %2}"
22293   [(set_attr "type" "mmxcvt")
22294    (set_attr "mode" "DI")])
22295
22296 (define_insn "mmx_punpcklwd"
22297   [(set (match_operand:V4HI 0 "register_operand" "=y")
22298         (vec_merge:V4HI
22299          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22300                           (parallel [(const_int 2)
22301                                      (const_int 0)
22302                                      (const_int 3)
22303                                      (const_int 1)]))
22304          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22305                           (parallel [(const_int 0)
22306                                      (const_int 2)
22307                                      (const_int 1)
22308                                      (const_int 3)]))
22309          (const_int 5)))]
22310   "TARGET_MMX"
22311   "punpcklwd\t{%2, %0|%0, %2}"
22312   [(set_attr "type" "mmxcvt")
22313    (set_attr "mode" "DI")])
22314
22315 (define_insn "mmx_punpckldq"
22316   [(set (match_operand:V2SI 0 "register_operand" "=y")
22317         (vec_merge:V2SI
22318          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22319                            (parallel [(const_int 1)
22320                                       (const_int 0)]))
22321          (match_operand:V2SI 2 "register_operand" "y")
22322          (const_int 1)))]
22323   "TARGET_MMX"
22324   "punpckldq\t{%2, %0|%0, %2}"
22325   [(set_attr "type" "mmxcvt")
22326    (set_attr "mode" "DI")])
22327
22328
22329 ;; Miscellaneous stuff
22330
22331 (define_insn "emms"
22332   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22333    (clobber (reg:XF 8))
22334    (clobber (reg:XF 9))
22335    (clobber (reg:XF 10))
22336    (clobber (reg:XF 11))
22337    (clobber (reg:XF 12))
22338    (clobber (reg:XF 13))
22339    (clobber (reg:XF 14))
22340    (clobber (reg:XF 15))
22341    (clobber (reg:DI 29))
22342    (clobber (reg:DI 30))
22343    (clobber (reg:DI 31))
22344    (clobber (reg:DI 32))
22345    (clobber (reg:DI 33))
22346    (clobber (reg:DI 34))
22347    (clobber (reg:DI 35))
22348    (clobber (reg:DI 36))]
22349   "TARGET_MMX"
22350   "emms"
22351   [(set_attr "type" "mmx")
22352    (set_attr "memory" "unknown")])
22353
22354 (define_insn "ldmxcsr"
22355   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22356                     UNSPECV_LDMXCSR)]
22357   "TARGET_SSE"
22358   "ldmxcsr\t%0"
22359   [(set_attr "type" "sse")
22360    (set_attr "memory" "load")])
22361
22362 (define_insn "stmxcsr"
22363   [(set (match_operand:SI 0 "memory_operand" "=m")
22364         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22365   "TARGET_SSE"
22366   "stmxcsr\t%0"
22367   [(set_attr "type" "sse")
22368    (set_attr "memory" "store")])
22369
22370 (define_expand "sfence"
22371   [(set (match_dup 0)
22372         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22373   "TARGET_SSE || TARGET_3DNOW_A"
22374 {
22375   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22376   MEM_VOLATILE_P (operands[0]) = 1;
22377 })
22378
22379 (define_insn "*sfence_insn"
22380   [(set (match_operand:BLK 0 "" "")
22381         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22382   "TARGET_SSE || TARGET_3DNOW_A"
22383   "sfence"
22384   [(set_attr "type" "sse")
22385    (set_attr "memory" "unknown")])
22386
22387 (define_expand "sse_prologue_save"
22388   [(parallel [(set (match_operand:BLK 0 "" "")
22389                    (unspec:BLK [(reg:DI 21)
22390                                 (reg:DI 22)
22391                                 (reg:DI 23)
22392                                 (reg:DI 24)
22393                                 (reg:DI 25)
22394                                 (reg:DI 26)
22395                                 (reg:DI 27)
22396                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22397               (use (match_operand:DI 1 "register_operand" ""))
22398               (use (match_operand:DI 2 "immediate_operand" ""))
22399               (use (label_ref:DI (match_operand 3 "" "")))])]
22400   "TARGET_64BIT"
22401   "")
22402
22403 (define_insn "*sse_prologue_save_insn"
22404   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22405                           (match_operand:DI 4 "const_int_operand" "n")))
22406         (unspec:BLK [(reg:DI 21)
22407                      (reg:DI 22)
22408                      (reg:DI 23)
22409                      (reg:DI 24)
22410                      (reg:DI 25)
22411                      (reg:DI 26)
22412                      (reg:DI 27)
22413                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22414    (use (match_operand:DI 1 "register_operand" "r"))
22415    (use (match_operand:DI 2 "const_int_operand" "i"))
22416    (use (label_ref:DI (match_operand 3 "" "X")))]
22417   "TARGET_64BIT
22418    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22419    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22420   "*
22421 {
22422   int i;
22423   operands[0] = gen_rtx_MEM (Pmode,
22424                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22425   output_asm_insn (\"jmp\\t%A1\", operands);
22426   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22427     {
22428       operands[4] = adjust_address (operands[0], DImode, i*16);
22429       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22430       PUT_MODE (operands[4], TImode);
22431       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22432         output_asm_insn (\"rex\", operands);
22433       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22434     }
22435   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22436                              CODE_LABEL_NUMBER (operands[3]));
22437   RET;
22438 }
22439   "
22440   [(set_attr "type" "other")
22441    (set_attr "length_immediate" "0")
22442    (set_attr "length_address" "0")
22443    (set_attr "length" "135")
22444    (set_attr "memory" "store")
22445    (set_attr "modrm" "0")
22446    (set_attr "mode" "DI")])
22447
22448 ;; 3Dnow! instructions
22449
22450 (define_insn "addv2sf3"
22451   [(set (match_operand:V2SF 0 "register_operand" "=y")
22452         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22453                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22454   "TARGET_3DNOW"
22455   "pfadd\\t{%2, %0|%0, %2}"
22456   [(set_attr "type" "mmxadd")
22457    (set_attr "mode" "V2SF")])
22458
22459 (define_insn "subv2sf3"
22460   [(set (match_operand:V2SF 0 "register_operand" "=y")
22461         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22462                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22463   "TARGET_3DNOW"
22464   "pfsub\\t{%2, %0|%0, %2}"
22465   [(set_attr "type" "mmxadd")
22466    (set_attr "mode" "V2SF")])
22467
22468 (define_insn "subrv2sf3"
22469   [(set (match_operand:V2SF 0 "register_operand" "=y")
22470         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22471                     (match_operand:V2SF 1 "register_operand" "0")))]
22472   "TARGET_3DNOW"
22473   "pfsubr\\t{%2, %0|%0, %2}"
22474   [(set_attr "type" "mmxadd")
22475    (set_attr "mode" "V2SF")])
22476
22477 (define_insn "gtv2sf3"
22478   [(set (match_operand:V2SI 0 "register_operand" "=y")
22479         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22480                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22481  "TARGET_3DNOW"
22482   "pfcmpgt\\t{%2, %0|%0, %2}"
22483   [(set_attr "type" "mmxcmp")
22484    (set_attr "mode" "V2SF")])
22485
22486 (define_insn "gev2sf3"
22487   [(set (match_operand:V2SI 0 "register_operand" "=y")
22488         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22489                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22490   "TARGET_3DNOW"
22491   "pfcmpge\\t{%2, %0|%0, %2}"
22492   [(set_attr "type" "mmxcmp")
22493    (set_attr "mode" "V2SF")])
22494
22495 (define_insn "eqv2sf3"
22496   [(set (match_operand:V2SI 0 "register_operand" "=y")
22497         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22498                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22499   "TARGET_3DNOW"
22500   "pfcmpeq\\t{%2, %0|%0, %2}"
22501   [(set_attr "type" "mmxcmp")
22502    (set_attr "mode" "V2SF")])
22503
22504 (define_insn "pfmaxv2sf3"
22505   [(set (match_operand:V2SF 0 "register_operand" "=y")
22506         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22507                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22508   "TARGET_3DNOW"
22509   "pfmax\\t{%2, %0|%0, %2}"
22510   [(set_attr "type" "mmxadd")
22511    (set_attr "mode" "V2SF")])
22512
22513 (define_insn "pfminv2sf3"
22514   [(set (match_operand:V2SF 0 "register_operand" "=y")
22515         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22516                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22517   "TARGET_3DNOW"
22518   "pfmin\\t{%2, %0|%0, %2}"
22519   [(set_attr "type" "mmxadd")
22520    (set_attr "mode" "V2SF")])
22521
22522 (define_insn "mulv2sf3"
22523   [(set (match_operand:V2SF 0 "register_operand" "=y")
22524         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22525                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22526   "TARGET_3DNOW"
22527   "pfmul\\t{%2, %0|%0, %2}"
22528   [(set_attr "type" "mmxmul")
22529    (set_attr "mode" "V2SF")])
22530
22531 (define_insn "femms"
22532   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22533    (clobber (reg:XF 8))
22534    (clobber (reg:XF 9))
22535    (clobber (reg:XF 10))
22536    (clobber (reg:XF 11))
22537    (clobber (reg:XF 12))
22538    (clobber (reg:XF 13))
22539    (clobber (reg:XF 14))
22540    (clobber (reg:XF 15))
22541    (clobber (reg:DI 29))
22542    (clobber (reg:DI 30))
22543    (clobber (reg:DI 31))
22544    (clobber (reg:DI 32))
22545    (clobber (reg:DI 33))
22546    (clobber (reg:DI 34))
22547    (clobber (reg:DI 35))
22548    (clobber (reg:DI 36))]
22549   "TARGET_3DNOW"
22550   "femms"
22551   [(set_attr "type" "mmx")
22552    (set_attr "memory" "none")]) 
22553
22554 (define_insn "pf2id"
22555   [(set (match_operand:V2SI 0 "register_operand" "=y")
22556         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22557   "TARGET_3DNOW"
22558   "pf2id\\t{%1, %0|%0, %1}"
22559   [(set_attr "type" "mmxcvt")
22560    (set_attr "mode" "V2SF")])
22561
22562 (define_insn "pf2iw"
22563   [(set (match_operand:V2SI 0 "register_operand" "=y")
22564         (sign_extend:V2SI
22565            (ss_truncate:V2HI
22566               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22567   "TARGET_3DNOW_A"
22568   "pf2iw\\t{%1, %0|%0, %1}"
22569   [(set_attr "type" "mmxcvt")
22570    (set_attr "mode" "V2SF")])
22571
22572 (define_insn "pfacc"
22573   [(set (match_operand:V2SF 0 "register_operand" "=y")
22574         (vec_concat:V2SF
22575            (plus:SF
22576               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22577                              (parallel [(const_int  0)]))
22578               (vec_select:SF (match_dup 1)
22579                              (parallel [(const_int 1)])))
22580            (plus:SF
22581               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22582                              (parallel [(const_int  0)]))
22583               (vec_select:SF (match_dup 2)
22584                              (parallel [(const_int 1)])))))]
22585   "TARGET_3DNOW"
22586   "pfacc\\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "mmxadd")
22588    (set_attr "mode" "V2SF")])
22589
22590 (define_insn "pfnacc"
22591   [(set (match_operand:V2SF 0 "register_operand" "=y")
22592         (vec_concat:V2SF
22593            (minus:SF
22594               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22595                              (parallel [(const_int 0)]))
22596               (vec_select:SF (match_dup 1)
22597                              (parallel [(const_int 1)])))
22598            (minus:SF
22599               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22600                              (parallel [(const_int  0)]))
22601               (vec_select:SF (match_dup 2)
22602                              (parallel [(const_int 1)])))))]
22603   "TARGET_3DNOW_A"
22604   "pfnacc\\t{%2, %0|%0, %2}"
22605   [(set_attr "type" "mmxadd")
22606    (set_attr "mode" "V2SF")])
22607
22608 (define_insn "pfpnacc"
22609   [(set (match_operand:V2SF 0 "register_operand" "=y")
22610         (vec_concat:V2SF
22611            (minus:SF
22612               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22613                              (parallel [(const_int 0)]))
22614               (vec_select:SF (match_dup 1)
22615                              (parallel [(const_int 1)])))
22616            (plus:SF
22617               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22618                              (parallel [(const_int 0)]))
22619               (vec_select:SF (match_dup 2)
22620                              (parallel [(const_int 1)])))))]
22621   "TARGET_3DNOW_A"
22622   "pfpnacc\\t{%2, %0|%0, %2}"
22623   [(set_attr "type" "mmxadd")
22624    (set_attr "mode" "V2SF")])
22625
22626 (define_insn "pi2fw"
22627   [(set (match_operand:V2SF 0 "register_operand" "=y")
22628         (float:V2SF
22629            (vec_concat:V2SI
22630               (sign_extend:SI
22631                  (truncate:HI
22632                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22633                                    (parallel [(const_int 0)]))))
22634               (sign_extend:SI
22635                  (truncate:HI
22636                     (vec_select:SI (match_dup 1)
22637                                    (parallel [(const_int  1)])))))))]
22638   "TARGET_3DNOW_A"
22639   "pi2fw\\t{%1, %0|%0, %1}"
22640   [(set_attr "type" "mmxcvt")
22641    (set_attr "mode" "V2SF")])
22642
22643 (define_insn "floatv2si2"
22644   [(set (match_operand:V2SF 0 "register_operand" "=y")
22645         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22646   "TARGET_3DNOW"
22647   "pi2fd\\t{%1, %0|%0, %1}"
22648   [(set_attr "type" "mmxcvt")
22649    (set_attr "mode" "V2SF")])
22650
22651 ;; This insn is identical to pavgb in operation, but the opcode is
22652 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22653
22654 (define_insn "pavgusb"
22655  [(set (match_operand:V8QI 0 "register_operand" "=y")
22656        (unspec:V8QI
22657           [(match_operand:V8QI 1 "register_operand" "0")
22658            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22659           UNSPEC_PAVGUSB))]
22660   "TARGET_3DNOW"
22661   "pavgusb\\t{%2, %0|%0, %2}"
22662   [(set_attr "type" "mmxshft")
22663    (set_attr "mode" "TI")])
22664
22665 ;; 3DNow reciprocal and sqrt
22666  
22667 (define_insn "pfrcpv2sf2"
22668   [(set (match_operand:V2SF 0 "register_operand" "=y")
22669         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22670         UNSPEC_PFRCP))]
22671   "TARGET_3DNOW"
22672   "pfrcp\\t{%1, %0|%0, %1}"
22673   [(set_attr "type" "mmx")
22674    (set_attr "mode" "TI")])
22675
22676 (define_insn "pfrcpit1v2sf3"
22677   [(set (match_operand:V2SF 0 "register_operand" "=y")
22678         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22679                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22680                      UNSPEC_PFRCPIT1))]
22681   "TARGET_3DNOW"
22682   "pfrcpit1\\t{%2, %0|%0, %2}"
22683   [(set_attr "type" "mmx")
22684    (set_attr "mode" "TI")])
22685
22686 (define_insn "pfrcpit2v2sf3"
22687   [(set (match_operand:V2SF 0 "register_operand" "=y")
22688         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22689                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22690                      UNSPEC_PFRCPIT2))]
22691   "TARGET_3DNOW"
22692   "pfrcpit2\\t{%2, %0|%0, %2}"
22693   [(set_attr "type" "mmx")
22694    (set_attr "mode" "TI")])
22695
22696 (define_insn "pfrsqrtv2sf2"
22697   [(set (match_operand:V2SF 0 "register_operand" "=y")
22698         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22699                      UNSPEC_PFRSQRT))]
22700   "TARGET_3DNOW"
22701   "pfrsqrt\\t{%1, %0|%0, %1}"
22702   [(set_attr "type" "mmx")
22703    (set_attr "mode" "TI")])
22704                 
22705 (define_insn "pfrsqit1v2sf3"
22706   [(set (match_operand:V2SF 0 "register_operand" "=y")
22707         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22708                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22709                      UNSPEC_PFRSQIT1))]
22710   "TARGET_3DNOW"
22711   "pfrsqit1\\t{%2, %0|%0, %2}"
22712   [(set_attr "type" "mmx")
22713    (set_attr "mode" "TI")])
22714
22715 (define_insn "pmulhrwv4hi3"
22716   [(set (match_operand:V4HI 0 "register_operand" "=y")
22717         (truncate:V4HI
22718            (lshiftrt:V4SI
22719               (plus:V4SI
22720                  (mult:V4SI
22721                     (sign_extend:V4SI
22722                        (match_operand:V4HI 1 "register_operand" "0"))
22723                     (sign_extend:V4SI
22724                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22725                  (const_vector:V4SI [(const_int 32768)
22726                                      (const_int 32768)
22727                                      (const_int 32768)
22728                                      (const_int 32768)]))
22729               (const_int 16))))]
22730   "TARGET_3DNOW"
22731   "pmulhrw\\t{%2, %0|%0, %2}"
22732   [(set_attr "type" "mmxmul")
22733    (set_attr "mode" "TI")])
22734
22735 (define_insn "pswapdv2si2"
22736   [(set (match_operand:V2SI 0 "register_operand" "=y")
22737         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22738                          (parallel [(const_int 1) (const_int 0)])))]
22739   "TARGET_3DNOW_A"
22740   "pswapd\\t{%1, %0|%0, %1}"
22741   [(set_attr "type" "mmxcvt")
22742    (set_attr "mode" "TI")])
22743
22744 (define_insn "pswapdv2sf2"
22745   [(set (match_operand:V2SF 0 "register_operand" "=y")
22746         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22747                          (parallel [(const_int 1) (const_int 0)])))]
22748   "TARGET_3DNOW_A"
22749   "pswapd\\t{%1, %0|%0, %1}"
22750   [(set_attr "type" "mmxcvt")
22751    (set_attr "mode" "TI")])
22752
22753 (define_expand "prefetch"
22754   [(prefetch (match_operand 0 "address_operand" "")
22755              (match_operand:SI 1 "const_int_operand" "")
22756              (match_operand:SI 2 "const_int_operand" ""))]
22757   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22758 {
22759   int rw = INTVAL (operands[1]);
22760   int locality = INTVAL (operands[2]);
22761
22762   if (rw != 0 && rw != 1)
22763     abort ();
22764   if (locality < 0 || locality > 3)
22765     abort ();
22766   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22767     abort ();
22768
22769   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22770      suported by SSE counterpart or the SSE prefetch is not available
22771      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22772      of locality.  */
22773   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22774     operands[2] = GEN_INT (3);
22775   else
22776     operands[1] = const0_rtx;
22777 })
22778
22779 (define_insn "*prefetch_sse"
22780   [(prefetch (match_operand:SI 0 "address_operand" "p")
22781              (const_int 0)
22782              (match_operand:SI 1 "const_int_operand" ""))]
22783   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22784 {
22785   static const char * const patterns[4] = {
22786    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22787   };
22788
22789   int locality = INTVAL (operands[1]);
22790   if (locality < 0 || locality > 3)
22791     abort ();
22792
22793   return patterns[locality];  
22794 }
22795   [(set_attr "type" "sse")
22796    (set_attr "memory" "none")])
22797
22798 (define_insn "*prefetch_sse_rex"
22799   [(prefetch (match_operand:DI 0 "address_operand" "p")
22800              (const_int 0)
22801              (match_operand:SI 1 "const_int_operand" ""))]
22802   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22803 {
22804   static const char * const patterns[4] = {
22805    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22806   };
22807
22808   int locality = INTVAL (operands[1]);
22809   if (locality < 0 || locality > 3)
22810     abort ();
22811
22812   return patterns[locality];  
22813 }
22814   [(set_attr "type" "sse")
22815    (set_attr "memory" "none")])
22816
22817 (define_insn "*prefetch_3dnow"
22818   [(prefetch (match_operand:SI 0 "address_operand" "p")
22819              (match_operand:SI 1 "const_int_operand" "n")
22820              (const_int 3))]
22821   "TARGET_3DNOW && !TARGET_64BIT"
22822 {
22823   if (INTVAL (operands[1]) == 0)
22824     return "prefetch\t%a0";
22825   else
22826     return "prefetchw\t%a0";
22827 }
22828   [(set_attr "type" "mmx")
22829    (set_attr "memory" "none")])
22830
22831 (define_insn "*prefetch_3dnow_rex"
22832   [(prefetch (match_operand:DI 0 "address_operand" "p")
22833              (match_operand:SI 1 "const_int_operand" "n")
22834              (const_int 3))]
22835   "TARGET_3DNOW && TARGET_64BIT"
22836 {
22837   if (INTVAL (operands[1]) == 0)
22838     return "prefetch\t%a0";
22839   else
22840     return "prefetchw\t%a0";
22841 }
22842   [(set_attr "type" "mmx")
22843    (set_attr "memory" "none")])
22844
22845 ;; SSE2 support
22846
22847 (define_insn "addv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22851   "TARGET_SSE2"
22852   "addpd\t{%2, %0|%0, %2}"
22853   [(set_attr "type" "sseadd")
22854    (set_attr "mode" "V2DF")])
22855
22856 (define_insn "vmaddv2df3"
22857   [(set (match_operand:V2DF 0 "register_operand" "=x")
22858         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22859                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22860                         (match_dup 1)
22861                         (const_int 1)))]
22862   "TARGET_SSE2"
22863   "addsd\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "sseadd")
22865    (set_attr "mode" "DF")])
22866
22867 (define_insn "subv2df3"
22868   [(set (match_operand:V2DF 0 "register_operand" "=x")
22869         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22870                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22871   "TARGET_SSE2"
22872   "subpd\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "sseadd")
22874    (set_attr "mode" "V2DF")])
22875
22876 (define_insn "vmsubv2df3"
22877   [(set (match_operand:V2DF 0 "register_operand" "=x")
22878         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22879                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22880                         (match_dup 1)
22881                         (const_int 1)))]
22882   "TARGET_SSE2"
22883   "subsd\t{%2, %0|%0, %2}"
22884   [(set_attr "type" "sseadd")
22885    (set_attr "mode" "DF")])
22886
22887 (define_insn "mulv2df3"
22888   [(set (match_operand:V2DF 0 "register_operand" "=x")
22889         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22890                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22891   "TARGET_SSE2"
22892   "mulpd\t{%2, %0|%0, %2}"
22893   [(set_attr "type" "ssemul")
22894    (set_attr "mode" "V2DF")])
22895
22896 (define_insn "vmmulv2df3"
22897   [(set (match_operand:V2DF 0 "register_operand" "=x")
22898         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22899                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22900                         (match_dup 1)
22901                         (const_int 1)))]
22902   "TARGET_SSE2"
22903   "mulsd\t{%2, %0|%0, %2}"
22904   [(set_attr "type" "ssemul")
22905    (set_attr "mode" "DF")])
22906
22907 (define_insn "divv2df3"
22908   [(set (match_operand:V2DF 0 "register_operand" "=x")
22909         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22910                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22911   "TARGET_SSE2"
22912   "divpd\t{%2, %0|%0, %2}"
22913   [(set_attr "type" "ssediv")
22914    (set_attr "mode" "V2DF")])
22915
22916 (define_insn "vmdivv2df3"
22917   [(set (match_operand:V2DF 0 "register_operand" "=x")
22918         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22919                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22920                         (match_dup 1)
22921                         (const_int 1)))]
22922   "TARGET_SSE2"
22923   "divsd\t{%2, %0|%0, %2}"
22924   [(set_attr "type" "ssediv")
22925    (set_attr "mode" "DF")])
22926
22927 ;; SSE min/max
22928
22929 (define_insn "smaxv2df3"
22930   [(set (match_operand:V2DF 0 "register_operand" "=x")
22931         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22932                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22933   "TARGET_SSE2"
22934   "maxpd\t{%2, %0|%0, %2}"
22935   [(set_attr "type" "sseadd")
22936    (set_attr "mode" "V2DF")])
22937
22938 (define_insn "vmsmaxv2df3"
22939   [(set (match_operand:V2DF 0 "register_operand" "=x")
22940         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22941                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22942                         (match_dup 1)
22943                         (const_int 1)))]
22944   "TARGET_SSE2"
22945   "maxsd\t{%2, %0|%0, %2}"
22946   [(set_attr "type" "sseadd")
22947    (set_attr "mode" "DF")])
22948
22949 (define_insn "sminv2df3"
22950   [(set (match_operand:V2DF 0 "register_operand" "=x")
22951         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22952                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22953   "TARGET_SSE2"
22954   "minpd\t{%2, %0|%0, %2}"
22955   [(set_attr "type" "sseadd")
22956    (set_attr "mode" "V2DF")])
22957
22958 (define_insn "vmsminv2df3"
22959   [(set (match_operand:V2DF 0 "register_operand" "=x")
22960         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22961                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22962                         (match_dup 1)
22963                         (const_int 1)))]
22964   "TARGET_SSE2"
22965   "minsd\t{%2, %0|%0, %2}"
22966   [(set_attr "type" "sseadd")
22967    (set_attr "mode" "DF")])
22968 ;; SSE2 square root.  There doesn't appear to be an extension for the
22969 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22970
22971 (define_insn "sqrtv2df2"
22972   [(set (match_operand:V2DF 0 "register_operand" "=x")
22973         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22974   "TARGET_SSE2"
22975   "sqrtpd\t{%1, %0|%0, %1}"
22976   [(set_attr "type" "sse")
22977    (set_attr "mode" "V2DF")])
22978
22979 (define_insn "vmsqrtv2df2"
22980   [(set (match_operand:V2DF 0 "register_operand" "=x")
22981         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22982                         (match_operand:V2DF 2 "register_operand" "0")
22983                         (const_int 1)))]
22984   "TARGET_SSE2"
22985   "sqrtsd\t{%1, %0|%0, %1}"
22986   [(set_attr "type" "sse")
22987    (set_attr "mode" "SF")])
22988
22989 ;; SSE mask-generating compares
22990
22991 (define_insn "maskcmpv2df3"
22992   [(set (match_operand:V2DI 0 "register_operand" "=x")
22993         (match_operator:V2DI 3 "sse_comparison_operator"
22994                              [(match_operand:V2DF 1 "register_operand" "0")
22995                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22996   "TARGET_SSE2"
22997   "cmp%D3pd\t{%2, %0|%0, %2}"
22998   [(set_attr "type" "ssecmp")
22999    (set_attr "mode" "V2DF")])
23000
23001 (define_insn "maskncmpv2df3"
23002   [(set (match_operand:V2DI 0 "register_operand" "=x")
23003         (not:V2DI
23004          (match_operator:V2DI 3 "sse_comparison_operator"
23005                               [(match_operand:V2DF 1 "register_operand" "0")
23006                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
23007   "TARGET_SSE2"
23008 {
23009   if (GET_CODE (operands[3]) == UNORDERED)
23010     return "cmpordps\t{%2, %0|%0, %2}";
23011   else
23012     return "cmpn%D3pd\t{%2, %0|%0, %2}";
23013 }
23014   [(set_attr "type" "ssecmp")
23015    (set_attr "mode" "V2DF")])
23016
23017 (define_insn "vmmaskcmpv2df3"
23018   [(set (match_operand:V2DI 0 "register_operand" "=x")
23019         (vec_merge:V2DI
23020          (match_operator:V2DI 3 "sse_comparison_operator"
23021                               [(match_operand:V2DF 1 "register_operand" "0")
23022                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
23023          (subreg:V2DI (match_dup 1) 0)
23024          (const_int 1)))]
23025   "TARGET_SSE2"
23026   "cmp%D3sd\t{%2, %0|%0, %2}"
23027   [(set_attr "type" "ssecmp")
23028    (set_attr "mode" "DF")])
23029
23030 (define_insn "vmmaskncmpv2df3"
23031   [(set (match_operand:V2DI 0 "register_operand" "=x")
23032         (vec_merge:V2DI
23033          (not:V2DI
23034           (match_operator:V2DI 3 "sse_comparison_operator"
23035                                [(match_operand:V2DF 1 "register_operand" "0")
23036                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
23037          (subreg:V2DI (match_dup 1) 0)
23038          (const_int 1)))]
23039   "TARGET_SSE2"
23040 {
23041   if (GET_CODE (operands[3]) == UNORDERED)
23042     return "cmpordsd\t{%2, %0|%0, %2}";
23043   else
23044     return "cmpn%D3sd\t{%2, %0|%0, %2}";
23045 }
23046   [(set_attr "type" "ssecmp")
23047    (set_attr "mode" "DF")])
23048
23049 (define_insn "sse2_comi"
23050   [(set (reg:CCFP FLAGS_REG)
23051         (compare:CCFP (vec_select:DF
23052                        (match_operand:V2DF 0 "register_operand" "x")
23053                        (parallel [(const_int 0)]))
23054                       (vec_select:DF
23055                        (match_operand:V2DF 1 "register_operand" "x")
23056                        (parallel [(const_int 0)]))))]
23057   "TARGET_SSE2"
23058   "comisd\t{%1, %0|%0, %1}"
23059   [(set_attr "type" "ssecomi")
23060    (set_attr "mode" "DF")])
23061
23062 (define_insn "sse2_ucomi"
23063   [(set (reg:CCFPU FLAGS_REG)
23064         (compare:CCFPU (vec_select:DF
23065                          (match_operand:V2DF 0 "register_operand" "x")
23066                          (parallel [(const_int 0)]))
23067                         (vec_select:DF
23068                          (match_operand:V2DF 1 "register_operand" "x")
23069                          (parallel [(const_int 0)]))))]
23070   "TARGET_SSE2"
23071   "ucomisd\t{%1, %0|%0, %1}"
23072   [(set_attr "type" "ssecomi")
23073    (set_attr "mode" "DF")])
23074
23075 ;; SSE Strange Moves.
23076
23077 (define_insn "sse2_movmskpd"
23078   [(set (match_operand:SI 0 "register_operand" "=r")
23079         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23080                    UNSPEC_MOVMSK))]
23081   "TARGET_SSE2"
23082   "movmskpd\t{%1, %0|%0, %1}"
23083   [(set_attr "type" "ssecvt")
23084    (set_attr "mode" "V2DF")])
23085
23086 (define_insn "sse2_pmovmskb"
23087   [(set (match_operand:SI 0 "register_operand" "=r")
23088         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23089                    UNSPEC_MOVMSK))]
23090   "TARGET_SSE2"
23091   "pmovmskb\t{%1, %0|%0, %1}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "V2DF")])
23094
23095 (define_insn "sse2_maskmovdqu"
23096   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23097         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23098                        (match_operand:V16QI 2 "register_operand" "x")]
23099                       UNSPEC_MASKMOV))]
23100   "TARGET_SSE2"
23101   ;; @@@ check ordering of operands in intel/nonintel syntax
23102   "maskmovdqu\t{%2, %1|%1, %2}"
23103   [(set_attr "type" "ssecvt")
23104    (set_attr "mode" "TI")])
23105
23106 (define_insn "sse2_maskmovdqu_rex64"
23107   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23108         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23109                        (match_operand:V16QI 2 "register_operand" "x")]
23110                       UNSPEC_MASKMOV))]
23111   "TARGET_SSE2"
23112   ;; @@@ check ordering of operands in intel/nonintel syntax
23113   "maskmovdqu\t{%2, %1|%1, %2}"
23114   [(set_attr "type" "ssecvt")
23115    (set_attr "mode" "TI")])
23116
23117 (define_insn "sse2_movntv2df"
23118   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23119         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23120                      UNSPEC_MOVNT))]
23121   "TARGET_SSE2"
23122   "movntpd\t{%1, %0|%0, %1}"
23123   [(set_attr "type" "ssecvt")
23124    (set_attr "mode" "V2DF")])
23125
23126 (define_insn "sse2_movntv2di"
23127   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23128         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23129                      UNSPEC_MOVNT))]
23130   "TARGET_SSE2"
23131   "movntdq\t{%1, %0|%0, %1}"
23132   [(set_attr "type" "ssecvt")
23133    (set_attr "mode" "TI")])
23134
23135 (define_insn "sse2_movntsi"
23136   [(set (match_operand:SI 0 "memory_operand" "=m")
23137         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23138                    UNSPEC_MOVNT))]
23139   "TARGET_SSE2"
23140   "movnti\t{%1, %0|%0, %1}"
23141   [(set_attr "type" "ssecvt")
23142    (set_attr "mode" "V2DF")])
23143
23144 ;; SSE <-> integer/MMX conversions
23145
23146 ;; Conversions between SI and SF
23147
23148 (define_insn "cvtdq2ps"
23149   [(set (match_operand:V4SF 0 "register_operand" "=x")
23150         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23151   "TARGET_SSE2"
23152   "cvtdq2ps\t{%1, %0|%0, %1}"
23153   [(set_attr "type" "ssecvt")
23154    (set_attr "mode" "V2DF")])
23155
23156 (define_insn "cvtps2dq"
23157   [(set (match_operand:V4SI 0 "register_operand" "=x")
23158         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23159   "TARGET_SSE2"
23160   "cvtps2dq\t{%1, %0|%0, %1}"
23161   [(set_attr "type" "ssecvt")
23162    (set_attr "mode" "TI")])
23163
23164 (define_insn "cvttps2dq"
23165   [(set (match_operand:V4SI 0 "register_operand" "=x")
23166         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23167                      UNSPEC_FIX))]
23168   "TARGET_SSE2"
23169   "cvttps2dq\t{%1, %0|%0, %1}"
23170   [(set_attr "type" "ssecvt")
23171    (set_attr "mode" "TI")])
23172
23173 ;; Conversions between SI and DF
23174
23175 (define_insn "cvtdq2pd"
23176   [(set (match_operand:V2DF 0 "register_operand" "=x")
23177         (float:V2DF (vec_select:V2SI
23178                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23179                      (parallel
23180                       [(const_int 0)
23181                        (const_int 1)]))))]
23182   "TARGET_SSE2"
23183   "cvtdq2pd\t{%1, %0|%0, %1}"
23184   [(set_attr "type" "ssecvt")
23185    (set_attr "mode" "V2DF")])
23186
23187 (define_insn "cvtpd2dq"
23188   [(set (match_operand:V4SI 0 "register_operand" "=x")
23189         (vec_concat:V4SI
23190          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23191          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23192   "TARGET_SSE2"
23193   "cvtpd2dq\t{%1, %0|%0, %1}"
23194   [(set_attr "type" "ssecvt")
23195    (set_attr "mode" "TI")])
23196
23197 (define_insn "cvttpd2dq"
23198   [(set (match_operand:V4SI 0 "register_operand" "=x")
23199         (vec_concat:V4SI
23200          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23201                       UNSPEC_FIX)
23202          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23203   "TARGET_SSE2"
23204   "cvttpd2dq\t{%1, %0|%0, %1}"
23205   [(set_attr "type" "ssecvt")
23206    (set_attr "mode" "TI")])
23207
23208 (define_insn "cvtpd2pi"
23209   [(set (match_operand:V2SI 0 "register_operand" "=y")
23210         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23211   "TARGET_SSE2"
23212   "cvtpd2pi\t{%1, %0|%0, %1}"
23213   [(set_attr "type" "ssecvt")
23214    (set_attr "mode" "TI")])
23215
23216 (define_insn "cvttpd2pi"
23217   [(set (match_operand:V2SI 0 "register_operand" "=y")
23218         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23219                      UNSPEC_FIX))]
23220   "TARGET_SSE2"
23221   "cvttpd2pi\t{%1, %0|%0, %1}"
23222   [(set_attr "type" "ssecvt")
23223    (set_attr "mode" "TI")])
23224
23225 (define_insn "cvtpi2pd"
23226   [(set (match_operand:V2DF 0 "register_operand" "=x")
23227         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23228   "TARGET_SSE2"
23229   "cvtpi2pd\t{%1, %0|%0, %1}"
23230   [(set_attr "type" "ssecvt")
23231    (set_attr "mode" "TI")])
23232
23233 ;; Conversions between SI and DF
23234
23235 (define_insn "cvtsd2si"
23236   [(set (match_operand:SI 0 "register_operand" "=r,r")
23237         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23238                                (parallel [(const_int 0)]))))]
23239   "TARGET_SSE2"
23240   "cvtsd2si\t{%1, %0|%0, %1}"
23241   [(set_attr "type" "sseicvt")
23242    (set_attr "athlon_decode" "double,vector")
23243    (set_attr "mode" "SI")])
23244
23245 (define_insn "cvtsd2siq"
23246   [(set (match_operand:DI 0 "register_operand" "=r,r")
23247         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23248                                (parallel [(const_int 0)]))))]
23249   "TARGET_SSE2 && TARGET_64BIT"
23250   "cvtsd2siq\t{%1, %0|%0, %1}"
23251   [(set_attr "type" "sseicvt")
23252    (set_attr "athlon_decode" "double,vector")
23253    (set_attr "mode" "DI")])
23254
23255 (define_insn "cvttsd2si"
23256   [(set (match_operand:SI 0 "register_operand" "=r,r")
23257         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23258                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23259   "TARGET_SSE2"
23260   "cvttsd2si\t{%1, %0|%0, %1}"
23261   [(set_attr "type" "sseicvt")
23262    (set_attr "mode" "SI")
23263    (set_attr "athlon_decode" "double,vector")])
23264
23265 (define_insn "cvttsd2siq"
23266   [(set (match_operand:DI 0 "register_operand" "=r,r")
23267         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23268                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23269   "TARGET_SSE2 && TARGET_64BIT"
23270   "cvttsd2siq\t{%1, %0|%0, %1}"
23271   [(set_attr "type" "sseicvt")
23272    (set_attr "mode" "DI")
23273    (set_attr "athlon_decode" "double,vector")])
23274
23275 (define_insn "cvtsi2sd"
23276   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23277         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23278                         (vec_duplicate:V2DF
23279                           (float:DF
23280                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23281                         (const_int 2)))]
23282   "TARGET_SSE2"
23283   "cvtsi2sd\t{%2, %0|%0, %2}"
23284   [(set_attr "type" "sseicvt")
23285    (set_attr "mode" "DF")
23286    (set_attr "athlon_decode" "double,direct")])
23287
23288 (define_insn "cvtsi2sdq"
23289   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23290         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23291                         (vec_duplicate:V2DF
23292                           (float:DF
23293                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23294                         (const_int 2)))]
23295   "TARGET_SSE2 && TARGET_64BIT"
23296   "cvtsi2sdq\t{%2, %0|%0, %2}"
23297   [(set_attr "type" "sseicvt")
23298    (set_attr "mode" "DF")
23299    (set_attr "athlon_decode" "double,direct")])
23300
23301 ;; Conversions between SF and DF
23302
23303 (define_insn "cvtsd2ss"
23304   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23305         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23306                         (vec_duplicate:V4SF
23307                           (float_truncate:V2SF
23308                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23309                         (const_int 14)))]
23310   "TARGET_SSE2"
23311   "cvtsd2ss\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "ssecvt")
23313    (set_attr "athlon_decode" "vector,double")
23314    (set_attr "mode" "SF")])
23315
23316 (define_insn "cvtss2sd"
23317   [(set (match_operand:V2DF 0 "register_operand" "=x")
23318         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23319                         (float_extend:V2DF
23320                           (vec_select:V2SF
23321                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23322                             (parallel [(const_int 0)
23323                                        (const_int 1)])))
23324                         (const_int 2)))]
23325   "TARGET_SSE2"
23326   "cvtss2sd\t{%2, %0|%0, %2}"
23327   [(set_attr "type" "ssecvt")
23328    (set_attr "mode" "DF")])
23329
23330 (define_insn "cvtpd2ps"
23331   [(set (match_operand:V4SF 0 "register_operand" "=x")
23332         (subreg:V4SF
23333           (vec_concat:V4SI
23334             (subreg:V2SI (float_truncate:V2SF
23335                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23336             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23337   "TARGET_SSE2"
23338   "cvtpd2ps\t{%1, %0|%0, %1}"
23339   [(set_attr "type" "ssecvt")
23340    (set_attr "mode" "V4SF")])
23341
23342 (define_insn "cvtps2pd"
23343   [(set (match_operand:V2DF 0 "register_operand" "=x")
23344         (float_extend:V2DF
23345           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23346                            (parallel [(const_int 0)
23347                                       (const_int 1)]))))]
23348   "TARGET_SSE2"
23349   "cvtps2pd\t{%1, %0|%0, %1}"
23350   [(set_attr "type" "ssecvt")
23351    (set_attr "mode" "V2DF")])
23352
23353 ;; SSE2 variants of MMX insns
23354
23355 ;; MMX arithmetic
23356
23357 (define_insn "addv16qi3"
23358   [(set (match_operand:V16QI 0 "register_operand" "=x")
23359         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23360                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23361   "TARGET_SSE2"
23362   "paddb\t{%2, %0|%0, %2}"
23363   [(set_attr "type" "sseiadd")
23364    (set_attr "mode" "TI")])
23365
23366 (define_insn "addv8hi3"
23367   [(set (match_operand:V8HI 0 "register_operand" "=x")
23368         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23369                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23370   "TARGET_SSE2"
23371   "paddw\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseiadd")
23373    (set_attr "mode" "TI")])
23374
23375 (define_insn "addv4si3"
23376   [(set (match_operand:V4SI 0 "register_operand" "=x")
23377         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23378                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23379   "TARGET_SSE2"
23380   "paddd\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseiadd")
23382    (set_attr "mode" "TI")])
23383
23384 (define_insn "addv2di3"
23385   [(set (match_operand:V2DI 0 "register_operand" "=x")
23386         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23387                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23388   "TARGET_SSE2"
23389   "paddq\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseiadd")
23391    (set_attr "mode" "TI")])
23392
23393 (define_insn "ssaddv16qi3"
23394   [(set (match_operand:V16QI 0 "register_operand" "=x")
23395         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23396                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23397   "TARGET_SSE2"
23398   "paddsb\t{%2, %0|%0, %2}"
23399   [(set_attr "type" "sseiadd")
23400    (set_attr "mode" "TI")])
23401
23402 (define_insn "ssaddv8hi3"
23403   [(set (match_operand:V8HI 0 "register_operand" "=x")
23404         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23405                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23406   "TARGET_SSE2"
23407   "paddsw\t{%2, %0|%0, %2}"
23408   [(set_attr "type" "sseiadd")
23409    (set_attr "mode" "TI")])
23410
23411 (define_insn "usaddv16qi3"
23412   [(set (match_operand:V16QI 0 "register_operand" "=x")
23413         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23414                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23415   "TARGET_SSE2"
23416   "paddusb\t{%2, %0|%0, %2}"
23417   [(set_attr "type" "sseiadd")
23418    (set_attr "mode" "TI")])
23419
23420 (define_insn "usaddv8hi3"
23421   [(set (match_operand:V8HI 0 "register_operand" "=x")
23422         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23423                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23424   "TARGET_SSE2"
23425   "paddusw\t{%2, %0|%0, %2}"
23426   [(set_attr "type" "sseiadd")
23427    (set_attr "mode" "TI")])
23428
23429 (define_insn "subv16qi3"
23430   [(set (match_operand:V16QI 0 "register_operand" "=x")
23431         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23432                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23433   "TARGET_SSE2"
23434   "psubb\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseiadd")
23436    (set_attr "mode" "TI")])
23437
23438 (define_insn "subv8hi3"
23439   [(set (match_operand:V8HI 0 "register_operand" "=x")
23440         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23441                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23442   "TARGET_SSE2"
23443   "psubw\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseiadd")
23445    (set_attr "mode" "TI")])
23446
23447 (define_insn "subv4si3"
23448   [(set (match_operand:V4SI 0 "register_operand" "=x")
23449         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23450                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23451   "TARGET_SSE2"
23452   "psubd\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseiadd")
23454    (set_attr "mode" "TI")])
23455
23456 (define_insn "subv2di3"
23457   [(set (match_operand:V2DI 0 "register_operand" "=x")
23458         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23459                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23460   "TARGET_SSE2"
23461   "psubq\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseiadd")
23463    (set_attr "mode" "TI")])
23464
23465 (define_insn "sssubv16qi3"
23466   [(set (match_operand:V16QI 0 "register_operand" "=x")
23467         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23468                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23469   "TARGET_SSE2"
23470   "psubsb\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseiadd")
23472    (set_attr "mode" "TI")])
23473
23474 (define_insn "sssubv8hi3"
23475   [(set (match_operand:V8HI 0 "register_operand" "=x")
23476         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23477                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23478   "TARGET_SSE2"
23479   "psubsw\t{%2, %0|%0, %2}"
23480   [(set_attr "type" "sseiadd")
23481    (set_attr "mode" "TI")])
23482
23483 (define_insn "ussubv16qi3"
23484   [(set (match_operand:V16QI 0 "register_operand" "=x")
23485         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23486                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23487   "TARGET_SSE2"
23488   "psubusb\t{%2, %0|%0, %2}"
23489   [(set_attr "type" "sseiadd")
23490    (set_attr "mode" "TI")])
23491
23492 (define_insn "ussubv8hi3"
23493   [(set (match_operand:V8HI 0 "register_operand" "=x")
23494         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23495                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23496   "TARGET_SSE2"
23497   "psubusw\t{%2, %0|%0, %2}"
23498   [(set_attr "type" "sseiadd")
23499    (set_attr "mode" "TI")])
23500
23501 (define_insn "mulv8hi3"
23502   [(set (match_operand:V8HI 0 "register_operand" "=x")
23503         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23504                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23505   "TARGET_SSE2"
23506   "pmullw\t{%2, %0|%0, %2}"
23507   [(set_attr "type" "sseimul")
23508    (set_attr "mode" "TI")])
23509
23510 (define_insn "smulv8hi3_highpart"
23511   [(set (match_operand:V8HI 0 "register_operand" "=x")
23512         (truncate:V8HI
23513          (lshiftrt:V8SI
23514           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23515                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23516           (const_int 16))))]
23517   "TARGET_SSE2"
23518   "pmulhw\t{%2, %0|%0, %2}"
23519   [(set_attr "type" "sseimul")
23520    (set_attr "mode" "TI")])
23521
23522 (define_insn "umulv8hi3_highpart"
23523   [(set (match_operand:V8HI 0 "register_operand" "=x")
23524         (truncate:V8HI
23525          (lshiftrt:V8SI
23526           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23527                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23528           (const_int 16))))]
23529   "TARGET_SSE2"
23530   "pmulhuw\t{%2, %0|%0, %2}"
23531   [(set_attr "type" "sseimul")
23532    (set_attr "mode" "TI")])
23533
23534 (define_insn "sse2_umulsidi3"
23535   [(set (match_operand:DI 0 "register_operand" "=y")
23536         (mult:DI (zero_extend:DI (vec_select:SI
23537                                   (match_operand:V2SI 1 "register_operand" "0")
23538                                   (parallel [(const_int 0)])))
23539                  (zero_extend:DI (vec_select:SI
23540                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23541                                   (parallel [(const_int 0)])))))]
23542   "TARGET_SSE2"
23543   "pmuludq\t{%2, %0|%0, %2}"
23544   [(set_attr "type" "mmxmul")
23545    (set_attr "mode" "DI")])
23546
23547 (define_insn "sse2_umulv2siv2di3"
23548   [(set (match_operand:V2DI 0 "register_operand" "=x")
23549         (mult:V2DI (zero_extend:V2DI
23550                      (vec_select:V2SI
23551                        (match_operand:V4SI 1 "register_operand" "0")
23552                        (parallel [(const_int 0) (const_int 2)])))
23553                    (zero_extend:V2DI
23554                      (vec_select:V2SI
23555                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23556                        (parallel [(const_int 0) (const_int 2)])))))]
23557   "TARGET_SSE2"
23558   "pmuludq\t{%2, %0|%0, %2}"
23559   [(set_attr "type" "sseimul")
23560    (set_attr "mode" "TI")])
23561
23562 (define_insn "sse2_pmaddwd"
23563   [(set (match_operand:V4SI 0 "register_operand" "=x")
23564         (plus:V4SI
23565          (mult:V4SI
23566           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23567                                              (parallel [(const_int 0)
23568                                                         (const_int 2)
23569                                                         (const_int 4)
23570                                                         (const_int 6)])))
23571           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23572                                              (parallel [(const_int 0)
23573                                                         (const_int 2)
23574                                                         (const_int 4)
23575                                                         (const_int 6)]))))
23576          (mult:V4SI
23577           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23578                                              (parallel [(const_int 1)
23579                                                         (const_int 3)
23580                                                         (const_int 5)
23581                                                         (const_int 7)])))
23582           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23583                                              (parallel [(const_int 1)
23584                                                         (const_int 3)
23585                                                         (const_int 5)
23586                                                         (const_int 7)]))))))]
23587   "TARGET_SSE2"
23588   "pmaddwd\t{%2, %0|%0, %2}"
23589   [(set_attr "type" "sseiadd")
23590    (set_attr "mode" "TI")])
23591
23592 ;; Same as pxor, but don't show input operands so that we don't think
23593 ;; they are live.
23594 (define_insn "sse2_clrti"
23595   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23596   "TARGET_SSE2"
23597 {
23598   if (get_attr_mode (insn) == MODE_TI)
23599     return "pxor\t%0, %0";
23600   else
23601     return "xorps\t%0, %0";
23602 }
23603   [(set_attr "type" "ssemov")
23604    (set_attr "memory" "none")
23605    (set (attr "mode")
23606               (if_then_else
23607                 (ne (symbol_ref "optimize_size")
23608                     (const_int 0))
23609                 (const_string "V4SF")
23610                 (const_string "TI")))])
23611
23612 ;; MMX unsigned averages/sum of absolute differences
23613
23614 (define_insn "sse2_uavgv16qi3"
23615   [(set (match_operand:V16QI 0 "register_operand" "=x")
23616         (ashiftrt:V16QI
23617          (plus:V16QI (plus:V16QI
23618                      (match_operand:V16QI 1 "register_operand" "0")
23619                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23620                      (const_vector:V16QI [(const_int 1) (const_int 1)
23621                                           (const_int 1) (const_int 1)
23622                                           (const_int 1) (const_int 1)
23623                                           (const_int 1) (const_int 1)
23624                                           (const_int 1) (const_int 1)
23625                                           (const_int 1) (const_int 1)
23626                                           (const_int 1) (const_int 1)
23627                                           (const_int 1) (const_int 1)]))
23628          (const_int 1)))]
23629   "TARGET_SSE2"
23630   "pavgb\t{%2, %0|%0, %2}"
23631   [(set_attr "type" "sseiadd")
23632    (set_attr "mode" "TI")])
23633
23634 (define_insn "sse2_uavgv8hi3"
23635   [(set (match_operand:V8HI 0 "register_operand" "=x")
23636         (ashiftrt:V8HI
23637          (plus:V8HI (plus:V8HI
23638                      (match_operand:V8HI 1 "register_operand" "0")
23639                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23640                     (const_vector:V8HI [(const_int 1) (const_int 1)
23641                                         (const_int 1) (const_int 1)
23642                                         (const_int 1) (const_int 1)
23643                                         (const_int 1) (const_int 1)]))
23644          (const_int 1)))]
23645   "TARGET_SSE2"
23646   "pavgw\t{%2, %0|%0, %2}"
23647   [(set_attr "type" "sseiadd")
23648    (set_attr "mode" "TI")])
23649
23650 ;; @@@ this isn't the right representation.
23651 (define_insn "sse2_psadbw"
23652   [(set (match_operand:V2DI 0 "register_operand" "=x")
23653         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23654                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23655                      UNSPEC_PSADBW))]
23656   "TARGET_SSE2"
23657   "psadbw\t{%2, %0|%0, %2}"
23658   [(set_attr "type" "sseiadd")
23659    (set_attr "mode" "TI")])
23660
23661
23662 ;; MMX insert/extract/shuffle
23663
23664 (define_insn "sse2_pinsrw"
23665   [(set (match_operand:V8HI 0 "register_operand" "=x")
23666         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23667                         (vec_duplicate:V8HI
23668                          (truncate:HI
23669                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23670                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23671   "TARGET_SSE2"
23672   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23673   [(set_attr "type" "ssecvt")
23674    (set_attr "mode" "TI")])
23675
23676 (define_insn "sse2_pextrw"
23677   [(set (match_operand:SI 0 "register_operand" "=r")
23678         (zero_extend:SI
23679           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23680                          (parallel
23681                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23682   "TARGET_SSE2"
23683   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23684   [(set_attr "type" "ssecvt")
23685    (set_attr "mode" "TI")])
23686
23687 (define_insn "sse2_pshufd"
23688   [(set (match_operand:V4SI 0 "register_operand" "=x")
23689         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23690                       (match_operand:SI 2 "immediate_operand" "i")]
23691                      UNSPEC_SHUFFLE))]
23692   "TARGET_SSE2"
23693   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23694   [(set_attr "type" "ssecvt")
23695    (set_attr "mode" "TI")])
23696
23697 (define_insn "sse2_pshuflw"
23698   [(set (match_operand:V8HI 0 "register_operand" "=x")
23699         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23700                       (match_operand:SI 2 "immediate_operand" "i")]
23701                      UNSPEC_PSHUFLW))]
23702   "TARGET_SSE2"
23703   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23704   [(set_attr "type" "ssecvt")
23705    (set_attr "mode" "TI")])
23706
23707 (define_insn "sse2_pshufhw"
23708   [(set (match_operand:V8HI 0 "register_operand" "=x")
23709         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23710                       (match_operand:SI 2 "immediate_operand" "i")]
23711                      UNSPEC_PSHUFHW))]
23712   "TARGET_SSE2"
23713   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23714   [(set_attr "type" "ssecvt")
23715    (set_attr "mode" "TI")])
23716
23717 ;; MMX mask-generating comparisons
23718
23719 (define_insn "eqv16qi3"
23720   [(set (match_operand:V16QI 0 "register_operand" "=x")
23721         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23722                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23723   "TARGET_SSE2"
23724   "pcmpeqb\t{%2, %0|%0, %2}"
23725   [(set_attr "type" "ssecmp")
23726    (set_attr "mode" "TI")])
23727
23728 (define_insn "eqv8hi3"
23729   [(set (match_operand:V8HI 0 "register_operand" "=x")
23730         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23731                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23732   "TARGET_SSE2"
23733   "pcmpeqw\t{%2, %0|%0, %2}"
23734   [(set_attr "type" "ssecmp")
23735    (set_attr "mode" "TI")])
23736
23737 (define_insn "eqv4si3"
23738   [(set (match_operand:V4SI 0 "register_operand" "=x")
23739         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23740                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23741   "TARGET_SSE2"
23742   "pcmpeqd\t{%2, %0|%0, %2}"
23743   [(set_attr "type" "ssecmp")
23744    (set_attr "mode" "TI")])
23745
23746 (define_insn "gtv16qi3"
23747   [(set (match_operand:V16QI 0 "register_operand" "=x")
23748         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23749                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23750   "TARGET_SSE2"
23751   "pcmpgtb\t{%2, %0|%0, %2}"
23752   [(set_attr "type" "ssecmp")
23753    (set_attr "mode" "TI")])
23754
23755 (define_insn "gtv8hi3"
23756   [(set (match_operand:V8HI 0 "register_operand" "=x")
23757         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23758                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23759   "TARGET_SSE2"
23760   "pcmpgtw\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "ssecmp")
23762    (set_attr "mode" "TI")])
23763
23764 (define_insn "gtv4si3"
23765   [(set (match_operand:V4SI 0 "register_operand" "=x")
23766         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23767                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23768   "TARGET_SSE2"
23769   "pcmpgtd\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "ssecmp")
23771    (set_attr "mode" "TI")])
23772
23773
23774 ;; MMX max/min insns
23775
23776 (define_insn "umaxv16qi3"
23777   [(set (match_operand:V16QI 0 "register_operand" "=x")
23778         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23779                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23780   "TARGET_SSE2"
23781   "pmaxub\t{%2, %0|%0, %2}"
23782   [(set_attr "type" "sseiadd")
23783    (set_attr "mode" "TI")])
23784
23785 (define_insn "smaxv8hi3"
23786   [(set (match_operand:V8HI 0 "register_operand" "=x")
23787         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23788                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23789   "TARGET_SSE2"
23790   "pmaxsw\t{%2, %0|%0, %2}"
23791   [(set_attr "type" "sseiadd")
23792    (set_attr "mode" "TI")])
23793
23794 (define_insn "uminv16qi3"
23795   [(set (match_operand:V16QI 0 "register_operand" "=x")
23796         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23797                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23798   "TARGET_SSE2"
23799   "pminub\t{%2, %0|%0, %2}"
23800   [(set_attr "type" "sseiadd")
23801    (set_attr "mode" "TI")])
23802
23803 (define_insn "sminv8hi3"
23804   [(set (match_operand:V8HI 0 "register_operand" "=x")
23805         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23806                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23807   "TARGET_SSE2"
23808   "pminsw\t{%2, %0|%0, %2}"
23809   [(set_attr "type" "sseiadd")
23810    (set_attr "mode" "TI")])
23811
23812
23813 ;; MMX shifts
23814
23815 (define_insn "ashrv8hi3"
23816   [(set (match_operand:V8HI 0 "register_operand" "=x")
23817         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23818                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23819   "TARGET_SSE2"
23820   "psraw\t{%2, %0|%0, %2}"
23821   [(set_attr "type" "sseishft")
23822    (set_attr "mode" "TI")])
23823
23824 (define_insn "ashrv4si3"
23825   [(set (match_operand:V4SI 0 "register_operand" "=x")
23826         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23827                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23828   "TARGET_SSE2"
23829   "psrad\t{%2, %0|%0, %2}"
23830   [(set_attr "type" "sseishft")
23831    (set_attr "mode" "TI")])
23832
23833 (define_insn "lshrv8hi3"
23834   [(set (match_operand:V8HI 0 "register_operand" "=x")
23835         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23836                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23837   "TARGET_SSE2"
23838   "psrlw\t{%2, %0|%0, %2}"
23839   [(set_attr "type" "sseishft")
23840    (set_attr "mode" "TI")])
23841
23842 (define_insn "lshrv4si3"
23843   [(set (match_operand:V4SI 0 "register_operand" "=x")
23844         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23845                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23846   "TARGET_SSE2"
23847   "psrld\t{%2, %0|%0, %2}"
23848   [(set_attr "type" "sseishft")
23849    (set_attr "mode" "TI")])
23850
23851 (define_insn "lshrv2di3"
23852   [(set (match_operand:V2DI 0 "register_operand" "=x")
23853         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23854                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23855   "TARGET_SSE2"
23856   "psrlq\t{%2, %0|%0, %2}"
23857   [(set_attr "type" "sseishft")
23858    (set_attr "mode" "TI")])
23859
23860 (define_insn "ashlv8hi3"
23861   [(set (match_operand:V8HI 0 "register_operand" "=x")
23862         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23863                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23864   "TARGET_SSE2"
23865   "psllw\t{%2, %0|%0, %2}"
23866   [(set_attr "type" "sseishft")
23867    (set_attr "mode" "TI")])
23868
23869 (define_insn "ashlv4si3"
23870   [(set (match_operand:V4SI 0 "register_operand" "=x")
23871         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23872                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23873   "TARGET_SSE2"
23874   "pslld\t{%2, %0|%0, %2}"
23875   [(set_attr "type" "sseishft")
23876    (set_attr "mode" "TI")])
23877
23878 (define_insn "ashlv2di3"
23879   [(set (match_operand:V2DI 0 "register_operand" "=x")
23880         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23881                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23882   "TARGET_SSE2"
23883   "psllq\t{%2, %0|%0, %2}"
23884   [(set_attr "type" "sseishft")
23885    (set_attr "mode" "TI")])
23886
23887 (define_insn "ashrv8hi3_ti"
23888   [(set (match_operand:V8HI 0 "register_operand" "=x")
23889         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23890                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23891   "TARGET_SSE2"
23892   "psraw\t{%2, %0|%0, %2}"
23893   [(set_attr "type" "sseishft")
23894    (set_attr "mode" "TI")])
23895
23896 (define_insn "ashrv4si3_ti"
23897   [(set (match_operand:V4SI 0 "register_operand" "=x")
23898         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23899                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23900   "TARGET_SSE2"
23901   "psrad\t{%2, %0|%0, %2}"
23902   [(set_attr "type" "sseishft")
23903    (set_attr "mode" "TI")])
23904
23905 (define_insn "lshrv8hi3_ti"
23906   [(set (match_operand:V8HI 0 "register_operand" "=x")
23907         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23908                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23909   "TARGET_SSE2"
23910   "psrlw\t{%2, %0|%0, %2}"
23911   [(set_attr "type" "sseishft")
23912    (set_attr "mode" "TI")])
23913
23914 (define_insn "lshrv4si3_ti"
23915   [(set (match_operand:V4SI 0 "register_operand" "=x")
23916         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23917                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23918   "TARGET_SSE2"
23919   "psrld\t{%2, %0|%0, %2}"
23920   [(set_attr "type" "sseishft")
23921    (set_attr "mode" "TI")])
23922
23923 (define_insn "lshrv2di3_ti"
23924   [(set (match_operand:V2DI 0 "register_operand" "=x")
23925         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23926                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23927   "TARGET_SSE2"
23928   "psrlq\t{%2, %0|%0, %2}"
23929   [(set_attr "type" "sseishft")
23930    (set_attr "mode" "TI")])
23931
23932 (define_insn "ashlv8hi3_ti"
23933   [(set (match_operand:V8HI 0 "register_operand" "=x")
23934         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23935                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23936   "TARGET_SSE2"
23937   "psllw\t{%2, %0|%0, %2}"
23938   [(set_attr "type" "sseishft")
23939    (set_attr "mode" "TI")])
23940
23941 (define_insn "ashlv4si3_ti"
23942   [(set (match_operand:V4SI 0 "register_operand" "=x")
23943         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23944                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23945   "TARGET_SSE2"
23946   "pslld\t{%2, %0|%0, %2}"
23947   [(set_attr "type" "sseishft")
23948    (set_attr "mode" "TI")])
23949
23950 (define_insn "ashlv2di3_ti"
23951   [(set (match_operand:V2DI 0 "register_operand" "=x")
23952         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23953                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23954   "TARGET_SSE2"
23955   "psllq\t{%2, %0|%0, %2}"
23956   [(set_attr "type" "sseishft")
23957    (set_attr "mode" "TI")])
23958
23959 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23960 ;; we wouldn't need here it since we never generate TImode arithmetic.
23961
23962 ;; There has to be some kind of prize for the weirdest new instruction...
23963 (define_insn "sse2_ashlti3"
23964   [(set (match_operand:TI 0 "register_operand" "=x")
23965         (unspec:TI
23966          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23967                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23968                                (const_int 8)))] UNSPEC_NOP))]
23969   "TARGET_SSE2"
23970   "pslldq\t{%2, %0|%0, %2}"
23971   [(set_attr "type" "sseishft")
23972    (set_attr "mode" "TI")])
23973
23974 (define_insn "sse2_lshrti3"
23975   [(set (match_operand:TI 0 "register_operand" "=x")
23976         (unspec:TI
23977          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23978                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23979                                 (const_int 8)))] UNSPEC_NOP))]
23980   "TARGET_SSE2"
23981   "psrldq\t{%2, %0|%0, %2}"
23982   [(set_attr "type" "sseishft")
23983    (set_attr "mode" "TI")])
23984
23985 ;; SSE unpack
23986
23987 (define_insn "sse2_unpckhpd"
23988   [(set (match_operand:V2DF 0 "register_operand" "=x")
23989         (vec_concat:V2DF
23990          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23991                         (parallel [(const_int 1)]))
23992          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23993                         (parallel [(const_int 1)]))))]
23994   "TARGET_SSE2"
23995   "unpckhpd\t{%2, %0|%0, %2}"
23996   [(set_attr "type" "ssecvt")
23997    (set_attr "mode" "V2DF")])
23998
23999 (define_insn "sse2_unpcklpd"
24000   [(set (match_operand:V2DF 0 "register_operand" "=x")
24001         (vec_concat:V2DF
24002          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
24003                         (parallel [(const_int 0)]))
24004          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
24005                         (parallel [(const_int 0)]))))]
24006   "TARGET_SSE2"
24007   "unpcklpd\t{%2, %0|%0, %2}"
24008   [(set_attr "type" "ssecvt")
24009    (set_attr "mode" "V2DF")])
24010
24011 ;; MMX pack/unpack insns.
24012
24013 (define_insn "sse2_packsswb"
24014   [(set (match_operand:V16QI 0 "register_operand" "=x")
24015         (vec_concat:V16QI
24016          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
24017          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
24018   "TARGET_SSE2"
24019   "packsswb\t{%2, %0|%0, %2}"
24020   [(set_attr "type" "ssecvt")
24021    (set_attr "mode" "TI")])
24022
24023 (define_insn "sse2_packssdw"
24024   [(set (match_operand:V8HI 0 "register_operand" "=x")
24025         (vec_concat:V8HI
24026          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
24027          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
24028   "TARGET_SSE2"
24029   "packssdw\t{%2, %0|%0, %2}"
24030   [(set_attr "type" "ssecvt")
24031    (set_attr "mode" "TI")])
24032
24033 (define_insn "sse2_packuswb"
24034   [(set (match_operand:V16QI 0 "register_operand" "=x")
24035         (vec_concat:V16QI
24036          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
24037          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
24038   "TARGET_SSE2"
24039   "packuswb\t{%2, %0|%0, %2}"
24040   [(set_attr "type" "ssecvt")
24041    (set_attr "mode" "TI")])
24042
24043 (define_insn "sse2_punpckhbw"
24044   [(set (match_operand:V16QI 0 "register_operand" "=x")
24045         (vec_merge:V16QI
24046          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24047                            (parallel [(const_int 8) (const_int 0)
24048                                       (const_int 9) (const_int 1)
24049                                       (const_int 10) (const_int 2)
24050                                       (const_int 11) (const_int 3)
24051                                       (const_int 12) (const_int 4)
24052                                       (const_int 13) (const_int 5)
24053                                       (const_int 14) (const_int 6)
24054                                       (const_int 15) (const_int 7)]))
24055          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24056                            (parallel [(const_int 0) (const_int 8)
24057                                       (const_int 1) (const_int 9)
24058                                       (const_int 2) (const_int 10)
24059                                       (const_int 3) (const_int 11)
24060                                       (const_int 4) (const_int 12)
24061                                       (const_int 5) (const_int 13)
24062                                       (const_int 6) (const_int 14)
24063                                       (const_int 7) (const_int 15)]))
24064          (const_int 21845)))]
24065   "TARGET_SSE2"
24066   "punpckhbw\t{%2, %0|%0, %2}"
24067   [(set_attr "type" "ssecvt")
24068    (set_attr "mode" "TI")])
24069
24070 (define_insn "sse2_punpckhwd"
24071   [(set (match_operand:V8HI 0 "register_operand" "=x")
24072         (vec_merge:V8HI
24073          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24074                           (parallel [(const_int 4) (const_int 0)
24075                                      (const_int 5) (const_int 1)
24076                                      (const_int 6) (const_int 2)
24077                                      (const_int 7) (const_int 3)]))
24078          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24079                           (parallel [(const_int 0) (const_int 4)
24080                                      (const_int 1) (const_int 5)
24081                                      (const_int 2) (const_int 6)
24082                                      (const_int 3) (const_int 7)]))
24083          (const_int 85)))]
24084   "TARGET_SSE2"
24085   "punpckhwd\t{%2, %0|%0, %2}"
24086   [(set_attr "type" "ssecvt")
24087    (set_attr "mode" "TI")])
24088
24089 (define_insn "sse2_punpckhdq"
24090   [(set (match_operand:V4SI 0 "register_operand" "=x")
24091         (vec_merge:V4SI
24092          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24093                           (parallel [(const_int 2) (const_int 0)
24094                                      (const_int 3) (const_int 1)]))
24095          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24096                           (parallel [(const_int 0) (const_int 2)
24097                                      (const_int 1) (const_int 3)]))
24098          (const_int 5)))]
24099   "TARGET_SSE2"
24100   "punpckhdq\t{%2, %0|%0, %2}"
24101   [(set_attr "type" "ssecvt")
24102    (set_attr "mode" "TI")])
24103
24104 (define_insn "sse2_punpcklbw"
24105   [(set (match_operand:V16QI 0 "register_operand" "=x")
24106         (vec_merge:V16QI
24107          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24108                            (parallel [(const_int 0) (const_int 8)
24109                                       (const_int 1) (const_int 9)
24110                                       (const_int 2) (const_int 10)
24111                                       (const_int 3) (const_int 11)
24112                                       (const_int 4) (const_int 12)
24113                                       (const_int 5) (const_int 13)
24114                                       (const_int 6) (const_int 14)
24115                                       (const_int 7) (const_int 15)]))
24116          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24117                            (parallel [(const_int 8) (const_int 0)
24118                                       (const_int 9) (const_int 1)
24119                                       (const_int 10) (const_int 2)
24120                                       (const_int 11) (const_int 3)
24121                                       (const_int 12) (const_int 4)
24122                                       (const_int 13) (const_int 5)
24123                                       (const_int 14) (const_int 6)
24124                                       (const_int 15) (const_int 7)]))
24125          (const_int 21845)))]
24126   "TARGET_SSE2"
24127   "punpcklbw\t{%2, %0|%0, %2}"
24128   [(set_attr "type" "ssecvt")
24129    (set_attr "mode" "TI")])
24130
24131 (define_insn "sse2_punpcklwd"
24132   [(set (match_operand:V8HI 0 "register_operand" "=x")
24133         (vec_merge:V8HI
24134          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24135                           (parallel [(const_int 0) (const_int 4)
24136                                      (const_int 1) (const_int 5)
24137                                      (const_int 2) (const_int 6)
24138                                      (const_int 3) (const_int 7)]))
24139          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24140                           (parallel [(const_int 4) (const_int 0)
24141                                      (const_int 5) (const_int 1)
24142                                      (const_int 6) (const_int 2)
24143                                      (const_int 7) (const_int 3)]))
24144          (const_int 85)))]
24145   "TARGET_SSE2"
24146   "punpcklwd\t{%2, %0|%0, %2}"
24147   [(set_attr "type" "ssecvt")
24148    (set_attr "mode" "TI")])
24149
24150 (define_insn "sse2_punpckldq"
24151   [(set (match_operand:V4SI 0 "register_operand" "=x")
24152         (vec_merge:V4SI
24153          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24154                           (parallel [(const_int 0) (const_int 2)
24155                                      (const_int 1) (const_int 3)]))
24156          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24157                           (parallel [(const_int 2) (const_int 0)
24158                                      (const_int 3) (const_int 1)]))
24159          (const_int 5)))]
24160   "TARGET_SSE2"
24161   "punpckldq\t{%2, %0|%0, %2}"
24162   [(set_attr "type" "ssecvt")
24163    (set_attr "mode" "TI")])
24164
24165 (define_insn "sse2_punpcklqdq"
24166   [(set (match_operand:V2DI 0 "register_operand" "=x")
24167         (vec_merge:V2DI
24168          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24169                           (parallel [(const_int 1)
24170                                      (const_int 0)]))
24171          (match_operand:V2DI 1 "register_operand" "0")
24172          (const_int 1)))]
24173   "TARGET_SSE2"
24174   "punpcklqdq\t{%2, %0|%0, %2}"
24175   [(set_attr "type" "ssecvt")
24176    (set_attr "mode" "TI")])
24177
24178 (define_insn "sse2_punpckhqdq"
24179   [(set (match_operand:V2DI 0 "register_operand" "=x")
24180         (vec_merge:V2DI
24181          (match_operand:V2DI 1 "register_operand" "0")
24182          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24183                           (parallel [(const_int 1)
24184                                      (const_int 0)]))
24185          (const_int 1)))]
24186   "TARGET_SSE2"
24187   "punpckhqdq\t{%2, %0|%0, %2}"
24188   [(set_attr "type" "ssecvt")
24189    (set_attr "mode" "TI")])
24190
24191 ;; SSE2 moves
24192
24193 (define_insn "sse2_movapd"
24194   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24195         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24196                      UNSPEC_MOVA))]
24197   "TARGET_SSE2
24198    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24199   "movapd\t{%1, %0|%0, %1}"
24200   [(set_attr "type" "ssemov")
24201    (set_attr "mode" "V2DF")])
24202
24203 (define_insn "sse2_movupd"
24204   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24205         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24206                      UNSPEC_MOVU))]
24207   "TARGET_SSE2
24208    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24209   "movupd\t{%1, %0|%0, %1}"
24210   [(set_attr "type" "ssecvt")
24211    (set_attr "mode" "V2DF")])
24212
24213 (define_insn "sse2_movdqa"
24214   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24215         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24216                        UNSPEC_MOVA))]
24217   "TARGET_SSE2
24218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24219   "movdqa\t{%1, %0|%0, %1}"
24220   [(set_attr "type" "ssemov")
24221    (set_attr "mode" "TI")])
24222
24223 (define_insn "sse2_movdqu"
24224   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24225         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24226                        UNSPEC_MOVU))]
24227   "TARGET_SSE2
24228    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24229   "movdqu\t{%1, %0|%0, %1}"
24230   [(set_attr "type" "ssecvt")
24231    (set_attr "mode" "TI")])
24232
24233 (define_insn "sse2_movdq2q"
24234   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24235         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24236                        (parallel [(const_int 0)])))]
24237   "TARGET_SSE2 && !TARGET_64BIT"
24238   "@
24239    movq\t{%1, %0|%0, %1}
24240    movdq2q\t{%1, %0|%0, %1}"
24241   [(set_attr "type" "ssecvt")
24242    (set_attr "mode" "TI")])
24243
24244 (define_insn "sse2_movdq2q_rex64"
24245   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24246         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24247                        (parallel [(const_int 0)])))]
24248   "TARGET_SSE2 && TARGET_64BIT"
24249   "@
24250    movq\t{%1, %0|%0, %1}
24251    movdq2q\t{%1, %0|%0, %1}
24252    movd\t{%1, %0|%0, %1}"
24253   [(set_attr "type" "ssecvt")
24254    (set_attr "mode" "TI")])
24255
24256 (define_insn "sse2_movq2dq"
24257   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24258         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24259                          (const_int 0)))]
24260   "TARGET_SSE2 && !TARGET_64BIT"
24261   "@
24262    movq\t{%1, %0|%0, %1}
24263    movq2dq\t{%1, %0|%0, %1}"
24264   [(set_attr "type" "ssecvt,ssemov")
24265    (set_attr "mode" "TI")])
24266
24267 (define_insn "sse2_movq2dq_rex64"
24268   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24269         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24270                          (const_int 0)))]
24271   "TARGET_SSE2 && TARGET_64BIT"
24272   "@
24273    movq\t{%1, %0|%0, %1}
24274    movq2dq\t{%1, %0|%0, %1}
24275    movd\t{%1, %0|%0, %1}"
24276   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24277    (set_attr "mode" "TI")])
24278
24279 (define_insn "sse2_movq"
24280   [(set (match_operand:V2DI 0 "register_operand" "=x")
24281         (vec_concat:V2DI (vec_select:DI
24282                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24283                           (parallel [(const_int 0)]))
24284                          (const_int 0)))]
24285   "TARGET_SSE2"
24286   "movq\t{%1, %0|%0, %1}"
24287   [(set_attr "type" "ssemov")
24288    (set_attr "mode" "TI")])
24289
24290 (define_insn "sse2_loadd"
24291   [(set (match_operand:V4SI 0 "register_operand" "=x")
24292         (vec_merge:V4SI
24293          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24294          (const_vector:V4SI [(const_int 0)
24295                              (const_int 0)
24296                              (const_int 0)
24297                              (const_int 0)])
24298          (const_int 1)))]
24299   "TARGET_SSE2"
24300   "movd\t{%1, %0|%0, %1}"
24301   [(set_attr "type" "ssemov")
24302    (set_attr "mode" "TI")])
24303
24304 (define_insn "sse2_stored"
24305   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24306         (vec_select:SI
24307          (match_operand:V4SI 1 "register_operand" "x")
24308          (parallel [(const_int 0)])))]
24309   "TARGET_SSE2"
24310   "movd\t{%1, %0|%0, %1}"
24311   [(set_attr "type" "ssemov")
24312    (set_attr "mode" "TI")])
24313
24314 (define_insn "sse2_movhpd"
24315   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24316         (vec_merge:V2DF
24317          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24318          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24319          (const_int 2)))]
24320   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24321   "movhpd\t{%2, %0|%0, %2}"
24322   [(set_attr "type" "ssecvt")
24323    (set_attr "mode" "V2DF")])
24324
24325 (define_expand "sse2_loadsd"
24326   [(match_operand:V2DF 0 "register_operand" "")
24327    (match_operand:DF 1 "memory_operand" "")]
24328   "TARGET_SSE2"
24329 {
24330   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24331                                 CONST0_RTX (V2DFmode)));
24332   DONE;
24333 })
24334
24335 (define_insn "sse2_loadsd_1"
24336   [(set (match_operand:V2DF 0 "register_operand" "=x")
24337         (vec_merge:V2DF
24338          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24339          (match_operand:V2DF 2 "const0_operand" "X")
24340          (const_int 1)))]
24341   "TARGET_SSE2"
24342   "movsd\t{%1, %0|%0, %1}"
24343   [(set_attr "type" "ssecvt")
24344    (set_attr "mode" "DF")])
24345
24346 (define_insn "sse2_movsd"
24347   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24348         (vec_merge:V2DF
24349          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24350          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24351          (const_int 1)))]
24352   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24353   "@movsd\t{%2, %0|%0, %2}
24354     movlpd\t{%2, %0|%0, %2}
24355     movlpd\t{%2, %0|%0, %2}"
24356   [(set_attr "type" "ssecvt")
24357    (set_attr "mode" "DF,V2DF,V2DF")])
24358
24359 (define_insn "sse2_storesd"
24360   [(set (match_operand:DF 0 "memory_operand" "=m")
24361         (vec_select:DF
24362          (match_operand:V2DF 1 "register_operand" "x")
24363          (parallel [(const_int 0)])))]
24364   "TARGET_SSE2"
24365   "movsd\t{%1, %0|%0, %1}"
24366   [(set_attr "type" "ssecvt")
24367    (set_attr "mode" "DF")])
24368
24369 (define_insn "sse2_shufpd"
24370   [(set (match_operand:V2DF 0 "register_operand" "=x")
24371         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24372                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24373                       (match_operand:SI 3 "immediate_operand" "i")]
24374                      UNSPEC_SHUFFLE))]
24375   "TARGET_SSE2"
24376   ;; @@@ check operand order for intel/nonintel syntax
24377   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24378   [(set_attr "type" "ssecvt")
24379    (set_attr "mode" "V2DF")])
24380
24381 (define_insn "sse2_clflush"
24382   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24383                     UNSPECV_CLFLUSH)]
24384   "TARGET_SSE2"
24385   "clflush\t%a0"
24386   [(set_attr "type" "sse")
24387    (set_attr "memory" "unknown")])
24388
24389 (define_expand "sse2_mfence"
24390   [(set (match_dup 0)
24391         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24392   "TARGET_SSE2"
24393 {
24394   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24395   MEM_VOLATILE_P (operands[0]) = 1;
24396 })
24397
24398 (define_insn "*mfence_insn"
24399   [(set (match_operand:BLK 0 "" "")
24400         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24401   "TARGET_SSE2"
24402   "mfence"
24403   [(set_attr "type" "sse")
24404    (set_attr "memory" "unknown")])
24405
24406 (define_expand "sse2_lfence"
24407   [(set (match_dup 0)
24408         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24409   "TARGET_SSE2"
24410 {
24411   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24412   MEM_VOLATILE_P (operands[0]) = 1;
24413 })
24414
24415 (define_insn "*lfence_insn"
24416   [(set (match_operand:BLK 0 "" "")
24417         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24418   "TARGET_SSE2"
24419   "lfence"
24420   [(set_attr "type" "sse")
24421    (set_attr "memory" "unknown")])
24422
24423 ;; SSE3
24424
24425 (define_insn "mwait"
24426   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24427                      (match_operand:SI 1 "register_operand" "c")]
24428                     UNSPECV_MWAIT)]
24429   "TARGET_SSE3"
24430   "mwait\t%0, %1"
24431   [(set_attr "length" "3")])
24432
24433 (define_insn "monitor"
24434   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24435                      (match_operand:SI 1 "register_operand" "c")
24436                      (match_operand:SI 2 "register_operand" "d")]
24437                     UNSPECV_MONITOR)]
24438   "TARGET_SSE3"
24439   "monitor\t%0, %1, %2"
24440   [(set_attr "length" "3")])
24441
24442 ;; SSE3 arithmetic
24443
24444 (define_insn "addsubv4sf3"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24447                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24448                      UNSPEC_ADDSUB))]
24449   "TARGET_SSE3"
24450   "addsubps\t{%2, %0|%0, %2}"
24451   [(set_attr "type" "sseadd")
24452    (set_attr "mode" "V4SF")])
24453
24454 (define_insn "addsubv2df3"
24455   [(set (match_operand:V2DF 0 "register_operand" "=x")
24456         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24457                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24458                      UNSPEC_ADDSUB))]
24459   "TARGET_SSE3"
24460   "addsubpd\t{%2, %0|%0, %2}"
24461   [(set_attr "type" "sseadd")
24462    (set_attr "mode" "V2DF")])
24463
24464 (define_insn "haddv4sf3"
24465   [(set (match_operand:V4SF 0 "register_operand" "=x")
24466         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24467                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24468                      UNSPEC_HADD))]
24469   "TARGET_SSE3"
24470   "haddps\t{%2, %0|%0, %2}"
24471   [(set_attr "type" "sseadd")
24472    (set_attr "mode" "V4SF")])
24473
24474 (define_insn "haddv2df3"
24475   [(set (match_operand:V2DF 0 "register_operand" "=x")
24476         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24477                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24478                      UNSPEC_HADD))]
24479   "TARGET_SSE3"
24480   "haddpd\t{%2, %0|%0, %2}"
24481   [(set_attr "type" "sseadd")
24482    (set_attr "mode" "V2DF")])
24483
24484 (define_insn "hsubv4sf3"
24485   [(set (match_operand:V4SF 0 "register_operand" "=x")
24486         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24487                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24488                      UNSPEC_HSUB))]
24489   "TARGET_SSE3"
24490   "hsubps\t{%2, %0|%0, %2}"
24491   [(set_attr "type" "sseadd")
24492    (set_attr "mode" "V4SF")])
24493
24494 (define_insn "hsubv2df3"
24495   [(set (match_operand:V2DF 0 "register_operand" "=x")
24496         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24497                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24498                      UNSPEC_HSUB))]
24499   "TARGET_SSE3"
24500   "hsubpd\t{%2, %0|%0, %2}"
24501   [(set_attr "type" "sseadd")
24502    (set_attr "mode" "V2DF")])
24503
24504 (define_insn "movshdup"
24505   [(set (match_operand:V4SF 0 "register_operand" "=x")
24506         (unspec:V4SF
24507          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24508   "TARGET_SSE3"
24509   "movshdup\t{%1, %0|%0, %1}"
24510   [(set_attr "type" "sse")
24511    (set_attr "mode" "V4SF")])
24512
24513 (define_insn "movsldup"
24514   [(set (match_operand:V4SF 0 "register_operand" "=x")
24515         (unspec:V4SF
24516          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24517   "TARGET_SSE3"
24518   "movsldup\t{%1, %0|%0, %1}"
24519   [(set_attr "type" "sse")
24520    (set_attr "mode" "V4SF")])
24521
24522 (define_insn "lddqu"
24523   [(set (match_operand:V16QI 0 "register_operand" "=x")
24524         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24525                        UNSPEC_LDQQU))]
24526   "TARGET_SSE3"
24527   "lddqu\t{%1, %0|%0, %1}"
24528   [(set_attr "type" "ssecvt")
24529    (set_attr "mode" "TI")])
24530
24531 (define_insn "loadddup"
24532   [(set (match_operand:V2DF 0 "register_operand" "=x")
24533         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24534   "TARGET_SSE3"
24535   "movddup\t{%1, %0|%0, %1}"
24536   [(set_attr "type" "ssecvt")
24537    (set_attr "mode" "DF")])
24538
24539 (define_insn "movddup"
24540   [(set (match_operand:V2DF 0 "register_operand" "=x")
24541         (vec_duplicate:V2DF
24542          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24543                         (parallel [(const_int 0)]))))]
24544   "TARGET_SSE3"
24545   "movddup\t{%1, %0|%0, %1}"
24546   [(set_attr "type" "ssecvt")
24547    (set_attr "mode" "DF")])