OSDN Git Service

* config/i386/i386.c (ix86_split_ashldi): Special case op1 as one
[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,uninitialized,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 && (flag_peephole2 ? flow2_completed : reload_completed)
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 && (flag_peephole2 ? flow2_completed : reload_completed)
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 FLAGS_REG)
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   [(set (match_operand:DI 0 "shiftdi_operand" "")
10627         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10628                    (match_operand:QI 2 "nonmemory_operand" "")))]
10629   ""
10630   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10631
10632 (define_insn "*ashldi3_1_rex64"
10633   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10634         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10635                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10638 {
10639   switch (get_attr_type (insn))
10640     {
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       if (!rtx_equal_p (operands[0], operands[1]))
10645         abort ();
10646       return "add{q}\t{%0, %0|%0, %0}";
10647
10648     case TYPE_LEA:
10649       if (GET_CODE (operands[2]) != CONST_INT
10650           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10651         abort ();
10652       operands[1] = gen_rtx_MULT (DImode, operands[1],
10653                                   GEN_INT (1 << INTVAL (operands[2])));
10654       return "lea{q}\t{%a1, %0|%0, %a1}";
10655
10656     default:
10657       if (REG_P (operands[2]))
10658         return "sal{q}\t{%b2, %0|%0, %b2}";
10659       else if (operands[2] == const1_rtx
10660                && (TARGET_SHIFT1 || optimize_size))
10661         return "sal{q}\t%0";
10662       else
10663         return "sal{q}\t{%2, %0|%0, %2}";
10664     }
10665 }
10666   [(set (attr "type")
10667      (cond [(eq_attr "alternative" "1")
10668               (const_string "lea")
10669             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10670                           (const_int 0))
10671                       (match_operand 0 "register_operand" ""))
10672                  (match_operand 2 "const1_operand" ""))
10673               (const_string "alu")
10674            ]
10675            (const_string "ishift")))
10676    (set_attr "mode" "DI")])
10677
10678 ;; Convert lea to the lea pattern to avoid flags dependency.
10679 (define_split
10680   [(set (match_operand:DI 0 "register_operand" "")
10681         (ashift:DI (match_operand:DI 1 "register_operand" "")
10682                    (match_operand:QI 2 "immediate_operand" "")))
10683    (clobber (reg:CC FLAGS_REG))]
10684   "TARGET_64BIT && reload_completed
10685    && true_regnum (operands[0]) != true_regnum (operands[1])"
10686   [(set (match_dup 0)
10687         (mult:DI (match_dup 1)
10688                  (match_dup 2)))]
10689   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10690
10691 ;; This pattern can't accept a variable shift count, since shifts by
10692 ;; zero don't affect the flags.  We assume that shifts by constant
10693 ;; zero are optimized away.
10694 (define_insn "*ashldi3_cmp_rex64"
10695   [(set (reg 17)
10696         (compare
10697           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10698                      (match_operand:QI 2 "immediate_operand" "e"))
10699           (const_int 0)))
10700    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10701         (ashift:DI (match_dup 1) (match_dup 2)))]
10702   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10703    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10704 {
10705   switch (get_attr_type (insn))
10706     {
10707     case TYPE_ALU:
10708       if (operands[2] != const1_rtx)
10709         abort ();
10710       return "add{q}\t{%0, %0|%0, %0}";
10711
10712     default:
10713       if (REG_P (operands[2]))
10714         return "sal{q}\t{%b2, %0|%0, %b2}";
10715       else if (operands[2] == const1_rtx
10716                && (TARGET_SHIFT1 || optimize_size))
10717         return "sal{q}\t%0";
10718       else
10719         return "sal{q}\t{%2, %0|%0, %2}";
10720     }
10721 }
10722   [(set (attr "type")
10723      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10724                           (const_int 0))
10725                       (match_operand 0 "register_operand" ""))
10726                  (match_operand 2 "const1_operand" ""))
10727               (const_string "alu")
10728            ]
10729            (const_string "ishift")))
10730    (set_attr "mode" "DI")])
10731
10732 (define_insn "*ashldi3_1"
10733   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10734         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10735                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10736    (clobber (reg:CC FLAGS_REG))]
10737   "!TARGET_64BIT"
10738   "#"
10739   [(set_attr "type" "multi")])
10740
10741 ;; By default we don't ask for a scratch register, because when DImode
10742 ;; values are manipulated, registers are already at a premium.  But if
10743 ;; we have one handy, we won't turn it away.
10744 (define_peephole2
10745   [(match_scratch:SI 3 "r")
10746    (parallel [(set (match_operand:DI 0 "register_operand" "")
10747                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10748                               (match_operand:QI 2 "nonmemory_operand" "")))
10749               (clobber (reg:CC FLAGS_REG))])
10750    (match_dup 3)]
10751   "!TARGET_64BIT && TARGET_CMOVE"
10752   [(const_int 0)]
10753   "ix86_split_ashldi (operands, operands[3]); DONE;")
10754
10755 (define_split
10756   [(set (match_operand:DI 0 "register_operand" "")
10757         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10758                    (match_operand:QI 2 "nonmemory_operand" "")))
10759    (clobber (reg:CC FLAGS_REG))]
10760   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10761   [(const_int 0)]
10762   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10763
10764 (define_insn "x86_shld_1"
10765   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10766         (ior:SI (ashift:SI (match_dup 0)
10767                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10768                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10769                   (minus:QI (const_int 32) (match_dup 2)))))
10770    (clobber (reg:CC FLAGS_REG))]
10771   ""
10772   "@
10773    shld{l}\t{%2, %1, %0|%0, %1, %2}
10774    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10775   [(set_attr "type" "ishift")
10776    (set_attr "prefix_0f" "1")
10777    (set_attr "mode" "SI")
10778    (set_attr "pent_pair" "np")
10779    (set_attr "athlon_decode" "vector")])
10780
10781 (define_expand "x86_shift_adj_1"
10782   [(set (reg:CCZ FLAGS_REG)
10783         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10784                              (const_int 32))
10785                      (const_int 0)))
10786    (set (match_operand:SI 0 "register_operand" "")
10787         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10788                          (match_operand:SI 1 "register_operand" "")
10789                          (match_dup 0)))
10790    (set (match_dup 1)
10791         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10792                          (match_operand:SI 3 "register_operand" "r")
10793                          (match_dup 1)))]
10794   "TARGET_CMOVE"
10795   "")
10796
10797 (define_expand "x86_shift_adj_2"
10798   [(use (match_operand:SI 0 "register_operand" ""))
10799    (use (match_operand:SI 1 "register_operand" ""))
10800    (use (match_operand:QI 2 "register_operand" ""))]
10801   ""
10802 {
10803   rtx label = gen_label_rtx ();
10804   rtx tmp;
10805
10806   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10807
10808   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10809   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10810   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10811                               gen_rtx_LABEL_REF (VOIDmode, label),
10812                               pc_rtx);
10813   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10814   JUMP_LABEL (tmp) = label;
10815
10816   emit_move_insn (operands[0], operands[1]);
10817   ix86_expand_clear (operands[1]);
10818
10819   emit_label (label);
10820   LABEL_NUSES (label) = 1;
10821
10822   DONE;
10823 })
10824
10825 (define_expand "ashlsi3"
10826   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10827         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10828                    (match_operand:QI 2 "nonmemory_operand" "")))
10829    (clobber (reg:CC FLAGS_REG))]
10830   ""
10831   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10832
10833 (define_insn "*ashlsi3_1"
10834   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10835         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10836                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10837    (clobber (reg:CC FLAGS_REG))]
10838   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10839 {
10840   switch (get_attr_type (insn))
10841     {
10842     case TYPE_ALU:
10843       if (operands[2] != const1_rtx)
10844         abort ();
10845       if (!rtx_equal_p (operands[0], operands[1]))
10846         abort ();
10847       return "add{l}\t{%0, %0|%0, %0}";
10848
10849     case TYPE_LEA:
10850       return "#";
10851
10852     default:
10853       if (REG_P (operands[2]))
10854         return "sal{l}\t{%b2, %0|%0, %b2}";
10855       else if (operands[2] == const1_rtx
10856                && (TARGET_SHIFT1 || optimize_size))
10857         return "sal{l}\t%0";
10858       else
10859         return "sal{l}\t{%2, %0|%0, %2}";
10860     }
10861 }
10862   [(set (attr "type")
10863      (cond [(eq_attr "alternative" "1")
10864               (const_string "lea")
10865             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10866                           (const_int 0))
10867                       (match_operand 0 "register_operand" ""))
10868                  (match_operand 2 "const1_operand" ""))
10869               (const_string "alu")
10870            ]
10871            (const_string "ishift")))
10872    (set_attr "mode" "SI")])
10873
10874 ;; Convert lea to the lea pattern to avoid flags dependency.
10875 (define_split
10876   [(set (match_operand 0 "register_operand" "")
10877         (ashift (match_operand 1 "index_register_operand" "")
10878                 (match_operand:QI 2 "const_int_operand" "")))
10879    (clobber (reg:CC FLAGS_REG))]
10880   "reload_completed
10881    && true_regnum (operands[0]) != true_regnum (operands[1])"
10882   [(const_int 0)]
10883 {
10884   rtx pat;
10885   operands[0] = gen_lowpart (SImode, operands[0]);
10886   operands[1] = gen_lowpart (Pmode, operands[1]);
10887   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10888   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10889   if (Pmode != SImode)
10890     pat = gen_rtx_SUBREG (SImode, pat, 0);
10891   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10892   DONE;
10893 })
10894
10895 ;; Rare case of shifting RSP is handled by generating move and shift
10896 (define_split
10897   [(set (match_operand 0 "register_operand" "")
10898         (ashift (match_operand 1 "register_operand" "")
10899                 (match_operand:QI 2 "const_int_operand" "")))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "reload_completed
10902    && true_regnum (operands[0]) != true_regnum (operands[1])"
10903   [(const_int 0)]
10904 {
10905   rtx pat, clob;
10906   emit_move_insn (operands[1], operands[0]);
10907   pat = gen_rtx_SET (VOIDmode, operands[0],
10908                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10909                                      operands[0], operands[2]));
10910   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10911   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10912   DONE;
10913 })
10914
10915 (define_insn "*ashlsi3_1_zext"
10916   [(set (match_operand:DI 0 "register_operand" "=r,r")
10917         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10918                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10919    (clobber (reg:CC FLAGS_REG))]
10920   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10921 {
10922   switch (get_attr_type (insn))
10923     {
10924     case TYPE_ALU:
10925       if (operands[2] != const1_rtx)
10926         abort ();
10927       return "add{l}\t{%k0, %k0|%k0, %k0}";
10928
10929     case TYPE_LEA:
10930       return "#";
10931
10932     default:
10933       if (REG_P (operands[2]))
10934         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10935       else if (operands[2] == const1_rtx
10936                && (TARGET_SHIFT1 || optimize_size))
10937         return "sal{l}\t%k0";
10938       else
10939         return "sal{l}\t{%2, %k0|%k0, %2}";
10940     }
10941 }
10942   [(set (attr "type")
10943      (cond [(eq_attr "alternative" "1")
10944               (const_string "lea")
10945             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10946                      (const_int 0))
10947                  (match_operand 2 "const1_operand" ""))
10948               (const_string "alu")
10949            ]
10950            (const_string "ishift")))
10951    (set_attr "mode" "SI")])
10952
10953 ;; Convert lea to the lea pattern to avoid flags dependency.
10954 (define_split
10955   [(set (match_operand:DI 0 "register_operand" "")
10956         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10957                                 (match_operand:QI 2 "const_int_operand" ""))))
10958    (clobber (reg:CC FLAGS_REG))]
10959   "TARGET_64BIT && reload_completed
10960    && true_regnum (operands[0]) != true_regnum (operands[1])"
10961   [(set (match_dup 0) (zero_extend:DI
10962                         (subreg:SI (mult:SI (match_dup 1)
10963                                             (match_dup 2)) 0)))]
10964 {
10965   operands[1] = gen_lowpart (Pmode, operands[1]);
10966   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10967 })
10968
10969 ;; This pattern can't accept a variable shift count, since shifts by
10970 ;; zero don't affect the flags.  We assume that shifts by constant
10971 ;; zero are optimized away.
10972 (define_insn "*ashlsi3_cmp"
10973   [(set (reg 17)
10974         (compare
10975           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10976                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10977           (const_int 0)))
10978    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10979         (ashift:SI (match_dup 1) (match_dup 2)))]
10980   "ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10982 {
10983   switch (get_attr_type (insn))
10984     {
10985     case TYPE_ALU:
10986       if (operands[2] != const1_rtx)
10987         abort ();
10988       return "add{l}\t{%0, %0|%0, %0}";
10989
10990     default:
10991       if (REG_P (operands[2]))
10992         return "sal{l}\t{%b2, %0|%0, %b2}";
10993       else if (operands[2] == const1_rtx
10994                && (TARGET_SHIFT1 || optimize_size))
10995         return "sal{l}\t%0";
10996       else
10997         return "sal{l}\t{%2, %0|%0, %2}";
10998     }
10999 }
11000   [(set (attr "type")
11001      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11002                           (const_int 0))
11003                       (match_operand 0 "register_operand" ""))
11004                  (match_operand 2 "const1_operand" ""))
11005               (const_string "alu")
11006            ]
11007            (const_string "ishift")))
11008    (set_attr "mode" "SI")])
11009
11010 (define_insn "*ashlsi3_cmp_zext"
11011   [(set (reg 17)
11012         (compare
11013           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11014                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11015           (const_int 0)))
11016    (set (match_operand:DI 0 "register_operand" "=r")
11017         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11018   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11019    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11020 {
11021   switch (get_attr_type (insn))
11022     {
11023     case TYPE_ALU:
11024       if (operands[2] != const1_rtx)
11025         abort ();
11026       return "add{l}\t{%k0, %k0|%k0, %k0}";
11027
11028     default:
11029       if (REG_P (operands[2]))
11030         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11031       else if (operands[2] == const1_rtx
11032                && (TARGET_SHIFT1 || optimize_size))
11033         return "sal{l}\t%k0";
11034       else
11035         return "sal{l}\t{%2, %k0|%k0, %2}";
11036     }
11037 }
11038   [(set (attr "type")
11039      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11040                      (const_int 0))
11041                  (match_operand 2 "const1_operand" ""))
11042               (const_string "alu")
11043            ]
11044            (const_string "ishift")))
11045    (set_attr "mode" "SI")])
11046
11047 (define_expand "ashlhi3"
11048   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11049         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11050                    (match_operand:QI 2 "nonmemory_operand" "")))
11051    (clobber (reg:CC FLAGS_REG))]
11052   "TARGET_HIMODE_MATH"
11053   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11054
11055 (define_insn "*ashlhi3_1_lea"
11056   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11057         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11058                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11059    (clobber (reg:CC FLAGS_REG))]
11060   "!TARGET_PARTIAL_REG_STALL
11061    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11062 {
11063   switch (get_attr_type (insn))
11064     {
11065     case TYPE_LEA:
11066       return "#";
11067     case TYPE_ALU:
11068       if (operands[2] != const1_rtx)
11069         abort ();
11070       return "add{w}\t{%0, %0|%0, %0}";
11071
11072     default:
11073       if (REG_P (operands[2]))
11074         return "sal{w}\t{%b2, %0|%0, %b2}";
11075       else if (operands[2] == const1_rtx
11076                && (TARGET_SHIFT1 || optimize_size))
11077         return "sal{w}\t%0";
11078       else
11079         return "sal{w}\t{%2, %0|%0, %2}";
11080     }
11081 }
11082   [(set (attr "type")
11083      (cond [(eq_attr "alternative" "1")
11084               (const_string "lea")
11085             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11086                           (const_int 0))
11087                       (match_operand 0 "register_operand" ""))
11088                  (match_operand 2 "const1_operand" ""))
11089               (const_string "alu")
11090            ]
11091            (const_string "ishift")))
11092    (set_attr "mode" "HI,SI")])
11093
11094 (define_insn "*ashlhi3_1"
11095   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11096         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11097                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11098    (clobber (reg:CC FLAGS_REG))]
11099   "TARGET_PARTIAL_REG_STALL
11100    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11101 {
11102   switch (get_attr_type (insn))
11103     {
11104     case TYPE_ALU:
11105       if (operands[2] != const1_rtx)
11106         abort ();
11107       return "add{w}\t{%0, %0|%0, %0}";
11108
11109     default:
11110       if (REG_P (operands[2]))
11111         return "sal{w}\t{%b2, %0|%0, %b2}";
11112       else if (operands[2] == const1_rtx
11113                && (TARGET_SHIFT1 || optimize_size))
11114         return "sal{w}\t%0";
11115       else
11116         return "sal{w}\t{%2, %0|%0, %2}";
11117     }
11118 }
11119   [(set (attr "type")
11120      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11121                           (const_int 0))
11122                       (match_operand 0 "register_operand" ""))
11123                  (match_operand 2 "const1_operand" ""))
11124               (const_string "alu")
11125            ]
11126            (const_string "ishift")))
11127    (set_attr "mode" "HI")])
11128
11129 ;; This pattern can't accept a variable shift count, since shifts by
11130 ;; zero don't affect the flags.  We assume that shifts by constant
11131 ;; zero are optimized away.
11132 (define_insn "*ashlhi3_cmp"
11133   [(set (reg 17)
11134         (compare
11135           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11136                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11137           (const_int 0)))
11138    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11139         (ashift:HI (match_dup 1) (match_dup 2)))]
11140   "ix86_match_ccmode (insn, CCGOCmode)
11141    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11142 {
11143   switch (get_attr_type (insn))
11144     {
11145     case TYPE_ALU:
11146       if (operands[2] != const1_rtx)
11147         abort ();
11148       return "add{w}\t{%0, %0|%0, %0}";
11149
11150     default:
11151       if (REG_P (operands[2]))
11152         return "sal{w}\t{%b2, %0|%0, %b2}";
11153       else if (operands[2] == const1_rtx
11154                && (TARGET_SHIFT1 || optimize_size))
11155         return "sal{w}\t%0";
11156       else
11157         return "sal{w}\t{%2, %0|%0, %2}";
11158     }
11159 }
11160   [(set (attr "type")
11161      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11162                           (const_int 0))
11163                       (match_operand 0 "register_operand" ""))
11164                  (match_operand 2 "const1_operand" ""))
11165               (const_string "alu")
11166            ]
11167            (const_string "ishift")))
11168    (set_attr "mode" "HI")])
11169
11170 (define_expand "ashlqi3"
11171   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11172         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11173                    (match_operand:QI 2 "nonmemory_operand" "")))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "TARGET_QIMODE_MATH"
11176   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11177
11178 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11179
11180 (define_insn "*ashlqi3_1_lea"
11181   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11182         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11183                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11184    (clobber (reg:CC FLAGS_REG))]
11185   "!TARGET_PARTIAL_REG_STALL
11186    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11187 {
11188   switch (get_attr_type (insn))
11189     {
11190     case TYPE_LEA:
11191       return "#";
11192     case TYPE_ALU:
11193       if (operands[2] != const1_rtx)
11194         abort ();
11195       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11196         return "add{l}\t{%k0, %k0|%k0, %k0}";
11197       else
11198         return "add{b}\t{%0, %0|%0, %0}";
11199
11200     default:
11201       if (REG_P (operands[2]))
11202         {
11203           if (get_attr_mode (insn) == MODE_SI)
11204             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11205           else
11206             return "sal{b}\t{%b2, %0|%0, %b2}";
11207         }
11208       else if (operands[2] == const1_rtx
11209                && (TARGET_SHIFT1 || optimize_size))
11210         {
11211           if (get_attr_mode (insn) == MODE_SI)
11212             return "sal{l}\t%0";
11213           else
11214             return "sal{b}\t%0";
11215         }
11216       else
11217         {
11218           if (get_attr_mode (insn) == MODE_SI)
11219             return "sal{l}\t{%2, %k0|%k0, %2}";
11220           else
11221             return "sal{b}\t{%2, %0|%0, %2}";
11222         }
11223     }
11224 }
11225   [(set (attr "type")
11226      (cond [(eq_attr "alternative" "2")
11227               (const_string "lea")
11228             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11229                           (const_int 0))
11230                       (match_operand 0 "register_operand" ""))
11231                  (match_operand 2 "const1_operand" ""))
11232               (const_string "alu")
11233            ]
11234            (const_string "ishift")))
11235    (set_attr "mode" "QI,SI,SI")])
11236
11237 (define_insn "*ashlqi3_1"
11238   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11239         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11240                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11241    (clobber (reg:CC FLAGS_REG))]
11242   "TARGET_PARTIAL_REG_STALL
11243    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11244 {
11245   switch (get_attr_type (insn))
11246     {
11247     case TYPE_ALU:
11248       if (operands[2] != const1_rtx)
11249         abort ();
11250       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11251         return "add{l}\t{%k0, %k0|%k0, %k0}";
11252       else
11253         return "add{b}\t{%0, %0|%0, %0}";
11254
11255     default:
11256       if (REG_P (operands[2]))
11257         {
11258           if (get_attr_mode (insn) == MODE_SI)
11259             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11260           else
11261             return "sal{b}\t{%b2, %0|%0, %b2}";
11262         }
11263       else if (operands[2] == const1_rtx
11264                && (TARGET_SHIFT1 || optimize_size))
11265         {
11266           if (get_attr_mode (insn) == MODE_SI)
11267             return "sal{l}\t%0";
11268           else
11269             return "sal{b}\t%0";
11270         }
11271       else
11272         {
11273           if (get_attr_mode (insn) == MODE_SI)
11274             return "sal{l}\t{%2, %k0|%k0, %2}";
11275           else
11276             return "sal{b}\t{%2, %0|%0, %2}";
11277         }
11278     }
11279 }
11280   [(set (attr "type")
11281      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11282                           (const_int 0))
11283                       (match_operand 0 "register_operand" ""))
11284                  (match_operand 2 "const1_operand" ""))
11285               (const_string "alu")
11286            ]
11287            (const_string "ishift")))
11288    (set_attr "mode" "QI,SI")])
11289
11290 ;; This pattern can't accept a variable shift count, since shifts by
11291 ;; zero don't affect the flags.  We assume that shifts by constant
11292 ;; zero are optimized away.
11293 (define_insn "*ashlqi3_cmp"
11294   [(set (reg 17)
11295         (compare
11296           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11297                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11298           (const_int 0)))
11299    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300         (ashift:QI (match_dup 1) (match_dup 2)))]
11301   "ix86_match_ccmode (insn, CCGOCmode)
11302    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11303 {
11304   switch (get_attr_type (insn))
11305     {
11306     case TYPE_ALU:
11307       if (operands[2] != const1_rtx)
11308         abort ();
11309       return "add{b}\t{%0, %0|%0, %0}";
11310
11311     default:
11312       if (REG_P (operands[2]))
11313         return "sal{b}\t{%b2, %0|%0, %b2}";
11314       else if (operands[2] == const1_rtx
11315                && (TARGET_SHIFT1 || optimize_size))
11316         return "sal{b}\t%0";
11317       else
11318         return "sal{b}\t{%2, %0|%0, %2}";
11319     }
11320 }
11321   [(set (attr "type")
11322      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11323                           (const_int 0))
11324                       (match_operand 0 "register_operand" ""))
11325                  (match_operand 2 "const1_operand" ""))
11326               (const_string "alu")
11327            ]
11328            (const_string "ishift")))
11329    (set_attr "mode" "QI")])
11330
11331 ;; See comment above `ashldi3' about how this works.
11332
11333 (define_expand "ashrdi3"
11334   [(set (match_operand:DI 0 "shiftdi_operand" "")
11335         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11336                      (match_operand:QI 2 "nonmemory_operand" "")))]
11337   ""
11338   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11339
11340 (define_insn "*ashrdi3_63_rex64"
11341   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11342         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11343                      (match_operand:DI 2 "const_int_operand" "i,i")))
11344    (clobber (reg:CC FLAGS_REG))]
11345   "TARGET_64BIT && INTVAL (operands[2]) == 63
11346    && (TARGET_USE_CLTD || optimize_size)
11347    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11348   "@
11349    {cqto|cqo}
11350    sar{q}\t{%2, %0|%0, %2}"
11351   [(set_attr "type" "imovx,ishift")
11352    (set_attr "prefix_0f" "0,*")
11353    (set_attr "length_immediate" "0,*")
11354    (set_attr "modrm" "0,1")
11355    (set_attr "mode" "DI")])
11356
11357 (define_insn "*ashrdi3_1_one_bit_rex64"
11358   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11359         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11360                      (match_operand:QI 2 "const1_operand" "")))
11361    (clobber (reg:CC FLAGS_REG))]
11362   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11363    && (TARGET_SHIFT1 || optimize_size)"
11364   "sar{q}\t%0"
11365   [(set_attr "type" "ishift")
11366    (set (attr "length") 
11367      (if_then_else (match_operand:DI 0 "register_operand" "") 
11368         (const_string "2")
11369         (const_string "*")))])
11370
11371 (define_insn "*ashrdi3_1_rex64"
11372   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11373         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11374                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11375    (clobber (reg:CC FLAGS_REG))]
11376   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11377   "@
11378    sar{q}\t{%2, %0|%0, %2}
11379    sar{q}\t{%b2, %0|%0, %b2}"
11380   [(set_attr "type" "ishift")
11381    (set_attr "mode" "DI")])
11382
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags.  We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11387   [(set (reg 17)
11388         (compare
11389           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390                        (match_operand:QI 2 "const1_operand" ""))
11391           (const_int 0)))
11392    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395    && (TARGET_SHIFT1 || optimize_size)
11396    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11397   "sar{q}\t%0"
11398   [(set_attr "type" "ishift")
11399    (set (attr "length") 
11400      (if_then_else (match_operand:DI 0 "register_operand" "") 
11401         (const_string "2")
11402         (const_string "*")))])
11403
11404 ;; This pattern can't accept a variable shift count, since shifts by
11405 ;; zero don't affect the flags.  We assume that shifts by constant
11406 ;; zero are optimized away.
11407 (define_insn "*ashrdi3_cmp_rex64"
11408   [(set (reg 17)
11409         (compare
11410           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411                        (match_operand:QI 2 "const_int_operand" "n"))
11412           (const_int 0)))
11413    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11414         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11415   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11416    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11417   "sar{q}\t{%2, %0|%0, %2}"
11418   [(set_attr "type" "ishift")
11419    (set_attr "mode" "DI")])
11420
11421 (define_insn "*ashrdi3_1"
11422   [(set (match_operand:DI 0 "register_operand" "=r")
11423         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11424                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "!TARGET_64BIT"
11427   "#"
11428   [(set_attr "type" "multi")])
11429
11430 ;; By default we don't ask for a scratch register, because when DImode
11431 ;; values are manipulated, registers are already at a premium.  But if
11432 ;; we have one handy, we won't turn it away.
11433 (define_peephole2
11434   [(match_scratch:SI 3 "r")
11435    (parallel [(set (match_operand:DI 0 "register_operand" "")
11436                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11437                                 (match_operand:QI 2 "nonmemory_operand" "")))
11438               (clobber (reg:CC FLAGS_REG))])
11439    (match_dup 3)]
11440   "!TARGET_64BIT && TARGET_CMOVE"
11441   [(const_int 0)]
11442   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11443
11444 (define_split
11445   [(set (match_operand:DI 0 "register_operand" "")
11446         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11447                      (match_operand:QI 2 "nonmemory_operand" "")))
11448    (clobber (reg:CC FLAGS_REG))]
11449   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11450   [(const_int 0)]
11451   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11452
11453 (define_insn "x86_shrd_1"
11454   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11455         (ior:SI (ashiftrt:SI (match_dup 0)
11456                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11457                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11458                   (minus:QI (const_int 32) (match_dup 2)))))
11459    (clobber (reg:CC FLAGS_REG))]
11460   ""
11461   "@
11462    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11463    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11464   [(set_attr "type" "ishift")
11465    (set_attr "prefix_0f" "1")
11466    (set_attr "pent_pair" "np")
11467    (set_attr "mode" "SI")])
11468
11469 (define_expand "x86_shift_adj_3"
11470   [(use (match_operand:SI 0 "register_operand" ""))
11471    (use (match_operand:SI 1 "register_operand" ""))
11472    (use (match_operand:QI 2 "register_operand" ""))]
11473   ""
11474 {
11475   rtx label = gen_label_rtx ();
11476   rtx tmp;
11477
11478   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11479
11480   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11481   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11482   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11483                               gen_rtx_LABEL_REF (VOIDmode, label),
11484                               pc_rtx);
11485   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11486   JUMP_LABEL (tmp) = label;
11487
11488   emit_move_insn (operands[0], operands[1]);
11489   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11490
11491   emit_label (label);
11492   LABEL_NUSES (label) = 1;
11493
11494   DONE;
11495 })
11496
11497 (define_insn "ashrsi3_31"
11498   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11499         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11500                      (match_operand:SI 2 "const_int_operand" "i,i")))
11501    (clobber (reg:CC FLAGS_REG))]
11502   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11503    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11504   "@
11505    {cltd|cdq}
11506    sar{l}\t{%2, %0|%0, %2}"
11507   [(set_attr "type" "imovx,ishift")
11508    (set_attr "prefix_0f" "0,*")
11509    (set_attr "length_immediate" "0,*")
11510    (set_attr "modrm" "0,1")
11511    (set_attr "mode" "SI")])
11512
11513 (define_insn "*ashrsi3_31_zext"
11514   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11515         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11516                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11517    (clobber (reg:CC FLAGS_REG))]
11518   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11519    && INTVAL (operands[2]) == 31
11520    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11521   "@
11522    {cltd|cdq}
11523    sar{l}\t{%2, %k0|%k0, %2}"
11524   [(set_attr "type" "imovx,ishift")
11525    (set_attr "prefix_0f" "0,*")
11526    (set_attr "length_immediate" "0,*")
11527    (set_attr "modrm" "0,1")
11528    (set_attr "mode" "SI")])
11529
11530 (define_expand "ashrsi3"
11531   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11532         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11533                      (match_operand:QI 2 "nonmemory_operand" "")))
11534    (clobber (reg:CC FLAGS_REG))]
11535   ""
11536   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11537
11538 (define_insn "*ashrsi3_1_one_bit"
11539   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11540         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11541                      (match_operand:QI 2 "const1_operand" "")))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11544    && (TARGET_SHIFT1 || optimize_size)"
11545   "sar{l}\t%0"
11546   [(set_attr "type" "ishift")
11547    (set (attr "length") 
11548      (if_then_else (match_operand:SI 0 "register_operand" "") 
11549         (const_string "2")
11550         (const_string "*")))])
11551
11552 (define_insn "*ashrsi3_1_one_bit_zext"
11553   [(set (match_operand:DI 0 "register_operand" "=r")
11554         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11555                                      (match_operand:QI 2 "const1_operand" ""))))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11558    && (TARGET_SHIFT1 || optimize_size)"
11559   "sar{l}\t%k0"
11560   [(set_attr "type" "ishift")
11561    (set_attr "length" "2")])
11562
11563 (define_insn "*ashrsi3_1"
11564   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11565         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11566                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11567    (clobber (reg:CC FLAGS_REG))]
11568   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569   "@
11570    sar{l}\t{%2, %0|%0, %2}
11571    sar{l}\t{%b2, %0|%0, %b2}"
11572   [(set_attr "type" "ishift")
11573    (set_attr "mode" "SI")])
11574
11575 (define_insn "*ashrsi3_1_zext"
11576   [(set (match_operand:DI 0 "register_operand" "=r,r")
11577         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11578                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11581   "@
11582    sar{l}\t{%2, %k0|%k0, %2}
11583    sar{l}\t{%b2, %k0|%k0, %b2}"
11584   [(set_attr "type" "ishift")
11585    (set_attr "mode" "SI")])
11586
11587 ;; This pattern can't accept a variable shift count, since shifts by
11588 ;; zero don't affect the flags.  We assume that shifts by constant
11589 ;; zero are optimized away.
11590 (define_insn "*ashrsi3_one_bit_cmp"
11591   [(set (reg 17)
11592         (compare
11593           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11594                        (match_operand:QI 2 "const1_operand" ""))
11595           (const_int 0)))
11596    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11597         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11598   "ix86_match_ccmode (insn, CCGOCmode)
11599    && (TARGET_SHIFT1 || optimize_size)
11600    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11601   "sar{l}\t%0"
11602   [(set_attr "type" "ishift")
11603    (set (attr "length") 
11604      (if_then_else (match_operand:SI 0 "register_operand" "") 
11605         (const_string "2")
11606         (const_string "*")))])
11607
11608 (define_insn "*ashrsi3_one_bit_cmp_zext"
11609   [(set (reg 17)
11610         (compare
11611           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11612                        (match_operand:QI 2 "const1_operand" ""))
11613           (const_int 0)))
11614    (set (match_operand:DI 0 "register_operand" "=r")
11615         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11616   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11617    && (TARGET_SHIFT1 || optimize_size)
11618    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11619   "sar{l}\t%k0"
11620   [(set_attr "type" "ishift")
11621    (set_attr "length" "2")])
11622
11623 ;; This pattern can't accept a variable shift count, since shifts by
11624 ;; zero don't affect the flags.  We assume that shifts by constant
11625 ;; zero are optimized away.
11626 (define_insn "*ashrsi3_cmp"
11627   [(set (reg 17)
11628         (compare
11629           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11630                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11631           (const_int 0)))
11632    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11633         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11634   "ix86_match_ccmode (insn, CCGOCmode)
11635    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11636   "sar{l}\t{%2, %0|%0, %2}"
11637   [(set_attr "type" "ishift")
11638    (set_attr "mode" "SI")])
11639
11640 (define_insn "*ashrsi3_cmp_zext"
11641   [(set (reg 17)
11642         (compare
11643           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11644                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11645           (const_int 0)))
11646    (set (match_operand:DI 0 "register_operand" "=r")
11647         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11648   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11649    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11650   "sar{l}\t{%2, %k0|%k0, %2}"
11651   [(set_attr "type" "ishift")
11652    (set_attr "mode" "SI")])
11653
11654 (define_expand "ashrhi3"
11655   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11656         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11657                      (match_operand:QI 2 "nonmemory_operand" "")))
11658    (clobber (reg:CC FLAGS_REG))]
11659   "TARGET_HIMODE_MATH"
11660   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11661
11662 (define_insn "*ashrhi3_1_one_bit"
11663   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11664         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11665                      (match_operand:QI 2 "const1_operand" "")))
11666    (clobber (reg:CC FLAGS_REG))]
11667   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11668    && (TARGET_SHIFT1 || optimize_size)"
11669   "sar{w}\t%0"
11670   [(set_attr "type" "ishift")
11671    (set (attr "length") 
11672      (if_then_else (match_operand 0 "register_operand" "") 
11673         (const_string "2")
11674         (const_string "*")))])
11675
11676 (define_insn "*ashrhi3_1"
11677   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11678         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11679                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11682   "@
11683    sar{w}\t{%2, %0|%0, %2}
11684    sar{w}\t{%b2, %0|%0, %b2}"
11685   [(set_attr "type" "ishift")
11686    (set_attr "mode" "HI")])
11687
11688 ;; This pattern can't accept a variable shift count, since shifts by
11689 ;; zero don't affect the flags.  We assume that shifts by constant
11690 ;; zero are optimized away.
11691 (define_insn "*ashrhi3_one_bit_cmp"
11692   [(set (reg 17)
11693         (compare
11694           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695                        (match_operand:QI 2 "const1_operand" ""))
11696           (const_int 0)))
11697    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11698         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11699   "ix86_match_ccmode (insn, CCGOCmode)
11700    && (TARGET_SHIFT1 || optimize_size)
11701    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11702   "sar{w}\t%0"
11703   [(set_attr "type" "ishift")
11704    (set (attr "length") 
11705      (if_then_else (match_operand 0 "register_operand" "") 
11706         (const_string "2")
11707         (const_string "*")))])
11708
11709 ;; This pattern can't accept a variable shift count, since shifts by
11710 ;; zero don't affect the flags.  We assume that shifts by constant
11711 ;; zero are optimized away.
11712 (define_insn "*ashrhi3_cmp"
11713   [(set (reg 17)
11714         (compare
11715           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11717           (const_int 0)))
11718    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720   "ix86_match_ccmode (insn, CCGOCmode)
11721    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11722   "sar{w}\t{%2, %0|%0, %2}"
11723   [(set_attr "type" "ishift")
11724    (set_attr "mode" "HI")])
11725
11726 (define_expand "ashrqi3"
11727   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11728         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11729                      (match_operand:QI 2 "nonmemory_operand" "")))
11730    (clobber (reg:CC FLAGS_REG))]
11731   "TARGET_QIMODE_MATH"
11732   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11733
11734 (define_insn "*ashrqi3_1_one_bit"
11735   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11736         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11737                      (match_operand:QI 2 "const1_operand" "")))
11738    (clobber (reg:CC FLAGS_REG))]
11739   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11740    && (TARGET_SHIFT1 || optimize_size)"
11741   "sar{b}\t%0"
11742   [(set_attr "type" "ishift")
11743    (set (attr "length") 
11744      (if_then_else (match_operand 0 "register_operand" "") 
11745         (const_string "2")
11746         (const_string "*")))])
11747
11748 (define_insn "*ashrqi3_1_one_bit_slp"
11749   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11750         (ashiftrt:QI (match_dup 0)
11751                      (match_operand:QI 1 "const1_operand" "")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11754    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11755    && (TARGET_SHIFT1 || optimize_size)"
11756   "sar{b}\t%0"
11757   [(set_attr "type" "ishift1")
11758    (set (attr "length") 
11759      (if_then_else (match_operand 0 "register_operand" "") 
11760         (const_string "2")
11761         (const_string "*")))])
11762
11763 (define_insn "*ashrqi3_1"
11764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11765         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11766                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11767    (clobber (reg:CC FLAGS_REG))]
11768   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11769   "@
11770    sar{b}\t{%2, %0|%0, %2}
11771    sar{b}\t{%b2, %0|%0, %b2}"
11772   [(set_attr "type" "ishift")
11773    (set_attr "mode" "QI")])
11774
11775 (define_insn "*ashrqi3_1_slp"
11776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11777         (ashiftrt:QI (match_dup 0)
11778                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11779    (clobber (reg:CC FLAGS_REG))]
11780   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11781    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11782   "@
11783    sar{b}\t{%1, %0|%0, %1}
11784    sar{b}\t{%b1, %0|%0, %b1}"
11785   [(set_attr "type" "ishift1")
11786    (set_attr "mode" "QI")])
11787
11788 ;; This pattern can't accept a variable shift count, since shifts by
11789 ;; zero don't affect the flags.  We assume that shifts by constant
11790 ;; zero are optimized away.
11791 (define_insn "*ashrqi3_one_bit_cmp"
11792   [(set (reg 17)
11793         (compare
11794           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11795                        (match_operand:QI 2 "const1_operand" "I"))
11796           (const_int 0)))
11797    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11798         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11799   "ix86_match_ccmode (insn, CCGOCmode)
11800    && (TARGET_SHIFT1 || optimize_size)
11801    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11802   "sar{b}\t%0"
11803   [(set_attr "type" "ishift")
11804    (set (attr "length") 
11805      (if_then_else (match_operand 0 "register_operand" "") 
11806         (const_string "2")
11807         (const_string "*")))])
11808
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags.  We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*ashrqi3_cmp"
11813   [(set (reg 17)
11814         (compare
11815           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11817           (const_int 0)))
11818    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11819         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11820   "ix86_match_ccmode (insn, CCGOCmode)
11821    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11822   "sar{b}\t{%2, %0|%0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "QI")])
11825 \f
11826 ;; Logical shift instructions
11827
11828 ;; See comment above `ashldi3' about how this works.
11829
11830 (define_expand "lshrdi3"
11831   [(set (match_operand:DI 0 "shiftdi_operand" "")
11832         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11833                      (match_operand:QI 2 "nonmemory_operand" "")))]
11834   ""
11835   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11836
11837 (define_insn "*lshrdi3_1_one_bit_rex64"
11838   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11839         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11840                      (match_operand:QI 2 "const1_operand" "")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11843    && (TARGET_SHIFT1 || optimize_size)"
11844   "shr{q}\t%0"
11845   [(set_attr "type" "ishift")
11846    (set (attr "length") 
11847      (if_then_else (match_operand:DI 0 "register_operand" "") 
11848         (const_string "2")
11849         (const_string "*")))])
11850
11851 (define_insn "*lshrdi3_1_rex64"
11852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11853         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11854                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857   "@
11858    shr{q}\t{%2, %0|%0, %2}
11859    shr{q}\t{%b2, %0|%0, %b2}"
11860   [(set_attr "type" "ishift")
11861    (set_attr "mode" "DI")])
11862
11863 ;; This pattern can't accept a variable shift count, since shifts by
11864 ;; zero don't affect the flags.  We assume that shifts by constant
11865 ;; zero are optimized away.
11866 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11867   [(set (reg 17)
11868         (compare
11869           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11870                        (match_operand:QI 2 "const1_operand" ""))
11871           (const_int 0)))
11872    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11873         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11874   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11875    && (TARGET_SHIFT1 || optimize_size)
11876    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11877   "shr{q}\t%0"
11878   [(set_attr "type" "ishift")
11879    (set (attr "length") 
11880      (if_then_else (match_operand:DI 0 "register_operand" "") 
11881         (const_string "2")
11882         (const_string "*")))])
11883
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags.  We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*lshrdi3_cmp_rex64"
11888   [(set (reg 17)
11889         (compare
11890           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11891                        (match_operand:QI 2 "const_int_operand" "e"))
11892           (const_int 0)))
11893    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11894         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11895   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11897   "shr{q}\t{%2, %0|%0, %2}"
11898   [(set_attr "type" "ishift")
11899    (set_attr "mode" "DI")])
11900
11901 (define_insn "*lshrdi3_1"
11902   [(set (match_operand:DI 0 "register_operand" "=r")
11903         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11904                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11905    (clobber (reg:CC FLAGS_REG))]
11906   "!TARGET_64BIT"
11907   "#"
11908   [(set_attr "type" "multi")])
11909
11910 ;; By default we don't ask for a scratch register, because when DImode
11911 ;; values are manipulated, registers are already at a premium.  But if
11912 ;; we have one handy, we won't turn it away.
11913 (define_peephole2
11914   [(match_scratch:SI 3 "r")
11915    (parallel [(set (match_operand:DI 0 "register_operand" "")
11916                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11917                                 (match_operand:QI 2 "nonmemory_operand" "")))
11918               (clobber (reg:CC FLAGS_REG))])
11919    (match_dup 3)]
11920   "!TARGET_64BIT && TARGET_CMOVE"
11921   [(const_int 0)]
11922   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11923
11924 (define_split 
11925   [(set (match_operand:DI 0 "register_operand" "")
11926         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11927                      (match_operand:QI 2 "nonmemory_operand" "")))
11928    (clobber (reg:CC FLAGS_REG))]
11929   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11930   [(const_int 0)]
11931   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11932
11933 (define_expand "lshrsi3"
11934   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11935         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11936                      (match_operand:QI 2 "nonmemory_operand" "")))
11937    (clobber (reg:CC FLAGS_REG))]
11938   ""
11939   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11940
11941 (define_insn "*lshrsi3_1_one_bit"
11942   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11943         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11944                      (match_operand:QI 2 "const1_operand" "")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11947    && (TARGET_SHIFT1 || optimize_size)"
11948   "shr{l}\t%0"
11949   [(set_attr "type" "ishift")
11950    (set (attr "length") 
11951      (if_then_else (match_operand:SI 0 "register_operand" "") 
11952         (const_string "2")
11953         (const_string "*")))])
11954
11955 (define_insn "*lshrsi3_1_one_bit_zext"
11956   [(set (match_operand:DI 0 "register_operand" "=r")
11957         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11958                      (match_operand:QI 2 "const1_operand" "")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11961    && (TARGET_SHIFT1 || optimize_size)"
11962   "shr{l}\t%k0"
11963   [(set_attr "type" "ishift")
11964    (set_attr "length" "2")])
11965
11966 (define_insn "*lshrsi3_1"
11967   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11968         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11969                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11970    (clobber (reg:CC FLAGS_REG))]
11971   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11972   "@
11973    shr{l}\t{%2, %0|%0, %2}
11974    shr{l}\t{%b2, %0|%0, %b2}"
11975   [(set_attr "type" "ishift")
11976    (set_attr "mode" "SI")])
11977
11978 (define_insn "*lshrsi3_1_zext"
11979   [(set (match_operand:DI 0 "register_operand" "=r,r")
11980         (zero_extend:DI
11981           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11982                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11985   "@
11986    shr{l}\t{%2, %k0|%k0, %2}
11987    shr{l}\t{%b2, %k0|%k0, %b2}"
11988   [(set_attr "type" "ishift")
11989    (set_attr "mode" "SI")])
11990
11991 ;; This pattern can't accept a variable shift count, since shifts by
11992 ;; zero don't affect the flags.  We assume that shifts by constant
11993 ;; zero are optimized away.
11994 (define_insn "*lshrsi3_one_bit_cmp"
11995   [(set (reg 17)
11996         (compare
11997           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11998                        (match_operand:QI 2 "const1_operand" ""))
11999           (const_int 0)))
12000    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12002   "ix86_match_ccmode (insn, CCGOCmode)
12003    && (TARGET_SHIFT1 || optimize_size)
12004    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005   "shr{l}\t%0"
12006   [(set_attr "type" "ishift")
12007    (set (attr "length") 
12008      (if_then_else (match_operand:SI 0 "register_operand" "") 
12009         (const_string "2")
12010         (const_string "*")))])
12011
12012 (define_insn "*lshrsi3_cmp_one_bit_zext"
12013   [(set (reg 17)
12014         (compare
12015           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12016                        (match_operand:QI 2 "const1_operand" ""))
12017           (const_int 0)))
12018    (set (match_operand:DI 0 "register_operand" "=r")
12019         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12020   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12021    && (TARGET_SHIFT1 || optimize_size)
12022    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12023   "shr{l}\t%k0"
12024   [(set_attr "type" "ishift")
12025    (set_attr "length" "2")])
12026
12027 ;; This pattern can't accept a variable shift count, since shifts by
12028 ;; zero don't affect the flags.  We assume that shifts by constant
12029 ;; zero are optimized away.
12030 (define_insn "*lshrsi3_cmp"
12031   [(set (reg 17)
12032         (compare
12033           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12034                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12035           (const_int 0)))
12036    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12037         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12038   "ix86_match_ccmode (insn, CCGOCmode)
12039    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12040   "shr{l}\t{%2, %0|%0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "SI")])
12043
12044 (define_insn "*lshrsi3_cmp_zext"
12045   [(set (reg 17)
12046         (compare
12047           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12048                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12049           (const_int 0)))
12050    (set (match_operand:DI 0 "register_operand" "=r")
12051         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12052   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12053    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12054   "shr{l}\t{%2, %k0|%k0, %2}"
12055   [(set_attr "type" "ishift")
12056    (set_attr "mode" "SI")])
12057
12058 (define_expand "lshrhi3"
12059   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12060         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12061                      (match_operand:QI 2 "nonmemory_operand" "")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "TARGET_HIMODE_MATH"
12064   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12065
12066 (define_insn "*lshrhi3_1_one_bit"
12067   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12068         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12069                      (match_operand:QI 2 "const1_operand" "")))
12070    (clobber (reg:CC FLAGS_REG))]
12071   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12072    && (TARGET_SHIFT1 || optimize_size)"
12073   "shr{w}\t%0"
12074   [(set_attr "type" "ishift")
12075    (set (attr "length") 
12076      (if_then_else (match_operand 0 "register_operand" "") 
12077         (const_string "2")
12078         (const_string "*")))])
12079
12080 (define_insn "*lshrhi3_1"
12081   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12082         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12083                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12084    (clobber (reg:CC FLAGS_REG))]
12085   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12086   "@
12087    shr{w}\t{%2, %0|%0, %2}
12088    shr{w}\t{%b2, %0|%0, %b2}"
12089   [(set_attr "type" "ishift")
12090    (set_attr "mode" "HI")])
12091
12092 ;; This pattern can't accept a variable shift count, since shifts by
12093 ;; zero don't affect the flags.  We assume that shifts by constant
12094 ;; zero are optimized away.
12095 (define_insn "*lshrhi3_one_bit_cmp"
12096   [(set (reg 17)
12097         (compare
12098           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12099                        (match_operand:QI 2 "const1_operand" ""))
12100           (const_int 0)))
12101    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12102         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12103   "ix86_match_ccmode (insn, CCGOCmode)
12104    && (TARGET_SHIFT1 || optimize_size)
12105    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12106   "shr{w}\t%0"
12107   [(set_attr "type" "ishift")
12108    (set (attr "length") 
12109      (if_then_else (match_operand:SI 0 "register_operand" "") 
12110         (const_string "2")
12111         (const_string "*")))])
12112
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags.  We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*lshrhi3_cmp"
12117   [(set (reg 17)
12118         (compare
12119           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12121           (const_int 0)))
12122    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12124   "ix86_match_ccmode (insn, CCGOCmode)
12125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12126   "shr{w}\t{%2, %0|%0, %2}"
12127   [(set_attr "type" "ishift")
12128    (set_attr "mode" "HI")])
12129
12130 (define_expand "lshrqi3"
12131   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12132         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12133                      (match_operand:QI 2 "nonmemory_operand" "")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "TARGET_QIMODE_MATH"
12136   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12137
12138 (define_insn "*lshrqi3_1_one_bit"
12139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12140         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12141                      (match_operand:QI 2 "const1_operand" "")))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12144    && (TARGET_SHIFT1 || optimize_size)"
12145   "shr{b}\t%0"
12146   [(set_attr "type" "ishift")
12147    (set (attr "length") 
12148      (if_then_else (match_operand 0 "register_operand" "") 
12149         (const_string "2")
12150         (const_string "*")))])
12151
12152 (define_insn "*lshrqi3_1_one_bit_slp"
12153   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12154         (lshiftrt:QI (match_dup 0)
12155                      (match_operand:QI 1 "const1_operand" "")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12158    && (TARGET_SHIFT1 || optimize_size)"
12159   "shr{b}\t%0"
12160   [(set_attr "type" "ishift1")
12161    (set (attr "length") 
12162      (if_then_else (match_operand 0 "register_operand" "") 
12163         (const_string "2")
12164         (const_string "*")))])
12165
12166 (define_insn "*lshrqi3_1"
12167   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12168         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12169                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12172   "@
12173    shr{b}\t{%2, %0|%0, %2}
12174    shr{b}\t{%b2, %0|%0, %b2}"
12175   [(set_attr "type" "ishift")
12176    (set_attr "mode" "QI")])
12177
12178 (define_insn "*lshrqi3_1_slp"
12179   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12180         (lshiftrt:QI (match_dup 0)
12181                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12182    (clobber (reg:CC FLAGS_REG))]
12183   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12184    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12185   "@
12186    shr{b}\t{%1, %0|%0, %1}
12187    shr{b}\t{%b1, %0|%0, %b1}"
12188   [(set_attr "type" "ishift1")
12189    (set_attr "mode" "QI")])
12190
12191 ;; This pattern can't accept a variable shift count, since shifts by
12192 ;; zero don't affect the flags.  We assume that shifts by constant
12193 ;; zero are optimized away.
12194 (define_insn "*lshrqi2_one_bit_cmp"
12195   [(set (reg 17)
12196         (compare
12197           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12198                        (match_operand:QI 2 "const1_operand" ""))
12199           (const_int 0)))
12200    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12201         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12202   "ix86_match_ccmode (insn, CCGOCmode)
12203    && (TARGET_SHIFT1 || optimize_size)
12204    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12205   "shr{b}\t%0"
12206   [(set_attr "type" "ishift")
12207    (set (attr "length") 
12208      (if_then_else (match_operand:SI 0 "register_operand" "") 
12209         (const_string "2")
12210         (const_string "*")))])
12211
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags.  We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*lshrqi2_cmp"
12216   [(set (reg 17)
12217         (compare
12218           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12220           (const_int 0)))
12221    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12225   "shr{b}\t{%2, %0|%0, %2}"
12226   [(set_attr "type" "ishift")
12227    (set_attr "mode" "QI")])
12228 \f
12229 ;; Rotate instructions
12230
12231 (define_expand "rotldi3"
12232   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12233         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12234                    (match_operand:QI 2 "nonmemory_operand" "")))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT"
12237   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12238
12239 (define_insn "*rotlsi3_1_one_bit_rex64"
12240   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12241         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12242                    (match_operand:QI 2 "const1_operand" "")))
12243    (clobber (reg:CC FLAGS_REG))]
12244   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12245    && (TARGET_SHIFT1 || optimize_size)"
12246   "rol{q}\t%0"
12247   [(set_attr "type" "rotate")
12248    (set (attr "length") 
12249      (if_then_else (match_operand:DI 0 "register_operand" "") 
12250         (const_string "2")
12251         (const_string "*")))])
12252
12253 (define_insn "*rotldi3_1_rex64"
12254   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12255         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12256                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12257    (clobber (reg:CC FLAGS_REG))]
12258   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12259   "@
12260    rol{q}\t{%2, %0|%0, %2}
12261    rol{q}\t{%b2, %0|%0, %b2}"
12262   [(set_attr "type" "rotate")
12263    (set_attr "mode" "DI")])
12264
12265 (define_expand "rotlsi3"
12266   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12267         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12268                    (match_operand:QI 2 "nonmemory_operand" "")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   ""
12271   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12272
12273 (define_insn "*rotlsi3_1_one_bit"
12274   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12275         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12276                    (match_operand:QI 2 "const1_operand" "")))
12277    (clobber (reg:CC FLAGS_REG))]
12278   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12279    && (TARGET_SHIFT1 || optimize_size)"
12280   "rol{l}\t%0"
12281   [(set_attr "type" "rotate")
12282    (set (attr "length") 
12283      (if_then_else (match_operand:SI 0 "register_operand" "") 
12284         (const_string "2")
12285         (const_string "*")))])
12286
12287 (define_insn "*rotlsi3_1_one_bit_zext"
12288   [(set (match_operand:DI 0 "register_operand" "=r")
12289         (zero_extend:DI
12290           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12291                      (match_operand:QI 2 "const1_operand" ""))))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12294    && (TARGET_SHIFT1 || optimize_size)"
12295   "rol{l}\t%k0"
12296   [(set_attr "type" "rotate")
12297    (set_attr "length" "2")])
12298
12299 (define_insn "*rotlsi3_1"
12300   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12301         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12302                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12303    (clobber (reg:CC FLAGS_REG))]
12304   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12305   "@
12306    rol{l}\t{%2, %0|%0, %2}
12307    rol{l}\t{%b2, %0|%0, %b2}"
12308   [(set_attr "type" "rotate")
12309    (set_attr "mode" "SI")])
12310
12311 (define_insn "*rotlsi3_1_zext"
12312   [(set (match_operand:DI 0 "register_operand" "=r,r")
12313         (zero_extend:DI
12314           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12315                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12318   "@
12319    rol{l}\t{%2, %k0|%k0, %2}
12320    rol{l}\t{%b2, %k0|%k0, %b2}"
12321   [(set_attr "type" "rotate")
12322    (set_attr "mode" "SI")])
12323
12324 (define_expand "rotlhi3"
12325   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12326         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12327                    (match_operand:QI 2 "nonmemory_operand" "")))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_HIMODE_MATH"
12330   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12331
12332 (define_insn "*rotlhi3_1_one_bit"
12333   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12334         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12335                    (match_operand:QI 2 "const1_operand" "")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12338    && (TARGET_SHIFT1 || optimize_size)"
12339   "rol{w}\t%0"
12340   [(set_attr "type" "rotate")
12341    (set (attr "length") 
12342      (if_then_else (match_operand 0 "register_operand" "") 
12343         (const_string "2")
12344         (const_string "*")))])
12345
12346 (define_insn "*rotlhi3_1"
12347   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12348         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12349                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12350    (clobber (reg:CC FLAGS_REG))]
12351   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12352   "@
12353    rol{w}\t{%2, %0|%0, %2}
12354    rol{w}\t{%b2, %0|%0, %b2}"
12355   [(set_attr "type" "rotate")
12356    (set_attr "mode" "HI")])
12357
12358 (define_expand "rotlqi3"
12359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12360         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12361                    (match_operand:QI 2 "nonmemory_operand" "")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_QIMODE_MATH"
12364   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12365
12366 (define_insn "*rotlqi3_1_one_bit_slp"
12367   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12368         (rotate:QI (match_dup 0)
12369                    (match_operand:QI 1 "const1_operand" "")))
12370    (clobber (reg:CC FLAGS_REG))]
12371   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12372    && (TARGET_SHIFT1 || optimize_size)"
12373   "rol{b}\t%0"
12374   [(set_attr "type" "rotate1")
12375    (set (attr "length") 
12376      (if_then_else (match_operand 0 "register_operand" "") 
12377         (const_string "2")
12378         (const_string "*")))])
12379
12380 (define_insn "*rotlqi3_1_one_bit"
12381   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12382         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12383                    (match_operand:QI 2 "const1_operand" "")))
12384    (clobber (reg:CC FLAGS_REG))]
12385   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12386    && (TARGET_SHIFT1 || optimize_size)"
12387   "rol{b}\t%0"
12388   [(set_attr "type" "rotate")
12389    (set (attr "length") 
12390      (if_then_else (match_operand 0 "register_operand" "") 
12391         (const_string "2")
12392         (const_string "*")))])
12393
12394 (define_insn "*rotlqi3_1_slp"
12395   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12396         (rotate:QI (match_dup 0)
12397                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12400    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12401   "@
12402    rol{b}\t{%1, %0|%0, %1}
12403    rol{b}\t{%b1, %0|%0, %b1}"
12404   [(set_attr "type" "rotate1")
12405    (set_attr "mode" "QI")])
12406
12407 (define_insn "*rotlqi3_1"
12408   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12409         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12410                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12413   "@
12414    rol{b}\t{%2, %0|%0, %2}
12415    rol{b}\t{%b2, %0|%0, %b2}"
12416   [(set_attr "type" "rotate")
12417    (set_attr "mode" "QI")])
12418
12419 (define_expand "rotrdi3"
12420   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12421         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12422                      (match_operand:QI 2 "nonmemory_operand" "")))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "TARGET_64BIT"
12425   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12426
12427 (define_insn "*rotrdi3_1_one_bit_rex64"
12428   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12429         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12430                      (match_operand:QI 2 "const1_operand" "")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12433    && (TARGET_SHIFT1 || optimize_size)"
12434   "ror{q}\t%0"
12435   [(set_attr "type" "rotate")
12436    (set (attr "length") 
12437      (if_then_else (match_operand:DI 0 "register_operand" "") 
12438         (const_string "2")
12439         (const_string "*")))])
12440
12441 (define_insn "*rotrdi3_1_rex64"
12442   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12443         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12444                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12445    (clobber (reg:CC FLAGS_REG))]
12446   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12447   "@
12448    ror{q}\t{%2, %0|%0, %2}
12449    ror{q}\t{%b2, %0|%0, %b2}"
12450   [(set_attr "type" "rotate")
12451    (set_attr "mode" "DI")])
12452
12453 (define_expand "rotrsi3"
12454   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12455         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12456                      (match_operand:QI 2 "nonmemory_operand" "")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   ""
12459   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12460
12461 (define_insn "*rotrsi3_1_one_bit"
12462   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12463         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12464                      (match_operand:QI 2 "const1_operand" "")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12467    && (TARGET_SHIFT1 || optimize_size)"
12468   "ror{l}\t%0"
12469   [(set_attr "type" "rotate")
12470    (set (attr "length") 
12471      (if_then_else (match_operand:SI 0 "register_operand" "") 
12472         (const_string "2")
12473         (const_string "*")))])
12474
12475 (define_insn "*rotrsi3_1_one_bit_zext"
12476   [(set (match_operand:DI 0 "register_operand" "=r")
12477         (zero_extend:DI
12478           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12479                        (match_operand:QI 2 "const1_operand" ""))))
12480    (clobber (reg:CC FLAGS_REG))]
12481   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12482    && (TARGET_SHIFT1 || optimize_size)"
12483   "ror{l}\t%k0"
12484   [(set_attr "type" "rotate")
12485    (set (attr "length") 
12486      (if_then_else (match_operand:SI 0 "register_operand" "") 
12487         (const_string "2")
12488         (const_string "*")))])
12489
12490 (define_insn "*rotrsi3_1"
12491   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12492         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12493                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12494    (clobber (reg:CC FLAGS_REG))]
12495   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12496   "@
12497    ror{l}\t{%2, %0|%0, %2}
12498    ror{l}\t{%b2, %0|%0, %b2}"
12499   [(set_attr "type" "rotate")
12500    (set_attr "mode" "SI")])
12501
12502 (define_insn "*rotrsi3_1_zext"
12503   [(set (match_operand:DI 0 "register_operand" "=r,r")
12504         (zero_extend:DI
12505           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12506                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12507    (clobber (reg:CC FLAGS_REG))]
12508   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12509   "@
12510    ror{l}\t{%2, %k0|%k0, %2}
12511    ror{l}\t{%b2, %k0|%k0, %b2}"
12512   [(set_attr "type" "rotate")
12513    (set_attr "mode" "SI")])
12514
12515 (define_expand "rotrhi3"
12516   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12517         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12518                      (match_operand:QI 2 "nonmemory_operand" "")))
12519    (clobber (reg:CC FLAGS_REG))]
12520   "TARGET_HIMODE_MATH"
12521   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12522
12523 (define_insn "*rotrhi3_one_bit"
12524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12525         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12526                      (match_operand:QI 2 "const1_operand" "")))
12527    (clobber (reg:CC FLAGS_REG))]
12528   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12529    && (TARGET_SHIFT1 || optimize_size)"
12530   "ror{w}\t%0"
12531   [(set_attr "type" "rotate")
12532    (set (attr "length") 
12533      (if_then_else (match_operand 0 "register_operand" "") 
12534         (const_string "2")
12535         (const_string "*")))])
12536
12537 (define_insn "*rotrhi3"
12538   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12539         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12540                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12541    (clobber (reg:CC FLAGS_REG))]
12542   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12543   "@
12544    ror{w}\t{%2, %0|%0, %2}
12545    ror{w}\t{%b2, %0|%0, %b2}"
12546   [(set_attr "type" "rotate")
12547    (set_attr "mode" "HI")])
12548
12549 (define_expand "rotrqi3"
12550   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12551         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12552                      (match_operand:QI 2 "nonmemory_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_QIMODE_MATH"
12555   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12556
12557 (define_insn "*rotrqi3_1_one_bit"
12558   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12559         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12560                      (match_operand:QI 2 "const1_operand" "")))
12561    (clobber (reg:CC FLAGS_REG))]
12562   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12563    && (TARGET_SHIFT1 || optimize_size)"
12564   "ror{b}\t%0"
12565   [(set_attr "type" "rotate")
12566    (set (attr "length") 
12567      (if_then_else (match_operand 0 "register_operand" "") 
12568         (const_string "2")
12569         (const_string "*")))])
12570
12571 (define_insn "*rotrqi3_1_one_bit_slp"
12572   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12573         (rotatert:QI (match_dup 0)
12574                      (match_operand:QI 1 "const1_operand" "")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12577    && (TARGET_SHIFT1 || optimize_size)"
12578   "ror{b}\t%0"
12579   [(set_attr "type" "rotate1")
12580    (set (attr "length") 
12581      (if_then_else (match_operand 0 "register_operand" "") 
12582         (const_string "2")
12583         (const_string "*")))])
12584
12585 (define_insn "*rotrqi3_1"
12586   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12587         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12588                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12589    (clobber (reg:CC FLAGS_REG))]
12590   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12591   "@
12592    ror{b}\t{%2, %0|%0, %2}
12593    ror{b}\t{%b2, %0|%0, %b2}"
12594   [(set_attr "type" "rotate")
12595    (set_attr "mode" "QI")])
12596
12597 (define_insn "*rotrqi3_1_slp"
12598   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12599         (rotatert:QI (match_dup 0)
12600                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12601    (clobber (reg:CC FLAGS_REG))]
12602   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12603    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12604   "@
12605    ror{b}\t{%1, %0|%0, %1}
12606    ror{b}\t{%b1, %0|%0, %b1}"
12607   [(set_attr "type" "rotate1")
12608    (set_attr "mode" "QI")])
12609 \f
12610 ;; Bit set / bit test instructions
12611
12612 (define_expand "extv"
12613   [(set (match_operand:SI 0 "register_operand" "")
12614         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12615                          (match_operand:SI 2 "immediate_operand" "")
12616                          (match_operand:SI 3 "immediate_operand" "")))]
12617   ""
12618 {
12619   /* Handle extractions from %ah et al.  */
12620   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12621     FAIL;
12622
12623   /* From mips.md: extract_bit_field doesn't verify that our source
12624      matches the predicate, so check it again here.  */
12625   if (! register_operand (operands[1], VOIDmode))
12626     FAIL;
12627 })
12628
12629 (define_expand "extzv"
12630   [(set (match_operand:SI 0 "register_operand" "")
12631         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12632                          (match_operand:SI 2 "immediate_operand" "")
12633                          (match_operand:SI 3 "immediate_operand" "")))]
12634   ""
12635 {
12636   /* Handle extractions from %ah et al.  */
12637   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12638     FAIL;
12639
12640   /* From mips.md: extract_bit_field doesn't verify that our source
12641      matches the predicate, so check it again here.  */
12642   if (! register_operand (operands[1], VOIDmode))
12643     FAIL;
12644 })
12645
12646 (define_expand "insv"
12647   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12648                       (match_operand 1 "immediate_operand" "")
12649                       (match_operand 2 "immediate_operand" ""))
12650         (match_operand 3 "register_operand" ""))]
12651   ""
12652 {
12653   /* Handle extractions from %ah et al.  */
12654   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12655     FAIL;
12656
12657   /* From mips.md: insert_bit_field doesn't verify that our source
12658      matches the predicate, so check it again here.  */
12659   if (! register_operand (operands[0], VOIDmode))
12660     FAIL;
12661
12662   if (TARGET_64BIT)
12663     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12664   else
12665     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12666
12667   DONE;
12668 })
12669
12670 ;; %%% bts, btr, btc, bt.
12671 \f
12672 ;; Store-flag instructions.
12673
12674 ;; For all sCOND expanders, also expand the compare or test insn that
12675 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12676
12677 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12678 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12679 ;; way, which can later delete the movzx if only QImode is needed.
12680
12681 (define_expand "seq"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sne"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sgt"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sgtu"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "slt"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sltu"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sge"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   ""
12721   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sgeu"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   ""
12727   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sle"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   ""
12733   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sleu"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   ""
12739   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sunordered"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387 || TARGET_SSE"
12745   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "sordered"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387"
12751   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "suneq"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sunge"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sungt"
12766   [(set (match_operand:QI 0 "register_operand" "")
12767         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768   "TARGET_80387 || TARGET_SSE"
12769   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sunle"
12772   [(set (match_operand:QI 0 "register_operand" "")
12773         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774   "TARGET_80387 || TARGET_SSE"
12775   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12776
12777 (define_expand "sunlt"
12778   [(set (match_operand:QI 0 "register_operand" "")
12779         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780   "TARGET_80387 || TARGET_SSE"
12781   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12782
12783 (define_expand "sltgt"
12784   [(set (match_operand:QI 0 "register_operand" "")
12785         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12786   "TARGET_80387 || TARGET_SSE"
12787   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12788
12789 (define_insn "*setcc_1"
12790   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12791         (match_operator:QI 1 "ix86_comparison_operator"
12792           [(reg 17) (const_int 0)]))]
12793   ""
12794   "set%C1\t%0"
12795   [(set_attr "type" "setcc")
12796    (set_attr "mode" "QI")])
12797
12798 (define_insn "*setcc_2"
12799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12800         (match_operator:QI 1 "ix86_comparison_operator"
12801           [(reg 17) (const_int 0)]))]
12802   ""
12803   "set%C1\t%0"
12804   [(set_attr "type" "setcc")
12805    (set_attr "mode" "QI")])
12806
12807 ;; In general it is not safe to assume too much about CCmode registers,
12808 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12809 ;; conditions this is safe on x86, so help combine not create
12810 ;;
12811 ;;      seta    %al
12812 ;;      testb   %al, %al
12813 ;;      sete    %al
12814
12815 (define_split 
12816   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12817         (ne:QI (match_operator 1 "ix86_comparison_operator"
12818                  [(reg 17) (const_int 0)])
12819             (const_int 0)))]
12820   ""
12821   [(set (match_dup 0) (match_dup 1))]
12822 {
12823   PUT_MODE (operands[1], QImode);
12824 })
12825
12826 (define_split 
12827   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12828         (ne:QI (match_operator 1 "ix86_comparison_operator"
12829                  [(reg 17) (const_int 0)])
12830             (const_int 0)))]
12831   ""
12832   [(set (match_dup 0) (match_dup 1))]
12833 {
12834   PUT_MODE (operands[1], QImode);
12835 })
12836
12837 (define_split 
12838   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12839         (eq:QI (match_operator 1 "ix86_comparison_operator"
12840                  [(reg 17) (const_int 0)])
12841             (const_int 0)))]
12842   ""
12843   [(set (match_dup 0) (match_dup 1))]
12844 {
12845   rtx new_op1 = copy_rtx (operands[1]);
12846   operands[1] = new_op1;
12847   PUT_MODE (new_op1, QImode);
12848   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12849                                              GET_MODE (XEXP (new_op1, 0))));
12850
12851   /* Make sure that (a) the CCmode we have for the flags is strong
12852      enough for the reversed compare or (b) we have a valid FP compare.  */
12853   if (! ix86_comparison_operator (new_op1, VOIDmode))
12854     FAIL;
12855 })
12856
12857 (define_split 
12858   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12859         (eq:QI (match_operator 1 "ix86_comparison_operator"
12860                  [(reg 17) (const_int 0)])
12861             (const_int 0)))]
12862   ""
12863   [(set (match_dup 0) (match_dup 1))]
12864 {
12865   rtx new_op1 = copy_rtx (operands[1]);
12866   operands[1] = new_op1;
12867   PUT_MODE (new_op1, QImode);
12868   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12869                                              GET_MODE (XEXP (new_op1, 0))));
12870
12871   /* Make sure that (a) the CCmode we have for the flags is strong
12872      enough for the reversed compare or (b) we have a valid FP compare.  */
12873   if (! ix86_comparison_operator (new_op1, VOIDmode))
12874     FAIL;
12875 })
12876
12877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12878 ;; subsequent logical operations are used to imitate conditional moves.
12879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12880 ;; it directly.  Further holding this value in pseudo register might bring
12881 ;; problem in implicit normalization in spill code.
12882 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12883 ;; instructions after reload by splitting the conditional move patterns.
12884
12885 (define_insn "*sse_setccsf"
12886   [(set (match_operand:SF 0 "register_operand" "=x")
12887         (match_operator:SF 1 "sse_comparison_operator"
12888           [(match_operand:SF 2 "register_operand" "0")
12889            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12890   "TARGET_SSE && reload_completed"
12891   "cmp%D1ss\t{%3, %0|%0, %3}"
12892   [(set_attr "type" "ssecmp")
12893    (set_attr "mode" "SF")])
12894
12895 (define_insn "*sse_setccdf"
12896   [(set (match_operand:DF 0 "register_operand" "=Y")
12897         (match_operator:DF 1 "sse_comparison_operator"
12898           [(match_operand:DF 2 "register_operand" "0")
12899            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12900   "TARGET_SSE2 && reload_completed"
12901   "cmp%D1sd\t{%3, %0|%0, %3}"
12902   [(set_attr "type" "ssecmp")
12903    (set_attr "mode" "DF")])
12904 \f
12905 ;; Basic conditional jump instructions.
12906 ;; We ignore the overflow flag for signed branch instructions.
12907
12908 ;; For all bCOND expanders, also expand the compare or test insn that
12909 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12910
12911 (define_expand "beq"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (EQ, operands[0]); DONE;")
12918
12919 (define_expand "bne"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (NE, operands[0]); DONE;")
12926
12927 (define_expand "bgt"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (GT, operands[0]); DONE;")
12934
12935 (define_expand "bgtu"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (GTU, operands[0]); DONE;")
12942
12943 (define_expand "blt"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (LT, operands[0]); DONE;")
12950
12951 (define_expand "bltu"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (LTU, operands[0]); DONE;")
12958
12959 (define_expand "bge"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (GE, operands[0]); DONE;")
12966
12967 (define_expand "bgeu"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (GEU, operands[0]); DONE;")
12974
12975 (define_expand "ble"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (LE, operands[0]); DONE;")
12982
12983 (define_expand "bleu"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   ""
12989   "ix86_expand_branch (LEU, operands[0]); DONE;")
12990
12991 (define_expand "bunordered"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE"
12997   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12998
12999 (define_expand "bordered"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE"
13005   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13006
13007 (define_expand "buneq"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13014
13015 (define_expand "bunge"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13022
13023 (define_expand "bungt"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13030
13031 (define_expand "bunle"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE"
13037   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13038
13039 (define_expand "bunlt"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE"
13045   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13046
13047 (define_expand "bltgt"
13048   [(set (pc)
13049         (if_then_else (match_dup 1)
13050                       (label_ref (match_operand 0 "" ""))
13051                       (pc)))]
13052   "TARGET_80387 || TARGET_SSE"
13053   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13054
13055 (define_insn "*jcc_1"
13056   [(set (pc)
13057         (if_then_else (match_operator 1 "ix86_comparison_operator"
13058                                       [(reg 17) (const_int 0)])
13059                       (label_ref (match_operand 0 "" ""))
13060                       (pc)))]
13061   ""
13062   "%+j%C1\t%l0"
13063   [(set_attr "type" "ibr")
13064    (set_attr "modrm" "0")
13065    (set (attr "length")
13066            (if_then_else (and (ge (minus (match_dup 0) (pc))
13067                                   (const_int -126))
13068                               (lt (minus (match_dup 0) (pc))
13069                                   (const_int 128)))
13070              (const_int 2)
13071              (const_int 6)))])
13072
13073 (define_insn "*jcc_2"
13074   [(set (pc)
13075         (if_then_else (match_operator 1 "ix86_comparison_operator"
13076                                       [(reg 17) (const_int 0)])
13077                       (pc)
13078                       (label_ref (match_operand 0 "" ""))))]
13079   ""
13080   "%+j%c1\t%l0"
13081   [(set_attr "type" "ibr")
13082    (set_attr "modrm" "0")
13083    (set (attr "length")
13084            (if_then_else (and (ge (minus (match_dup 0) (pc))
13085                                   (const_int -126))
13086                               (lt (minus (match_dup 0) (pc))
13087                                   (const_int 128)))
13088              (const_int 2)
13089              (const_int 6)))])
13090
13091 ;; In general it is not safe to assume too much about CCmode registers,
13092 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13093 ;; conditions this is safe on x86, so help combine not create
13094 ;;
13095 ;;      seta    %al
13096 ;;      testb   %al, %al
13097 ;;      je      Lfoo
13098
13099 (define_split 
13100   [(set (pc)
13101         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13102                                       [(reg 17) (const_int 0)])
13103                           (const_int 0))
13104                       (label_ref (match_operand 1 "" ""))
13105                       (pc)))]
13106   ""
13107   [(set (pc)
13108         (if_then_else (match_dup 0)
13109                       (label_ref (match_dup 1))
13110                       (pc)))]
13111 {
13112   PUT_MODE (operands[0], VOIDmode);
13113 })
13114   
13115 (define_split 
13116   [(set (pc)
13117         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13118                                       [(reg 17) (const_int 0)])
13119                           (const_int 0))
13120                       (label_ref (match_operand 1 "" ""))
13121                       (pc)))]
13122   ""
13123   [(set (pc)
13124         (if_then_else (match_dup 0)
13125                       (label_ref (match_dup 1))
13126                       (pc)))]
13127 {
13128   rtx new_op0 = copy_rtx (operands[0]);
13129   operands[0] = new_op0;
13130   PUT_MODE (new_op0, VOIDmode);
13131   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13132                                              GET_MODE (XEXP (new_op0, 0))));
13133
13134   /* Make sure that (a) the CCmode we have for the flags is strong
13135      enough for the reversed compare or (b) we have a valid FP compare.  */
13136   if (! ix86_comparison_operator (new_op0, VOIDmode))
13137     FAIL;
13138 })
13139
13140 ;; Define combination compare-and-branch fp compare instructions to use
13141 ;; during early optimization.  Splitting the operation apart early makes
13142 ;; for bad code when we want to reverse the operation.
13143
13144 (define_insn "*fp_jcc_1"
13145   [(set (pc)
13146         (if_then_else (match_operator 0 "comparison_operator"
13147                         [(match_operand 1 "register_operand" "f")
13148                          (match_operand 2 "register_operand" "f")])
13149           (label_ref (match_operand 3 "" ""))
13150           (pc)))
13151    (clobber (reg:CCFP FPSR_REG))
13152    (clobber (reg:CCFP FLAGS_REG))]
13153   "TARGET_CMOVE && TARGET_80387
13154    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13155    && FLOAT_MODE_P (GET_MODE (operands[1]))
13156    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13157    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13158   "#")
13159
13160 (define_insn "*fp_jcc_1_sse"
13161   [(set (pc)
13162         (if_then_else (match_operator 0 "comparison_operator"
13163                         [(match_operand 1 "register_operand" "f#x,x#f")
13164                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13165           (label_ref (match_operand 3 "" ""))
13166           (pc)))
13167    (clobber (reg:CCFP FPSR_REG))
13168    (clobber (reg:CCFP FLAGS_REG))]
13169   "TARGET_80387
13170    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13171    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13172    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13173   "#")
13174
13175 (define_insn "*fp_jcc_1_sse_only"
13176   [(set (pc)
13177         (if_then_else (match_operator 0 "comparison_operator"
13178                         [(match_operand 1 "register_operand" "x")
13179                          (match_operand 2 "nonimmediate_operand" "xm")])
13180           (label_ref (match_operand 3 "" ""))
13181           (pc)))
13182    (clobber (reg:CCFP FPSR_REG))
13183    (clobber (reg:CCFP FLAGS_REG))]
13184   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13185    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13186    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13187   "#")
13188
13189 (define_insn "*fp_jcc_2"
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           (pc)
13195           (label_ref (match_operand 3 "" ""))))
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_2_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           (pc)
13211           (label_ref (match_operand 3 "" ""))))
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_2_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           (pc)
13226           (label_ref (match_operand 3 "" ""))))
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_3"
13235   [(set (pc)
13236         (if_then_else (match_operator 0 "comparison_operator"
13237                         [(match_operand 1 "register_operand" "f")
13238                          (match_operand 2 "nonimmediate_operand" "fm")])
13239           (label_ref (match_operand 3 "" ""))
13240           (pc)))
13241    (clobber (reg:CCFP FPSR_REG))
13242    (clobber (reg:CCFP FLAGS_REG))
13243    (clobber (match_scratch:HI 4 "=a"))]
13244   "TARGET_80387
13245    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13246    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13248    && SELECT_CC_MODE (GET_CODE (operands[0]),
13249                       operands[1], operands[2]) == CCFPmode
13250    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13251   "#")
13252
13253 (define_insn "*fp_jcc_4"
13254   [(set (pc)
13255         (if_then_else (match_operator 0 "comparison_operator"
13256                         [(match_operand 1 "register_operand" "f")
13257                          (match_operand 2 "nonimmediate_operand" "fm")])
13258           (pc)
13259           (label_ref (match_operand 3 "" ""))))
13260    (clobber (reg:CCFP FPSR_REG))
13261    (clobber (reg:CCFP FLAGS_REG))
13262    (clobber (match_scratch:HI 4 "=a"))]
13263   "TARGET_80387
13264    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13265    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13266    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13267    && SELECT_CC_MODE (GET_CODE (operands[0]),
13268                       operands[1], operands[2]) == CCFPmode
13269    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270   "#")
13271
13272 (define_insn "*fp_jcc_5"
13273   [(set (pc)
13274         (if_then_else (match_operator 0 "comparison_operator"
13275                         [(match_operand 1 "register_operand" "f")
13276                          (match_operand 2 "register_operand" "f")])
13277           (label_ref (match_operand 3 "" ""))
13278           (pc)))
13279    (clobber (reg:CCFP FPSR_REG))
13280    (clobber (reg:CCFP FLAGS_REG))
13281    (clobber (match_scratch:HI 4 "=a"))]
13282   "TARGET_80387
13283    && FLOAT_MODE_P (GET_MODE (operands[1]))
13284    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13285    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13286   "#")
13287
13288 (define_insn "*fp_jcc_6"
13289   [(set (pc)
13290         (if_then_else (match_operator 0 "comparison_operator"
13291                         [(match_operand 1 "register_operand" "f")
13292                          (match_operand 2 "register_operand" "f")])
13293           (pc)
13294           (label_ref (match_operand 3 "" ""))))
13295    (clobber (reg:CCFP FPSR_REG))
13296    (clobber (reg:CCFP FLAGS_REG))
13297    (clobber (match_scratch:HI 4 "=a"))]
13298   "TARGET_80387
13299    && FLOAT_MODE_P (GET_MODE (operands[1]))
13300    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13301    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13302   "#")
13303
13304 (define_insn "*fp_jcc_7"
13305   [(set (pc)
13306         (if_then_else (match_operator 0 "comparison_operator"
13307                         [(match_operand 1 "register_operand" "f")
13308                          (match_operand 2 "const_double_operand" "C")])
13309           (label_ref (match_operand 3 "" ""))
13310           (pc)))
13311    (clobber (reg:CCFP FPSR_REG))
13312    (clobber (reg:CCFP FLAGS_REG))
13313    (clobber (match_scratch:HI 4 "=a"))]
13314   "TARGET_80387
13315    && FLOAT_MODE_P (GET_MODE (operands[1]))
13316    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13317    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13318    && SELECT_CC_MODE (GET_CODE (operands[0]),
13319                       operands[1], operands[2]) == CCFPmode
13320    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13321   "#")
13322
13323 (define_split
13324   [(set (pc)
13325         (if_then_else (match_operator 0 "comparison_operator"
13326                         [(match_operand 1 "register_operand" "")
13327                          (match_operand 2 "nonimmediate_operand" "")])
13328           (match_operand 3 "" "")
13329           (match_operand 4 "" "")))
13330    (clobber (reg:CCFP FPSR_REG))
13331    (clobber (reg:CCFP FLAGS_REG))]
13332   "reload_completed"
13333   [(const_int 0)]
13334 {
13335   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13336                         operands[3], operands[4], NULL_RTX);
13337   DONE;
13338 })
13339
13340 (define_split
13341   [(set (pc)
13342         (if_then_else (match_operator 0 "comparison_operator"
13343                         [(match_operand 1 "register_operand" "")
13344                          (match_operand 2 "general_operand" "")])
13345           (match_operand 3 "" "")
13346           (match_operand 4 "" "")))
13347    (clobber (reg:CCFP FPSR_REG))
13348    (clobber (reg:CCFP FLAGS_REG))
13349    (clobber (match_scratch:HI 5 "=a"))]
13350   "reload_completed"
13351   [(const_int 0)]
13352 {
13353   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13354                         operands[3], operands[4], operands[5]);
13355   DONE;
13356 })
13357 \f
13358 ;; Unconditional and other jump instructions
13359
13360 (define_insn "jump"
13361   [(set (pc)
13362         (label_ref (match_operand 0 "" "")))]
13363   ""
13364   "jmp\t%l0"
13365   [(set_attr "type" "ibr")
13366    (set (attr "length")
13367            (if_then_else (and (ge (minus (match_dup 0) (pc))
13368                                   (const_int -126))
13369                               (lt (minus (match_dup 0) (pc))
13370                                   (const_int 128)))
13371              (const_int 2)
13372              (const_int 5)))
13373    (set_attr "modrm" "0")])
13374
13375 (define_expand "indirect_jump"
13376   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13377   ""
13378   "")
13379
13380 (define_insn "*indirect_jump"
13381   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13382   "!TARGET_64BIT"
13383   "jmp\t%A0"
13384   [(set_attr "type" "ibr")
13385    (set_attr "length_immediate" "0")])
13386
13387 (define_insn "*indirect_jump_rtx64"
13388   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13389   "TARGET_64BIT"
13390   "jmp\t%A0"
13391   [(set_attr "type" "ibr")
13392    (set_attr "length_immediate" "0")])
13393
13394 (define_expand "tablejump"
13395   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13396               (use (label_ref (match_operand 1 "" "")))])]
13397   ""
13398 {
13399   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13400      relative.  Convert the relative address to an absolute address.  */
13401   if (flag_pic)
13402     {
13403       rtx op0, op1;
13404       enum rtx_code code;
13405
13406       if (TARGET_64BIT)
13407         {
13408           code = PLUS;
13409           op0 = operands[0];
13410           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13411         }
13412       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13413         {
13414           code = PLUS;
13415           op0 = operands[0];
13416           op1 = pic_offset_table_rtx;
13417         }
13418       else
13419         {
13420           code = MINUS;
13421           op0 = pic_offset_table_rtx;
13422           op1 = operands[0];
13423         }
13424
13425       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13426                                          OPTAB_DIRECT);
13427     }
13428 })
13429
13430 (define_insn "*tablejump_1"
13431   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13432    (use (label_ref (match_operand 1 "" "")))]
13433   "!TARGET_64BIT"
13434   "jmp\t%A0"
13435   [(set_attr "type" "ibr")
13436    (set_attr "length_immediate" "0")])
13437
13438 (define_insn "*tablejump_1_rtx64"
13439   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13440    (use (label_ref (match_operand 1 "" "")))]
13441   "TARGET_64BIT"
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13445 \f
13446 ;; Loop instruction
13447 ;;
13448 ;; This is all complicated by the fact that since this is a jump insn
13449 ;; we must handle our own reloads.
13450
13451 (define_expand "doloop_end"
13452   [(use (match_operand 0 "" ""))        ; loop pseudo
13453    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13454    (use (match_operand 2 "" ""))        ; max iterations
13455    (use (match_operand 3 "" ""))        ; loop level 
13456    (use (match_operand 4 "" ""))]       ; label
13457   "!TARGET_64BIT && TARGET_USE_LOOP"
13458   "                                 
13459 {
13460   /* Only use cloop on innermost loops.  */
13461   if (INTVAL (operands[3]) > 1)
13462     FAIL;
13463   if (GET_MODE (operands[0]) != SImode)
13464     FAIL;
13465   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13466                                            operands[0]));
13467   DONE;
13468 }")
13469
13470 (define_insn "doloop_end_internal"
13471   [(set (pc)
13472         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13473                           (const_int 1))
13474                       (label_ref (match_operand 0 "" ""))
13475                       (pc)))
13476    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13477         (plus:SI (match_dup 1)
13478                  (const_int -1)))
13479    (clobber (match_scratch:SI 3 "=X,X,r"))
13480    (clobber (reg:CC FLAGS_REG))]
13481   "!TARGET_64BIT && TARGET_USE_LOOP
13482    && (reload_in_progress || reload_completed
13483        || register_operand (operands[2], VOIDmode))"
13484 {
13485   if (which_alternative != 0)
13486     return "#";
13487   if (get_attr_length (insn) == 2)
13488     return "%+loop\t%l0";
13489   else
13490     return "dec{l}\t%1\;%+jne\t%l0";
13491 }
13492   [(set (attr "length")
13493         (if_then_else (and (eq_attr "alternative" "0")
13494                            (and (ge (minus (match_dup 0) (pc))
13495                                     (const_int -126))
13496                                 (lt (minus (match_dup 0) (pc))
13497                                     (const_int 128))))
13498                       (const_int 2)
13499                       (const_int 16)))
13500    ;; We don't know the type before shorten branches.  Optimistically expect
13501    ;; the loop instruction to match.
13502    (set (attr "type") (const_string "ibr"))])
13503
13504 (define_split
13505   [(set (pc)
13506         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13507                           (const_int 1))
13508                       (match_operand 0 "" "")
13509                       (pc)))
13510    (set (match_dup 1)
13511         (plus:SI (match_dup 1)
13512                  (const_int -1)))
13513    (clobber (match_scratch:SI 2 ""))
13514    (clobber (reg:CC FLAGS_REG))]
13515   "!TARGET_64BIT && TARGET_USE_LOOP
13516    && reload_completed
13517    && REGNO (operands[1]) != 2"
13518   [(parallel [(set (reg:CCZ FLAGS_REG)
13519                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13520                                  (const_int 0)))
13521               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13522    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13523                            (match_dup 0)
13524                            (pc)))]
13525   "")
13526   
13527 (define_split
13528   [(set (pc)
13529         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13530                           (const_int 1))
13531                       (match_operand 0 "" "")
13532                       (pc)))
13533    (set (match_operand:SI 2 "nonimmediate_operand" "")
13534         (plus:SI (match_dup 1)
13535                  (const_int -1)))
13536    (clobber (match_scratch:SI 3 ""))
13537    (clobber (reg:CC FLAGS_REG))]
13538   "!TARGET_64BIT && TARGET_USE_LOOP
13539    && reload_completed
13540    && (! REG_P (operands[2])
13541        || ! rtx_equal_p (operands[1], operands[2]))"
13542   [(set (match_dup 3) (match_dup 1))
13543    (parallel [(set (reg:CCZ FLAGS_REG)
13544                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13545                                 (const_int 0)))
13546               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13547    (set (match_dup 2) (match_dup 3))
13548    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13549                            (match_dup 0)
13550                            (pc)))]
13551   "")
13552
13553 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13554
13555 (define_peephole2
13556   [(set (reg 17) (match_operand 0 "" ""))
13557    (set (match_operand:QI 1 "register_operand" "")
13558         (match_operator:QI 2 "ix86_comparison_operator"
13559           [(reg 17) (const_int 0)]))
13560    (set (match_operand 3 "q_regs_operand" "")
13561         (zero_extend (match_dup 1)))]
13562   "(peep2_reg_dead_p (3, operands[1])
13563     || operands_match_p (operands[1], operands[3]))
13564    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13565   [(set (match_dup 4) (match_dup 0))
13566    (set (strict_low_part (match_dup 5))
13567         (match_dup 2))]
13568 {
13569   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13570   operands[5] = gen_lowpart (QImode, operands[3]);
13571   ix86_expand_clear (operands[3]);
13572 })
13573
13574 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13575
13576 (define_peephole2
13577   [(set (reg 17) (match_operand 0 "" ""))
13578    (set (match_operand:QI 1 "register_operand" "")
13579         (match_operator:QI 2 "ix86_comparison_operator"
13580           [(reg 17) (const_int 0)]))
13581    (parallel [(set (match_operand 3 "q_regs_operand" "")
13582                    (zero_extend (match_dup 1)))
13583               (clobber (reg:CC FLAGS_REG))])]
13584   "(peep2_reg_dead_p (3, operands[1])
13585     || operands_match_p (operands[1], operands[3]))
13586    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13587   [(set (match_dup 4) (match_dup 0))
13588    (set (strict_low_part (match_dup 5))
13589         (match_dup 2))]
13590 {
13591   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13592   operands[5] = gen_lowpart (QImode, operands[3]);
13593   ix86_expand_clear (operands[3]);
13594 })
13595 \f
13596 ;; Call instructions.
13597
13598 ;; The predicates normally associated with named expanders are not properly
13599 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13600 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13601
13602 ;; Call subroutine returning no value.
13603
13604 (define_expand "call_pop"
13605   [(parallel [(call (match_operand:QI 0 "" "")
13606                     (match_operand:SI 1 "" ""))
13607               (set (reg:SI SP_REG)
13608                    (plus:SI (reg:SI SP_REG)
13609                             (match_operand:SI 3 "" "")))])]
13610   "!TARGET_64BIT"
13611 {
13612   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13613   DONE;
13614 })
13615
13616 (define_insn "*call_pop_0"
13617   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13618          (match_operand:SI 1 "" ""))
13619    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13620                             (match_operand:SI 2 "immediate_operand" "")))]
13621   "!TARGET_64BIT"
13622 {
13623   if (SIBLING_CALL_P (insn))
13624     return "jmp\t%P0";
13625   else
13626     return "call\t%P0";
13627 }
13628   [(set_attr "type" "call")])
13629   
13630 (define_insn "*call_pop_1"
13631   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13632          (match_operand:SI 1 "" ""))
13633    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13634                             (match_operand:SI 2 "immediate_operand" "i")))]
13635   "!TARGET_64BIT"
13636 {
13637   if (constant_call_address_operand (operands[0], Pmode))
13638     {
13639       if (SIBLING_CALL_P (insn))
13640         return "jmp\t%P0";
13641       else
13642         return "call\t%P0";
13643     }
13644   if (SIBLING_CALL_P (insn))
13645     return "jmp\t%A0";
13646   else
13647     return "call\t%A0";
13648 }
13649   [(set_attr "type" "call")])
13650
13651 (define_expand "call"
13652   [(call (match_operand:QI 0 "" "")
13653          (match_operand 1 "" ""))
13654    (use (match_operand 2 "" ""))]
13655   ""
13656 {
13657   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13658   DONE;
13659 })
13660
13661 (define_expand "sibcall"
13662   [(call (match_operand:QI 0 "" "")
13663          (match_operand 1 "" ""))
13664    (use (match_operand 2 "" ""))]
13665   ""
13666 {
13667   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13668   DONE;
13669 })
13670
13671 (define_insn "*call_0"
13672   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13673          (match_operand 1 "" ""))]
13674   ""
13675 {
13676   if (SIBLING_CALL_P (insn))
13677     return "jmp\t%P0";
13678   else
13679     return "call\t%P0";
13680 }
13681   [(set_attr "type" "call")])
13682
13683 (define_insn "*call_1"
13684   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13685          (match_operand 1 "" ""))]
13686   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13687 {
13688   if (constant_call_address_operand (operands[0], Pmode))
13689     return "call\t%P0";
13690   return "call\t%A0";
13691 }
13692   [(set_attr "type" "call")])
13693
13694 (define_insn "*sibcall_1"
13695   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13696          (match_operand 1 "" ""))]
13697   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13698 {
13699   if (constant_call_address_operand (operands[0], Pmode))
13700     return "jmp\t%P0";
13701   return "jmp\t%A0";
13702 }
13703   [(set_attr "type" "call")])
13704
13705 (define_insn "*call_1_rex64"
13706   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13707          (match_operand 1 "" ""))]
13708   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13709 {
13710   if (constant_call_address_operand (operands[0], Pmode))
13711     return "call\t%P0";
13712   return "call\t%A0";
13713 }
13714   [(set_attr "type" "call")])
13715
13716 (define_insn "*sibcall_1_rex64"
13717   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13718          (match_operand 1 "" ""))]
13719   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13720   "jmp\t%P0"
13721   [(set_attr "type" "call")])
13722
13723 (define_insn "*sibcall_1_rex64_v"
13724   [(call (mem:QI (reg:DI 40))
13725          (match_operand 0 "" ""))]
13726   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13727   "jmp\t*%%r11"
13728   [(set_attr "type" "call")])
13729
13730
13731 ;; Call subroutine, returning value in operand 0
13732
13733 (define_expand "call_value_pop"
13734   [(parallel [(set (match_operand 0 "" "")
13735                    (call (match_operand:QI 1 "" "")
13736                          (match_operand:SI 2 "" "")))
13737               (set (reg:SI SP_REG)
13738                    (plus:SI (reg:SI SP_REG)
13739                             (match_operand:SI 4 "" "")))])]
13740   "!TARGET_64BIT"
13741 {
13742   ix86_expand_call (operands[0], operands[1], operands[2],
13743                     operands[3], operands[4], 0);
13744   DONE;
13745 })
13746
13747 (define_expand "call_value"
13748   [(set (match_operand 0 "" "")
13749         (call (match_operand:QI 1 "" "")
13750               (match_operand:SI 2 "" "")))
13751    (use (match_operand:SI 3 "" ""))]
13752   ;; Operand 2 not used on the i386.
13753   ""
13754 {
13755   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13756   DONE;
13757 })
13758
13759 (define_expand "sibcall_value"
13760   [(set (match_operand 0 "" "")
13761         (call (match_operand:QI 1 "" "")
13762               (match_operand:SI 2 "" "")))
13763    (use (match_operand:SI 3 "" ""))]
13764   ;; Operand 2 not used on the i386.
13765   ""
13766 {
13767   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13768   DONE;
13769 })
13770
13771 ;; Call subroutine returning any type.
13772
13773 (define_expand "untyped_call"
13774   [(parallel [(call (match_operand 0 "" "")
13775                     (const_int 0))
13776               (match_operand 1 "" "")
13777               (match_operand 2 "" "")])]
13778   ""
13779 {
13780   int i;
13781
13782   /* In order to give reg-stack an easier job in validating two
13783      coprocessor registers as containing a possible return value,
13784      simply pretend the untyped call returns a complex long double
13785      value.  */
13786
13787   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13788                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13789                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13790                     NULL, 0);
13791
13792   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13793     {
13794       rtx set = XVECEXP (operands[2], 0, i);
13795       emit_move_insn (SET_DEST (set), SET_SRC (set));
13796     }
13797
13798   /* The optimizer does not know that the call sets the function value
13799      registers we stored in the result block.  We avoid problems by
13800      claiming that all hard registers are used and clobbered at this
13801      point.  */
13802   emit_insn (gen_blockage (const0_rtx));
13803
13804   DONE;
13805 })
13806 \f
13807 ;; Prologue and epilogue instructions
13808
13809 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13810 ;; all of memory.  This blocks insns from being moved across this point.
13811
13812 (define_insn "blockage"
13813   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13814   ""
13815   ""
13816   [(set_attr "length" "0")])
13817
13818 ;; Insn emitted into the body of a function to return from a function.
13819 ;; This is only done if the function's epilogue is known to be simple.
13820 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13821
13822 (define_expand "return"
13823   [(return)]
13824   "ix86_can_use_return_insn_p ()"
13825 {
13826   if (current_function_pops_args)
13827     {
13828       rtx popc = GEN_INT (current_function_pops_args);
13829       emit_jump_insn (gen_return_pop_internal (popc));
13830       DONE;
13831     }
13832 })
13833
13834 (define_insn "return_internal"
13835   [(return)]
13836   "reload_completed"
13837   "ret"
13838   [(set_attr "length" "1")
13839    (set_attr "length_immediate" "0")
13840    (set_attr "modrm" "0")])
13841
13842 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13843 ;; instruction Athlon and K8 have.
13844
13845 (define_insn "return_internal_long"
13846   [(return)
13847    (unspec [(const_int 0)] UNSPEC_REP)]
13848   "reload_completed"
13849   "rep {;} ret"
13850   [(set_attr "length" "1")
13851    (set_attr "length_immediate" "0")
13852    (set_attr "prefix_rep" "1")
13853    (set_attr "modrm" "0")])
13854
13855 (define_insn "return_pop_internal"
13856   [(return)
13857    (use (match_operand:SI 0 "const_int_operand" ""))]
13858   "reload_completed"
13859   "ret\t%0"
13860   [(set_attr "length" "3")
13861    (set_attr "length_immediate" "2")
13862    (set_attr "modrm" "0")])
13863
13864 (define_insn "return_indirect_internal"
13865   [(return)
13866    (use (match_operand:SI 0 "register_operand" "r"))]
13867   "reload_completed"
13868   "jmp\t%A0"
13869   [(set_attr "type" "ibr")
13870    (set_attr "length_immediate" "0")])
13871
13872 (define_insn "nop"
13873   [(const_int 0)]
13874   ""
13875   "nop"
13876   [(set_attr "length" "1")
13877    (set_attr "length_immediate" "0")
13878    (set_attr "modrm" "0")])
13879
13880 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13881 ;; branch prediction penalty for the third jump in a 16-byte
13882 ;; block on K8.
13883
13884 (define_insn "align"
13885   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13886   ""
13887 {
13888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13889   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13890 #else
13891   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13892      The align insn is used to avoid 3 jump instructions in the row to improve
13893      branch prediction and the benefits hardly outweight the cost of extra 8
13894      nops on the average inserted by full alignment pseudo operation.  */
13895 #endif
13896   return "";
13897 }
13898   [(set_attr "length" "16")])
13899
13900 (define_expand "prologue"
13901   [(const_int 1)]
13902   ""
13903   "ix86_expand_prologue (); DONE;")
13904
13905 (define_insn "set_got"
13906   [(set (match_operand:SI 0 "register_operand" "=r")
13907         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13908    (clobber (reg:CC FLAGS_REG))]
13909   "!TARGET_64BIT"
13910   { return output_set_got (operands[0]); }
13911   [(set_attr "type" "multi")
13912    (set_attr "length" "12")])
13913
13914 (define_expand "epilogue"
13915   [(const_int 1)]
13916   ""
13917   "ix86_expand_epilogue (1); DONE;")
13918
13919 (define_expand "sibcall_epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (0); DONE;")
13923
13924 (define_expand "eh_return"
13925   [(use (match_operand 0 "register_operand" ""))]
13926   ""
13927 {
13928   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13929
13930   /* Tricky bit: we write the address of the handler to which we will
13931      be returning into someone else's stack frame, one word below the
13932      stack address we wish to restore.  */
13933   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13934   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13935   tmp = gen_rtx_MEM (Pmode, tmp);
13936   emit_move_insn (tmp, ra);
13937
13938   if (Pmode == SImode)
13939     emit_jump_insn (gen_eh_return_si (sa));
13940   else
13941     emit_jump_insn (gen_eh_return_di (sa));
13942   emit_barrier ();
13943   DONE;
13944 })
13945
13946 (define_insn_and_split "eh_return_si"
13947   [(set (pc) 
13948         (unspec [(match_operand:SI 0 "register_operand" "c")]
13949                  UNSPEC_EH_RETURN))]
13950   "!TARGET_64BIT"
13951   "#"
13952   "reload_completed"
13953   [(const_int 1)]
13954   "ix86_expand_epilogue (2); DONE;")
13955
13956 (define_insn_and_split "eh_return_di"
13957   [(set (pc) 
13958         (unspec [(match_operand:DI 0 "register_operand" "c")]
13959                  UNSPEC_EH_RETURN))]
13960   "TARGET_64BIT"
13961   "#"
13962   "reload_completed"
13963   [(const_int 1)]
13964   "ix86_expand_epilogue (2); DONE;")
13965
13966 (define_insn "leave"
13967   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13968    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13969    (clobber (mem:BLK (scratch)))]
13970   "!TARGET_64BIT"
13971   "leave"
13972   [(set_attr "type" "leave")])
13973
13974 (define_insn "leave_rex64"
13975   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13976    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13977    (clobber (mem:BLK (scratch)))]
13978   "TARGET_64BIT"
13979   "leave"
13980   [(set_attr "type" "leave")])
13981 \f
13982 (define_expand "ffssi2"
13983   [(parallel
13984      [(set (match_operand:SI 0 "register_operand" "") 
13985            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13986       (clobber (match_scratch:SI 2 ""))
13987       (clobber (reg:CC FLAGS_REG))])]
13988   ""
13989   "")
13990
13991 (define_insn_and_split "*ffs_cmove"
13992   [(set (match_operand:SI 0 "register_operand" "=r") 
13993         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13994    (clobber (match_scratch:SI 2 "=&r"))
13995    (clobber (reg:CC FLAGS_REG))]
13996   "TARGET_CMOVE"
13997   "#"
13998   "&& reload_completed"
13999   [(set (match_dup 2) (const_int -1))
14000    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14001               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14002    (set (match_dup 0) (if_then_else:SI
14003                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14004                         (match_dup 2)
14005                         (match_dup 0)))
14006    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14007               (clobber (reg:CC FLAGS_REG))])]
14008   "")
14009
14010 (define_insn_and_split "*ffs_no_cmove"
14011   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14012         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14013    (clobber (match_scratch:SI 2 "=&q"))
14014    (clobber (reg:CC FLAGS_REG))]
14015   ""
14016   "#"
14017   "reload_completed"
14018   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14019               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14020    (set (strict_low_part (match_dup 3))
14021         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14022    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14023               (clobber (reg:CC FLAGS_REG))])
14024    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14025               (clobber (reg:CC FLAGS_REG))])
14026    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14027               (clobber (reg:CC FLAGS_REG))])]
14028 {
14029   operands[3] = gen_lowpart (QImode, operands[2]);
14030   ix86_expand_clear (operands[2]);
14031 })
14032
14033 (define_insn "*ffssi_1"
14034   [(set (reg:CCZ FLAGS_REG)
14035         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14036                      (const_int 0)))
14037    (set (match_operand:SI 0 "register_operand" "=r")
14038         (ctz:SI (match_dup 1)))]
14039   ""
14040   "bsf{l}\t{%1, %0|%0, %1}"
14041   [(set_attr "prefix_0f" "1")])
14042
14043 (define_expand "ffsdi2"
14044   [(parallel
14045      [(set (match_operand:DI 0 "register_operand" "") 
14046            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14047       (clobber (match_scratch:DI 2 ""))
14048       (clobber (reg:CC 17))])]
14049   "TARGET_64BIT && TARGET_CMOVE"
14050   "")
14051
14052 (define_insn_and_split "*ffs_rex64"
14053   [(set (match_operand:DI 0 "register_operand" "=r") 
14054         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14055    (clobber (match_scratch:DI 2 "=&r"))
14056    (clobber (reg:CC 17))]
14057   "TARGET_64BIT && TARGET_CMOVE"
14058   "#"
14059   "&& reload_completed"
14060   [(set (match_dup 2) (const_int -1))
14061    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14062               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14063    (set (match_dup 0) (if_then_else:DI
14064                         (eq (reg:CCZ 17) (const_int 0))
14065                         (match_dup 2)
14066                         (match_dup 0)))
14067    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14068               (clobber (reg:CC 17))])]
14069   "")
14070
14071 (define_insn "*ffsdi_1"
14072   [(set (reg:CCZ 17)
14073         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14074                      (const_int 0)))
14075    (set (match_operand:DI 0 "register_operand" "=r")
14076         (ctz:DI (match_dup 1)))]
14077   "TARGET_64BIT"
14078   "bsf{q}\t{%1, %0|%0, %1}"
14079   [(set_attr "prefix_0f" "1")])
14080
14081 (define_insn "ctzsi2"
14082   [(set (match_operand:SI 0 "register_operand" "=r")
14083         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14084    (clobber (reg:CC FLAGS_REG))]
14085   ""
14086   "bsf{l}\t{%1, %0|%0, %1}"
14087   [(set_attr "prefix_0f" "1")])
14088
14089 (define_insn "ctzdi2"
14090   [(set (match_operand:DI 0 "register_operand" "=r")
14091         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14092    (clobber (reg:CC 17))]
14093   "TARGET_64BIT"
14094   "bsf{q}\t{%1, %0|%0, %1}"
14095   [(set_attr "prefix_0f" "1")])
14096
14097 (define_expand "clzsi2"
14098   [(parallel
14099      [(set (match_operand:SI 0 "register_operand" "")
14100            (minus:SI (const_int 31)
14101                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14102       (clobber (reg:CC FLAGS_REG))])
14103    (parallel
14104      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14105       (clobber (reg:CC FLAGS_REG))])]
14106   ""
14107   "")
14108
14109 (define_insn "*bsr"
14110   [(set (match_operand:SI 0 "register_operand" "=r")
14111         (minus:SI (const_int 31)
14112                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14113    (clobber (reg:CC FLAGS_REG))]
14114   ""
14115   "bsr{l}\t{%1, %0|%0, %1}"
14116   [(set_attr "prefix_0f" "1")])
14117
14118 (define_expand "clzdi2"
14119   [(parallel
14120      [(set (match_operand:DI 0 "register_operand" "")
14121            (minus:DI (const_int 63)
14122                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14123       (clobber (reg:CC 17))])
14124    (parallel
14125      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14126       (clobber (reg:CC 17))])]
14127   "TARGET_64BIT"
14128   "")
14129
14130 (define_insn "*bsr_rex64"
14131   [(set (match_operand:DI 0 "register_operand" "=r")
14132         (minus:DI (const_int 63)
14133                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14134    (clobber (reg:CC 17))]
14135   "TARGET_64BIT"
14136   "bsr{q}\t{%1, %0|%0, %1}"
14137   [(set_attr "prefix_0f" "1")])
14138 \f
14139 ;; Thread-local storage patterns for ELF.
14140 ;;
14141 ;; Note that these code sequences must appear exactly as shown
14142 ;; in order to allow linker relaxation.
14143
14144 (define_insn "*tls_global_dynamic_32_gnu"
14145   [(set (match_operand:SI 0 "register_operand" "=a")
14146         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14147                     (match_operand:SI 2 "tls_symbolic_operand" "")
14148                     (match_operand:SI 3 "call_insn_operand" "")]
14149                     UNSPEC_TLS_GD))
14150    (clobber (match_scratch:SI 4 "=d"))
14151    (clobber (match_scratch:SI 5 "=c"))
14152    (clobber (reg:CC FLAGS_REG))]
14153   "!TARGET_64BIT && TARGET_GNU_TLS"
14154   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14155   [(set_attr "type" "multi")
14156    (set_attr "length" "12")])
14157
14158 (define_insn "*tls_global_dynamic_32_sun"
14159   [(set (match_operand:SI 0 "register_operand" "=a")
14160         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14161                     (match_operand:SI 2 "tls_symbolic_operand" "")
14162                     (match_operand:SI 3 "call_insn_operand" "")]
14163                     UNSPEC_TLS_GD))
14164    (clobber (match_scratch:SI 4 "=d"))
14165    (clobber (match_scratch:SI 5 "=c"))
14166    (clobber (reg:CC FLAGS_REG))]
14167   "!TARGET_64BIT && TARGET_SUN_TLS"
14168   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14169         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14170   [(set_attr "type" "multi")
14171    (set_attr "length" "14")])
14172
14173 (define_expand "tls_global_dynamic_32"
14174   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14175                    (unspec:SI
14176                     [(match_dup 2)
14177                      (match_operand:SI 1 "tls_symbolic_operand" "")
14178                      (match_dup 3)]
14179                     UNSPEC_TLS_GD))
14180               (clobber (match_scratch:SI 4 ""))
14181               (clobber (match_scratch:SI 5 ""))
14182               (clobber (reg:CC FLAGS_REG))])]
14183   ""
14184 {
14185   if (flag_pic)
14186     operands[2] = pic_offset_table_rtx;
14187   else
14188     {
14189       operands[2] = gen_reg_rtx (Pmode);
14190       emit_insn (gen_set_got (operands[2]));
14191     }
14192   operands[3] = ix86_tls_get_addr ();
14193 })
14194
14195 (define_insn "*tls_global_dynamic_64"
14196   [(set (match_operand:DI 0 "register_operand" "=a")
14197         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14198                       (match_operand:DI 3 "" "")))
14199    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14200               UNSPEC_TLS_GD)]
14201   "TARGET_64BIT"
14202   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14203   [(set_attr "type" "multi")
14204    (set_attr "length" "16")])
14205
14206 (define_expand "tls_global_dynamic_64"
14207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14208                    (call (mem:QI (match_dup 2)) (const_int 0)))
14209               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14210                          UNSPEC_TLS_GD)])]
14211   ""
14212 {
14213   operands[2] = ix86_tls_get_addr ();
14214 })
14215
14216 (define_insn "*tls_local_dynamic_base_32_gnu"
14217   [(set (match_operand:SI 0 "register_operand" "=a")
14218         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14219                     (match_operand:SI 2 "call_insn_operand" "")]
14220                    UNSPEC_TLS_LD_BASE))
14221    (clobber (match_scratch:SI 3 "=d"))
14222    (clobber (match_scratch:SI 4 "=c"))
14223    (clobber (reg:CC FLAGS_REG))]
14224   "!TARGET_64BIT && TARGET_GNU_TLS"
14225   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14226   [(set_attr "type" "multi")
14227    (set_attr "length" "11")])
14228
14229 (define_insn "*tls_local_dynamic_base_32_sun"
14230   [(set (match_operand:SI 0 "register_operand" "=a")
14231         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14232                     (match_operand:SI 2 "call_insn_operand" "")]
14233                    UNSPEC_TLS_LD_BASE))
14234    (clobber (match_scratch:SI 3 "=d"))
14235    (clobber (match_scratch:SI 4 "=c"))
14236    (clobber (reg:CC FLAGS_REG))]
14237   "!TARGET_64BIT && TARGET_SUN_TLS"
14238   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14239         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14240   [(set_attr "type" "multi")
14241    (set_attr "length" "13")])
14242
14243 (define_expand "tls_local_dynamic_base_32"
14244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14245                    (unspec:SI [(match_dup 1) (match_dup 2)]
14246                               UNSPEC_TLS_LD_BASE))
14247               (clobber (match_scratch:SI 3 ""))
14248               (clobber (match_scratch:SI 4 ""))
14249               (clobber (reg:CC FLAGS_REG))])]
14250   ""
14251 {
14252   if (flag_pic)
14253     operands[1] = pic_offset_table_rtx;
14254   else
14255     {
14256       operands[1] = gen_reg_rtx (Pmode);
14257       emit_insn (gen_set_got (operands[1]));
14258     }
14259   operands[2] = ix86_tls_get_addr ();
14260 })
14261
14262 (define_insn "*tls_local_dynamic_base_64"
14263   [(set (match_operand:DI 0 "register_operand" "=a")
14264         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14265                       (match_operand:DI 2 "" "")))
14266    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14267   "TARGET_64BIT"
14268   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14269   [(set_attr "type" "multi")
14270    (set_attr "length" "12")])
14271
14272 (define_expand "tls_local_dynamic_base_64"
14273   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14274                    (call (mem:QI (match_dup 1)) (const_int 0)))
14275               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14276   ""
14277 {
14278   operands[1] = ix86_tls_get_addr ();
14279 })
14280
14281 ;; Local dynamic of a single variable is a lose.  Show combine how
14282 ;; to convert that back to global dynamic.
14283
14284 (define_insn_and_split "*tls_local_dynamic_32_once"
14285   [(set (match_operand:SI 0 "register_operand" "=a")
14286         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14287                              (match_operand:SI 2 "call_insn_operand" "")]
14288                             UNSPEC_TLS_LD_BASE)
14289                  (const:SI (unspec:SI
14290                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14291                             UNSPEC_DTPOFF))))
14292    (clobber (match_scratch:SI 4 "=d"))
14293    (clobber (match_scratch:SI 5 "=c"))
14294    (clobber (reg:CC FLAGS_REG))]
14295   ""
14296   "#"
14297   ""
14298   [(parallel [(set (match_dup 0)
14299                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14300                               UNSPEC_TLS_GD))
14301               (clobber (match_dup 4))
14302               (clobber (match_dup 5))
14303               (clobber (reg:CC FLAGS_REG))])]
14304   "")
14305
14306 ;; Load and add the thread base pointer from %gs:0.
14307
14308 (define_insn "*load_tp_si"
14309   [(set (match_operand:SI 0 "register_operand" "=r")
14310         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14311   "!TARGET_64BIT"
14312   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14313   [(set_attr "type" "imov")
14314    (set_attr "modrm" "0")
14315    (set_attr "length" "7")
14316    (set_attr "memory" "load")
14317    (set_attr "imm_disp" "false")])
14318
14319 (define_insn "*add_tp_si"
14320   [(set (match_operand:SI 0 "register_operand" "=r")
14321         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14322                  (match_operand:SI 1 "register_operand" "0")))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "!TARGET_64BIT"
14325   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14326   [(set_attr "type" "alu")
14327    (set_attr "modrm" "0")
14328    (set_attr "length" "7")
14329    (set_attr "memory" "load")
14330    (set_attr "imm_disp" "false")])
14331
14332 (define_insn "*load_tp_di"
14333   [(set (match_operand:DI 0 "register_operand" "=r")
14334         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14335   "TARGET_64BIT"
14336   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14337   [(set_attr "type" "imov")
14338    (set_attr "modrm" "0")
14339    (set_attr "length" "7")
14340    (set_attr "memory" "load")
14341    (set_attr "imm_disp" "false")])
14342
14343 (define_insn "*add_tp_di"
14344   [(set (match_operand:DI 0 "register_operand" "=r")
14345         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14346                  (match_operand:DI 1 "register_operand" "0")))
14347    (clobber (reg:CC FLAGS_REG))]
14348   "TARGET_64BIT"
14349   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14350   [(set_attr "type" "alu")
14351    (set_attr "modrm" "0")
14352    (set_attr "length" "7")
14353    (set_attr "memory" "load")
14354    (set_attr "imm_disp" "false")])
14355 \f
14356 ;; These patterns match the binary 387 instructions for addM3, subM3,
14357 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14358 ;; SFmode.  The first is the normal insn, the second the same insn but
14359 ;; with one operand a conversion, and the third the same insn but with
14360 ;; the other operand a conversion.  The conversion may be SFmode or
14361 ;; SImode if the target mode DFmode, but only SImode if the target mode
14362 ;; is SFmode.
14363
14364 ;; Gcc is slightly more smart about handling normal two address instructions
14365 ;; so use special patterns for add and mull.
14366 (define_insn "*fop_sf_comm_nosse"
14367   [(set (match_operand:SF 0 "register_operand" "=f")
14368         (match_operator:SF 3 "binary_fp_operator"
14369                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14370                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14371   "TARGET_80387 && !TARGET_SSE_MATH
14372    && COMMUTATIVE_ARITH_P (operands[3])
14373    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374   "* return output_387_binary_op (insn, operands);"
14375   [(set (attr "type") 
14376         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14377            (const_string "fmul")
14378            (const_string "fop")))
14379    (set_attr "mode" "SF")])
14380
14381 (define_insn "*fop_sf_comm"
14382   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14383         (match_operator:SF 3 "binary_fp_operator"
14384                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14385                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14386   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14387    && COMMUTATIVE_ARITH_P (operands[3])
14388    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14389   "* return output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (if_then_else (eq_attr "alternative" "1")
14392            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14393               (const_string "ssemul")
14394               (const_string "sseadd"))
14395            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14396               (const_string "fmul")
14397               (const_string "fop"))))
14398    (set_attr "mode" "SF")])
14399
14400 (define_insn "*fop_sf_comm_sse"
14401   [(set (match_operand:SF 0 "register_operand" "=x")
14402         (match_operator:SF 3 "binary_fp_operator"
14403                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14404                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14405   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14406    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407   "* return output_387_binary_op (insn, operands);"
14408   [(set (attr "type") 
14409         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14410            (const_string "ssemul")
14411            (const_string "sseadd")))
14412    (set_attr "mode" "SF")])
14413
14414 (define_insn "*fop_df_comm_nosse"
14415   [(set (match_operand:DF 0 "register_operand" "=f")
14416         (match_operator:DF 3 "binary_fp_operator"
14417                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14418                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14419   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14420    && COMMUTATIVE_ARITH_P (operands[3])
14421    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422   "* return output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14425            (const_string "fmul")
14426            (const_string "fop")))
14427    (set_attr "mode" "DF")])
14428
14429 (define_insn "*fop_df_comm"
14430   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14431         (match_operator:DF 3 "binary_fp_operator"
14432                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14433                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14434   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14435    && COMMUTATIVE_ARITH_P (operands[3])
14436    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14437   "* return output_387_binary_op (insn, operands);"
14438   [(set (attr "type") 
14439         (if_then_else (eq_attr "alternative" "1")
14440            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14441               (const_string "ssemul")
14442               (const_string "sseadd"))
14443            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14444               (const_string "fmul")
14445               (const_string "fop"))))
14446    (set_attr "mode" "DF")])
14447
14448 (define_insn "*fop_df_comm_sse"
14449   [(set (match_operand:DF 0 "register_operand" "=Y")
14450         (match_operator:DF 3 "binary_fp_operator"
14451                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14452                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14453   "TARGET_SSE2 && TARGET_SSE_MATH
14454    && COMMUTATIVE_ARITH_P (operands[3])
14455    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14456   "* return output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14459            (const_string "ssemul")
14460            (const_string "sseadd")))
14461    (set_attr "mode" "DF")])
14462
14463 (define_insn "*fop_xf_comm"
14464   [(set (match_operand:XF 0 "register_operand" "=f")
14465         (match_operator:XF 3 "binary_fp_operator"
14466                         [(match_operand:XF 1 "register_operand" "%0")
14467                          (match_operand:XF 2 "register_operand" "f")]))]
14468   "TARGET_80387
14469    && COMMUTATIVE_ARITH_P (operands[3])"
14470   "* return output_387_binary_op (insn, operands);"
14471   [(set (attr "type") 
14472         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14473            (const_string "fmul")
14474            (const_string "fop")))
14475    (set_attr "mode" "XF")])
14476
14477 (define_insn "*fop_sf_1_nosse"
14478   [(set (match_operand:SF 0 "register_operand" "=f,f")
14479         (match_operator:SF 3 "binary_fp_operator"
14480                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14481                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14482   "TARGET_80387 && !TARGET_SSE_MATH
14483    && !COMMUTATIVE_ARITH_P (operands[3])
14484    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14485   "* return output_387_binary_op (insn, operands);"
14486   [(set (attr "type") 
14487         (cond [(match_operand:SF 3 "mult_operator" "") 
14488                  (const_string "fmul")
14489                (match_operand:SF 3 "div_operator" "") 
14490                  (const_string "fdiv")
14491               ]
14492               (const_string "fop")))
14493    (set_attr "mode" "SF")])
14494
14495 (define_insn "*fop_sf_1"
14496   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14497         (match_operator:SF 3 "binary_fp_operator"
14498                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14499                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14500   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14501    && !COMMUTATIVE_ARITH_P (operands[3])
14502    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14503   "* return output_387_binary_op (insn, operands);"
14504   [(set (attr "type") 
14505         (cond [(and (eq_attr "alternative" "2")
14506                     (match_operand:SF 3 "mult_operator" ""))
14507                  (const_string "ssemul")
14508                (and (eq_attr "alternative" "2")
14509                     (match_operand:SF 3 "div_operator" ""))
14510                  (const_string "ssediv")
14511                (eq_attr "alternative" "2")
14512                  (const_string "sseadd")
14513                (match_operand:SF 3 "mult_operator" "") 
14514                  (const_string "fmul")
14515                (match_operand:SF 3 "div_operator" "") 
14516                  (const_string "fdiv")
14517               ]
14518               (const_string "fop")))
14519    (set_attr "mode" "SF")])
14520
14521 (define_insn "*fop_sf_1_sse"
14522   [(set (match_operand:SF 0 "register_operand" "=x")
14523         (match_operator:SF 3 "binary_fp_operator"
14524                         [(match_operand:SF 1 "register_operand" "0")
14525                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14526   "TARGET_SSE_MATH
14527    && !COMMUTATIVE_ARITH_P (operands[3])"
14528   "* return output_387_binary_op (insn, operands);"
14529   [(set (attr "type") 
14530         (cond [(match_operand:SF 3 "mult_operator" "")
14531                  (const_string "ssemul")
14532                (match_operand:SF 3 "div_operator" "")
14533                  (const_string "ssediv")
14534               ]
14535               (const_string "sseadd")))
14536    (set_attr "mode" "SF")])
14537
14538 ;; ??? Add SSE splitters for these!
14539 (define_insn "*fop_sf_2"
14540   [(set (match_operand:SF 0 "register_operand" "=f,f")
14541         (match_operator:SF 3 "binary_fp_operator"
14542           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14543            (match_operand:SF 2 "register_operand" "0,0")]))]
14544   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14545   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14546   [(set (attr "type") 
14547         (cond [(match_operand:SF 3 "mult_operator" "") 
14548                  (const_string "fmul")
14549                (match_operand:SF 3 "div_operator" "") 
14550                  (const_string "fdiv")
14551               ]
14552               (const_string "fop")))
14553    (set_attr "fp_int_src" "true")
14554    (set_attr "mode" "SI")])
14555
14556 (define_insn "*fop_sf_3"
14557   [(set (match_operand:SF 0 "register_operand" "=f,f")
14558         (match_operator:SF 3 "binary_fp_operator"
14559           [(match_operand:SF 1 "register_operand" "0,0")
14560            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14561   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14562   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14563   [(set (attr "type") 
14564         (cond [(match_operand:SF 3 "mult_operator" "") 
14565                  (const_string "fmul")
14566                (match_operand:SF 3 "div_operator" "") 
14567                  (const_string "fdiv")
14568               ]
14569               (const_string "fop")))
14570    (set_attr "fp_int_src" "true")
14571    (set_attr "mode" "SI")])
14572
14573 (define_insn "*fop_df_1_nosse"
14574   [(set (match_operand:DF 0 "register_operand" "=f,f")
14575         (match_operator:DF 3 "binary_fp_operator"
14576                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14577                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14578   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14579    && !COMMUTATIVE_ARITH_P (operands[3])
14580    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14581   "* return output_387_binary_op (insn, operands);"
14582   [(set (attr "type") 
14583         (cond [(match_operand:DF 3 "mult_operator" "") 
14584                  (const_string "fmul")
14585                (match_operand:DF 3 "div_operator" "")
14586                  (const_string "fdiv")
14587               ]
14588               (const_string "fop")))
14589    (set_attr "mode" "DF")])
14590
14591
14592 (define_insn "*fop_df_1"
14593   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14594         (match_operator:DF 3 "binary_fp_operator"
14595                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14596                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14597   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14598    && !COMMUTATIVE_ARITH_P (operands[3])
14599    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14600   "* return output_387_binary_op (insn, operands);"
14601   [(set (attr "type") 
14602         (cond [(and (eq_attr "alternative" "2")
14603                     (match_operand:SF 3 "mult_operator" ""))
14604                  (const_string "ssemul")
14605                (and (eq_attr "alternative" "2")
14606                     (match_operand:SF 3 "div_operator" ""))
14607                  (const_string "ssediv")
14608                (eq_attr "alternative" "2")
14609                  (const_string "sseadd")
14610                (match_operand:DF 3 "mult_operator" "") 
14611                  (const_string "fmul")
14612                (match_operand:DF 3 "div_operator" "") 
14613                  (const_string "fdiv")
14614               ]
14615               (const_string "fop")))
14616    (set_attr "mode" "DF")])
14617
14618 (define_insn "*fop_df_1_sse"
14619   [(set (match_operand:DF 0 "register_operand" "=Y")
14620         (match_operator:DF 3 "binary_fp_operator"
14621                         [(match_operand:DF 1 "register_operand" "0")
14622                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14623   "TARGET_SSE2 && TARGET_SSE_MATH
14624    && !COMMUTATIVE_ARITH_P (operands[3])"
14625   "* return output_387_binary_op (insn, operands);"
14626   [(set_attr "mode" "DF")
14627    (set (attr "type") 
14628         (cond [(match_operand:SF 3 "mult_operator" "")
14629                  (const_string "ssemul")
14630                (match_operand:SF 3 "div_operator" "")
14631                  (const_string "ssediv")
14632               ]
14633               (const_string "sseadd")))])
14634
14635 ;; ??? Add SSE splitters for these!
14636 (define_insn "*fop_df_2"
14637   [(set (match_operand:DF 0 "register_operand" "=f,f")
14638         (match_operator:DF 3 "binary_fp_operator"
14639            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14640             (match_operand:DF 2 "register_operand" "0,0")]))]
14641   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14642   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14643   [(set (attr "type") 
14644         (cond [(match_operand:DF 3 "mult_operator" "") 
14645                  (const_string "fmul")
14646                (match_operand:DF 3 "div_operator" "") 
14647                  (const_string "fdiv")
14648               ]
14649               (const_string "fop")))
14650    (set_attr "fp_int_src" "true")
14651    (set_attr "mode" "SI")])
14652
14653 (define_insn "*fop_df_3"
14654   [(set (match_operand:DF 0 "register_operand" "=f,f")
14655         (match_operator:DF 3 "binary_fp_operator"
14656            [(match_operand:DF 1 "register_operand" "0,0")
14657             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14658   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14659   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14660   [(set (attr "type") 
14661         (cond [(match_operand:DF 3 "mult_operator" "") 
14662                  (const_string "fmul")
14663                (match_operand:DF 3 "div_operator" "") 
14664                  (const_string "fdiv")
14665               ]
14666               (const_string "fop")))
14667    (set_attr "fp_int_src" "true")
14668    (set_attr "mode" "SI")])
14669
14670 (define_insn "*fop_df_4"
14671   [(set (match_operand:DF 0 "register_operand" "=f,f")
14672         (match_operator:DF 3 "binary_fp_operator"
14673            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14674             (match_operand:DF 2 "register_operand" "0,f")]))]
14675   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14677   "* return output_387_binary_op (insn, operands);"
14678   [(set (attr "type") 
14679         (cond [(match_operand:DF 3 "mult_operator" "") 
14680                  (const_string "fmul")
14681                (match_operand:DF 3 "div_operator" "") 
14682                  (const_string "fdiv")
14683               ]
14684               (const_string "fop")))
14685    (set_attr "mode" "SF")])
14686
14687 (define_insn "*fop_df_5"
14688   [(set (match_operand:DF 0 "register_operand" "=f,f")
14689         (match_operator:DF 3 "binary_fp_operator"
14690           [(match_operand:DF 1 "register_operand" "0,f")
14691            (float_extend:DF
14692             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14693   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14694   "* return output_387_binary_op (insn, operands);"
14695   [(set (attr "type") 
14696         (cond [(match_operand:DF 3 "mult_operator" "") 
14697                  (const_string "fmul")
14698                (match_operand:DF 3 "div_operator" "") 
14699                  (const_string "fdiv")
14700               ]
14701               (const_string "fop")))
14702    (set_attr "mode" "SF")])
14703
14704 (define_insn "*fop_df_6"
14705   [(set (match_operand:DF 0 "register_operand" "=f,f")
14706         (match_operator:DF 3 "binary_fp_operator"
14707           [(float_extend:DF
14708             (match_operand:SF 1 "register_operand" "0,f"))
14709            (float_extend:DF
14710             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14711   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14712   "* return output_387_binary_op (insn, operands);"
14713   [(set (attr "type") 
14714         (cond [(match_operand:DF 3 "mult_operator" "") 
14715                  (const_string "fmul")
14716                (match_operand:DF 3 "div_operator" "") 
14717                  (const_string "fdiv")
14718               ]
14719               (const_string "fop")))
14720    (set_attr "mode" "SF")])
14721
14722 (define_insn "*fop_xf_1"
14723   [(set (match_operand:XF 0 "register_operand" "=f,f")
14724         (match_operator:XF 3 "binary_fp_operator"
14725                         [(match_operand:XF 1 "register_operand" "0,f")
14726                          (match_operand:XF 2 "register_operand" "f,0")]))]
14727   "TARGET_80387
14728    && !COMMUTATIVE_ARITH_P (operands[3])"
14729   "* return output_387_binary_op (insn, operands);"
14730   [(set (attr "type") 
14731         (cond [(match_operand:XF 3 "mult_operator" "") 
14732                  (const_string "fmul")
14733                (match_operand:XF 3 "div_operator" "") 
14734                  (const_string "fdiv")
14735               ]
14736               (const_string "fop")))
14737    (set_attr "mode" "XF")])
14738
14739 (define_insn "*fop_xf_2"
14740   [(set (match_operand:XF 0 "register_operand" "=f,f")
14741         (match_operator:XF 3 "binary_fp_operator"
14742            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14743             (match_operand:XF 2 "register_operand" "0,0")]))]
14744   "TARGET_80387 && TARGET_USE_FIOP"
14745   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14746   [(set (attr "type") 
14747         (cond [(match_operand:XF 3 "mult_operator" "") 
14748                  (const_string "fmul")
14749                (match_operand:XF 3 "div_operator" "") 
14750                  (const_string "fdiv")
14751               ]
14752               (const_string "fop")))
14753    (set_attr "fp_int_src" "true")
14754    (set_attr "mode" "SI")])
14755
14756 (define_insn "*fop_xf_3"
14757   [(set (match_operand:XF 0 "register_operand" "=f,f")
14758         (match_operator:XF 3 "binary_fp_operator"
14759           [(match_operand:XF 1 "register_operand" "0,0")
14760            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14761   "TARGET_80387 && TARGET_USE_FIOP"
14762   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14763   [(set (attr "type") 
14764         (cond [(match_operand:XF 3 "mult_operator" "") 
14765                  (const_string "fmul")
14766                (match_operand:XF 3 "div_operator" "") 
14767                  (const_string "fdiv")
14768               ]
14769               (const_string "fop")))
14770    (set_attr "fp_int_src" "true")
14771    (set_attr "mode" "SI")])
14772
14773 (define_insn "*fop_xf_4"
14774   [(set (match_operand:XF 0 "register_operand" "=f,f")
14775         (match_operator:XF 3 "binary_fp_operator"
14776            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14777             (match_operand:XF 2 "register_operand" "0,f")]))]
14778   "TARGET_80387"
14779   "* return output_387_binary_op (insn, operands);"
14780   [(set (attr "type") 
14781         (cond [(match_operand:XF 3 "mult_operator" "") 
14782                  (const_string "fmul")
14783                (match_operand:XF 3 "div_operator" "") 
14784                  (const_string "fdiv")
14785               ]
14786               (const_string "fop")))
14787    (set_attr "mode" "SF")])
14788
14789 (define_insn "*fop_xf_5"
14790   [(set (match_operand:XF 0 "register_operand" "=f,f")
14791         (match_operator:XF 3 "binary_fp_operator"
14792           [(match_operand:XF 1 "register_operand" "0,f")
14793            (float_extend:XF
14794             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14795   "TARGET_80387"
14796   "* return output_387_binary_op (insn, operands);"
14797   [(set (attr "type") 
14798         (cond [(match_operand:XF 3 "mult_operator" "") 
14799                  (const_string "fmul")
14800                (match_operand:XF 3 "div_operator" "") 
14801                  (const_string "fdiv")
14802               ]
14803               (const_string "fop")))
14804    (set_attr "mode" "SF")])
14805
14806 (define_insn "*fop_xf_6"
14807   [(set (match_operand:XF 0 "register_operand" "=f,f")
14808         (match_operator:XF 3 "binary_fp_operator"
14809           [(float_extend:XF
14810             (match_operand 1 "register_operand" "0,f"))
14811            (float_extend:XF
14812             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14813   "TARGET_80387"
14814   "* return output_387_binary_op (insn, operands);"
14815   [(set (attr "type") 
14816         (cond [(match_operand:XF 3 "mult_operator" "") 
14817                  (const_string "fmul")
14818                (match_operand:XF 3 "div_operator" "") 
14819                  (const_string "fdiv")
14820               ]
14821               (const_string "fop")))
14822    (set_attr "mode" "SF")])
14823
14824 (define_split
14825   [(set (match_operand 0 "register_operand" "")
14826         (match_operator 3 "binary_fp_operator"
14827            [(float (match_operand:SI 1 "register_operand" ""))
14828             (match_operand 2 "register_operand" "")]))]
14829   "TARGET_80387 && reload_completed
14830    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14831   [(const_int 0)]
14832
14833   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14834   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14835   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14836                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14837                                           GET_MODE (operands[3]),
14838                                           operands[4],
14839                                           operands[2])));
14840   ix86_free_from_memory (GET_MODE (operands[1]));
14841   DONE;
14842 })
14843
14844 (define_split
14845   [(set (match_operand 0 "register_operand" "")
14846         (match_operator 3 "binary_fp_operator"
14847            [(match_operand 1 "register_operand" "")
14848             (float (match_operand:SI 2 "register_operand" ""))]))]
14849   "TARGET_80387 && reload_completed
14850    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14851   [(const_int 0)]
14852 {
14853   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14854   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14855   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14856                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14857                                           GET_MODE (operands[3]),
14858                                           operands[1],
14859                                           operands[4])));
14860   ix86_free_from_memory (GET_MODE (operands[2]));
14861   DONE;
14862 })
14863 \f
14864 ;; FPU special functions.
14865
14866 (define_expand "sqrtsf2"
14867   [(set (match_operand:SF 0 "register_operand" "")
14868         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14869   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14870 {
14871   if (!TARGET_SSE_MATH)
14872     operands[1] = force_reg (SFmode, operands[1]);
14873 })
14874
14875 (define_insn "sqrtsf2_1"
14876   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14877         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14878   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14879    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14880   "@
14881    fsqrt
14882    sqrtss\t{%1, %0|%0, %1}"
14883   [(set_attr "type" "fpspc,sse")
14884    (set_attr "mode" "SF,SF")
14885    (set_attr "athlon_decode" "direct,*")])
14886
14887 (define_insn "sqrtsf2_1_sse_only"
14888   [(set (match_operand:SF 0 "register_operand" "=x")
14889         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14890   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14891   "sqrtss\t{%1, %0|%0, %1}"
14892   [(set_attr "type" "sse")
14893    (set_attr "mode" "SF")
14894    (set_attr "athlon_decode" "*")])
14895
14896 (define_insn "sqrtsf2_i387"
14897   [(set (match_operand:SF 0 "register_operand" "=f")
14898         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14899   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14900    && !TARGET_SSE_MATH"
14901   "fsqrt"
14902   [(set_attr "type" "fpspc")
14903    (set_attr "mode" "SF")
14904    (set_attr "athlon_decode" "direct")])
14905
14906 (define_expand "sqrtdf2"
14907   [(set (match_operand:DF 0 "register_operand" "")
14908         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14909   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14910    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14911 {
14912   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14913     operands[1] = force_reg (DFmode, operands[1]);
14914 })
14915
14916 (define_insn "sqrtdf2_1"
14917   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14918         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14919   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14920    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14921   "@
14922    fsqrt
14923    sqrtsd\t{%1, %0|%0, %1}"
14924   [(set_attr "type" "fpspc,sse")
14925    (set_attr "mode" "DF,DF")
14926    (set_attr "athlon_decode" "direct,*")])
14927
14928 (define_insn "sqrtdf2_1_sse_only"
14929   [(set (match_operand:DF 0 "register_operand" "=Y")
14930         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14931   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14932   "sqrtsd\t{%1, %0|%0, %1}"
14933   [(set_attr "type" "sse")
14934    (set_attr "mode" "DF")
14935    (set_attr "athlon_decode" "*")])
14936
14937 (define_insn "sqrtdf2_i387"
14938   [(set (match_operand:DF 0 "register_operand" "=f")
14939         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14941    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14942   "fsqrt"
14943   [(set_attr "type" "fpspc")
14944    (set_attr "mode" "DF")
14945    (set_attr "athlon_decode" "direct")])
14946
14947 (define_insn "*sqrtextendsfdf2"
14948   [(set (match_operand:DF 0 "register_operand" "=f")
14949         (sqrt:DF (float_extend:DF
14950                   (match_operand:SF 1 "register_operand" "0"))))]
14951   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14952    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14953   "fsqrt"
14954   [(set_attr "type" "fpspc")
14955    (set_attr "mode" "DF")
14956    (set_attr "athlon_decode" "direct")])
14957
14958 (define_insn "sqrtxf2"
14959   [(set (match_operand:XF 0 "register_operand" "=f")
14960         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14961   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14962    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14963   "fsqrt"
14964   [(set_attr "type" "fpspc")
14965    (set_attr "mode" "XF")
14966    (set_attr "athlon_decode" "direct")])
14967
14968 (define_insn "*sqrtextenddfxf2"
14969   [(set (match_operand:XF 0 "register_operand" "=f")
14970         (sqrt:XF (float_extend:XF
14971                   (match_operand:DF 1 "register_operand" "0"))))]
14972   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14973   "fsqrt"
14974   [(set_attr "type" "fpspc")
14975    (set_attr "mode" "XF")
14976    (set_attr "athlon_decode" "direct")])
14977
14978 (define_insn "*sqrtextendsfxf2"
14979   [(set (match_operand:XF 0 "register_operand" "=f")
14980         (sqrt:XF (float_extend:XF
14981                   (match_operand:SF 1 "register_operand" "0"))))]
14982   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14983   "fsqrt"
14984   [(set_attr "type" "fpspc")
14985    (set_attr "mode" "XF")
14986    (set_attr "athlon_decode" "direct")])
14987
14988 (define_insn "fpremxf4"
14989   [(set (match_operand:XF 0 "register_operand" "=f")
14990         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14991                     (match_operand:XF 3 "register_operand" "1")]
14992                    UNSPEC_FPREM_F))
14993    (set (match_operand:XF 1 "register_operand" "=u")
14994         (unspec:XF [(match_dup 2) (match_dup 3)]
14995                    UNSPEC_FPREM_U))
14996    (set (reg:CCFP FPSR_REG)
14997         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14998   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14999    && flag_unsafe_math_optimizations"
15000   "fprem"
15001   [(set_attr "type" "fpspc")
15002    (set_attr "mode" "XF")])
15003
15004 (define_expand "fmodsf3"
15005   [(use (match_operand:SF 0 "register_operand" ""))
15006    (use (match_operand:SF 1 "register_operand" ""))
15007    (use (match_operand:SF 2 "register_operand" ""))]
15008   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009    && flag_unsafe_math_optimizations"
15010 {
15011   rtx label = gen_label_rtx ();
15012
15013   rtx op1 = gen_reg_rtx (XFmode);
15014   rtx op2 = gen_reg_rtx (XFmode);
15015
15016   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15017   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15018
15019   emit_label (label);
15020
15021   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022   ix86_emit_fp_unordered_jump (label);
15023
15024   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15025   DONE;
15026 })
15027
15028 (define_expand "fmoddf3"
15029   [(use (match_operand:DF 0 "register_operand" ""))
15030    (use (match_operand:DF 1 "register_operand" ""))
15031    (use (match_operand:DF 2 "register_operand" ""))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15034 {
15035   rtx label = gen_label_rtx ();
15036
15037   rtx op1 = gen_reg_rtx (XFmode);
15038   rtx op2 = gen_reg_rtx (XFmode);
15039
15040   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15041   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15042
15043   emit_label (label);
15044
15045   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15046   ix86_emit_fp_unordered_jump (label);
15047
15048   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15049   DONE;
15050 })
15051
15052 (define_expand "fmodxf3"
15053   [(use (match_operand:XF 0 "register_operand" ""))
15054    (use (match_operand:XF 1 "register_operand" ""))
15055    (use (match_operand:XF 2 "register_operand" ""))]
15056   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15057    && flag_unsafe_math_optimizations"
15058 {
15059   rtx label = gen_label_rtx ();
15060
15061   emit_label (label);
15062
15063   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15064                            operands[1], operands[2]));
15065   ix86_emit_fp_unordered_jump (label);
15066
15067   emit_move_insn (operands[0], operands[1]);
15068   DONE;
15069 })
15070
15071 (define_insn "fprem1xf4"
15072   [(set (match_operand:XF 0 "register_operand" "=f")
15073         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15074                     (match_operand:XF 3 "register_operand" "1")]
15075                    UNSPEC_FPREM1_F))
15076    (set (match_operand:XF 1 "register_operand" "=u")
15077         (unspec:XF [(match_dup 2) (match_dup 3)]
15078                    UNSPEC_FPREM1_U))
15079    (set (reg:CCFP FPSR_REG)
15080         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15081   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15082    && flag_unsafe_math_optimizations"
15083   "fprem1"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "mode" "XF")])
15086
15087 (define_expand "dremsf3"
15088   [(use (match_operand:SF 0 "register_operand" ""))
15089    (use (match_operand:SF 1 "register_operand" ""))
15090    (use (match_operand:SF 2 "register_operand" ""))]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15093 {
15094   rtx label = gen_label_rtx ();
15095
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15098
15099   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15100   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15101
15102   emit_label (label);
15103
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15106
15107   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15108   DONE;
15109 })
15110
15111 (define_expand "dremdf3"
15112   [(use (match_operand:DF 0 "register_operand" ""))
15113    (use (match_operand:DF 1 "register_operand" ""))
15114    (use (match_operand:DF 2 "register_operand" ""))]
15115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116    && flag_unsafe_math_optimizations"
15117 {
15118   rtx label = gen_label_rtx ();
15119
15120   rtx op1 = gen_reg_rtx (XFmode);
15121   rtx op2 = gen_reg_rtx (XFmode);
15122
15123   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15124   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15125
15126   emit_label (label);
15127
15128   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15129   ix86_emit_fp_unordered_jump (label);
15130
15131   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15132   DONE;
15133 })
15134
15135 (define_expand "dremxf3"
15136   [(use (match_operand:XF 0 "register_operand" ""))
15137    (use (match_operand:XF 1 "register_operand" ""))
15138    (use (match_operand:XF 2 "register_operand" ""))]
15139   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15140    && flag_unsafe_math_optimizations"
15141 {
15142   rtx label = gen_label_rtx ();
15143
15144   emit_label (label);
15145
15146   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15147                             operands[1], operands[2]));
15148   ix86_emit_fp_unordered_jump (label);
15149
15150   emit_move_insn (operands[0], operands[1]);
15151   DONE;
15152 })
15153
15154 (define_insn "*sindf2"
15155   [(set (match_operand:DF 0 "register_operand" "=f")
15156         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15157   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15158    && flag_unsafe_math_optimizations"
15159   "fsin"
15160   [(set_attr "type" "fpspc")
15161    (set_attr "mode" "DF")])
15162
15163 (define_insn "*sinsf2"
15164   [(set (match_operand:SF 0 "register_operand" "=f")
15165         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15166   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15167    && flag_unsafe_math_optimizations"
15168   "fsin"
15169   [(set_attr "type" "fpspc")
15170    (set_attr "mode" "SF")])
15171
15172 (define_insn "*sinextendsfdf2"
15173   [(set (match_operand:DF 0 "register_operand" "=f")
15174         (unspec:DF [(float_extend:DF
15175                      (match_operand:SF 1 "register_operand" "0"))]
15176                    UNSPEC_SIN))]
15177   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15178    && flag_unsafe_math_optimizations"
15179   "fsin"
15180   [(set_attr "type" "fpspc")
15181    (set_attr "mode" "DF")])
15182
15183 (define_insn "*sinxf2"
15184   [(set (match_operand:XF 0 "register_operand" "=f")
15185         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15186   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15187    && flag_unsafe_math_optimizations"
15188   "fsin"
15189   [(set_attr "type" "fpspc")
15190    (set_attr "mode" "XF")])
15191
15192 (define_insn "*cosdf2"
15193   [(set (match_operand:DF 0 "register_operand" "=f")
15194         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15195   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15196    && flag_unsafe_math_optimizations"
15197   "fcos"
15198   [(set_attr "type" "fpspc")
15199    (set_attr "mode" "DF")])
15200
15201 (define_insn "*cossf2"
15202   [(set (match_operand:SF 0 "register_operand" "=f")
15203         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15204   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15205    && flag_unsafe_math_optimizations"
15206   "fcos"
15207   [(set_attr "type" "fpspc")
15208    (set_attr "mode" "SF")])
15209
15210 (define_insn "*cosextendsfdf2"
15211   [(set (match_operand:DF 0 "register_operand" "=f")
15212         (unspec:DF [(float_extend:DF
15213                      (match_operand:SF 1 "register_operand" "0"))]
15214                    UNSPEC_COS))]
15215   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15216    && flag_unsafe_math_optimizations"
15217   "fcos"
15218   [(set_attr "type" "fpspc")
15219    (set_attr "mode" "DF")])
15220
15221 (define_insn "*cosxf2"
15222   [(set (match_operand:XF 0 "register_operand" "=f")
15223         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15224   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15225    && flag_unsafe_math_optimizations"
15226   "fcos"
15227   [(set_attr "type" "fpspc")
15228    (set_attr "mode" "XF")])
15229
15230 ;; With sincos pattern defined, sin and cos builtin function will be
15231 ;; expanded to sincos pattern with one of its outputs left unused. 
15232 ;; Cse pass  will detected, if two sincos patterns can be combined,
15233 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15234 ;; depending on the unused output.
15235
15236 (define_insn "sincosdf3"
15237   [(set (match_operand:DF 0 "register_operand" "=f")
15238         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15239                    UNSPEC_SINCOS_COS))
15240    (set (match_operand:DF 1 "register_operand" "=u")
15241         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15243    && flag_unsafe_math_optimizations"
15244   "fsincos"
15245   [(set_attr "type" "fpspc")
15246    (set_attr "mode" "DF")])
15247
15248 (define_split
15249   [(set (match_operand:DF 0 "register_operand" "")
15250         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15251                    UNSPEC_SINCOS_COS))
15252    (set (match_operand:DF 1 "register_operand" "")
15253         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15254   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15255    && !reload_completed && !reload_in_progress"
15256   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15257   "")
15258
15259 (define_split
15260   [(set (match_operand:DF 0 "register_operand" "")
15261         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15262                    UNSPEC_SINCOS_COS))
15263    (set (match_operand:DF 1 "register_operand" "")
15264         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15265   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15266    && !reload_completed && !reload_in_progress"
15267   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15268   "")
15269
15270 (define_insn "sincossf3"
15271   [(set (match_operand:SF 0 "register_operand" "=f")
15272         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15273                    UNSPEC_SINCOS_COS))
15274    (set (match_operand:SF 1 "register_operand" "=u")
15275         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15276   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15277    && flag_unsafe_math_optimizations"
15278   "fsincos"
15279   [(set_attr "type" "fpspc")
15280    (set_attr "mode" "SF")])
15281
15282 (define_split
15283   [(set (match_operand:SF 0 "register_operand" "")
15284         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15285                    UNSPEC_SINCOS_COS))
15286    (set (match_operand:SF 1 "register_operand" "")
15287         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15288   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15289    && !reload_completed && !reload_in_progress"
15290   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15291   "")
15292
15293 (define_split
15294   [(set (match_operand:SF 0 "register_operand" "")
15295         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15296                    UNSPEC_SINCOS_COS))
15297    (set (match_operand:SF 1 "register_operand" "")
15298         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15299   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15300    && !reload_completed && !reload_in_progress"
15301   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15302   "")
15303
15304 (define_insn "*sincosextendsfdf3"
15305   [(set (match_operand:DF 0 "register_operand" "=f")
15306         (unspec:DF [(float_extend:DF
15307                      (match_operand:SF 2 "register_operand" "0"))]
15308                    UNSPEC_SINCOS_COS))
15309    (set (match_operand:DF 1 "register_operand" "=u")
15310         (unspec:DF [(float_extend:DF
15311                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15312   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15313    && flag_unsafe_math_optimizations"
15314   "fsincos"
15315   [(set_attr "type" "fpspc")
15316    (set_attr "mode" "DF")])
15317
15318 (define_split
15319   [(set (match_operand:DF 0 "register_operand" "")
15320         (unspec:DF [(float_extend:DF
15321                      (match_operand:SF 2 "register_operand" ""))]
15322                    UNSPEC_SINCOS_COS))
15323    (set (match_operand:DF 1 "register_operand" "")
15324         (unspec:DF [(float_extend:DF
15325                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15326   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15327    && !reload_completed && !reload_in_progress"
15328   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15329                                    (match_dup 2))] UNSPEC_SIN))]
15330   "")
15331
15332 (define_split
15333   [(set (match_operand:DF 0 "register_operand" "")
15334         (unspec:DF [(float_extend:DF
15335                      (match_operand:SF 2 "register_operand" ""))]
15336                    UNSPEC_SINCOS_COS))
15337    (set (match_operand:DF 1 "register_operand" "")
15338         (unspec:DF [(float_extend:DF
15339                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15340   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15343                                    (match_dup 2))] UNSPEC_COS))]
15344   "")
15345
15346 (define_insn "sincosxf3"
15347   [(set (match_operand:XF 0 "register_operand" "=f")
15348         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15349                    UNSPEC_SINCOS_COS))
15350    (set (match_operand:XF 1 "register_operand" "=u")
15351         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15352   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15353    && flag_unsafe_math_optimizations"
15354   "fsincos"
15355   [(set_attr "type" "fpspc")
15356    (set_attr "mode" "XF")])
15357
15358 (define_split
15359   [(set (match_operand:XF 0 "register_operand" "")
15360         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15361                    UNSPEC_SINCOS_COS))
15362    (set (match_operand:XF 1 "register_operand" "")
15363         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15364   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15365    && !reload_completed && !reload_in_progress"
15366   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15367   "")
15368
15369 (define_split
15370   [(set (match_operand:XF 0 "register_operand" "")
15371         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15372                    UNSPEC_SINCOS_COS))
15373    (set (match_operand:XF 1 "register_operand" "")
15374         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15375   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15376    && !reload_completed && !reload_in_progress"
15377   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15378   "")
15379
15380 (define_insn "*tandf3_1"
15381   [(set (match_operand:DF 0 "register_operand" "=f")
15382         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15383                    UNSPEC_TAN_ONE))
15384    (set (match_operand:DF 1 "register_operand" "=u")
15385         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15386   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15387    && flag_unsafe_math_optimizations"
15388   "fptan"
15389   [(set_attr "type" "fpspc")
15390    (set_attr "mode" "DF")])
15391
15392 ;; optimize sequence: fptan
15393 ;;                    fstp    %st(0)
15394 ;;                    fld1
15395 ;; into fptan insn.
15396
15397 (define_peephole2
15398   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15399                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15400                              UNSPEC_TAN_ONE))
15401              (set (match_operand:DF 1 "register_operand" "")
15402                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15403    (set (match_dup 0)
15404         (match_operand:DF 3 "immediate_operand" ""))]
15405   "standard_80387_constant_p (operands[3]) == 2"
15406   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15407              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15408   "")
15409
15410 (define_expand "tandf2"
15411   [(parallel [(set (match_dup 2)
15412                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15413                               UNSPEC_TAN_ONE))
15414               (set (match_operand:DF 0 "register_operand" "")
15415                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15416   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15417    && flag_unsafe_math_optimizations"
15418 {
15419   operands[2] = gen_reg_rtx (DFmode);
15420 })
15421
15422 (define_insn "*tansf3_1"
15423   [(set (match_operand:SF 0 "register_operand" "=f")
15424         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15425                    UNSPEC_TAN_ONE))
15426    (set (match_operand:SF 1 "register_operand" "=u")
15427         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15428   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15429    && flag_unsafe_math_optimizations"
15430   "fptan"
15431   [(set_attr "type" "fpspc")
15432    (set_attr "mode" "SF")])
15433
15434 ;; optimize sequence: fptan
15435 ;;                    fstp    %st(0)
15436 ;;                    fld1
15437 ;; into fptan insn.
15438
15439 (define_peephole2
15440   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15441                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15442                              UNSPEC_TAN_ONE))
15443              (set (match_operand:SF 1 "register_operand" "")
15444                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15445    (set (match_dup 0)
15446         (match_operand:SF 3 "immediate_operand" ""))]
15447   "standard_80387_constant_p (operands[3]) == 2"
15448   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15449              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15450   "")
15451
15452 (define_expand "tansf2"
15453   [(parallel [(set (match_dup 2)
15454                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15455                               UNSPEC_TAN_ONE))
15456               (set (match_operand:SF 0 "register_operand" "")
15457                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15458   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15459    && flag_unsafe_math_optimizations"
15460 {
15461   operands[2] = gen_reg_rtx (SFmode);
15462 })
15463
15464 (define_insn "*tanxf3_1"
15465   [(set (match_operand:XF 0 "register_operand" "=f")
15466         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15467                    UNSPEC_TAN_ONE))
15468    (set (match_operand:XF 1 "register_operand" "=u")
15469         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15470   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15471    && flag_unsafe_math_optimizations"
15472   "fptan"
15473   [(set_attr "type" "fpspc")
15474    (set_attr "mode" "XF")])
15475
15476 ;; optimize sequence: fptan
15477 ;;                    fstp    %st(0)
15478 ;;                    fld1
15479 ;; into fptan insn.
15480
15481 (define_peephole2
15482   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15483                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15484                              UNSPEC_TAN_ONE))
15485              (set (match_operand:XF 1 "register_operand" "")
15486                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15487    (set (match_dup 0)
15488         (match_operand:XF 3 "immediate_operand" ""))]
15489   "standard_80387_constant_p (operands[3]) == 2"
15490   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15491              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15492   "")
15493
15494 (define_expand "tanxf2"
15495   [(parallel [(set (match_dup 2)
15496                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15497                               UNSPEC_TAN_ONE))
15498               (set (match_operand:XF 0 "register_operand" "")
15499                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15500   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15501    && flag_unsafe_math_optimizations"
15502 {
15503   operands[2] = gen_reg_rtx (XFmode);
15504 })
15505
15506 (define_insn "atan2df3_1"
15507   [(set (match_operand:DF 0 "register_operand" "=f")
15508         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15509                     (match_operand:DF 1 "register_operand" "u")]
15510                    UNSPEC_FPATAN))
15511    (clobber (match_scratch:DF 3 "=1"))]
15512   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15513    && flag_unsafe_math_optimizations"
15514   "fpatan"
15515   [(set_attr "type" "fpspc")
15516    (set_attr "mode" "DF")])
15517
15518 (define_expand "atan2df3"
15519   [(use (match_operand:DF 0 "register_operand" "=f"))
15520    (use (match_operand:DF 2 "register_operand" "0"))
15521    (use (match_operand:DF 1 "register_operand" "u"))]
15522   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15523    && flag_unsafe_math_optimizations"
15524 {
15525   rtx copy = gen_reg_rtx (DFmode);
15526   emit_move_insn (copy, operands[1]);
15527   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15528   DONE;
15529 })
15530
15531 (define_expand "atandf2"
15532   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15533                    (unspec:DF [(match_dup 2)
15534                                (match_operand:DF 1 "register_operand" "")]
15535                     UNSPEC_FPATAN))
15536               (clobber (match_scratch:DF 3 ""))])]
15537   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15538    && flag_unsafe_math_optimizations"
15539 {
15540   operands[2] = gen_reg_rtx (DFmode);
15541   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15542 })
15543
15544 (define_insn "atan2sf3_1"
15545   [(set (match_operand:SF 0 "register_operand" "=f")
15546         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15547                     (match_operand:SF 1 "register_operand" "u")]
15548                    UNSPEC_FPATAN))
15549    (clobber (match_scratch:SF 3 "=1"))]
15550   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15551    && flag_unsafe_math_optimizations"
15552   "fpatan"
15553   [(set_attr "type" "fpspc")
15554    (set_attr "mode" "SF")])
15555
15556 (define_expand "atan2sf3"
15557   [(use (match_operand:SF 0 "register_operand" "=f"))
15558    (use (match_operand:SF 2 "register_operand" "0"))
15559    (use (match_operand:SF 1 "register_operand" "u"))]
15560   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15561    && flag_unsafe_math_optimizations"
15562 {
15563   rtx copy = gen_reg_rtx (SFmode);
15564   emit_move_insn (copy, operands[1]);
15565   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15566   DONE;
15567 })
15568
15569 (define_expand "atansf2"
15570   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15571                    (unspec:SF [(match_dup 2)
15572                                (match_operand:SF 1 "register_operand" "")]
15573                     UNSPEC_FPATAN))
15574               (clobber (match_scratch:SF 3 ""))])]
15575   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15576    && flag_unsafe_math_optimizations"
15577 {
15578   operands[2] = gen_reg_rtx (SFmode);
15579   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15580 })
15581
15582 (define_insn "atan2xf3_1"
15583   [(set (match_operand:XF 0 "register_operand" "=f")
15584         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15585                     (match_operand:XF 1 "register_operand" "u")]
15586                    UNSPEC_FPATAN))
15587    (clobber (match_scratch:XF 3 "=1"))]
15588   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15589    && flag_unsafe_math_optimizations"
15590   "fpatan"
15591   [(set_attr "type" "fpspc")
15592    (set_attr "mode" "XF")])
15593
15594 (define_expand "atan2xf3"
15595   [(use (match_operand:XF 0 "register_operand" "=f"))
15596    (use (match_operand:XF 2 "register_operand" "0"))
15597    (use (match_operand:XF 1 "register_operand" "u"))]
15598   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15599    && flag_unsafe_math_optimizations"
15600 {
15601   rtx copy = gen_reg_rtx (XFmode);
15602   emit_move_insn (copy, operands[1]);
15603   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15604   DONE;
15605 })
15606
15607 (define_expand "atanxf2"
15608   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15609                    (unspec:XF [(match_dup 2)
15610                                (match_operand:XF 1 "register_operand" "")]
15611                     UNSPEC_FPATAN))
15612               (clobber (match_scratch:XF 3 ""))])]
15613   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15614    && flag_unsafe_math_optimizations"
15615 {
15616   operands[2] = gen_reg_rtx (XFmode);
15617   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15618 })
15619
15620 (define_expand "asindf2"
15621   [(set (match_dup 2)
15622         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15623    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15624    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15625    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15626    (parallel [(set (match_dup 7)
15627                    (unspec:XF [(match_dup 6) (match_dup 2)]
15628                               UNSPEC_FPATAN))
15629               (clobber (match_scratch:XF 8 ""))])
15630    (set (match_operand:DF 0 "register_operand" "")
15631         (float_truncate:DF (match_dup 7)))]
15632   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15633    && flag_unsafe_math_optimizations"
15634 {
15635   int i;
15636
15637   for (i=2; i<8; i++)
15638     operands[i] = gen_reg_rtx (XFmode);
15639
15640   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15641 })
15642
15643 (define_expand "asinsf2"
15644   [(set (match_dup 2)
15645         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15646    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15647    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15648    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15649    (parallel [(set (match_dup 7)
15650                    (unspec:XF [(match_dup 6) (match_dup 2)]
15651                               UNSPEC_FPATAN))
15652               (clobber (match_scratch:XF 8 ""))])
15653    (set (match_operand:SF 0 "register_operand" "")
15654         (float_truncate:SF (match_dup 7)))]
15655   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15656    && flag_unsafe_math_optimizations"
15657 {
15658   int i;
15659
15660   for (i=2; i<8; i++)
15661     operands[i] = gen_reg_rtx (XFmode);
15662
15663   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15664 })
15665
15666 (define_expand "asinxf2"
15667   [(set (match_dup 2)
15668         (mult:XF (match_operand:XF 1 "register_operand" "")
15669                  (match_dup 1)))
15670    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15671    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15672    (parallel [(set (match_operand:XF 0 "register_operand" "")
15673                    (unspec:XF [(match_dup 5) (match_dup 1)]
15674                               UNSPEC_FPATAN))
15675               (clobber (match_scratch:XF 6 ""))])]
15676   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15677    && flag_unsafe_math_optimizations"
15678 {
15679   int i;
15680
15681   for (i=2; i<6; i++)
15682     operands[i] = gen_reg_rtx (XFmode);
15683
15684   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15685 })
15686
15687 (define_expand "acosdf2"
15688   [(set (match_dup 2)
15689         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15690    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15691    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15692    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15693    (parallel [(set (match_dup 7)
15694                    (unspec:XF [(match_dup 2) (match_dup 6)]
15695                               UNSPEC_FPATAN))
15696               (clobber (match_scratch:XF 8 ""))])
15697    (set (match_operand:DF 0 "register_operand" "")
15698         (float_truncate:DF (match_dup 7)))]
15699   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15700    && flag_unsafe_math_optimizations"
15701 {
15702   int i;
15703
15704   for (i=2; i<8; i++)
15705     operands[i] = gen_reg_rtx (XFmode);
15706
15707   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15708 })
15709
15710 (define_expand "acossf2"
15711   [(set (match_dup 2)
15712         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15713    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15714    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15715    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15716    (parallel [(set (match_dup 7)
15717                    (unspec:XF [(match_dup 2) (match_dup 6)]
15718                               UNSPEC_FPATAN))
15719               (clobber (match_scratch:XF 8 ""))])
15720    (set (match_operand:SF 0 "register_operand" "")
15721         (float_truncate:SF (match_dup 7)))]
15722   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15723    && flag_unsafe_math_optimizations"
15724 {
15725   int i;
15726
15727   for (i=2; i<8; i++)
15728     operands[i] = gen_reg_rtx (XFmode);
15729
15730   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15731 })
15732
15733 (define_expand "acosxf2"
15734   [(set (match_dup 2)
15735         (mult:XF (match_operand:XF 1 "register_operand" "")
15736                  (match_dup 1)))
15737    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15738    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15739    (parallel [(set (match_operand:XF 0 "register_operand" "")
15740                    (unspec:XF [(match_dup 1) (match_dup 5)]
15741                               UNSPEC_FPATAN))
15742               (clobber (match_scratch:XF 6 ""))])]
15743   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15744    && flag_unsafe_math_optimizations"
15745 {
15746   int i;
15747
15748   for (i=2; i<6; i++)
15749     operands[i] = gen_reg_rtx (XFmode);
15750
15751   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15752 })
15753
15754 (define_insn "fyl2x_xf3"
15755   [(set (match_operand:XF 0 "register_operand" "=f")
15756         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15757                     (match_operand:XF 1 "register_operand" "u")]
15758                    UNSPEC_FYL2X))
15759    (clobber (match_scratch:XF 3 "=1"))]
15760   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15761    && flag_unsafe_math_optimizations"
15762   "fyl2x"
15763   [(set_attr "type" "fpspc")
15764    (set_attr "mode" "XF")])
15765
15766 (define_expand "logsf2"
15767   [(set (match_dup 2)
15768         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15769    (parallel [(set (match_dup 4)
15770                    (unspec:XF [(match_dup 2)
15771                                (match_dup 3)] UNSPEC_FYL2X))
15772               (clobber (match_scratch:XF 5 ""))])
15773    (set (match_operand:SF 0 "register_operand" "")
15774         (float_truncate:SF (match_dup 4)))]
15775   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15776    && flag_unsafe_math_optimizations"
15777 {
15778   rtx temp;
15779
15780   operands[2] = gen_reg_rtx (XFmode);
15781   operands[3] = gen_reg_rtx (XFmode);
15782   operands[4] = gen_reg_rtx (XFmode);
15783
15784   temp = standard_80387_constant_rtx (4); /* fldln2 */
15785   emit_move_insn (operands[3], temp);
15786 })
15787
15788 (define_expand "logdf2"
15789   [(set (match_dup 2)
15790         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791    (parallel [(set (match_dup 4)
15792                    (unspec:XF [(match_dup 2)
15793                                (match_dup 3)] UNSPEC_FYL2X))
15794               (clobber (match_scratch:XF 5 ""))])
15795    (set (match_operand:DF 0 "register_operand" "")
15796         (float_truncate:DF (match_dup 4)))]
15797   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15798    && flag_unsafe_math_optimizations"
15799 {
15800   rtx temp;
15801
15802   operands[2] = gen_reg_rtx (XFmode);
15803   operands[3] = gen_reg_rtx (XFmode);
15804   operands[4] = gen_reg_rtx (XFmode);
15805
15806   temp = standard_80387_constant_rtx (4); /* fldln2 */
15807   emit_move_insn (operands[3], temp);
15808 })
15809
15810 (define_expand "logxf2"
15811   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15812                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15813                                (match_dup 2)] UNSPEC_FYL2X))
15814               (clobber (match_scratch:XF 3 ""))])]
15815   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15816    && flag_unsafe_math_optimizations"
15817 {
15818   rtx temp;
15819
15820   operands[2] = gen_reg_rtx (XFmode);
15821   temp = standard_80387_constant_rtx (4); /* fldln2 */
15822   emit_move_insn (operands[2], temp);
15823 })
15824
15825 (define_expand "log10sf2"
15826   [(set (match_dup 2)
15827         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15828    (parallel [(set (match_dup 4)
15829                    (unspec:XF [(match_dup 2)
15830                                (match_dup 3)] UNSPEC_FYL2X))
15831               (clobber (match_scratch:XF 5 ""))])
15832    (set (match_operand:SF 0 "register_operand" "")
15833         (float_truncate:SF (match_dup 4)))]
15834   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15835    && flag_unsafe_math_optimizations"
15836 {
15837   rtx temp;
15838
15839   operands[2] = gen_reg_rtx (XFmode);
15840   operands[3] = gen_reg_rtx (XFmode);
15841   operands[4] = gen_reg_rtx (XFmode);
15842
15843   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15844   emit_move_insn (operands[3], temp);
15845 })
15846
15847 (define_expand "log10df2"
15848   [(set (match_dup 2)
15849         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15850    (parallel [(set (match_dup 4)
15851                    (unspec:XF [(match_dup 2)
15852                                (match_dup 3)] UNSPEC_FYL2X))
15853               (clobber (match_scratch:XF 5 ""))])
15854    (set (match_operand:DF 0 "register_operand" "")
15855         (float_truncate:DF (match_dup 4)))]
15856   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15857    && flag_unsafe_math_optimizations"
15858 {
15859   rtx temp;
15860
15861   operands[2] = gen_reg_rtx (XFmode);
15862   operands[3] = gen_reg_rtx (XFmode);
15863   operands[4] = gen_reg_rtx (XFmode);
15864
15865   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15866   emit_move_insn (operands[3], temp);
15867 })
15868
15869 (define_expand "log10xf2"
15870   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15871                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15872                                (match_dup 2)] UNSPEC_FYL2X))
15873               (clobber (match_scratch:XF 3 ""))])]
15874   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15875    && flag_unsafe_math_optimizations"
15876 {
15877   rtx temp;
15878
15879   operands[2] = gen_reg_rtx (XFmode);
15880   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15881   emit_move_insn (operands[2], temp);
15882 })
15883
15884 (define_expand "log2sf2"
15885   [(set (match_dup 2)
15886         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15887    (parallel [(set (match_dup 4)
15888                    (unspec:XF [(match_dup 2)
15889                                (match_dup 3)] UNSPEC_FYL2X))
15890               (clobber (match_scratch:XF 5 ""))])
15891    (set (match_operand:SF 0 "register_operand" "")
15892         (float_truncate:SF (match_dup 4)))]
15893   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15894    && flag_unsafe_math_optimizations"
15895 {
15896   operands[2] = gen_reg_rtx (XFmode);
15897   operands[3] = gen_reg_rtx (XFmode);
15898   operands[4] = gen_reg_rtx (XFmode);
15899
15900   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15901 })
15902
15903 (define_expand "log2df2"
15904   [(set (match_dup 2)
15905         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15906    (parallel [(set (match_dup 4)
15907                    (unspec:XF [(match_dup 2)
15908                                (match_dup 3)] UNSPEC_FYL2X))
15909               (clobber (match_scratch:XF 5 ""))])
15910    (set (match_operand:DF 0 "register_operand" "")
15911         (float_truncate:DF (match_dup 4)))]
15912   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15913    && flag_unsafe_math_optimizations"
15914 {
15915   operands[2] = gen_reg_rtx (XFmode);
15916   operands[3] = gen_reg_rtx (XFmode);
15917   operands[4] = gen_reg_rtx (XFmode);
15918
15919   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15920 })
15921
15922 (define_expand "log2xf2"
15923   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15924                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15925                                (match_dup 2)] UNSPEC_FYL2X))
15926               (clobber (match_scratch:XF 3 ""))])]
15927   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15928    && flag_unsafe_math_optimizations"
15929 {
15930   operands[2] = gen_reg_rtx (XFmode);
15931   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15932 })
15933
15934 (define_insn "fyl2xp1_xf3"
15935   [(set (match_operand:XF 0 "register_operand" "=f")
15936         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15937                     (match_operand:XF 1 "register_operand" "u")]
15938                    UNSPEC_FYL2XP1))
15939    (clobber (match_scratch:XF 3 "=1"))]
15940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941    && flag_unsafe_math_optimizations"
15942   "fyl2xp1"
15943   [(set_attr "type" "fpspc")
15944    (set_attr "mode" "XF")])
15945
15946 (define_expand "log1psf2"
15947   [(use (match_operand:XF 0 "register_operand" ""))
15948    (use (match_operand:XF 1 "register_operand" ""))]
15949   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15950    && flag_unsafe_math_optimizations"
15951 {
15952   rtx op0 = gen_reg_rtx (XFmode);
15953   rtx op1 = gen_reg_rtx (XFmode);
15954
15955   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15956   ix86_emit_i387_log1p (op0, op1);
15957   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15958   DONE;
15959 })
15960
15961 (define_expand "log1pdf2"
15962   [(use (match_operand:XF 0 "register_operand" ""))
15963    (use (match_operand:XF 1 "register_operand" ""))]
15964   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15965    && flag_unsafe_math_optimizations"
15966 {
15967   rtx op0 = gen_reg_rtx (XFmode);
15968   rtx op1 = gen_reg_rtx (XFmode);
15969
15970   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15971   ix86_emit_i387_log1p (op0, op1);
15972   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15973   DONE;
15974 })
15975
15976 (define_expand "log1pxf2"
15977   [(use (match_operand:XF 0 "register_operand" ""))
15978    (use (match_operand:XF 1 "register_operand" ""))]
15979   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15980    && flag_unsafe_math_optimizations"
15981 {
15982   ix86_emit_i387_log1p (operands[0], operands[1]);
15983   DONE;
15984 })
15985
15986 (define_insn "*fxtractxf3"
15987   [(set (match_operand:XF 0 "register_operand" "=f")
15988         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15989                    UNSPEC_XTRACT_FRACT))
15990    (set (match_operand:XF 1 "register_operand" "=u")
15991         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15992   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15993    && flag_unsafe_math_optimizations"
15994   "fxtract"
15995   [(set_attr "type" "fpspc")
15996    (set_attr "mode" "XF")])
15997
15998 (define_expand "logbsf2"
15999   [(set (match_dup 2)
16000         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001    (parallel [(set (match_dup 3)
16002                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16003               (set (match_dup 4)
16004                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16005    (set (match_operand:SF 0 "register_operand" "")
16006         (float_truncate:SF (match_dup 4)))]
16007   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16008    && flag_unsafe_math_optimizations"
16009 {
16010   operands[2] = gen_reg_rtx (XFmode);
16011   operands[3] = gen_reg_rtx (XFmode);
16012   operands[4] = gen_reg_rtx (XFmode);
16013 })
16014
16015 (define_expand "logbdf2"
16016   [(set (match_dup 2)
16017         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16018    (parallel [(set (match_dup 3)
16019                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16020               (set (match_dup 4)
16021                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16022    (set (match_operand:DF 0 "register_operand" "")
16023         (float_truncate:DF (match_dup 4)))]
16024   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16025    && flag_unsafe_math_optimizations"
16026 {
16027   operands[2] = gen_reg_rtx (XFmode);
16028   operands[3] = gen_reg_rtx (XFmode);
16029   operands[4] = gen_reg_rtx (XFmode);
16030 })
16031
16032 (define_expand "logbxf2"
16033   [(parallel [(set (match_dup 2)
16034                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16035                               UNSPEC_XTRACT_FRACT))
16036               (set (match_operand:XF 0 "register_operand" "")
16037                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16038   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16039    && flag_unsafe_math_optimizations"
16040 {
16041   operands[2] = gen_reg_rtx (XFmode);
16042 })
16043
16044 (define_expand "ilogbsi2"
16045   [(parallel [(set (match_dup 2)
16046                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16047                               UNSPEC_XTRACT_FRACT))
16048               (set (match_operand:XF 3 "register_operand" "")
16049                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16050    (parallel [(set (match_operand:SI 0 "register_operand" "")
16051                    (fix:SI (match_dup 3)))
16052               (clobber (reg:CC FLAGS_REG))])]
16053   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16054    && flag_unsafe_math_optimizations"
16055 {
16056   operands[2] = gen_reg_rtx (XFmode);
16057   operands[3] = gen_reg_rtx (XFmode);
16058 })
16059
16060 (define_insn "*f2xm1xf2"
16061   [(set (match_operand:XF 0 "register_operand" "=f")
16062         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16063          UNSPEC_F2XM1))]
16064   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16065    && flag_unsafe_math_optimizations"
16066   "f2xm1"
16067   [(set_attr "type" "fpspc")
16068    (set_attr "mode" "XF")])
16069
16070 (define_insn "*fscalexf4"
16071   [(set (match_operand:XF 0 "register_operand" "=f")
16072         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16073                     (match_operand:XF 3 "register_operand" "1")]
16074                    UNSPEC_FSCALE_FRACT))
16075    (set (match_operand:XF 1 "register_operand" "=u")
16076         (unspec:XF [(match_dup 2) (match_dup 3)]
16077                    UNSPEC_FSCALE_EXP))]
16078   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16079    && flag_unsafe_math_optimizations"
16080   "fscale"
16081   [(set_attr "type" "fpspc")
16082    (set_attr "mode" "XF")])
16083
16084 (define_expand "expsf2"
16085   [(set (match_dup 2)
16086         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16087    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16088    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16089    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16090    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16091    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16092    (parallel [(set (match_dup 10)
16093                    (unspec:XF [(match_dup 9) (match_dup 5)]
16094                               UNSPEC_FSCALE_FRACT))
16095               (set (match_dup 11)
16096                    (unspec:XF [(match_dup 9) (match_dup 5)]
16097                               UNSPEC_FSCALE_EXP))])
16098    (set (match_operand:SF 0 "register_operand" "")
16099         (float_truncate:SF (match_dup 10)))]
16100   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16101    && flag_unsafe_math_optimizations"
16102 {
16103   rtx temp;
16104   int i;
16105
16106   for (i=2; i<12; i++)
16107     operands[i] = gen_reg_rtx (XFmode);
16108   temp = standard_80387_constant_rtx (5); /* fldl2e */
16109   emit_move_insn (operands[3], temp);
16110   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16111 })
16112
16113 (define_expand "expdf2"
16114   [(set (match_dup 2)
16115         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121    (parallel [(set (match_dup 10)
16122                    (unspec:XF [(match_dup 9) (match_dup 5)]
16123                               UNSPEC_FSCALE_FRACT))
16124               (set (match_dup 11)
16125                    (unspec:XF [(match_dup 9) (match_dup 5)]
16126                               UNSPEC_FSCALE_EXP))])
16127    (set (match_operand:DF 0 "register_operand" "")
16128         (float_truncate:DF (match_dup 10)))]
16129   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16130    && flag_unsafe_math_optimizations"
16131 {
16132   rtx temp;
16133   int i;
16134
16135   for (i=2; i<12; i++)
16136     operands[i] = gen_reg_rtx (XFmode);
16137   temp = standard_80387_constant_rtx (5); /* fldl2e */
16138   emit_move_insn (operands[3], temp);
16139   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16140 })
16141
16142 (define_expand "expxf2"
16143   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16144                                (match_dup 2)))
16145    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16146    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16147    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16148    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16149    (parallel [(set (match_operand:XF 0 "register_operand" "")
16150                    (unspec:XF [(match_dup 8) (match_dup 4)]
16151                               UNSPEC_FSCALE_FRACT))
16152               (set (match_dup 9)
16153                    (unspec:XF [(match_dup 8) (match_dup 4)]
16154                               UNSPEC_FSCALE_EXP))])]
16155   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16156    && flag_unsafe_math_optimizations"
16157 {
16158   rtx temp;
16159   int i;
16160
16161   for (i=2; i<10; i++)
16162     operands[i] = gen_reg_rtx (XFmode);
16163   temp = standard_80387_constant_rtx (5); /* fldl2e */
16164   emit_move_insn (operands[2], temp);
16165   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16166 })
16167
16168 (define_expand "exp10sf2"
16169   [(set (match_dup 2)
16170         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16171    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16172    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16173    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16174    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16175    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16176    (parallel [(set (match_dup 10)
16177                    (unspec:XF [(match_dup 9) (match_dup 5)]
16178                               UNSPEC_FSCALE_FRACT))
16179               (set (match_dup 11)
16180                    (unspec:XF [(match_dup 9) (match_dup 5)]
16181                               UNSPEC_FSCALE_EXP))])
16182    (set (match_operand:SF 0 "register_operand" "")
16183         (float_truncate:SF (match_dup 10)))]
16184   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16185    && flag_unsafe_math_optimizations"
16186 {
16187   rtx temp;
16188   int i;
16189
16190   for (i=2; i<12; i++)
16191     operands[i] = gen_reg_rtx (XFmode);
16192   temp = standard_80387_constant_rtx (6); /* fldl2t */
16193   emit_move_insn (operands[3], temp);
16194   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16195 })
16196
16197 (define_expand "exp10df2"
16198   [(set (match_dup 2)
16199         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16200    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16201    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16202    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16203    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16204    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16205    (parallel [(set (match_dup 10)
16206                    (unspec:XF [(match_dup 9) (match_dup 5)]
16207                               UNSPEC_FSCALE_FRACT))
16208               (set (match_dup 11)
16209                    (unspec:XF [(match_dup 9) (match_dup 5)]
16210                               UNSPEC_FSCALE_EXP))])
16211    (set (match_operand:DF 0 "register_operand" "")
16212         (float_truncate:DF (match_dup 10)))]
16213   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16214    && flag_unsafe_math_optimizations"
16215 {
16216   rtx temp;
16217   int i;
16218
16219   for (i=2; i<12; i++)
16220     operands[i] = gen_reg_rtx (XFmode);
16221   temp = standard_80387_constant_rtx (6); /* fldl2t */
16222   emit_move_insn (operands[3], temp);
16223   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16224 })
16225
16226 (define_expand "exp10xf2"
16227   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16228                                (match_dup 2)))
16229    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16230    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16231    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16232    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16233    (parallel [(set (match_operand:XF 0 "register_operand" "")
16234                    (unspec:XF [(match_dup 8) (match_dup 4)]
16235                               UNSPEC_FSCALE_FRACT))
16236               (set (match_dup 9)
16237                    (unspec:XF [(match_dup 8) (match_dup 4)]
16238                               UNSPEC_FSCALE_EXP))])]
16239   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16240    && flag_unsafe_math_optimizations"
16241 {
16242   rtx temp;
16243   int i;
16244
16245   for (i=2; i<10; i++)
16246     operands[i] = gen_reg_rtx (XFmode);
16247   temp = standard_80387_constant_rtx (6); /* fldl2t */
16248   emit_move_insn (operands[2], temp);
16249   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16250 })
16251
16252 (define_expand "exp2sf2"
16253   [(set (match_dup 2)
16254         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16255    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16256    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16257    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16258    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16259    (parallel [(set (match_dup 8)
16260                    (unspec:XF [(match_dup 7) (match_dup 3)]
16261                               UNSPEC_FSCALE_FRACT))
16262               (set (match_dup 9)
16263                    (unspec:XF [(match_dup 7) (match_dup 3)]
16264                               UNSPEC_FSCALE_EXP))])
16265    (set (match_operand:SF 0 "register_operand" "")
16266         (float_truncate:SF (match_dup 8)))]
16267   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16268    && flag_unsafe_math_optimizations"
16269 {
16270   int i;
16271
16272   for (i=2; i<10; i++)
16273     operands[i] = gen_reg_rtx (XFmode);
16274   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16275 })
16276
16277 (define_expand "exp2df2"
16278   [(set (match_dup 2)
16279         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16280    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16281    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16282    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16283    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16284    (parallel [(set (match_dup 8)
16285                    (unspec:XF [(match_dup 7) (match_dup 3)]
16286                               UNSPEC_FSCALE_FRACT))
16287               (set (match_dup 9)
16288                    (unspec:XF [(match_dup 7) (match_dup 3)]
16289                               UNSPEC_FSCALE_EXP))])
16290    (set (match_operand:DF 0 "register_operand" "")
16291         (float_truncate:DF (match_dup 8)))]
16292   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16293    && flag_unsafe_math_optimizations"
16294 {
16295   int i;
16296
16297   for (i=2; i<10; i++)
16298     operands[i] = gen_reg_rtx (XFmode);
16299   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16300 })
16301
16302 (define_expand "exp2xf2"
16303   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16304    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16305    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16306    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16307    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16308    (parallel [(set (match_operand:XF 0 "register_operand" "")
16309                    (unspec:XF [(match_dup 7) (match_dup 3)]
16310                               UNSPEC_FSCALE_FRACT))
16311               (set (match_dup 8)
16312                    (unspec:XF [(match_dup 7) (match_dup 3)]
16313                               UNSPEC_FSCALE_EXP))])]
16314   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16315    && flag_unsafe_math_optimizations"
16316 {
16317   int i;
16318
16319   for (i=2; i<9; i++)
16320     operands[i] = gen_reg_rtx (XFmode);
16321   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16322 })
16323
16324 (define_expand "expm1df2"
16325   [(set (match_dup 2)
16326         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16327    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16328    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16329    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16330    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16331    (parallel [(set (match_dup 8)
16332                    (unspec:XF [(match_dup 7) (match_dup 5)]
16333                               UNSPEC_FSCALE_FRACT))
16334                    (set (match_dup 9)
16335                    (unspec:XF [(match_dup 7) (match_dup 5)]
16336                               UNSPEC_FSCALE_EXP))])
16337    (parallel [(set (match_dup 11)
16338                    (unspec:XF [(match_dup 10) (match_dup 9)]
16339                               UNSPEC_FSCALE_FRACT))
16340               (set (match_dup 12)
16341                    (unspec:XF [(match_dup 10) (match_dup 9)]
16342                               UNSPEC_FSCALE_EXP))])
16343    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16344    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16345    (set (match_operand:DF 0 "register_operand" "")
16346         (float_truncate:DF (match_dup 14)))]
16347   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16348    && flag_unsafe_math_optimizations"
16349 {
16350   rtx temp;
16351   int i;
16352
16353   for (i=2; i<15; i++)
16354     operands[i] = gen_reg_rtx (XFmode);
16355   temp = standard_80387_constant_rtx (5); /* fldl2e */
16356   emit_move_insn (operands[3], temp);
16357   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16358 })
16359
16360 (define_expand "expm1sf2"
16361   [(set (match_dup 2)
16362         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16363    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16364    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16365    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16366    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16367    (parallel [(set (match_dup 8)
16368                    (unspec:XF [(match_dup 7) (match_dup 5)]
16369                               UNSPEC_FSCALE_FRACT))
16370                    (set (match_dup 9)
16371                    (unspec:XF [(match_dup 7) (match_dup 5)]
16372                               UNSPEC_FSCALE_EXP))])
16373    (parallel [(set (match_dup 11)
16374                    (unspec:XF [(match_dup 10) (match_dup 9)]
16375                               UNSPEC_FSCALE_FRACT))
16376               (set (match_dup 12)
16377                    (unspec:XF [(match_dup 10) (match_dup 9)]
16378                               UNSPEC_FSCALE_EXP))])
16379    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16380    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16381    (set (match_operand:SF 0 "register_operand" "")
16382         (float_truncate:SF (match_dup 14)))]
16383   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16384    && flag_unsafe_math_optimizations"
16385 {
16386   rtx temp;
16387   int i;
16388
16389   for (i=2; i<15; i++)
16390     operands[i] = gen_reg_rtx (XFmode);
16391   temp = standard_80387_constant_rtx (5); /* fldl2e */
16392   emit_move_insn (operands[3], temp);
16393   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16394 })
16395
16396 (define_expand "expm1xf2"
16397   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16398                                (match_dup 2)))
16399    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16400    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16401    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16402    (parallel [(set (match_dup 7)
16403                    (unspec:XF [(match_dup 6) (match_dup 4)]
16404                               UNSPEC_FSCALE_FRACT))
16405                    (set (match_dup 8)
16406                    (unspec:XF [(match_dup 6) (match_dup 4)]
16407                               UNSPEC_FSCALE_EXP))])
16408    (parallel [(set (match_dup 10)
16409                    (unspec:XF [(match_dup 9) (match_dup 8)]
16410                               UNSPEC_FSCALE_FRACT))
16411               (set (match_dup 11)
16412                    (unspec:XF [(match_dup 9) (match_dup 8)]
16413                               UNSPEC_FSCALE_EXP))])
16414    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16415    (set (match_operand:XF 0 "register_operand" "")
16416         (plus:XF (match_dup 12) (match_dup 7)))]
16417   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16418    && flag_unsafe_math_optimizations"
16419 {
16420   rtx temp;
16421   int i;
16422
16423   for (i=2; i<13; i++)
16424     operands[i] = gen_reg_rtx (XFmode);
16425   temp = standard_80387_constant_rtx (5); /* fldl2e */
16426   emit_move_insn (operands[2], temp);
16427   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16428 })
16429 \f
16430
16431 (define_insn "frndintxf2"
16432   [(set (match_operand:XF 0 "register_operand" "=f")
16433         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16434          UNSPEC_FRNDINT))]
16435   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16436    && flag_unsafe_math_optimizations"
16437   "frndint"
16438   [(set_attr "type" "fpspc")
16439    (set_attr "mode" "XF")])
16440
16441 (define_expand "rintdf2"
16442   [(use (match_operand:DF 0 "register_operand" ""))
16443    (use (match_operand:DF 1 "register_operand" ""))]
16444   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16445    && flag_unsafe_math_optimizations"
16446 {
16447   rtx op0 = gen_reg_rtx (XFmode);
16448   rtx op1 = gen_reg_rtx (XFmode);
16449
16450   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16451   emit_insn (gen_frndintxf2 (op0, op1));
16452
16453   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16454   DONE;
16455 })
16456
16457 (define_expand "rintsf2"
16458   [(use (match_operand:SF 0 "register_operand" ""))
16459    (use (match_operand:SF 1 "register_operand" ""))]
16460   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16461    && flag_unsafe_math_optimizations"
16462 {
16463   rtx op0 = gen_reg_rtx (XFmode);
16464   rtx op1 = gen_reg_rtx (XFmode);
16465
16466   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16467   emit_insn (gen_frndintxf2 (op0, op1));
16468
16469   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16470   DONE;
16471 })
16472
16473 (define_expand "rintxf2"
16474   [(use (match_operand:XF 0 "register_operand" ""))
16475    (use (match_operand:XF 1 "register_operand" ""))]
16476   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16477    && flag_unsafe_math_optimizations"
16478 {
16479   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16480   DONE;
16481 })
16482
16483 (define_insn "frndintxf2_floor"
16484   [(set (match_operand:XF 0 "register_operand" "=f")
16485         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16486          UNSPEC_FRNDINT_FLOOR))
16487    (use (match_operand:HI 2 "memory_operand" "m"))
16488    (use (match_operand:HI 3 "memory_operand" "m"))]
16489   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16490    && flag_unsafe_math_optimizations"
16491   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16492   [(set_attr "type" "frndint")
16493    (set_attr "i387_cw" "floor")
16494    (set_attr "mode" "XF")])
16495
16496 (define_expand "floordf2"
16497   [(use (match_operand:DF 0 "register_operand" ""))
16498    (use (match_operand:DF 1 "register_operand" ""))]
16499   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16500    && flag_unsafe_math_optimizations"
16501 {
16502   rtx op0 = gen_reg_rtx (XFmode);
16503   rtx op1 = gen_reg_rtx (XFmode);
16504   rtx op2 = assign_386_stack_local (HImode, 1);
16505   rtx op3 = assign_386_stack_local (HImode, 2);
16506         
16507   ix86_optimize_mode_switching = 1;
16508
16509   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16510   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16511
16512   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16513   DONE;
16514 })
16515
16516 (define_expand "floorsf2"
16517   [(use (match_operand:SF 0 "register_operand" ""))
16518    (use (match_operand:SF 1 "register_operand" ""))]
16519   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16520    && flag_unsafe_math_optimizations"
16521 {
16522   rtx op0 = gen_reg_rtx (XFmode);
16523   rtx op1 = gen_reg_rtx (XFmode);
16524   rtx op2 = assign_386_stack_local (HImode, 1);
16525   rtx op3 = assign_386_stack_local (HImode, 2);
16526         
16527   ix86_optimize_mode_switching = 1;
16528
16529   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16530   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16531
16532   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16533   DONE;
16534 })
16535
16536 (define_expand "floorxf2"
16537   [(use (match_operand:XF 0 "register_operand" ""))
16538    (use (match_operand:XF 1 "register_operand" ""))]
16539   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16540    && flag_unsafe_math_optimizations"
16541 {
16542   rtx op2 = assign_386_stack_local (HImode, 1);
16543   rtx op3 = assign_386_stack_local (HImode, 2);
16544         
16545   ix86_optimize_mode_switching = 1;
16546
16547   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16548   DONE;
16549 })
16550
16551 (define_insn "frndintxf2_ceil"
16552   [(set (match_operand:XF 0 "register_operand" "=f")
16553         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16554          UNSPEC_FRNDINT_CEIL))
16555    (use (match_operand:HI 2 "memory_operand" "m"))
16556    (use (match_operand:HI 3 "memory_operand" "m"))]
16557   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16558    && flag_unsafe_math_optimizations"
16559   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16560   [(set_attr "type" "frndint")
16561    (set_attr "i387_cw" "ceil")
16562    (set_attr "mode" "XF")])
16563
16564 (define_expand "ceildf2"
16565   [(use (match_operand:DF 0 "register_operand" ""))
16566    (use (match_operand:DF 1 "register_operand" ""))]
16567   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16568    && flag_unsafe_math_optimizations"
16569 {
16570   rtx op0 = gen_reg_rtx (XFmode);
16571   rtx op1 = gen_reg_rtx (XFmode);
16572   rtx op2 = assign_386_stack_local (HImode, 1);
16573   rtx op3 = assign_386_stack_local (HImode, 2);
16574         
16575   ix86_optimize_mode_switching = 1;
16576
16577   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16578   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16579
16580   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16581   DONE;
16582 })
16583
16584 (define_expand "ceilsf2"
16585   [(use (match_operand:SF 0 "register_operand" ""))
16586    (use (match_operand:SF 1 "register_operand" ""))]
16587   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16588    && flag_unsafe_math_optimizations"
16589 {
16590   rtx op0 = gen_reg_rtx (XFmode);
16591   rtx op1 = gen_reg_rtx (XFmode);
16592   rtx op2 = assign_386_stack_local (HImode, 1);
16593   rtx op3 = assign_386_stack_local (HImode, 2);
16594         
16595   ix86_optimize_mode_switching = 1;
16596
16597   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16599
16600   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16601   DONE;
16602 })
16603
16604 (define_expand "ceilxf2"
16605   [(use (match_operand:XF 0 "register_operand" ""))
16606    (use (match_operand:XF 1 "register_operand" ""))]
16607   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16608    && flag_unsafe_math_optimizations"
16609 {
16610   rtx op2 = assign_386_stack_local (HImode, 1);
16611   rtx op3 = assign_386_stack_local (HImode, 2);
16612         
16613   ix86_optimize_mode_switching = 1;
16614
16615   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16616   DONE;
16617 })
16618
16619 (define_insn "frndintxf2_trunc"
16620   [(set (match_operand:XF 0 "register_operand" "=f")
16621         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16622          UNSPEC_FRNDINT_TRUNC))
16623    (use (match_operand:HI 2 "memory_operand" "m"))
16624    (use (match_operand:HI 3 "memory_operand" "m"))]
16625   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16626    && flag_unsafe_math_optimizations"
16627   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16628   [(set_attr "type" "frndint")
16629    (set_attr "i387_cw" "trunc")
16630    (set_attr "mode" "XF")])
16631
16632 (define_expand "btruncdf2"
16633   [(use (match_operand:DF 0 "register_operand" ""))
16634    (use (match_operand:DF 1 "register_operand" ""))]
16635   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16636    && flag_unsafe_math_optimizations"
16637 {
16638   rtx op0 = gen_reg_rtx (XFmode);
16639   rtx op1 = gen_reg_rtx (XFmode);
16640   rtx op2 = assign_386_stack_local (HImode, 1);
16641   rtx op3 = assign_386_stack_local (HImode, 2);
16642         
16643   ix86_optimize_mode_switching = 1;
16644
16645   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16646   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16647
16648   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16649   DONE;
16650 })
16651
16652 (define_expand "btruncsf2"
16653   [(use (match_operand:SF 0 "register_operand" ""))
16654    (use (match_operand:SF 1 "register_operand" ""))]
16655   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16656    && flag_unsafe_math_optimizations"
16657 {
16658   rtx op0 = gen_reg_rtx (XFmode);
16659   rtx op1 = gen_reg_rtx (XFmode);
16660   rtx op2 = assign_386_stack_local (HImode, 1);
16661   rtx op3 = assign_386_stack_local (HImode, 2);
16662         
16663   ix86_optimize_mode_switching = 1;
16664
16665   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16666   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16667
16668   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16669   DONE;
16670 })
16671
16672 (define_expand "btruncxf2"
16673   [(use (match_operand:XF 0 "register_operand" ""))
16674    (use (match_operand:XF 1 "register_operand" ""))]
16675   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16676    && flag_unsafe_math_optimizations"
16677 {
16678   rtx op2 = assign_386_stack_local (HImode, 1);
16679   rtx op3 = assign_386_stack_local (HImode, 2);
16680         
16681   ix86_optimize_mode_switching = 1;
16682
16683   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16684   DONE;
16685 })
16686
16687 (define_insn "frndintxf2_mask_pm"
16688   [(set (match_operand:XF 0 "register_operand" "=f")
16689         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16690          UNSPEC_FRNDINT_MASK_PM))
16691    (use (match_operand:HI 2 "memory_operand" "m"))
16692    (use (match_operand:HI 3 "memory_operand" "m"))]
16693   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16694    && flag_unsafe_math_optimizations"
16695   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16696   [(set_attr "type" "frndint")
16697    (set_attr "i387_cw" "mask_pm")
16698    (set_attr "mode" "XF")])
16699
16700 (define_expand "nearbyintdf2"
16701   [(use (match_operand:DF 0 "register_operand" ""))
16702    (use (match_operand:DF 1 "register_operand" ""))]
16703   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16704    && flag_unsafe_math_optimizations"
16705 {
16706   rtx op0 = gen_reg_rtx (XFmode);
16707   rtx op1 = gen_reg_rtx (XFmode);
16708   rtx op2 = assign_386_stack_local (HImode, 1);
16709   rtx op3 = assign_386_stack_local (HImode, 2);
16710         
16711   ix86_optimize_mode_switching = 1;
16712
16713   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16714   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16715
16716   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16717   DONE;
16718 })
16719
16720 (define_expand "nearbyintsf2"
16721   [(use (match_operand:SF 0 "register_operand" ""))
16722    (use (match_operand:SF 1 "register_operand" ""))]
16723   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16724    && flag_unsafe_math_optimizations"
16725 {
16726   rtx op0 = gen_reg_rtx (XFmode);
16727   rtx op1 = gen_reg_rtx (XFmode);
16728   rtx op2 = assign_386_stack_local (HImode, 1);
16729   rtx op3 = assign_386_stack_local (HImode, 2);
16730         
16731   ix86_optimize_mode_switching = 1;
16732
16733   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16734   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16735
16736   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16737   DONE;
16738 })
16739
16740 (define_expand "nearbyintxf2"
16741   [(use (match_operand:XF 0 "register_operand" ""))
16742    (use (match_operand:XF 1 "register_operand" ""))]
16743   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16744    && flag_unsafe_math_optimizations"
16745 {
16746   rtx op2 = assign_386_stack_local (HImode, 1);
16747   rtx op3 = assign_386_stack_local (HImode, 2);
16748         
16749   ix86_optimize_mode_switching = 1;
16750
16751   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16752                                      op2, op3));
16753   DONE;
16754 })
16755
16756 \f
16757 ;; Block operation instructions
16758
16759 (define_insn "cld"
16760  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16761  ""
16762  "cld"
16763   [(set_attr "type" "cld")])
16764
16765 (define_expand "movmemsi"
16766   [(use (match_operand:BLK 0 "memory_operand" ""))
16767    (use (match_operand:BLK 1 "memory_operand" ""))
16768    (use (match_operand:SI 2 "nonmemory_operand" ""))
16769    (use (match_operand:SI 3 "const_int_operand" ""))]
16770   "! optimize_size"
16771 {
16772  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16773    DONE;
16774  else
16775    FAIL;
16776 })
16777
16778 (define_expand "movmemdi"
16779   [(use (match_operand:BLK 0 "memory_operand" ""))
16780    (use (match_operand:BLK 1 "memory_operand" ""))
16781    (use (match_operand:DI 2 "nonmemory_operand" ""))
16782    (use (match_operand:DI 3 "const_int_operand" ""))]
16783   "TARGET_64BIT"
16784 {
16785  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16786    DONE;
16787  else
16788    FAIL;
16789 })
16790
16791 ;; Most CPUs don't like single string operations
16792 ;; Handle this case here to simplify previous expander.
16793
16794 (define_expand "strmov"
16795   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16796    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16797    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16798               (clobber (reg:CC FLAGS_REG))])
16799    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16800               (clobber (reg:CC FLAGS_REG))])]
16801   ""
16802 {
16803   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16804
16805   /* If .md ever supports :P for Pmode, these can be directly
16806      in the pattern above.  */
16807   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16808   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16809
16810   if (TARGET_SINGLE_STRINGOP || optimize_size)
16811     {
16812       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16813                                       operands[2], operands[3],
16814                                       operands[5], operands[6]));
16815       DONE;
16816     }
16817
16818   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16819 })
16820
16821 (define_expand "strmov_singleop"
16822   [(parallel [(set (match_operand 1 "memory_operand" "")
16823                    (match_operand 3 "memory_operand" ""))
16824               (set (match_operand 0 "register_operand" "")
16825                    (match_operand 4 "" ""))
16826               (set (match_operand 2 "register_operand" "")
16827                    (match_operand 5 "" ""))
16828               (use (reg:SI DIRFLAG_REG))])]
16829   "TARGET_SINGLE_STRINGOP || optimize_size"
16830   "")
16831
16832 (define_insn "*strmovdi_rex_1"
16833   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16834         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16835    (set (match_operand:DI 0 "register_operand" "=D")
16836         (plus:DI (match_dup 2)
16837                  (const_int 8)))
16838    (set (match_operand:DI 1 "register_operand" "=S")
16839         (plus:DI (match_dup 3)
16840                  (const_int 8)))
16841    (use (reg:SI DIRFLAG_REG))]
16842   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16843   "movsq"
16844   [(set_attr "type" "str")
16845    (set_attr "mode" "DI")
16846    (set_attr "memory" "both")])
16847
16848 (define_insn "*strmovsi_1"
16849   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16850         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16851    (set (match_operand:SI 0 "register_operand" "=D")
16852         (plus:SI (match_dup 2)
16853                  (const_int 4)))
16854    (set (match_operand:SI 1 "register_operand" "=S")
16855         (plus:SI (match_dup 3)
16856                  (const_int 4)))
16857    (use (reg:SI DIRFLAG_REG))]
16858   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16859   "{movsl|movsd}"
16860   [(set_attr "type" "str")
16861    (set_attr "mode" "SI")
16862    (set_attr "memory" "both")])
16863
16864 (define_insn "*strmovsi_rex_1"
16865   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16866         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16867    (set (match_operand:DI 0 "register_operand" "=D")
16868         (plus:DI (match_dup 2)
16869                  (const_int 4)))
16870    (set (match_operand:DI 1 "register_operand" "=S")
16871         (plus:DI (match_dup 3)
16872                  (const_int 4)))
16873    (use (reg:SI DIRFLAG_REG))]
16874   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16875   "{movsl|movsd}"
16876   [(set_attr "type" "str")
16877    (set_attr "mode" "SI")
16878    (set_attr "memory" "both")])
16879
16880 (define_insn "*strmovhi_1"
16881   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16882         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16883    (set (match_operand:SI 0 "register_operand" "=D")
16884         (plus:SI (match_dup 2)
16885                  (const_int 2)))
16886    (set (match_operand:SI 1 "register_operand" "=S")
16887         (plus:SI (match_dup 3)
16888                  (const_int 2)))
16889    (use (reg:SI DIRFLAG_REG))]
16890   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16891   "movsw"
16892   [(set_attr "type" "str")
16893    (set_attr "memory" "both")
16894    (set_attr "mode" "HI")])
16895
16896 (define_insn "*strmovhi_rex_1"
16897   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16898         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16899    (set (match_operand:DI 0 "register_operand" "=D")
16900         (plus:DI (match_dup 2)
16901                  (const_int 2)))
16902    (set (match_operand:DI 1 "register_operand" "=S")
16903         (plus:DI (match_dup 3)
16904                  (const_int 2)))
16905    (use (reg:SI DIRFLAG_REG))]
16906   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16907   "movsw"
16908   [(set_attr "type" "str")
16909    (set_attr "memory" "both")
16910    (set_attr "mode" "HI")])
16911
16912 (define_insn "*strmovqi_1"
16913   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16914         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16915    (set (match_operand:SI 0 "register_operand" "=D")
16916         (plus:SI (match_dup 2)
16917                  (const_int 1)))
16918    (set (match_operand:SI 1 "register_operand" "=S")
16919         (plus:SI (match_dup 3)
16920                  (const_int 1)))
16921    (use (reg:SI DIRFLAG_REG))]
16922   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16923   "movsb"
16924   [(set_attr "type" "str")
16925    (set_attr "memory" "both")
16926    (set_attr "mode" "QI")])
16927
16928 (define_insn "*strmovqi_rex_1"
16929   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16930         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16931    (set (match_operand:DI 0 "register_operand" "=D")
16932         (plus:DI (match_dup 2)
16933                  (const_int 1)))
16934    (set (match_operand:DI 1 "register_operand" "=S")
16935         (plus:DI (match_dup 3)
16936                  (const_int 1)))
16937    (use (reg:SI DIRFLAG_REG))]
16938   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16939   "movsb"
16940   [(set_attr "type" "str")
16941    (set_attr "memory" "both")
16942    (set_attr "mode" "QI")])
16943
16944 (define_expand "rep_mov"
16945   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16946               (set (match_operand 0 "register_operand" "")
16947                    (match_operand 5 "" ""))
16948               (set (match_operand 2 "register_operand" "")
16949                    (match_operand 6 "" ""))
16950               (set (match_operand 1 "memory_operand" "")
16951                    (match_operand 3 "memory_operand" ""))
16952               (use (match_dup 4))
16953               (use (reg:SI DIRFLAG_REG))])]
16954   ""
16955   "")
16956
16957 (define_insn "*rep_movdi_rex64"
16958   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16959    (set (match_operand:DI 0 "register_operand" "=D") 
16960         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16961                             (const_int 3))
16962                  (match_operand:DI 3 "register_operand" "0")))
16963    (set (match_operand:DI 1 "register_operand" "=S") 
16964         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16965                  (match_operand:DI 4 "register_operand" "1")))
16966    (set (mem:BLK (match_dup 3))
16967         (mem:BLK (match_dup 4)))
16968    (use (match_dup 5))
16969    (use (reg:SI DIRFLAG_REG))]
16970   "TARGET_64BIT"
16971   "{rep\;movsq|rep movsq}"
16972   [(set_attr "type" "str")
16973    (set_attr "prefix_rep" "1")
16974    (set_attr "memory" "both")
16975    (set_attr "mode" "DI")])
16976
16977 (define_insn "*rep_movsi"
16978   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16979    (set (match_operand:SI 0 "register_operand" "=D") 
16980         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16981                             (const_int 2))
16982                  (match_operand:SI 3 "register_operand" "0")))
16983    (set (match_operand:SI 1 "register_operand" "=S") 
16984         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16985                  (match_operand:SI 4 "register_operand" "1")))
16986    (set (mem:BLK (match_dup 3))
16987         (mem:BLK (match_dup 4)))
16988    (use (match_dup 5))
16989    (use (reg:SI DIRFLAG_REG))]
16990   "!TARGET_64BIT"
16991   "{rep\;movsl|rep movsd}"
16992   [(set_attr "type" "str")
16993    (set_attr "prefix_rep" "1")
16994    (set_attr "memory" "both")
16995    (set_attr "mode" "SI")])
16996
16997 (define_insn "*rep_movsi_rex64"
16998   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16999    (set (match_operand:DI 0 "register_operand" "=D") 
17000         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17001                             (const_int 2))
17002                  (match_operand:DI 3 "register_operand" "0")))
17003    (set (match_operand:DI 1 "register_operand" "=S") 
17004         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17005                  (match_operand:DI 4 "register_operand" "1")))
17006    (set (mem:BLK (match_dup 3))
17007         (mem:BLK (match_dup 4)))
17008    (use (match_dup 5))
17009    (use (reg:SI DIRFLAG_REG))]
17010   "TARGET_64BIT"
17011   "{rep\;movsl|rep movsd}"
17012   [(set_attr "type" "str")
17013    (set_attr "prefix_rep" "1")
17014    (set_attr "memory" "both")
17015    (set_attr "mode" "SI")])
17016
17017 (define_insn "*rep_movqi"
17018   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17019    (set (match_operand:SI 0 "register_operand" "=D") 
17020         (plus:SI (match_operand:SI 3 "register_operand" "0")
17021                  (match_operand:SI 5 "register_operand" "2")))
17022    (set (match_operand:SI 1 "register_operand" "=S") 
17023         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17024    (set (mem:BLK (match_dup 3))
17025         (mem:BLK (match_dup 4)))
17026    (use (match_dup 5))
17027    (use (reg:SI DIRFLAG_REG))]
17028   "!TARGET_64BIT"
17029   "{rep\;movsb|rep movsb}"
17030   [(set_attr "type" "str")
17031    (set_attr "prefix_rep" "1")
17032    (set_attr "memory" "both")
17033    (set_attr "mode" "SI")])
17034
17035 (define_insn "*rep_movqi_rex64"
17036   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17037    (set (match_operand:DI 0 "register_operand" "=D") 
17038         (plus:DI (match_operand:DI 3 "register_operand" "0")
17039                  (match_operand:DI 5 "register_operand" "2")))
17040    (set (match_operand:DI 1 "register_operand" "=S") 
17041         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17042    (set (mem:BLK (match_dup 3))
17043         (mem:BLK (match_dup 4)))
17044    (use (match_dup 5))
17045    (use (reg:SI DIRFLAG_REG))]
17046   "TARGET_64BIT"
17047   "{rep\;movsb|rep movsb}"
17048   [(set_attr "type" "str")
17049    (set_attr "prefix_rep" "1")
17050    (set_attr "memory" "both")
17051    (set_attr "mode" "SI")])
17052
17053 (define_expand "clrmemsi"
17054    [(use (match_operand:BLK 0 "memory_operand" ""))
17055     (use (match_operand:SI 1 "nonmemory_operand" ""))
17056     (use (match_operand 2 "const_int_operand" ""))]
17057   ""
17058 {
17059  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17060    DONE;
17061  else
17062    FAIL;
17063 })
17064
17065 (define_expand "clrmemdi"
17066    [(use (match_operand:BLK 0 "memory_operand" ""))
17067     (use (match_operand:DI 1 "nonmemory_operand" ""))
17068     (use (match_operand 2 "const_int_operand" ""))]
17069   "TARGET_64BIT"
17070 {
17071  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17072    DONE;
17073  else
17074    FAIL;
17075 })
17076
17077 ;; Most CPUs don't like single string operations
17078 ;; Handle this case here to simplify previous expander.
17079
17080 (define_expand "strset"
17081   [(set (match_operand 1 "memory_operand" "")
17082         (match_operand 2 "register_operand" ""))
17083    (parallel [(set (match_operand 0 "register_operand" "")
17084                    (match_dup 3))
17085               (clobber (reg:CC FLAGS_REG))])]
17086   ""
17087 {
17088   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17089     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17090
17091   /* If .md ever supports :P for Pmode, this can be directly
17092      in the pattern above.  */
17093   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17094                               GEN_INT (GET_MODE_SIZE (GET_MODE
17095                                                       (operands[2]))));
17096   if (TARGET_SINGLE_STRINGOP || optimize_size)
17097     {
17098       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17099                                       operands[3]));
17100       DONE;
17101     }
17102 })
17103
17104 (define_expand "strset_singleop"
17105   [(parallel [(set (match_operand 1 "memory_operand" "")
17106                    (match_operand 2 "register_operand" ""))
17107               (set (match_operand 0 "register_operand" "")
17108                    (match_operand 3 "" ""))
17109               (use (reg:SI DIRFLAG_REG))])]
17110   "TARGET_SINGLE_STRINGOP || optimize_size"
17111   "")
17112
17113 (define_insn "*strsetdi_rex_1"
17114   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17115         (match_operand:DI 2 "register_operand" "a"))
17116    (set (match_operand:DI 0 "register_operand" "=D")
17117         (plus:DI (match_dup 1)
17118                  (const_int 8)))
17119    (use (reg:SI DIRFLAG_REG))]
17120   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17121   "stosq"
17122   [(set_attr "type" "str")
17123    (set_attr "memory" "store")
17124    (set_attr "mode" "DI")])
17125
17126 (define_insn "*strsetsi_1"
17127   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17128         (match_operand:SI 2 "register_operand" "a"))
17129    (set (match_operand:SI 0 "register_operand" "=D")
17130         (plus:SI (match_dup 1)
17131                  (const_int 4)))
17132    (use (reg:SI DIRFLAG_REG))]
17133   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17134   "{stosl|stosd}"
17135   [(set_attr "type" "str")
17136    (set_attr "memory" "store")
17137    (set_attr "mode" "SI")])
17138
17139 (define_insn "*strsetsi_rex_1"
17140   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17141         (match_operand:SI 2 "register_operand" "a"))
17142    (set (match_operand:DI 0 "register_operand" "=D")
17143         (plus:DI (match_dup 1)
17144                  (const_int 4)))
17145    (use (reg:SI DIRFLAG_REG))]
17146   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17147   "{stosl|stosd}"
17148   [(set_attr "type" "str")
17149    (set_attr "memory" "store")
17150    (set_attr "mode" "SI")])
17151
17152 (define_insn "*strsethi_1"
17153   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17154         (match_operand:HI 2 "register_operand" "a"))
17155    (set (match_operand:SI 0 "register_operand" "=D")
17156         (plus:SI (match_dup 1)
17157                  (const_int 2)))
17158    (use (reg:SI DIRFLAG_REG))]
17159   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17160   "stosw"
17161   [(set_attr "type" "str")
17162    (set_attr "memory" "store")
17163    (set_attr "mode" "HI")])
17164
17165 (define_insn "*strsethi_rex_1"
17166   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17167         (match_operand:HI 2 "register_operand" "a"))
17168    (set (match_operand:DI 0 "register_operand" "=D")
17169         (plus:DI (match_dup 1)
17170                  (const_int 2)))
17171    (use (reg:SI DIRFLAG_REG))]
17172   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17173   "stosw"
17174   [(set_attr "type" "str")
17175    (set_attr "memory" "store")
17176    (set_attr "mode" "HI")])
17177
17178 (define_insn "*strsetqi_1"
17179   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17180         (match_operand:QI 2 "register_operand" "a"))
17181    (set (match_operand:SI 0 "register_operand" "=D")
17182         (plus:SI (match_dup 1)
17183                  (const_int 1)))
17184    (use (reg:SI DIRFLAG_REG))]
17185   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17186   "stosb"
17187   [(set_attr "type" "str")
17188    (set_attr "memory" "store")
17189    (set_attr "mode" "QI")])
17190
17191 (define_insn "*strsetqi_rex_1"
17192   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17193         (match_operand:QI 2 "register_operand" "a"))
17194    (set (match_operand:DI 0 "register_operand" "=D")
17195         (plus:DI (match_dup 1)
17196                  (const_int 1)))
17197    (use (reg:SI DIRFLAG_REG))]
17198   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17199   "stosb"
17200   [(set_attr "type" "str")
17201    (set_attr "memory" "store")
17202    (set_attr "mode" "QI")])
17203
17204 (define_expand "rep_stos"
17205   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17206               (set (match_operand 0 "register_operand" "")
17207                    (match_operand 4 "" ""))
17208               (set (match_operand 2 "memory_operand" "") (const_int 0))
17209               (use (match_operand 3 "register_operand" ""))
17210               (use (match_dup 1))
17211               (use (reg:SI DIRFLAG_REG))])]
17212   ""
17213   "")
17214
17215 (define_insn "*rep_stosdi_rex64"
17216   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17217    (set (match_operand:DI 0 "register_operand" "=D") 
17218         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17219                             (const_int 3))
17220                  (match_operand:DI 3 "register_operand" "0")))
17221    (set (mem:BLK (match_dup 3))
17222         (const_int 0))
17223    (use (match_operand:DI 2 "register_operand" "a"))
17224    (use (match_dup 4))
17225    (use (reg:SI DIRFLAG_REG))]
17226   "TARGET_64BIT"
17227   "{rep\;stosq|rep stosq}"
17228   [(set_attr "type" "str")
17229    (set_attr "prefix_rep" "1")
17230    (set_attr "memory" "store")
17231    (set_attr "mode" "DI")])
17232
17233 (define_insn "*rep_stossi"
17234   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17235    (set (match_operand:SI 0 "register_operand" "=D") 
17236         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17237                             (const_int 2))
17238                  (match_operand:SI 3 "register_operand" "0")))
17239    (set (mem:BLK (match_dup 3))
17240         (const_int 0))
17241    (use (match_operand:SI 2 "register_operand" "a"))
17242    (use (match_dup 4))
17243    (use (reg:SI DIRFLAG_REG))]
17244   "!TARGET_64BIT"
17245   "{rep\;stosl|rep stosd}"
17246   [(set_attr "type" "str")
17247    (set_attr "prefix_rep" "1")
17248    (set_attr "memory" "store")
17249    (set_attr "mode" "SI")])
17250
17251 (define_insn "*rep_stossi_rex64"
17252   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17253    (set (match_operand:DI 0 "register_operand" "=D") 
17254         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17255                             (const_int 2))
17256                  (match_operand:DI 3 "register_operand" "0")))
17257    (set (mem:BLK (match_dup 3))
17258         (const_int 0))
17259    (use (match_operand:SI 2 "register_operand" "a"))
17260    (use (match_dup 4))
17261    (use (reg:SI DIRFLAG_REG))]
17262   "TARGET_64BIT"
17263   "{rep\;stosl|rep stosd}"
17264   [(set_attr "type" "str")
17265    (set_attr "prefix_rep" "1")
17266    (set_attr "memory" "store")
17267    (set_attr "mode" "SI")])
17268
17269 (define_insn "*rep_stosqi"
17270   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17271    (set (match_operand:SI 0 "register_operand" "=D") 
17272         (plus:SI (match_operand:SI 3 "register_operand" "0")
17273                  (match_operand:SI 4 "register_operand" "1")))
17274    (set (mem:BLK (match_dup 3))
17275         (const_int 0))
17276    (use (match_operand:QI 2 "register_operand" "a"))
17277    (use (match_dup 4))
17278    (use (reg:SI DIRFLAG_REG))]
17279   "!TARGET_64BIT"
17280   "{rep\;stosb|rep stosb}"
17281   [(set_attr "type" "str")
17282    (set_attr "prefix_rep" "1")
17283    (set_attr "memory" "store")
17284    (set_attr "mode" "QI")])
17285
17286 (define_insn "*rep_stosqi_rex64"
17287   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17288    (set (match_operand:DI 0 "register_operand" "=D") 
17289         (plus:DI (match_operand:DI 3 "register_operand" "0")
17290                  (match_operand:DI 4 "register_operand" "1")))
17291    (set (mem:BLK (match_dup 3))
17292         (const_int 0))
17293    (use (match_operand:QI 2 "register_operand" "a"))
17294    (use (match_dup 4))
17295    (use (reg:SI DIRFLAG_REG))]
17296   "TARGET_64BIT"
17297   "{rep\;stosb|rep stosb}"
17298   [(set_attr "type" "str")
17299    (set_attr "prefix_rep" "1")
17300    (set_attr "memory" "store")
17301    (set_attr "mode" "QI")])
17302
17303 (define_expand "cmpstrsi"
17304   [(set (match_operand:SI 0 "register_operand" "")
17305         (compare:SI (match_operand:BLK 1 "general_operand" "")
17306                     (match_operand:BLK 2 "general_operand" "")))
17307    (use (match_operand 3 "general_operand" ""))
17308    (use (match_operand 4 "immediate_operand" ""))]
17309   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17310 {
17311   rtx addr1, addr2, out, outlow, count, countreg, align;
17312
17313   /* Can't use this if the user has appropriated esi or edi.  */
17314   if (global_regs[4] || global_regs[5])
17315     FAIL;
17316
17317   out = operands[0];
17318   if (GET_CODE (out) != REG)
17319     out = gen_reg_rtx (SImode);
17320
17321   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17322   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17323   if (addr1 != XEXP (operands[1], 0))
17324     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17325   if (addr2 != XEXP (operands[2], 0))
17326     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17327
17328   count = operands[3];
17329   countreg = ix86_zero_extend_to_Pmode (count);
17330
17331   /* %%% Iff we are testing strict equality, we can use known alignment
17332      to good advantage.  This may be possible with combine, particularly
17333      once cc0 is dead.  */
17334   align = operands[4];
17335
17336   emit_insn (gen_cld ());
17337   if (GET_CODE (count) == CONST_INT)
17338     {
17339       if (INTVAL (count) == 0)
17340         {
17341           emit_move_insn (operands[0], const0_rtx);
17342           DONE;
17343         }
17344       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17345                                     operands[1], operands[2]));
17346     }
17347   else
17348     {
17349       if (TARGET_64BIT)
17350         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17351       else
17352         emit_insn (gen_cmpsi_1 (countreg, countreg));
17353       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17354                                  operands[1], operands[2]));
17355     }
17356
17357   outlow = gen_lowpart (QImode, out);
17358   emit_insn (gen_cmpintqi (outlow));
17359   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17360
17361   if (operands[0] != out)
17362     emit_move_insn (operands[0], out);
17363
17364   DONE;
17365 })
17366
17367 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17368
17369 (define_expand "cmpintqi"
17370   [(set (match_dup 1)
17371         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17372    (set (match_dup 2)
17373         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17374    (parallel [(set (match_operand:QI 0 "register_operand" "")
17375                    (minus:QI (match_dup 1)
17376                              (match_dup 2)))
17377               (clobber (reg:CC FLAGS_REG))])]
17378   ""
17379   "operands[1] = gen_reg_rtx (QImode);
17380    operands[2] = gen_reg_rtx (QImode);")
17381
17382 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17383 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17384
17385 (define_expand "cmpstrqi_nz_1"
17386   [(parallel [(set (reg:CC FLAGS_REG)
17387                    (compare:CC (match_operand 4 "memory_operand" "")
17388                                (match_operand 5 "memory_operand" "")))
17389               (use (match_operand 2 "register_operand" ""))
17390               (use (match_operand:SI 3 "immediate_operand" ""))
17391               (use (reg:SI DIRFLAG_REG))
17392               (clobber (match_operand 0 "register_operand" ""))
17393               (clobber (match_operand 1 "register_operand" ""))
17394               (clobber (match_dup 2))])]
17395   ""
17396   "")
17397
17398 (define_insn "*cmpstrqi_nz_1"
17399   [(set (reg:CC FLAGS_REG)
17400         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17401                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17402    (use (match_operand:SI 6 "register_operand" "2"))
17403    (use (match_operand:SI 3 "immediate_operand" "i"))
17404    (use (reg:SI DIRFLAG_REG))
17405    (clobber (match_operand:SI 0 "register_operand" "=S"))
17406    (clobber (match_operand:SI 1 "register_operand" "=D"))
17407    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17408   "!TARGET_64BIT"
17409   "repz{\;| }cmpsb"
17410   [(set_attr "type" "str")
17411    (set_attr "mode" "QI")
17412    (set_attr "prefix_rep" "1")])
17413
17414 (define_insn "*cmpstrqi_nz_rex_1"
17415   [(set (reg:CC FLAGS_REG)
17416         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17417                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17418    (use (match_operand:DI 6 "register_operand" "2"))
17419    (use (match_operand:SI 3 "immediate_operand" "i"))
17420    (use (reg:SI DIRFLAG_REG))
17421    (clobber (match_operand:DI 0 "register_operand" "=S"))
17422    (clobber (match_operand:DI 1 "register_operand" "=D"))
17423    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17424   "TARGET_64BIT"
17425   "repz{\;| }cmpsb"
17426   [(set_attr "type" "str")
17427    (set_attr "mode" "QI")
17428    (set_attr "prefix_rep" "1")])
17429
17430 ;; The same, but the count is not known to not be zero.
17431
17432 (define_expand "cmpstrqi_1"
17433   [(parallel [(set (reg:CC FLAGS_REG)
17434                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17435                                      (const_int 0))
17436                   (compare:CC (match_operand 4 "memory_operand" "")
17437                               (match_operand 5 "memory_operand" ""))
17438                   (const_int 0)))
17439               (use (match_operand:SI 3 "immediate_operand" ""))
17440               (use (reg:CC FLAGS_REG))
17441               (use (reg:SI DIRFLAG_REG))
17442               (clobber (match_operand 0 "register_operand" ""))
17443               (clobber (match_operand 1 "register_operand" ""))
17444               (clobber (match_dup 2))])]
17445   ""
17446   "")
17447
17448 (define_insn "*cmpstrqi_1"
17449   [(set (reg:CC FLAGS_REG)
17450         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17451                              (const_int 0))
17452           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17453                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17454           (const_int 0)))
17455    (use (match_operand:SI 3 "immediate_operand" "i"))
17456    (use (reg:CC FLAGS_REG))
17457    (use (reg:SI DIRFLAG_REG))
17458    (clobber (match_operand:SI 0 "register_operand" "=S"))
17459    (clobber (match_operand:SI 1 "register_operand" "=D"))
17460    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17461   "!TARGET_64BIT"
17462   "repz{\;| }cmpsb"
17463   [(set_attr "type" "str")
17464    (set_attr "mode" "QI")
17465    (set_attr "prefix_rep" "1")])
17466
17467 (define_insn "*cmpstrqi_rex_1"
17468   [(set (reg:CC FLAGS_REG)
17469         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17470                              (const_int 0))
17471           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17472                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17473           (const_int 0)))
17474    (use (match_operand:SI 3 "immediate_operand" "i"))
17475    (use (reg:CC FLAGS_REG))
17476    (use (reg:SI DIRFLAG_REG))
17477    (clobber (match_operand:DI 0 "register_operand" "=S"))
17478    (clobber (match_operand:DI 1 "register_operand" "=D"))
17479    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17480   "TARGET_64BIT"
17481   "repz{\;| }cmpsb"
17482   [(set_attr "type" "str")
17483    (set_attr "mode" "QI")
17484    (set_attr "prefix_rep" "1")])
17485
17486 (define_expand "strlensi"
17487   [(set (match_operand:SI 0 "register_operand" "")
17488         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17489                     (match_operand:QI 2 "immediate_operand" "")
17490                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17491   ""
17492 {
17493  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17494    DONE;
17495  else
17496    FAIL;
17497 })
17498
17499 (define_expand "strlendi"
17500   [(set (match_operand:DI 0 "register_operand" "")
17501         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17502                     (match_operand:QI 2 "immediate_operand" "")
17503                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17504   ""
17505 {
17506  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17507    DONE;
17508  else
17509    FAIL;
17510 })
17511
17512 (define_expand "strlenqi_1"
17513   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17514               (use (reg:SI DIRFLAG_REG))
17515               (clobber (match_operand 1 "register_operand" ""))
17516               (clobber (reg:CC FLAGS_REG))])]
17517   ""
17518   "")
17519
17520 (define_insn "*strlenqi_1"
17521   [(set (match_operand:SI 0 "register_operand" "=&c")
17522         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17523                     (match_operand:QI 2 "register_operand" "a")
17524                     (match_operand:SI 3 "immediate_operand" "i")
17525                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17526    (use (reg:SI DIRFLAG_REG))
17527    (clobber (match_operand:SI 1 "register_operand" "=D"))
17528    (clobber (reg:CC FLAGS_REG))]
17529   "!TARGET_64BIT"
17530   "repnz{\;| }scasb"
17531   [(set_attr "type" "str")
17532    (set_attr "mode" "QI")
17533    (set_attr "prefix_rep" "1")])
17534
17535 (define_insn "*strlenqi_rex_1"
17536   [(set (match_operand:DI 0 "register_operand" "=&c")
17537         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17538                     (match_operand:QI 2 "register_operand" "a")
17539                     (match_operand:DI 3 "immediate_operand" "i")
17540                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17541    (use (reg:SI DIRFLAG_REG))
17542    (clobber (match_operand:DI 1 "register_operand" "=D"))
17543    (clobber (reg:CC FLAGS_REG))]
17544   "TARGET_64BIT"
17545   "repnz{\;| }scasb"
17546   [(set_attr "type" "str")
17547    (set_attr "mode" "QI")
17548    (set_attr "prefix_rep" "1")])
17549
17550 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17551 ;; handled in combine, but it is not currently up to the task.
17552 ;; When used for their truth value, the cmpstr* expanders generate
17553 ;; code like this:
17554 ;;
17555 ;;   repz cmpsb
17556 ;;   seta       %al
17557 ;;   setb       %dl
17558 ;;   cmpb       %al, %dl
17559 ;;   jcc        label
17560 ;;
17561 ;; The intermediate three instructions are unnecessary.
17562
17563 ;; This one handles cmpstr*_nz_1...
17564 (define_peephole2
17565   [(parallel[
17566      (set (reg:CC FLAGS_REG)
17567           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17568                       (mem:BLK (match_operand 5 "register_operand" ""))))
17569      (use (match_operand 6 "register_operand" ""))
17570      (use (match_operand:SI 3 "immediate_operand" ""))
17571      (use (reg:SI DIRFLAG_REG))
17572      (clobber (match_operand 0 "register_operand" ""))
17573      (clobber (match_operand 1 "register_operand" ""))
17574      (clobber (match_operand 2 "register_operand" ""))])
17575    (set (match_operand:QI 7 "register_operand" "")
17576         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17577    (set (match_operand:QI 8 "register_operand" "")
17578         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17579    (set (reg 17)
17580         (compare (match_dup 7) (match_dup 8)))
17581   ]
17582   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17583   [(parallel[
17584      (set (reg:CC FLAGS_REG)
17585           (compare:CC (mem:BLK (match_dup 4))
17586                       (mem:BLK (match_dup 5))))
17587      (use (match_dup 6))
17588      (use (match_dup 3))
17589      (use (reg:SI DIRFLAG_REG))
17590      (clobber (match_dup 0))
17591      (clobber (match_dup 1))
17592      (clobber (match_dup 2))])]
17593   "")
17594
17595 ;; ...and this one handles cmpstr*_1.
17596 (define_peephole2
17597   [(parallel[
17598      (set (reg:CC FLAGS_REG)
17599           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17600                                (const_int 0))
17601             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17602                         (mem:BLK (match_operand 5 "register_operand" "")))
17603             (const_int 0)))
17604      (use (match_operand:SI 3 "immediate_operand" ""))
17605      (use (reg:CC FLAGS_REG))
17606      (use (reg:SI DIRFLAG_REG))
17607      (clobber (match_operand 0 "register_operand" ""))
17608      (clobber (match_operand 1 "register_operand" ""))
17609      (clobber (match_operand 2 "register_operand" ""))])
17610    (set (match_operand:QI 7 "register_operand" "")
17611         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17612    (set (match_operand:QI 8 "register_operand" "")
17613         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17614    (set (reg 17)
17615         (compare (match_dup 7) (match_dup 8)))
17616   ]
17617   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17618   [(parallel[
17619      (set (reg:CC FLAGS_REG)
17620           (if_then_else:CC (ne (match_dup 6)
17621                                (const_int 0))
17622             (compare:CC (mem:BLK (match_dup 4))
17623                         (mem:BLK (match_dup 5)))
17624             (const_int 0)))
17625      (use (match_dup 3))
17626      (use (reg:CC FLAGS_REG))
17627      (use (reg:SI DIRFLAG_REG))
17628      (clobber (match_dup 0))
17629      (clobber (match_dup 1))
17630      (clobber (match_dup 2))])]
17631   "")
17632
17633
17634 \f
17635 ;; Conditional move instructions.
17636
17637 (define_expand "movdicc"
17638   [(set (match_operand:DI 0 "register_operand" "")
17639         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17640                          (match_operand:DI 2 "general_operand" "")
17641                          (match_operand:DI 3 "general_operand" "")))]
17642   "TARGET_64BIT"
17643   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17644
17645 (define_insn "x86_movdicc_0_m1_rex64"
17646   [(set (match_operand:DI 0 "register_operand" "=r")
17647         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17648           (const_int -1)
17649           (const_int 0)))
17650    (clobber (reg:CC FLAGS_REG))]
17651   "TARGET_64BIT"
17652   "sbb{q}\t%0, %0"
17653   ; Since we don't have the proper number of operands for an alu insn,
17654   ; fill in all the blanks.
17655   [(set_attr "type" "alu")
17656    (set_attr "pent_pair" "pu")
17657    (set_attr "memory" "none")
17658    (set_attr "imm_disp" "false")
17659    (set_attr "mode" "DI")
17660    (set_attr "length_immediate" "0")])
17661
17662 (define_insn "movdicc_c_rex64"
17663   [(set (match_operand:DI 0 "register_operand" "=r,r")
17664         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17665                                 [(reg 17) (const_int 0)])
17666                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17667                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17668   "TARGET_64BIT && TARGET_CMOVE
17669    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17670   "@
17671    cmov%O2%C1\t{%2, %0|%0, %2}
17672    cmov%O2%c1\t{%3, %0|%0, %3}"
17673   [(set_attr "type" "icmov")
17674    (set_attr "mode" "DI")])
17675
17676 (define_expand "movsicc"
17677   [(set (match_operand:SI 0 "register_operand" "")
17678         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17679                          (match_operand:SI 2 "general_operand" "")
17680                          (match_operand:SI 3 "general_operand" "")))]
17681   ""
17682   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17683
17684 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17685 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17686 ;; So just document what we're doing explicitly.
17687
17688 (define_insn "x86_movsicc_0_m1"
17689   [(set (match_operand:SI 0 "register_operand" "=r")
17690         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17691           (const_int -1)
17692           (const_int 0)))
17693    (clobber (reg:CC FLAGS_REG))]
17694   ""
17695   "sbb{l}\t%0, %0"
17696   ; Since we don't have the proper number of operands for an alu insn,
17697   ; fill in all the blanks.
17698   [(set_attr "type" "alu")
17699    (set_attr "pent_pair" "pu")
17700    (set_attr "memory" "none")
17701    (set_attr "imm_disp" "false")
17702    (set_attr "mode" "SI")
17703    (set_attr "length_immediate" "0")])
17704
17705 (define_insn "*movsicc_noc"
17706   [(set (match_operand:SI 0 "register_operand" "=r,r")
17707         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17708                                 [(reg 17) (const_int 0)])
17709                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17710                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17711   "TARGET_CMOVE
17712    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17713   "@
17714    cmov%O2%C1\t{%2, %0|%0, %2}
17715    cmov%O2%c1\t{%3, %0|%0, %3}"
17716   [(set_attr "type" "icmov")
17717    (set_attr "mode" "SI")])
17718
17719 (define_expand "movhicc"
17720   [(set (match_operand:HI 0 "register_operand" "")
17721         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17722                          (match_operand:HI 2 "general_operand" "")
17723                          (match_operand:HI 3 "general_operand" "")))]
17724   "TARGET_HIMODE_MATH"
17725   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17726
17727 (define_insn "*movhicc_noc"
17728   [(set (match_operand:HI 0 "register_operand" "=r,r")
17729         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17730                                 [(reg 17) (const_int 0)])
17731                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17732                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17733   "TARGET_CMOVE
17734    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17735   "@
17736    cmov%O2%C1\t{%2, %0|%0, %2}
17737    cmov%O2%c1\t{%3, %0|%0, %3}"
17738   [(set_attr "type" "icmov")
17739    (set_attr "mode" "HI")])
17740
17741 (define_expand "movqicc"
17742   [(set (match_operand:QI 0 "register_operand" "")
17743         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17744                          (match_operand:QI 2 "general_operand" "")
17745                          (match_operand:QI 3 "general_operand" "")))]
17746   "TARGET_QIMODE_MATH"
17747   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17748
17749 (define_insn_and_split "*movqicc_noc"
17750   [(set (match_operand:QI 0 "register_operand" "=r,r")
17751         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17752                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17753                       (match_operand:QI 2 "register_operand" "r,0")
17754                       (match_operand:QI 3 "register_operand" "0,r")))]
17755   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17756   "#"
17757   "&& reload_completed"
17758   [(set (match_dup 0)
17759         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17760                       (match_dup 2)
17761                       (match_dup 3)))]
17762   "operands[0] = gen_lowpart (SImode, operands[0]);
17763    operands[2] = gen_lowpart (SImode, operands[2]);
17764    operands[3] = gen_lowpart (SImode, operands[3]);"
17765   [(set_attr "type" "icmov")
17766    (set_attr "mode" "SI")])
17767
17768 (define_expand "movsfcc"
17769   [(set (match_operand:SF 0 "register_operand" "")
17770         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17771                          (match_operand:SF 2 "register_operand" "")
17772                          (match_operand:SF 3 "register_operand" "")))]
17773   "TARGET_CMOVE"
17774   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17775
17776 (define_insn "*movsfcc_1"
17777   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17778         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17779                                 [(reg 17) (const_int 0)])
17780                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17781                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17782   "TARGET_CMOVE
17783    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17784   "@
17785    fcmov%F1\t{%2, %0|%0, %2}
17786    fcmov%f1\t{%3, %0|%0, %3}
17787    cmov%O2%C1\t{%2, %0|%0, %2}
17788    cmov%O2%c1\t{%3, %0|%0, %3}"
17789   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17790    (set_attr "mode" "SF,SF,SI,SI")])
17791
17792 (define_expand "movdfcc"
17793   [(set (match_operand:DF 0 "register_operand" "")
17794         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17795                          (match_operand:DF 2 "register_operand" "")
17796                          (match_operand:DF 3 "register_operand" "")))]
17797   "TARGET_CMOVE"
17798   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17799
17800 (define_insn "*movdfcc_1"
17801   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17802         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17803                                 [(reg 17) (const_int 0)])
17804                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17805                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17806   "!TARGET_64BIT && TARGET_CMOVE
17807    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17808   "@
17809    fcmov%F1\t{%2, %0|%0, %2}
17810    fcmov%f1\t{%3, %0|%0, %3}
17811    #
17812    #"
17813   [(set_attr "type" "fcmov,fcmov,multi,multi")
17814    (set_attr "mode" "DF")])
17815
17816 (define_insn "*movdfcc_1_rex64"
17817   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17818         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17819                                 [(reg 17) (const_int 0)])
17820                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17821                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17822   "TARGET_64BIT && TARGET_CMOVE
17823    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17824   "@
17825    fcmov%F1\t{%2, %0|%0, %2}
17826    fcmov%f1\t{%3, %0|%0, %3}
17827    cmov%O2%C1\t{%2, %0|%0, %2}
17828    cmov%O2%c1\t{%3, %0|%0, %3}"
17829   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17830    (set_attr "mode" "DF")])
17831
17832 (define_split
17833   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17834         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17835                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17836                       (match_operand:DF 2 "nonimmediate_operand" "")
17837                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17838   "!TARGET_64BIT && reload_completed"
17839   [(set (match_dup 2)
17840         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17841                       (match_dup 5)
17842                       (match_dup 7)))
17843    (set (match_dup 3)
17844         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17845                       (match_dup 6)
17846                       (match_dup 8)))]
17847   "split_di (operands+2, 1, operands+5, operands+6);
17848    split_di (operands+3, 1, operands+7, operands+8);
17849    split_di (operands, 1, operands+2, operands+3);")
17850
17851 (define_expand "movxfcc"
17852   [(set (match_operand:XF 0 "register_operand" "")
17853         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17854                          (match_operand:XF 2 "register_operand" "")
17855                          (match_operand:XF 3 "register_operand" "")))]
17856   "TARGET_CMOVE"
17857   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17858
17859 (define_insn "*movxfcc_1"
17860   [(set (match_operand:XF 0 "register_operand" "=f,f")
17861         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17862                                 [(reg 17) (const_int 0)])
17863                       (match_operand:XF 2 "register_operand" "f,0")
17864                       (match_operand:XF 3 "register_operand" "0,f")))]
17865   "TARGET_CMOVE"
17866   "@
17867    fcmov%F1\t{%2, %0|%0, %2}
17868    fcmov%f1\t{%3, %0|%0, %3}"
17869   [(set_attr "type" "fcmov")
17870    (set_attr "mode" "XF")])
17871
17872 (define_expand "minsf3"
17873   [(parallel [
17874      (set (match_operand:SF 0 "register_operand" "")
17875           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17876                                (match_operand:SF 2 "nonimmediate_operand" ""))
17877                            (match_dup 1)
17878                            (match_dup 2)))
17879      (clobber (reg:CC FLAGS_REG))])]
17880   "TARGET_SSE"
17881   "")
17882
17883 (define_insn "*minsf"
17884   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17885         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17886                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17887                          (match_dup 1)
17888                          (match_dup 2)))
17889    (clobber (reg:CC FLAGS_REG))]
17890   "TARGET_SSE && TARGET_IEEE_FP"
17891   "#")
17892
17893 (define_insn "*minsf_nonieee"
17894   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17895         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17896                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17897                          (match_dup 1)
17898                          (match_dup 2)))
17899    (clobber (reg:CC FLAGS_REG))]
17900   "TARGET_SSE && !TARGET_IEEE_FP
17901    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17902   "#")
17903
17904 (define_split
17905   [(set (match_operand:SF 0 "register_operand" "")
17906         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17907                              (match_operand:SF 2 "nonimmediate_operand" ""))
17908                          (match_operand:SF 3 "register_operand" "")
17909                          (match_operand:SF 4 "nonimmediate_operand" "")))
17910    (clobber (reg:CC FLAGS_REG))]
17911   "SSE_REG_P (operands[0]) && reload_completed
17912    && ((operands_match_p (operands[1], operands[3])
17913         && operands_match_p (operands[2], operands[4]))
17914        || (operands_match_p (operands[1], operands[4])
17915            && operands_match_p (operands[2], operands[3])))"
17916   [(set (match_dup 0)
17917         (if_then_else:SF (lt (match_dup 1)
17918                              (match_dup 2))
17919                          (match_dup 1)
17920                          (match_dup 2)))])
17921
17922 ;; Conditional addition patterns
17923 (define_expand "addqicc"
17924   [(match_operand:QI 0 "register_operand" "")
17925    (match_operand 1 "comparison_operator" "")
17926    (match_operand:QI 2 "register_operand" "")
17927    (match_operand:QI 3 "const_int_operand" "")]
17928   ""
17929   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17930
17931 (define_expand "addhicc"
17932   [(match_operand:HI 0 "register_operand" "")
17933    (match_operand 1 "comparison_operator" "")
17934    (match_operand:HI 2 "register_operand" "")
17935    (match_operand:HI 3 "const_int_operand" "")]
17936   ""
17937   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17938
17939 (define_expand "addsicc"
17940   [(match_operand:SI 0 "register_operand" "")
17941    (match_operand 1 "comparison_operator" "")
17942    (match_operand:SI 2 "register_operand" "")
17943    (match_operand:SI 3 "const_int_operand" "")]
17944   ""
17945   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17946
17947 (define_expand "adddicc"
17948   [(match_operand:DI 0 "register_operand" "")
17949    (match_operand 1 "comparison_operator" "")
17950    (match_operand:DI 2 "register_operand" "")
17951    (match_operand:DI 3 "const_int_operand" "")]
17952   "TARGET_64BIT"
17953   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17954
17955 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17956
17957 (define_split
17958   [(set (match_operand:SF 0 "fp_register_operand" "")
17959         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17960                              (match_operand:SF 2 "register_operand" ""))
17961                          (match_operand:SF 3 "register_operand" "")
17962                          (match_operand:SF 4 "register_operand" "")))
17963    (clobber (reg:CC FLAGS_REG))]
17964   "reload_completed
17965    && ((operands_match_p (operands[1], operands[3])
17966         && operands_match_p (operands[2], operands[4]))
17967        || (operands_match_p (operands[1], operands[4])
17968            && operands_match_p (operands[2], operands[3])))"
17969   [(set (reg:CCFP FLAGS_REG)
17970         (compare:CCFP (match_dup 2)
17971                       (match_dup 1)))
17972    (set (match_dup 0)
17973         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17974                          (match_dup 1)
17975                          (match_dup 2)))])
17976
17977 (define_insn "*minsf_sse"
17978   [(set (match_operand:SF 0 "register_operand" "=x")
17979         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17980                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17981                          (match_dup 1)
17982                          (match_dup 2)))]
17983   "TARGET_SSE && reload_completed"
17984   "minss\t{%2, %0|%0, %2}"
17985   [(set_attr "type" "sse")
17986    (set_attr "mode" "SF")])
17987
17988 (define_expand "mindf3"
17989   [(parallel [
17990      (set (match_operand:DF 0 "register_operand" "")
17991           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17992                                (match_operand:DF 2 "nonimmediate_operand" ""))
17993                            (match_dup 1)
17994                            (match_dup 2)))
17995      (clobber (reg:CC FLAGS_REG))])]
17996   "TARGET_SSE2 && TARGET_SSE_MATH"
17997   "#")
17998
17999 (define_insn "*mindf"
18000   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18001         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18002                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18003                          (match_dup 1)
18004                          (match_dup 2)))
18005    (clobber (reg:CC FLAGS_REG))]
18006   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18007   "#")
18008
18009 (define_insn "*mindf_nonieee"
18010   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18011         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18012                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18013                          (match_dup 1)
18014                          (match_dup 2)))
18015    (clobber (reg:CC FLAGS_REG))]
18016   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18018   "#")
18019
18020 (define_split
18021   [(set (match_operand:DF 0 "register_operand" "")
18022         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18023                              (match_operand:DF 2 "nonimmediate_operand" ""))
18024                          (match_operand:DF 3 "register_operand" "")
18025                          (match_operand:DF 4 "nonimmediate_operand" "")))
18026    (clobber (reg:CC FLAGS_REG))]
18027   "SSE_REG_P (operands[0]) && reload_completed
18028    && ((operands_match_p (operands[1], operands[3])
18029         && operands_match_p (operands[2], operands[4]))
18030        || (operands_match_p (operands[1], operands[4])
18031            && operands_match_p (operands[2], operands[3])))"
18032   [(set (match_dup 0)
18033         (if_then_else:DF (lt (match_dup 1)
18034                              (match_dup 2))
18035                          (match_dup 1)
18036                          (match_dup 2)))])
18037
18038 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18039 (define_split
18040   [(set (match_operand:DF 0 "fp_register_operand" "")
18041         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18042                              (match_operand:DF 2 "register_operand" ""))
18043                          (match_operand:DF 3 "register_operand" "")
18044                          (match_operand:DF 4 "register_operand" "")))
18045    (clobber (reg:CC FLAGS_REG))]
18046   "reload_completed
18047    && ((operands_match_p (operands[1], operands[3])
18048         && operands_match_p (operands[2], operands[4]))
18049        || (operands_match_p (operands[1], operands[4])
18050            && operands_match_p (operands[2], operands[3])))"
18051   [(set (reg:CCFP FLAGS_REG)
18052         (compare:CCFP (match_dup 2)
18053                       (match_dup 1)))
18054    (set (match_dup 0)
18055         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18056                          (match_dup 1)
18057                          (match_dup 2)))])
18058
18059 (define_insn "*mindf_sse"
18060   [(set (match_operand:DF 0 "register_operand" "=Y")
18061         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18062                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18063                          (match_dup 1)
18064                          (match_dup 2)))]
18065   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18066   "minsd\t{%2, %0|%0, %2}"
18067   [(set_attr "type" "sse")
18068    (set_attr "mode" "DF")])
18069
18070 (define_expand "maxsf3"
18071   [(parallel [
18072      (set (match_operand:SF 0 "register_operand" "")
18073           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18074                                (match_operand:SF 2 "nonimmediate_operand" ""))
18075                            (match_dup 1)
18076                            (match_dup 2)))
18077      (clobber (reg:CC FLAGS_REG))])]
18078   "TARGET_SSE"
18079   "#")
18080
18081 (define_insn "*maxsf"
18082   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18083         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18084                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18085                          (match_dup 1)
18086                          (match_dup 2)))
18087    (clobber (reg:CC FLAGS_REG))]
18088   "TARGET_SSE && TARGET_IEEE_FP"
18089   "#")
18090
18091 (define_insn "*maxsf_nonieee"
18092   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18093         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18094                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18095                          (match_dup 1)
18096                          (match_dup 2)))
18097    (clobber (reg:CC FLAGS_REG))]
18098   "TARGET_SSE && !TARGET_IEEE_FP
18099    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18100   "#")
18101
18102 (define_split
18103   [(set (match_operand:SF 0 "register_operand" "")
18104         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18105                              (match_operand:SF 2 "nonimmediate_operand" ""))
18106                          (match_operand:SF 3 "register_operand" "")
18107                          (match_operand:SF 4 "nonimmediate_operand" "")))
18108    (clobber (reg:CC FLAGS_REG))]
18109   "SSE_REG_P (operands[0]) && reload_completed
18110    && ((operands_match_p (operands[1], operands[3])
18111         && operands_match_p (operands[2], operands[4]))
18112        || (operands_match_p (operands[1], operands[4])
18113            && operands_match_p (operands[2], operands[3])))"
18114   [(set (match_dup 0)
18115         (if_then_else:SF (gt (match_dup 1)
18116                              (match_dup 2))
18117                          (match_dup 1)
18118                          (match_dup 2)))])
18119
18120 (define_split
18121   [(set (match_operand:SF 0 "fp_register_operand" "")
18122         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18123                              (match_operand:SF 2 "register_operand" ""))
18124                          (match_operand:SF 3 "register_operand" "")
18125                          (match_operand:SF 4 "register_operand" "")))
18126    (clobber (reg:CC FLAGS_REG))]
18127   "reload_completed
18128    && ((operands_match_p (operands[1], operands[3])
18129         && operands_match_p (operands[2], operands[4]))
18130        || (operands_match_p (operands[1], operands[4])
18131            && operands_match_p (operands[2], operands[3])))"
18132   [(set (reg:CCFP FLAGS_REG)
18133         (compare:CCFP (match_dup 1)
18134                       (match_dup 2)))
18135    (set (match_dup 0)
18136         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18137                          (match_dup 1)
18138                          (match_dup 2)))])
18139
18140 (define_insn "*maxsf_sse"
18141   [(set (match_operand:SF 0 "register_operand" "=x")
18142         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18143                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18144                          (match_dup 1)
18145                          (match_dup 2)))]
18146   "TARGET_SSE && reload_completed"
18147   "maxss\t{%2, %0|%0, %2}"
18148   [(set_attr "type" "sse")
18149    (set_attr "mode" "SF")])
18150
18151 (define_expand "maxdf3"
18152   [(parallel [
18153      (set (match_operand:DF 0 "register_operand" "")
18154           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18155                                (match_operand:DF 2 "nonimmediate_operand" ""))
18156                            (match_dup 1)
18157                            (match_dup 2)))
18158      (clobber (reg:CC FLAGS_REG))])]
18159   "TARGET_SSE2 && TARGET_SSE_MATH"
18160   "#")
18161
18162 (define_insn "*maxdf"
18163   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18164         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18165                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18166                          (match_dup 1)
18167                          (match_dup 2)))
18168    (clobber (reg:CC FLAGS_REG))]
18169   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18170   "#")
18171
18172 (define_insn "*maxdf_nonieee"
18173   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18174         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18175                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18176                          (match_dup 1)
18177                          (match_dup 2)))
18178    (clobber (reg:CC FLAGS_REG))]
18179   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18181   "#")
18182
18183 (define_split
18184   [(set (match_operand:DF 0 "register_operand" "")
18185         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18186                              (match_operand:DF 2 "nonimmediate_operand" ""))
18187                          (match_operand:DF 3 "register_operand" "")
18188                          (match_operand:DF 4 "nonimmediate_operand" "")))
18189    (clobber (reg:CC FLAGS_REG))]
18190   "SSE_REG_P (operands[0]) && reload_completed
18191    && ((operands_match_p (operands[1], operands[3])
18192         && operands_match_p (operands[2], operands[4]))
18193        || (operands_match_p (operands[1], operands[4])
18194            && operands_match_p (operands[2], operands[3])))"
18195   [(set (match_dup 0)
18196         (if_then_else:DF (gt (match_dup 1)
18197                              (match_dup 2))
18198                          (match_dup 1)
18199                          (match_dup 2)))])
18200
18201 (define_split
18202   [(set (match_operand:DF 0 "fp_register_operand" "")
18203         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18204                              (match_operand:DF 2 "register_operand" ""))
18205                          (match_operand:DF 3 "register_operand" "")
18206                          (match_operand:DF 4 "register_operand" "")))
18207    (clobber (reg:CC FLAGS_REG))]
18208   "reload_completed
18209    && ((operands_match_p (operands[1], operands[3])
18210         && operands_match_p (operands[2], operands[4]))
18211        || (operands_match_p (operands[1], operands[4])
18212            && operands_match_p (operands[2], operands[3])))"
18213   [(set (reg:CCFP FLAGS_REG)
18214         (compare:CCFP (match_dup 1)
18215                       (match_dup 2)))
18216    (set (match_dup 0)
18217         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18218                          (match_dup 1)
18219                          (match_dup 2)))])
18220
18221 (define_insn "*maxdf_sse"
18222   [(set (match_operand:DF 0 "register_operand" "=Y")
18223         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18224                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18225                          (match_dup 1)
18226                          (match_dup 2)))]
18227   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18228   "maxsd\t{%2, %0|%0, %2}"
18229   [(set_attr "type" "sse")
18230    (set_attr "mode" "DF")])
18231 \f
18232 ;; Misc patterns (?)
18233
18234 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18235 ;; Otherwise there will be nothing to keep
18236 ;; 
18237 ;; [(set (reg ebp) (reg esp))]
18238 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18239 ;;  (clobber (eflags)]
18240 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18241 ;;
18242 ;; in proper program order.
18243 (define_insn "pro_epilogue_adjust_stack_1"
18244   [(set (match_operand:SI 0 "register_operand" "=r,r")
18245         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18246                  (match_operand:SI 2 "immediate_operand" "i,i")))
18247    (clobber (reg:CC FLAGS_REG))
18248    (clobber (mem:BLK (scratch)))]
18249   "!TARGET_64BIT"
18250 {
18251   switch (get_attr_type (insn))
18252     {
18253     case TYPE_IMOV:
18254       return "mov{l}\t{%1, %0|%0, %1}";
18255
18256     case TYPE_ALU:
18257       if (GET_CODE (operands[2]) == CONST_INT
18258           && (INTVAL (operands[2]) == 128
18259               || (INTVAL (operands[2]) < 0
18260                   && INTVAL (operands[2]) != -128)))
18261         {
18262           operands[2] = GEN_INT (-INTVAL (operands[2]));
18263           return "sub{l}\t{%2, %0|%0, %2}";
18264         }
18265       return "add{l}\t{%2, %0|%0, %2}";
18266
18267     case TYPE_LEA:
18268       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18269       return "lea{l}\t{%a2, %0|%0, %a2}";
18270
18271     default:
18272       abort ();
18273     }
18274 }
18275   [(set (attr "type")
18276         (cond [(eq_attr "alternative" "0")
18277                  (const_string "alu")
18278                (match_operand:SI 2 "const0_operand" "")
18279                  (const_string "imov")
18280               ]
18281               (const_string "lea")))
18282    (set_attr "mode" "SI")])
18283
18284 (define_insn "pro_epilogue_adjust_stack_rex64"
18285   [(set (match_operand:DI 0 "register_operand" "=r,r")
18286         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18287                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18288    (clobber (reg:CC FLAGS_REG))
18289    (clobber (mem:BLK (scratch)))]
18290   "TARGET_64BIT"
18291 {
18292   switch (get_attr_type (insn))
18293     {
18294     case TYPE_IMOV:
18295       return "mov{q}\t{%1, %0|%0, %1}";
18296
18297     case TYPE_ALU:
18298       if (GET_CODE (operands[2]) == CONST_INT
18299           /* Avoid overflows.  */
18300           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18301           && (INTVAL (operands[2]) == 128
18302               || (INTVAL (operands[2]) < 0
18303                   && INTVAL (operands[2]) != -128)))
18304         {
18305           operands[2] = GEN_INT (-INTVAL (operands[2]));
18306           return "sub{q}\t{%2, %0|%0, %2}";
18307         }
18308       return "add{q}\t{%2, %0|%0, %2}";
18309
18310     case TYPE_LEA:
18311       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18312       return "lea{q}\t{%a2, %0|%0, %a2}";
18313
18314     default:
18315       abort ();
18316     }
18317 }
18318   [(set (attr "type")
18319         (cond [(eq_attr "alternative" "0")
18320                  (const_string "alu")
18321                (match_operand:DI 2 "const0_operand" "")
18322                  (const_string "imov")
18323               ]
18324               (const_string "lea")))
18325    (set_attr "mode" "DI")])
18326
18327 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18328   [(set (match_operand:DI 0 "register_operand" "=r,r")
18329         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18330                  (match_operand:DI 3 "immediate_operand" "i,i")))
18331    (use (match_operand:DI 2 "register_operand" "r,r"))
18332    (clobber (reg:CC FLAGS_REG))
18333    (clobber (mem:BLK (scratch)))]
18334   "TARGET_64BIT"
18335 {
18336   switch (get_attr_type (insn))
18337     {
18338     case TYPE_ALU:
18339       return "add{q}\t{%2, %0|%0, %2}";
18340
18341     case TYPE_LEA:
18342       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18343       return "lea{q}\t{%a2, %0|%0, %a2}";
18344
18345     default:
18346       abort ();
18347     }
18348 }
18349   [(set_attr "type" "alu,lea")
18350    (set_attr "mode" "DI")])
18351
18352 ;; Placeholder for the conditional moves.  This one is split either to SSE
18353 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18354 ;; fact is that compares supported by the cmp??ss instructions are exactly
18355 ;; swapped of those supported by cmove sequence.
18356 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18357 ;; supported by i387 comparisons and we do need to emit two conditional moves
18358 ;; in tandem.
18359
18360 (define_insn "sse_movsfcc"
18361   [(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")
18362         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18363                         [(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")
18364                          (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")])
18365                       (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")
18366                       (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")))
18367    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18368    (clobber (reg:CC FLAGS_REG))]
18369   "TARGET_SSE
18370    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18371    /* Avoid combine from being smart and converting min/max
18372       instruction patterns into conditional moves.  */
18373    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18374         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18375        || !rtx_equal_p (operands[4], operands[2])
18376        || !rtx_equal_p (operands[5], operands[3]))
18377    && (!TARGET_IEEE_FP
18378        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18379   "#")
18380
18381 (define_insn "sse_movsfcc_eq"
18382   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18383         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18384                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18385                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18386                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18387    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18388    (clobber (reg:CC FLAGS_REG))]
18389   "TARGET_SSE
18390    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18391   "#")
18392
18393 (define_insn "sse_movdfcc"
18394   [(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")
18395         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18396                         [(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")
18397                          (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")])
18398                       (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")
18399                       (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")))
18400    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18401    (clobber (reg:CC FLAGS_REG))]
18402   "TARGET_SSE2
18403    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18404    /* Avoid combine from being smart and converting min/max
18405       instruction patterns into conditional moves.  */
18406    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18407         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18408        || !rtx_equal_p (operands[4], operands[2])
18409        || !rtx_equal_p (operands[5], operands[3]))
18410    && (!TARGET_IEEE_FP
18411        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18412   "#")
18413
18414 (define_insn "sse_movdfcc_eq"
18415   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18416         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18417                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18418                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18419                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18420    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18421    (clobber (reg:CC FLAGS_REG))]
18422   "TARGET_SSE
18423    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18424   "#")
18425
18426 ;; For non-sse moves just expand the usual cmove sequence.
18427 (define_split
18428   [(set (match_operand 0 "register_operand" "")
18429         (if_then_else (match_operator 1 "comparison_operator"
18430                         [(match_operand 4 "nonimmediate_operand" "")
18431                          (match_operand 5 "register_operand" "")])
18432                       (match_operand 2 "nonimmediate_operand" "")
18433                       (match_operand 3 "nonimmediate_operand" "")))
18434    (clobber (match_operand 6 "" ""))
18435    (clobber (reg:CC FLAGS_REG))]
18436   "!SSE_REG_P (operands[0]) && reload_completed
18437    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18438   [(const_int 0)]
18439 {
18440    ix86_compare_op0 = operands[5];
18441    ix86_compare_op1 = operands[4];
18442    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18443                                  VOIDmode, operands[5], operands[4]);
18444    ix86_expand_fp_movcc (operands);
18445    DONE;
18446 })
18447
18448 ;; Split SSE based conditional move into sequence:
18449 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18450 ;; and   op2, op0   -  zero op2 if comparison was false
18451 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18452 ;; or    op2, op0   -  get the nonzero one into the result.
18453 (define_split
18454   [(set (match_operand:SF 0 "register_operand" "")
18455         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18456                         [(match_operand:SF 4 "register_operand" "")
18457                          (match_operand:SF 5 "nonimmediate_operand" "")])
18458                       (match_operand:SF 2 "register_operand" "")
18459                       (match_operand:SF 3 "register_operand" "")))
18460    (clobber (match_operand 6 "" ""))
18461    (clobber (reg:CC FLAGS_REG))]
18462   "SSE_REG_P (operands[0]) && reload_completed"
18463   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18464    (set (match_dup 2) (and:V4SF (match_dup 2)
18465                                 (match_dup 8)))
18466    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18467                                           (match_dup 3)))
18468    (set (match_dup 0) (ior:V4SF (match_dup 6)
18469                                 (match_dup 7)))]
18470 {
18471   /* If op2 == op3, op3 would be clobbered before it is used.  */
18472   if (operands_match_p (operands[2], operands[3]))
18473     {
18474       emit_move_insn (operands[0], operands[2]);
18475       DONE;
18476     }
18477
18478   PUT_MODE (operands[1], GET_MODE (operands[0]));
18479   if (operands_match_p (operands[0], operands[4]))
18480     operands[6] = operands[4], operands[7] = operands[2];
18481   else
18482     operands[6] = operands[2], operands[7] = operands[4];
18483   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18484   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18485   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18486   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18487   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18488   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18489 })
18490
18491 (define_split
18492   [(set (match_operand:DF 0 "register_operand" "")
18493         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18494                         [(match_operand:DF 4 "register_operand" "")
18495                          (match_operand:DF 5 "nonimmediate_operand" "")])
18496                       (match_operand:DF 2 "register_operand" "")
18497                       (match_operand:DF 3 "register_operand" "")))
18498    (clobber (match_operand 6 "" ""))
18499    (clobber (reg:CC FLAGS_REG))]
18500   "SSE_REG_P (operands[0]) && reload_completed"
18501   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18502    (set (match_dup 2) (and:V2DF (match_dup 2)
18503                                 (match_dup 8)))
18504    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18505                                           (match_dup 3)))
18506    (set (match_dup 0) (ior:V2DF (match_dup 6)
18507                                 (match_dup 7)))]
18508 {
18509   if (GET_MODE (operands[2]) == DFmode
18510       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18511     {
18512       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18513       emit_insn (gen_sse2_unpcklpd (op, op, op));
18514       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18515       emit_insn (gen_sse2_unpcklpd (op, op, op));
18516     }
18517
18518   /* If op2 == op3, op3 would be clobbered before it is used.  */
18519   if (operands_match_p (operands[2], operands[3]))
18520     {
18521       emit_move_insn (operands[0], operands[2]);
18522       DONE;
18523     }
18524
18525   PUT_MODE (operands[1], GET_MODE (operands[0]));
18526   if (operands_match_p (operands[0], operands[4]))
18527     operands[6] = operands[4], operands[7] = operands[2];
18528   else
18529     operands[6] = operands[2], operands[7] = operands[4];
18530   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18531   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18532   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18533   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18534   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18535   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18536 })
18537
18538 ;; Special case of conditional move we can handle effectively.
18539 ;; Do not brother with the integer/floating point case, since these are
18540 ;; bot considerably slower, unlike in the generic case.
18541 (define_insn "*sse_movsfcc_const0_1"
18542   [(set (match_operand:SF 0 "register_operand" "=&x")
18543         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18544                         [(match_operand:SF 4 "register_operand" "0")
18545                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18546                       (match_operand:SF 2 "register_operand" "x")
18547                       (match_operand:SF 3 "const0_operand" "X")))]
18548   "TARGET_SSE"
18549   "#")
18550
18551 (define_insn "*sse_movsfcc_const0_2"
18552   [(set (match_operand:SF 0 "register_operand" "=&x")
18553         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18554                         [(match_operand:SF 4 "register_operand" "0")
18555                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18556                       (match_operand:SF 2 "const0_operand" "X")
18557                       (match_operand:SF 3 "register_operand" "x")))]
18558   "TARGET_SSE"
18559   "#")
18560
18561 (define_insn "*sse_movsfcc_const0_3"
18562   [(set (match_operand:SF 0 "register_operand" "=&x")
18563         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18564                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18565                          (match_operand:SF 5 "register_operand" "0")])
18566                       (match_operand:SF 2 "register_operand" "x")
18567                       (match_operand:SF 3 "const0_operand" "X")))]
18568   "TARGET_SSE"
18569   "#")
18570
18571 (define_insn "*sse_movsfcc_const0_4"
18572   [(set (match_operand:SF 0 "register_operand" "=&x")
18573         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18574                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18575                          (match_operand:SF 5 "register_operand" "0")])
18576                       (match_operand:SF 2 "const0_operand" "X")
18577                       (match_operand:SF 3 "register_operand" "x")))]
18578   "TARGET_SSE"
18579   "#")
18580
18581 (define_insn "*sse_movdfcc_const0_1"
18582   [(set (match_operand:DF 0 "register_operand" "=&Y")
18583         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18584                         [(match_operand:DF 4 "register_operand" "0")
18585                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18586                       (match_operand:DF 2 "register_operand" "Y")
18587                       (match_operand:DF 3 "const0_operand" "X")))]
18588   "TARGET_SSE2"
18589   "#")
18590
18591 (define_insn "*sse_movdfcc_const0_2"
18592   [(set (match_operand:DF 0 "register_operand" "=&Y")
18593         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18594                         [(match_operand:DF 4 "register_operand" "0")
18595                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18596                       (match_operand:DF 2 "const0_operand" "X")
18597                       (match_operand:DF 3 "register_operand" "Y")))]
18598   "TARGET_SSE2"
18599   "#")
18600
18601 (define_insn "*sse_movdfcc_const0_3"
18602   [(set (match_operand:DF 0 "register_operand" "=&Y")
18603         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18604                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18605                          (match_operand:DF 5 "register_operand" "0")])
18606                       (match_operand:DF 2 "register_operand" "Y")
18607                       (match_operand:DF 3 "const0_operand" "X")))]
18608   "TARGET_SSE2"
18609   "#")
18610
18611 (define_insn "*sse_movdfcc_const0_4"
18612   [(set (match_operand:DF 0 "register_operand" "=&Y")
18613         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18614                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18615                          (match_operand:DF 5 "register_operand" "0")])
18616                       (match_operand:DF 2 "const0_operand" "X")
18617                       (match_operand:DF 3 "register_operand" "Y")))]
18618   "TARGET_SSE2"
18619   "#")
18620
18621 (define_split
18622   [(set (match_operand:SF 0 "register_operand" "")
18623         (if_then_else (match_operator 1 "comparison_operator"
18624                         [(match_operand:SF 4 "nonimmediate_operand" "")
18625                          (match_operand:SF 5 "nonimmediate_operand" "")])
18626                       (match_operand:SF 2 "nonmemory_operand" "")
18627                       (match_operand:SF 3 "nonmemory_operand" "")))]
18628   "SSE_REG_P (operands[0]) && reload_completed
18629    && (const0_operand (operands[2], GET_MODE (operands[0]))
18630        || const0_operand (operands[3], GET_MODE (operands[0])))"
18631   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18632    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18633 {
18634   PUT_MODE (operands[1], GET_MODE (operands[0]));
18635   if (!sse_comparison_operator (operands[1], VOIDmode)
18636       || !rtx_equal_p (operands[0], operands[4]))
18637     {
18638       rtx tmp = operands[5];
18639       operands[5] = operands[4];
18640       operands[4] = tmp;
18641       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18642     }
18643   if (!rtx_equal_p (operands[0], operands[4]))
18644     abort ();
18645   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18646   if (const0_operand (operands[2], GET_MODE (operands[2])))
18647     {
18648       operands[7] = operands[3];
18649       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18650     }
18651   else
18652     {
18653       operands[7] = operands[2];
18654       operands[6] = operands[8];
18655     }
18656   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18657 })
18658
18659 (define_split
18660   [(set (match_operand:DF 0 "register_operand" "")
18661         (if_then_else (match_operator 1 "comparison_operator"
18662                         [(match_operand:DF 4 "nonimmediate_operand" "")
18663                          (match_operand:DF 5 "nonimmediate_operand" "")])
18664                       (match_operand:DF 2 "nonmemory_operand" "")
18665                       (match_operand:DF 3 "nonmemory_operand" "")))]
18666   "SSE_REG_P (operands[0]) && reload_completed
18667    && (const0_operand (operands[2], GET_MODE (operands[0]))
18668        || const0_operand (operands[3], GET_MODE (operands[0])))"
18669   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18670    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18671 {
18672   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18673       && GET_MODE (operands[2]) == DFmode)
18674     {
18675       if (REG_P (operands[2]))
18676         {
18677           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18678           emit_insn (gen_sse2_unpcklpd (op, op, op));
18679         }
18680       if (REG_P (operands[3]))
18681         {
18682           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18683           emit_insn (gen_sse2_unpcklpd (op, op, op));
18684         }
18685     }
18686   PUT_MODE (operands[1], GET_MODE (operands[0]));
18687   if (!sse_comparison_operator (operands[1], VOIDmode)
18688       || !rtx_equal_p (operands[0], operands[4]))
18689     {
18690       rtx tmp = operands[5];
18691       operands[5] = operands[4];
18692       operands[4] = tmp;
18693       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18694     }
18695   if (!rtx_equal_p (operands[0], operands[4]))
18696     abort ();
18697   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18698   if (const0_operand (operands[2], GET_MODE (operands[2])))
18699     {
18700       operands[7] = operands[3];
18701       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18702     }
18703   else
18704     {
18705       operands[7] = operands[2];
18706       operands[6] = operands[8];
18707     }
18708   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18709 })
18710
18711 (define_expand "allocate_stack_worker"
18712   [(match_operand:SI 0 "register_operand" "")]
18713   "TARGET_STACK_PROBE"
18714 {
18715   if (reload_completed)
18716     {
18717       if (TARGET_64BIT)
18718         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18719       else
18720         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18721     }
18722   else
18723     {
18724       if (TARGET_64BIT)
18725         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18726       else
18727         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18728     }
18729   DONE;
18730 })
18731
18732 (define_insn "allocate_stack_worker_1"
18733   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18734     UNSPECV_STACK_PROBE)
18735    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18736    (clobber (match_scratch:SI 1 "=0"))
18737    (clobber (reg:CC FLAGS_REG))]
18738   "!TARGET_64BIT && TARGET_STACK_PROBE"
18739   "call\t__alloca"
18740   [(set_attr "type" "multi")
18741    (set_attr "length" "5")])
18742
18743 (define_expand "allocate_stack_worker_postreload"
18744   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18745                                     UNSPECV_STACK_PROBE)
18746               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18747               (clobber (match_dup 0))
18748               (clobber (reg:CC FLAGS_REG))])]
18749   ""
18750   "")
18751
18752 (define_insn "allocate_stack_worker_rex64"
18753   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18754     UNSPECV_STACK_PROBE)
18755    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18756    (clobber (match_scratch:DI 1 "=0"))
18757    (clobber (reg:CC FLAGS_REG))]
18758   "TARGET_64BIT && TARGET_STACK_PROBE"
18759   "call\t__alloca"
18760   [(set_attr "type" "multi")
18761    (set_attr "length" "5")])
18762
18763 (define_expand "allocate_stack_worker_rex64_postreload"
18764   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18765                                     UNSPECV_STACK_PROBE)
18766               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18767               (clobber (match_dup 0))
18768               (clobber (reg:CC FLAGS_REG))])]
18769   ""
18770   "")
18771
18772 (define_expand "allocate_stack"
18773   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18774                    (minus:SI (reg:SI SP_REG)
18775                              (match_operand:SI 1 "general_operand" "")))
18776               (clobber (reg:CC FLAGS_REG))])
18777    (parallel [(set (reg:SI SP_REG)
18778                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18779               (clobber (reg:CC FLAGS_REG))])]
18780   "TARGET_STACK_PROBE"
18781 {
18782 #ifdef CHECK_STACK_LIMIT
18783   if (GET_CODE (operands[1]) == CONST_INT
18784       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18785     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18786                            operands[1]));
18787   else 
18788 #endif
18789     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18790                                                             operands[1])));
18791
18792   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18793   DONE;
18794 })
18795
18796 (define_expand "builtin_setjmp_receiver"
18797   [(label_ref (match_operand 0 "" ""))]
18798   "!TARGET_64BIT && flag_pic"
18799 {
18800   emit_insn (gen_set_got (pic_offset_table_rtx));
18801   DONE;
18802 })
18803 \f
18804 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18805
18806 (define_split
18807   [(set (match_operand 0 "register_operand" "")
18808         (match_operator 3 "promotable_binary_operator"
18809            [(match_operand 1 "register_operand" "")
18810             (match_operand 2 "aligned_operand" "")]))
18811    (clobber (reg:CC FLAGS_REG))]
18812   "! TARGET_PARTIAL_REG_STALL && reload_completed
18813    && ((GET_MODE (operands[0]) == HImode 
18814         && ((!optimize_size && !TARGET_FAST_PREFIX)
18815             || GET_CODE (operands[2]) != CONST_INT
18816             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18817        || (GET_MODE (operands[0]) == QImode 
18818            && (TARGET_PROMOTE_QImode || optimize_size)))"
18819   [(parallel [(set (match_dup 0)
18820                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18821               (clobber (reg:CC FLAGS_REG))])]
18822   "operands[0] = gen_lowpart (SImode, operands[0]);
18823    operands[1] = gen_lowpart (SImode, operands[1]);
18824    if (GET_CODE (operands[3]) != ASHIFT)
18825      operands[2] = gen_lowpart (SImode, operands[2]);
18826    PUT_MODE (operands[3], SImode);")
18827
18828 ; Promote the QImode tests, as i386 has encoding of the AND
18829 ; instruction with 32-bit sign-extended immediate and thus the
18830 ; instruction size is unchanged, except in the %eax case for
18831 ; which it is increased by one byte, hence the ! optimize_size.
18832 (define_split
18833   [(set (reg 17)
18834         (compare (and (match_operand 1 "aligned_operand" "")
18835                       (match_operand 2 "const_int_operand" ""))
18836                  (const_int 0)))
18837    (set (match_operand 0 "register_operand" "")
18838         (and (match_dup 1) (match_dup 2)))]
18839   "! TARGET_PARTIAL_REG_STALL && reload_completed
18840    /* Ensure that the operand will remain sign-extended immediate.  */
18841    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18842    && ! optimize_size
18843    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18844        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18845   [(parallel [(set (reg:CCNO FLAGS_REG)
18846                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18847                                  (const_int 0)))
18848               (set (match_dup 0)
18849                    (and:SI (match_dup 1) (match_dup 2)))])]
18850   "operands[2]
18851      = gen_int_mode (INTVAL (operands[2])
18852                      & GET_MODE_MASK (GET_MODE (operands[0])),
18853                      SImode);
18854    operands[0] = gen_lowpart (SImode, operands[0]);
18855    operands[1] = gen_lowpart (SImode, operands[1]);")
18856
18857 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18858 ; the TEST instruction with 32-bit sign-extended immediate and thus
18859 ; the instruction size would at least double, which is not what we
18860 ; want even with ! optimize_size.
18861 (define_split
18862   [(set (reg 17)
18863         (compare (and (match_operand:HI 0 "aligned_operand" "")
18864                       (match_operand:HI 1 "const_int_operand" ""))
18865                  (const_int 0)))]
18866   "! TARGET_PARTIAL_REG_STALL && reload_completed
18867    /* Ensure that the operand will remain sign-extended immediate.  */
18868    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18869    && ! TARGET_FAST_PREFIX
18870    && ! optimize_size"
18871   [(set (reg:CCNO FLAGS_REG)
18872         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18873                       (const_int 0)))]
18874   "operands[1]
18875      = gen_int_mode (INTVAL (operands[1])
18876                      & GET_MODE_MASK (GET_MODE (operands[0])),
18877                      SImode);
18878    operands[0] = gen_lowpart (SImode, operands[0]);")
18879
18880 (define_split
18881   [(set (match_operand 0 "register_operand" "")
18882         (neg (match_operand 1 "register_operand" "")))
18883    (clobber (reg:CC FLAGS_REG))]
18884   "! TARGET_PARTIAL_REG_STALL && reload_completed
18885    && (GET_MODE (operands[0]) == HImode
18886        || (GET_MODE (operands[0]) == QImode 
18887            && (TARGET_PROMOTE_QImode || optimize_size)))"
18888   [(parallel [(set (match_dup 0)
18889                    (neg:SI (match_dup 1)))
18890               (clobber (reg:CC FLAGS_REG))])]
18891   "operands[0] = gen_lowpart (SImode, operands[0]);
18892    operands[1] = gen_lowpart (SImode, operands[1]);")
18893
18894 (define_split
18895   [(set (match_operand 0 "register_operand" "")
18896         (not (match_operand 1 "register_operand" "")))]
18897   "! TARGET_PARTIAL_REG_STALL && reload_completed
18898    && (GET_MODE (operands[0]) == HImode
18899        || (GET_MODE (operands[0]) == QImode 
18900            && (TARGET_PROMOTE_QImode || optimize_size)))"
18901   [(set (match_dup 0)
18902         (not:SI (match_dup 1)))]
18903   "operands[0] = gen_lowpart (SImode, operands[0]);
18904    operands[1] = gen_lowpart (SImode, operands[1]);")
18905
18906 (define_split 
18907   [(set (match_operand 0 "register_operand" "")
18908         (if_then_else (match_operator 1 "comparison_operator" 
18909                                 [(reg 17) (const_int 0)])
18910                       (match_operand 2 "register_operand" "")
18911                       (match_operand 3 "register_operand" "")))]
18912   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18913    && (GET_MODE (operands[0]) == HImode
18914        || (GET_MODE (operands[0]) == QImode 
18915            && (TARGET_PROMOTE_QImode || optimize_size)))"
18916   [(set (match_dup 0)
18917         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18918   "operands[0] = gen_lowpart (SImode, operands[0]);
18919    operands[2] = gen_lowpart (SImode, operands[2]);
18920    operands[3] = gen_lowpart (SImode, operands[3]);")
18921                         
18922 \f
18923 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18924 ;; transform a complex memory operation into two memory to register operations.
18925
18926 ;; Don't push memory operands
18927 (define_peephole2
18928   [(set (match_operand:SI 0 "push_operand" "")
18929         (match_operand:SI 1 "memory_operand" ""))
18930    (match_scratch:SI 2 "r")]
18931   "! optimize_size && ! TARGET_PUSH_MEMORY"
18932   [(set (match_dup 2) (match_dup 1))
18933    (set (match_dup 0) (match_dup 2))]
18934   "")
18935
18936 (define_peephole2
18937   [(set (match_operand:DI 0 "push_operand" "")
18938         (match_operand:DI 1 "memory_operand" ""))
18939    (match_scratch:DI 2 "r")]
18940   "! optimize_size && ! TARGET_PUSH_MEMORY"
18941   [(set (match_dup 2) (match_dup 1))
18942    (set (match_dup 0) (match_dup 2))]
18943   "")
18944
18945 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18946 ;; SImode pushes.
18947 (define_peephole2
18948   [(set (match_operand:SF 0 "push_operand" "")
18949         (match_operand:SF 1 "memory_operand" ""))
18950    (match_scratch:SF 2 "r")]
18951   "! optimize_size && ! TARGET_PUSH_MEMORY"
18952   [(set (match_dup 2) (match_dup 1))
18953    (set (match_dup 0) (match_dup 2))]
18954   "")
18955
18956 (define_peephole2
18957   [(set (match_operand:HI 0 "push_operand" "")
18958         (match_operand:HI 1 "memory_operand" ""))
18959    (match_scratch:HI 2 "r")]
18960   "! optimize_size && ! TARGET_PUSH_MEMORY"
18961   [(set (match_dup 2) (match_dup 1))
18962    (set (match_dup 0) (match_dup 2))]
18963   "")
18964
18965 (define_peephole2
18966   [(set (match_operand:QI 0 "push_operand" "")
18967         (match_operand:QI 1 "memory_operand" ""))
18968    (match_scratch:QI 2 "q")]
18969   "! optimize_size && ! TARGET_PUSH_MEMORY"
18970   [(set (match_dup 2) (match_dup 1))
18971    (set (match_dup 0) (match_dup 2))]
18972   "")
18973
18974 ;; Don't move an immediate directly to memory when the instruction
18975 ;; gets too big.
18976 (define_peephole2
18977   [(match_scratch:SI 1 "r")
18978    (set (match_operand:SI 0 "memory_operand" "")
18979         (const_int 0))]
18980   "! optimize_size
18981    && ! TARGET_USE_MOV0
18982    && TARGET_SPLIT_LONG_MOVES
18983    && get_attr_length (insn) >= ix86_cost->large_insn
18984    && peep2_regno_dead_p (0, FLAGS_REG)"
18985   [(parallel [(set (match_dup 1) (const_int 0))
18986               (clobber (reg:CC FLAGS_REG))])
18987    (set (match_dup 0) (match_dup 1))]
18988   "")
18989
18990 (define_peephole2
18991   [(match_scratch:HI 1 "r")
18992    (set (match_operand:HI 0 "memory_operand" "")
18993         (const_int 0))]
18994   "! optimize_size
18995    && ! TARGET_USE_MOV0
18996    && TARGET_SPLIT_LONG_MOVES
18997    && get_attr_length (insn) >= ix86_cost->large_insn
18998    && peep2_regno_dead_p (0, FLAGS_REG)"
18999   [(parallel [(set (match_dup 2) (const_int 0))
19000               (clobber (reg:CC FLAGS_REG))])
19001    (set (match_dup 0) (match_dup 1))]
19002   "operands[2] = gen_lowpart (SImode, operands[1]);")
19003
19004 (define_peephole2
19005   [(match_scratch:QI 1 "q")
19006    (set (match_operand:QI 0 "memory_operand" "")
19007         (const_int 0))]
19008   "! optimize_size
19009    && ! TARGET_USE_MOV0
19010    && TARGET_SPLIT_LONG_MOVES
19011    && get_attr_length (insn) >= ix86_cost->large_insn
19012    && peep2_regno_dead_p (0, FLAGS_REG)"
19013   [(parallel [(set (match_dup 2) (const_int 0))
19014               (clobber (reg:CC FLAGS_REG))])
19015    (set (match_dup 0) (match_dup 1))]
19016   "operands[2] = gen_lowpart (SImode, operands[1]);")
19017
19018 (define_peephole2
19019   [(match_scratch:SI 2 "r")
19020    (set (match_operand:SI 0 "memory_operand" "")
19021         (match_operand:SI 1 "immediate_operand" ""))]
19022   "! optimize_size
19023    && get_attr_length (insn) >= ix86_cost->large_insn
19024    && TARGET_SPLIT_LONG_MOVES"
19025   [(set (match_dup 2) (match_dup 1))
19026    (set (match_dup 0) (match_dup 2))]
19027   "")
19028
19029 (define_peephole2
19030   [(match_scratch:HI 2 "r")
19031    (set (match_operand:HI 0 "memory_operand" "")
19032         (match_operand:HI 1 "immediate_operand" ""))]
19033   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19034   && TARGET_SPLIT_LONG_MOVES"
19035   [(set (match_dup 2) (match_dup 1))
19036    (set (match_dup 0) (match_dup 2))]
19037   "")
19038
19039 (define_peephole2
19040   [(match_scratch:QI 2 "q")
19041    (set (match_operand:QI 0 "memory_operand" "")
19042         (match_operand:QI 1 "immediate_operand" ""))]
19043   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19044   && TARGET_SPLIT_LONG_MOVES"
19045   [(set (match_dup 2) (match_dup 1))
19046    (set (match_dup 0) (match_dup 2))]
19047   "")
19048
19049 ;; Don't compare memory with zero, load and use a test instead.
19050 (define_peephole2
19051   [(set (reg 17)
19052         (compare (match_operand:SI 0 "memory_operand" "")
19053                  (const_int 0)))
19054    (match_scratch:SI 3 "r")]
19055   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19056   [(set (match_dup 3) (match_dup 0))
19057    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19058   "")
19059
19060 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19061 ;; Don't split NOTs with a displacement operand, because resulting XOR
19062 ;; will not be pairable anyway.
19063 ;;
19064 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19065 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19066 ;; so this split helps here as well.
19067 ;;
19068 ;; Note: Can't do this as a regular split because we can't get proper
19069 ;; lifetime information then.
19070
19071 (define_peephole2
19072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19073         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19074   "!optimize_size
19075    && peep2_regno_dead_p (0, FLAGS_REG)
19076    && ((TARGET_PENTIUM 
19077         && (GET_CODE (operands[0]) != MEM
19078             || !memory_displacement_operand (operands[0], SImode)))
19079        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19080   [(parallel [(set (match_dup 0)
19081                    (xor:SI (match_dup 1) (const_int -1)))
19082               (clobber (reg:CC FLAGS_REG))])]
19083   "")
19084
19085 (define_peephole2
19086   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19087         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19088   "!optimize_size
19089    && peep2_regno_dead_p (0, FLAGS_REG)
19090    && ((TARGET_PENTIUM 
19091         && (GET_CODE (operands[0]) != MEM
19092             || !memory_displacement_operand (operands[0], HImode)))
19093        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19094   [(parallel [(set (match_dup 0)
19095                    (xor:HI (match_dup 1) (const_int -1)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "")
19098
19099 (define_peephole2
19100   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19101         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19102   "!optimize_size
19103    && peep2_regno_dead_p (0, FLAGS_REG)
19104    && ((TARGET_PENTIUM 
19105         && (GET_CODE (operands[0]) != MEM
19106             || !memory_displacement_operand (operands[0], QImode)))
19107        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19108   [(parallel [(set (match_dup 0)
19109                    (xor:QI (match_dup 1) (const_int -1)))
19110               (clobber (reg:CC FLAGS_REG))])]
19111   "")
19112
19113 ;; Non pairable "test imm, reg" instructions can be translated to
19114 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19115 ;; byte opcode instead of two, have a short form for byte operands),
19116 ;; so do it for other CPUs as well.  Given that the value was dead,
19117 ;; this should not create any new dependencies.  Pass on the sub-word
19118 ;; versions if we're concerned about partial register stalls.
19119
19120 (define_peephole2
19121   [(set (reg 17)
19122         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19123                          (match_operand:SI 1 "immediate_operand" ""))
19124                  (const_int 0)))]
19125   "ix86_match_ccmode (insn, CCNOmode)
19126    && (true_regnum (operands[0]) != 0
19127        || (GET_CODE (operands[1]) == CONST_INT
19128            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19129    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19130   [(parallel
19131      [(set (reg:CCNO FLAGS_REG)
19132            (compare:CCNO (and:SI (match_dup 0)
19133                                  (match_dup 1))
19134                          (const_int 0)))
19135       (set (match_dup 0)
19136            (and:SI (match_dup 0) (match_dup 1)))])]
19137   "")
19138
19139 ;; We don't need to handle HImode case, because it will be promoted to SImode
19140 ;; on ! TARGET_PARTIAL_REG_STALL
19141
19142 (define_peephole2
19143   [(set (reg 17)
19144         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19145                          (match_operand:QI 1 "immediate_operand" ""))
19146                  (const_int 0)))]
19147   "! TARGET_PARTIAL_REG_STALL
19148    && ix86_match_ccmode (insn, CCNOmode)
19149    && true_regnum (operands[0]) != 0
19150    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19151   [(parallel
19152      [(set (reg:CCNO FLAGS_REG)
19153            (compare:CCNO (and:QI (match_dup 0)
19154                                  (match_dup 1))
19155                          (const_int 0)))
19156       (set (match_dup 0)
19157            (and:QI (match_dup 0) (match_dup 1)))])]
19158   "")
19159
19160 (define_peephole2
19161   [(set (reg 17)
19162         (compare
19163           (and:SI
19164             (zero_extract:SI
19165               (match_operand 0 "ext_register_operand" "")
19166               (const_int 8)
19167               (const_int 8))
19168             (match_operand 1 "const_int_operand" ""))
19169           (const_int 0)))]
19170   "! TARGET_PARTIAL_REG_STALL
19171    && ix86_match_ccmode (insn, CCNOmode)
19172    && true_regnum (operands[0]) != 0
19173    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19174   [(parallel [(set (reg:CCNO FLAGS_REG)
19175                    (compare:CCNO
19176                        (and:SI
19177                          (zero_extract:SI
19178                          (match_dup 0)
19179                          (const_int 8)
19180                          (const_int 8))
19181                         (match_dup 1))
19182                    (const_int 0)))
19183               (set (zero_extract:SI (match_dup 0)
19184                                     (const_int 8)
19185                                     (const_int 8))
19186                    (and:SI 
19187                      (zero_extract:SI
19188                        (match_dup 0)
19189                        (const_int 8)
19190                        (const_int 8))
19191                      (match_dup 1)))])]
19192   "")
19193
19194 ;; Don't do logical operations with memory inputs.
19195 (define_peephole2
19196   [(match_scratch:SI 2 "r")
19197    (parallel [(set (match_operand:SI 0 "register_operand" "")
19198                    (match_operator:SI 3 "arith_or_logical_operator"
19199                      [(match_dup 0)
19200                       (match_operand:SI 1 "memory_operand" "")]))
19201               (clobber (reg:CC FLAGS_REG))])]
19202   "! optimize_size && ! TARGET_READ_MODIFY"
19203   [(set (match_dup 2) (match_dup 1))
19204    (parallel [(set (match_dup 0)
19205                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19206               (clobber (reg:CC FLAGS_REG))])]
19207   "")
19208
19209 (define_peephole2
19210   [(match_scratch:SI 2 "r")
19211    (parallel [(set (match_operand:SI 0 "register_operand" "")
19212                    (match_operator:SI 3 "arith_or_logical_operator"
19213                      [(match_operand:SI 1 "memory_operand" "")
19214                       (match_dup 0)]))
19215               (clobber (reg:CC FLAGS_REG))])]
19216   "! optimize_size && ! TARGET_READ_MODIFY"
19217   [(set (match_dup 2) (match_dup 1))
19218    (parallel [(set (match_dup 0)
19219                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   "")
19222
19223 ; Don't do logical operations with memory outputs
19224 ;
19225 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19226 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19227 ; the same decoder scheduling characteristics as the original.
19228
19229 (define_peephole2
19230   [(match_scratch:SI 2 "r")
19231    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19232                    (match_operator:SI 3 "arith_or_logical_operator"
19233                      [(match_dup 0)
19234                       (match_operand:SI 1 "nonmemory_operand" "")]))
19235               (clobber (reg:CC FLAGS_REG))])]
19236   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19237   [(set (match_dup 2) (match_dup 0))
19238    (parallel [(set (match_dup 2)
19239                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19240               (clobber (reg:CC FLAGS_REG))])
19241    (set (match_dup 0) (match_dup 2))]
19242   "")
19243
19244 (define_peephole2
19245   [(match_scratch:SI 2 "r")
19246    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19247                    (match_operator:SI 3 "arith_or_logical_operator"
19248                      [(match_operand:SI 1 "nonmemory_operand" "")
19249                       (match_dup 0)]))
19250               (clobber (reg:CC FLAGS_REG))])]
19251   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19252   [(set (match_dup 2) (match_dup 0))
19253    (parallel [(set (match_dup 2)
19254                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19255               (clobber (reg:CC FLAGS_REG))])
19256    (set (match_dup 0) (match_dup 2))]
19257   "")
19258
19259 ;; Attempt to always use XOR for zeroing registers.
19260 (define_peephole2
19261   [(set (match_operand 0 "register_operand" "")
19262         (const_int 0))]
19263   "(GET_MODE (operands[0]) == QImode
19264     || GET_MODE (operands[0]) == HImode
19265     || GET_MODE (operands[0]) == SImode
19266     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19267    && (! TARGET_USE_MOV0 || optimize_size)
19268    && peep2_regno_dead_p (0, FLAGS_REG)"
19269   [(parallel [(set (match_dup 0) (const_int 0))
19270               (clobber (reg:CC FLAGS_REG))])]
19271   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19272                               operands[0]);")
19273
19274 (define_peephole2
19275   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19276         (const_int 0))]
19277   "(GET_MODE (operands[0]) == QImode
19278     || GET_MODE (operands[0]) == HImode)
19279    && (! TARGET_USE_MOV0 || optimize_size)
19280    && peep2_regno_dead_p (0, FLAGS_REG)"
19281   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19282               (clobber (reg:CC FLAGS_REG))])])
19283
19284 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19285 (define_peephole2
19286   [(set (match_operand 0 "register_operand" "")
19287         (const_int -1))]
19288   "(GET_MODE (operands[0]) == HImode
19289     || GET_MODE (operands[0]) == SImode 
19290     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19291    && (optimize_size || TARGET_PENTIUM)
19292    && peep2_regno_dead_p (0, FLAGS_REG)"
19293   [(parallel [(set (match_dup 0) (const_int -1))
19294               (clobber (reg:CC FLAGS_REG))])]
19295   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19296                               operands[0]);")
19297
19298 ;; Attempt to convert simple leas to adds. These can be created by
19299 ;; move expanders.
19300 (define_peephole2
19301   [(set (match_operand:SI 0 "register_operand" "")
19302         (plus:SI (match_dup 0)
19303                  (match_operand:SI 1 "nonmemory_operand" "")))]
19304   "peep2_regno_dead_p (0, FLAGS_REG)"
19305   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19306               (clobber (reg:CC FLAGS_REG))])]
19307   "")
19308
19309 (define_peephole2
19310   [(set (match_operand:SI 0 "register_operand" "")
19311         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19312                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19313   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19314   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19315               (clobber (reg:CC FLAGS_REG))])]
19316   "operands[2] = gen_lowpart (SImode, operands[2]);")
19317
19318 (define_peephole2
19319   [(set (match_operand:DI 0 "register_operand" "")
19320         (plus:DI (match_dup 0)
19321                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19322   "peep2_regno_dead_p (0, FLAGS_REG)"
19323   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19324               (clobber (reg:CC FLAGS_REG))])]
19325   "")
19326
19327 (define_peephole2
19328   [(set (match_operand:SI 0 "register_operand" "")
19329         (mult:SI (match_dup 0)
19330                  (match_operand:SI 1 "const_int_operand" "")))]
19331   "exact_log2 (INTVAL (operands[1])) >= 0
19332    && peep2_regno_dead_p (0, FLAGS_REG)"
19333   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19334               (clobber (reg:CC FLAGS_REG))])]
19335   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19336
19337 (define_peephole2
19338   [(set (match_operand:DI 0 "register_operand" "")
19339         (mult:DI (match_dup 0)
19340                  (match_operand:DI 1 "const_int_operand" "")))]
19341   "exact_log2 (INTVAL (operands[1])) >= 0
19342    && peep2_regno_dead_p (0, FLAGS_REG)"
19343   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19344               (clobber (reg:CC FLAGS_REG))])]
19345   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19346
19347 (define_peephole2
19348   [(set (match_operand:SI 0 "register_operand" "")
19349         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19350                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19351   "exact_log2 (INTVAL (operands[2])) >= 0
19352    && REGNO (operands[0]) == REGNO (operands[1])
19353    && peep2_regno_dead_p (0, FLAGS_REG)"
19354   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19355               (clobber (reg:CC FLAGS_REG))])]
19356   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19357
19358 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19359 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19360 ;; many CPUs it is also faster, since special hardware to avoid esp
19361 ;; dependencies is present.
19362
19363 ;; While some of these conversions may be done using splitters, we use peepholes
19364 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19365
19366 ;; Convert prologue esp subtractions to push.
19367 ;; We need register to push.  In order to keep verify_flow_info happy we have
19368 ;; two choices
19369 ;; - use scratch and clobber it in order to avoid dependencies
19370 ;; - use already live register
19371 ;; We can't use the second way right now, since there is no reliable way how to
19372 ;; verify that given register is live.  First choice will also most likely in
19373 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19374 ;; call clobbered registers are dead.  We may want to use base pointer as an
19375 ;; alternative when no register is available later.
19376
19377 (define_peephole2
19378   [(match_scratch:SI 0 "r")
19379    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19380               (clobber (reg:CC FLAGS_REG))
19381               (clobber (mem:BLK (scratch)))])]
19382   "optimize_size || !TARGET_SUB_ESP_4"
19383   [(clobber (match_dup 0))
19384    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19385               (clobber (mem:BLK (scratch)))])])
19386
19387 (define_peephole2
19388   [(match_scratch:SI 0 "r")
19389    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19390               (clobber (reg:CC FLAGS_REG))
19391               (clobber (mem:BLK (scratch)))])]
19392   "optimize_size || !TARGET_SUB_ESP_8"
19393   [(clobber (match_dup 0))
19394    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19395    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19396               (clobber (mem:BLK (scratch)))])])
19397
19398 ;; Convert esp subtractions to push.
19399 (define_peephole2
19400   [(match_scratch:SI 0 "r")
19401    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19402               (clobber (reg:CC FLAGS_REG))])]
19403   "optimize_size || !TARGET_SUB_ESP_4"
19404   [(clobber (match_dup 0))
19405    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19406
19407 (define_peephole2
19408   [(match_scratch:SI 0 "r")
19409    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19410               (clobber (reg:CC FLAGS_REG))])]
19411   "optimize_size || !TARGET_SUB_ESP_8"
19412   [(clobber (match_dup 0))
19413    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19414    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19415
19416 ;; Convert epilogue deallocator to pop.
19417 (define_peephole2
19418   [(match_scratch:SI 0 "r")
19419    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19420               (clobber (reg:CC FLAGS_REG))
19421               (clobber (mem:BLK (scratch)))])]
19422   "optimize_size || !TARGET_ADD_ESP_4"
19423   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19424               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19425               (clobber (mem:BLK (scratch)))])]
19426   "")
19427
19428 ;; Two pops case is tricky, since pop causes dependency on destination register.
19429 ;; We use two registers if available.
19430 (define_peephole2
19431   [(match_scratch:SI 0 "r")
19432    (match_scratch:SI 1 "r")
19433    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19434               (clobber (reg:CC FLAGS_REG))
19435               (clobber (mem:BLK (scratch)))])]
19436   "optimize_size || !TARGET_ADD_ESP_8"
19437   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19439               (clobber (mem:BLK (scratch)))])
19440    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19441               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19442   "")
19443
19444 (define_peephole2
19445   [(match_scratch:SI 0 "r")
19446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447               (clobber (reg:CC FLAGS_REG))
19448               (clobber (mem:BLK (scratch)))])]
19449   "optimize_size"
19450   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452               (clobber (mem:BLK (scratch)))])
19453    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19455   "")
19456
19457 ;; Convert esp additions to pop.
19458 (define_peephole2
19459   [(match_scratch:SI 0 "r")
19460    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19461               (clobber (reg:CC FLAGS_REG))])]
19462   ""
19463   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19465   "")
19466
19467 ;; Two pops case is tricky, since pop causes dependency on destination register.
19468 ;; We use two registers if available.
19469 (define_peephole2
19470   [(match_scratch:SI 0 "r")
19471    (match_scratch:SI 1 "r")
19472    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   ""
19475   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19476               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19477    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19478               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19479   "")
19480
19481 (define_peephole2
19482   [(match_scratch:SI 0 "r")
19483    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19484               (clobber (reg:CC FLAGS_REG))])]
19485   "optimize_size"
19486   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19487               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19488    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19490   "")
19491 \f
19492 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19493 ;; required and register dies.
19494 (define_peephole2
19495   [(set (reg 17)
19496         (compare (match_operand:SI 0 "register_operand" "")
19497                  (match_operand:SI 1 "incdec_operand" "")))]
19498   "ix86_match_ccmode (insn, CCGCmode)
19499    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19500   [(parallel [(set (reg:CCGC FLAGS_REG)
19501                    (compare:CCGC (match_dup 0)
19502                                  (match_dup 1)))
19503               (clobber (match_dup 0))])]
19504   "")
19505
19506 (define_peephole2
19507   [(set (reg 17)
19508         (compare (match_operand:HI 0 "register_operand" "")
19509                  (match_operand:HI 1 "incdec_operand" "")))]
19510   "ix86_match_ccmode (insn, CCGCmode)
19511    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19512   [(parallel [(set (reg:CCGC FLAGS_REG)
19513                    (compare:CCGC (match_dup 0)
19514                                  (match_dup 1)))
19515               (clobber (match_dup 0))])]
19516   "")
19517
19518 (define_peephole2
19519   [(set (reg 17)
19520         (compare (match_operand:QI 0 "register_operand" "")
19521                  (match_operand:QI 1 "incdec_operand" "")))]
19522   "ix86_match_ccmode (insn, CCGCmode)
19523    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19524   [(parallel [(set (reg:CCGC FLAGS_REG)
19525                    (compare:CCGC (match_dup 0)
19526                                  (match_dup 1)))
19527               (clobber (match_dup 0))])]
19528   "")
19529
19530 ;; Convert compares with 128 to shorter add -128
19531 (define_peephole2
19532   [(set (reg 17)
19533         (compare (match_operand:SI 0 "register_operand" "")
19534                  (const_int 128)))]
19535   "ix86_match_ccmode (insn, CCGCmode)
19536    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19537   [(parallel [(set (reg:CCGC FLAGS_REG)
19538                    (compare:CCGC (match_dup 0)
19539                                  (const_int 128)))
19540               (clobber (match_dup 0))])]
19541   "")
19542
19543 (define_peephole2
19544   [(set (reg 17)
19545         (compare (match_operand:HI 0 "register_operand" "")
19546                  (const_int 128)))]
19547   "ix86_match_ccmode (insn, CCGCmode)
19548    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19549   [(parallel [(set (reg:CCGC FLAGS_REG)
19550                    (compare:CCGC (match_dup 0)
19551                                  (const_int 128)))
19552               (clobber (match_dup 0))])]
19553   "")
19554 \f
19555 (define_peephole2
19556   [(match_scratch:DI 0 "r")
19557    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19558               (clobber (reg:CC FLAGS_REG))
19559               (clobber (mem:BLK (scratch)))])]
19560   "optimize_size || !TARGET_SUB_ESP_4"
19561   [(clobber (match_dup 0))
19562    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19563               (clobber (mem:BLK (scratch)))])])
19564
19565 (define_peephole2
19566   [(match_scratch:DI 0 "r")
19567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19568               (clobber (reg:CC FLAGS_REG))
19569               (clobber (mem:BLK (scratch)))])]
19570   "optimize_size || !TARGET_SUB_ESP_8"
19571   [(clobber (match_dup 0))
19572    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19573    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19574               (clobber (mem:BLK (scratch)))])])
19575
19576 ;; Convert esp subtractions to push.
19577 (define_peephole2
19578   [(match_scratch:DI 0 "r")
19579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   "optimize_size || !TARGET_SUB_ESP_4"
19582   [(clobber (match_dup 0))
19583    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19584
19585 (define_peephole2
19586   [(match_scratch:DI 0 "r")
19587    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19588               (clobber (reg:CC FLAGS_REG))])]
19589   "optimize_size || !TARGET_SUB_ESP_8"
19590   [(clobber (match_dup 0))
19591    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19592    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19593
19594 ;; Convert epilogue deallocator to pop.
19595 (define_peephole2
19596   [(match_scratch:DI 0 "r")
19597    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19598               (clobber (reg:CC FLAGS_REG))
19599               (clobber (mem:BLK (scratch)))])]
19600   "optimize_size || !TARGET_ADD_ESP_4"
19601   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19602               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19603               (clobber (mem:BLK (scratch)))])]
19604   "")
19605
19606 ;; Two pops case is tricky, since pop causes dependency on destination register.
19607 ;; We use two registers if available.
19608 (define_peephole2
19609   [(match_scratch:DI 0 "r")
19610    (match_scratch:DI 1 "r")
19611    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19612               (clobber (reg:CC FLAGS_REG))
19613               (clobber (mem:BLK (scratch)))])]
19614   "optimize_size || !TARGET_ADD_ESP_8"
19615   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19616               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19617               (clobber (mem:BLK (scratch)))])
19618    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19619               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19620   "")
19621
19622 (define_peephole2
19623   [(match_scratch:DI 0 "r")
19624    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19625               (clobber (reg:CC FLAGS_REG))
19626               (clobber (mem:BLK (scratch)))])]
19627   "optimize_size"
19628   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19629               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19630               (clobber (mem:BLK (scratch)))])
19631    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19633   "")
19634
19635 ;; Convert esp additions to pop.
19636 (define_peephole2
19637   [(match_scratch:DI 0 "r")
19638    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19639               (clobber (reg:CC FLAGS_REG))])]
19640   ""
19641   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19642               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19643   "")
19644
19645 ;; Two pops case is tricky, since pop causes dependency on destination register.
19646 ;; We use two registers if available.
19647 (define_peephole2
19648   [(match_scratch:DI 0 "r")
19649    (match_scratch:DI 1 "r")
19650    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19651               (clobber (reg:CC FLAGS_REG))])]
19652   ""
19653   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19654               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19655    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19656               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19657   "")
19658
19659 (define_peephole2
19660   [(match_scratch:DI 0 "r")
19661    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19662               (clobber (reg:CC FLAGS_REG))])]
19663   "optimize_size"
19664   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19665               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19666    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19667               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19668   "")
19669 \f
19670 ;; Convert imul by three, five and nine into lea
19671 (define_peephole2
19672   [(parallel
19673     [(set (match_operand:SI 0 "register_operand" "")
19674           (mult:SI (match_operand:SI 1 "register_operand" "")
19675                    (match_operand:SI 2 "const_int_operand" "")))
19676      (clobber (reg:CC FLAGS_REG))])]
19677   "INTVAL (operands[2]) == 3
19678    || INTVAL (operands[2]) == 5
19679    || INTVAL (operands[2]) == 9"
19680   [(set (match_dup 0)
19681         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19682                  (match_dup 1)))]
19683   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19684
19685 (define_peephole2
19686   [(parallel
19687     [(set (match_operand:SI 0 "register_operand" "")
19688           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19689                    (match_operand:SI 2 "const_int_operand" "")))
19690      (clobber (reg:CC FLAGS_REG))])]
19691   "!optimize_size 
19692    && (INTVAL (operands[2]) == 3
19693        || INTVAL (operands[2]) == 5
19694        || INTVAL (operands[2]) == 9)"
19695   [(set (match_dup 0) (match_dup 1))
19696    (set (match_dup 0)
19697         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19698                  (match_dup 0)))]
19699   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19700
19701 (define_peephole2
19702   [(parallel
19703     [(set (match_operand:DI 0 "register_operand" "")
19704           (mult:DI (match_operand:DI 1 "register_operand" "")
19705                    (match_operand:DI 2 "const_int_operand" "")))
19706      (clobber (reg:CC FLAGS_REG))])]
19707   "TARGET_64BIT
19708    && (INTVAL (operands[2]) == 3
19709        || INTVAL (operands[2]) == 5
19710        || INTVAL (operands[2]) == 9)"
19711   [(set (match_dup 0)
19712         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19713                  (match_dup 1)))]
19714   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19715
19716 (define_peephole2
19717   [(parallel
19718     [(set (match_operand:DI 0 "register_operand" "")
19719           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19720                    (match_operand:DI 2 "const_int_operand" "")))
19721      (clobber (reg:CC FLAGS_REG))])]
19722   "TARGET_64BIT
19723    && !optimize_size 
19724    && (INTVAL (operands[2]) == 3
19725        || INTVAL (operands[2]) == 5
19726        || INTVAL (operands[2]) == 9)"
19727   [(set (match_dup 0) (match_dup 1))
19728    (set (match_dup 0)
19729         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19730                  (match_dup 0)))]
19731   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19732
19733 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19734 ;; imul $32bit_imm, reg, reg is direct decoded.
19735 (define_peephole2
19736   [(match_scratch:DI 3 "r")
19737    (parallel [(set (match_operand:DI 0 "register_operand" "")
19738                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19739                             (match_operand:DI 2 "immediate_operand" "")))
19740               (clobber (reg:CC FLAGS_REG))])]
19741   "TARGET_K8 && !optimize_size
19742    && (GET_CODE (operands[2]) != CONST_INT
19743        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19744   [(set (match_dup 3) (match_dup 1))
19745    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19746               (clobber (reg:CC FLAGS_REG))])]
19747 "")
19748
19749 (define_peephole2
19750   [(match_scratch:SI 3 "r")
19751    (parallel [(set (match_operand:SI 0 "register_operand" "")
19752                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19753                             (match_operand:SI 2 "immediate_operand" "")))
19754               (clobber (reg:CC FLAGS_REG))])]
19755   "TARGET_K8 && !optimize_size
19756    && (GET_CODE (operands[2]) != CONST_INT
19757        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19758   [(set (match_dup 3) (match_dup 1))
19759    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19760               (clobber (reg:CC FLAGS_REG))])]
19761 "")
19762
19763 (define_peephole2
19764   [(match_scratch:SI 3 "r")
19765    (parallel [(set (match_operand:DI 0 "register_operand" "")
19766                    (zero_extend:DI
19767                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19768                               (match_operand:SI 2 "immediate_operand" ""))))
19769               (clobber (reg:CC FLAGS_REG))])]
19770   "TARGET_K8 && !optimize_size
19771    && (GET_CODE (operands[2]) != CONST_INT
19772        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19773   [(set (match_dup 3) (match_dup 1))
19774    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19775               (clobber (reg:CC FLAGS_REG))])]
19776 "")
19777
19778 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19779 ;; Convert it into imul reg, reg
19780 ;; It would be better to force assembler to encode instruction using long
19781 ;; immediate, but there is apparently no way to do so.
19782 (define_peephole2
19783   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19784                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19785                             (match_operand:DI 2 "const_int_operand" "")))
19786               (clobber (reg:CC FLAGS_REG))])
19787    (match_scratch:DI 3 "r")]
19788   "TARGET_K8 && !optimize_size
19789    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19790   [(set (match_dup 3) (match_dup 2))
19791    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19792               (clobber (reg:CC FLAGS_REG))])]
19793 {
19794   if (!rtx_equal_p (operands[0], operands[1]))
19795     emit_move_insn (operands[0], operands[1]);
19796 })
19797
19798 (define_peephole2
19799   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19800                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19801                             (match_operand:SI 2 "const_int_operand" "")))
19802               (clobber (reg:CC FLAGS_REG))])
19803    (match_scratch:SI 3 "r")]
19804   "TARGET_K8 && !optimize_size
19805    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19806   [(set (match_dup 3) (match_dup 2))
19807    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19808               (clobber (reg:CC FLAGS_REG))])]
19809 {
19810   if (!rtx_equal_p (operands[0], operands[1]))
19811     emit_move_insn (operands[0], operands[1]);
19812 })
19813
19814 (define_peephole2
19815   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19816                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19817                             (match_operand:HI 2 "immediate_operand" "")))
19818               (clobber (reg:CC FLAGS_REG))])
19819    (match_scratch:HI 3 "r")]
19820   "TARGET_K8 && !optimize_size"
19821   [(set (match_dup 3) (match_dup 2))
19822    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19823               (clobber (reg:CC FLAGS_REG))])]
19824 {
19825   if (!rtx_equal_p (operands[0], operands[1]))
19826     emit_move_insn (operands[0], operands[1]);
19827 })
19828 \f
19829 ;; Call-value patterns last so that the wildcard operand does not
19830 ;; disrupt insn-recog's switch tables.
19831
19832 (define_insn "*call_value_pop_0"
19833   [(set (match_operand 0 "" "")
19834         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19835               (match_operand:SI 2 "" "")))
19836    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19837                             (match_operand:SI 3 "immediate_operand" "")))]
19838   "!TARGET_64BIT"
19839 {
19840   if (SIBLING_CALL_P (insn))
19841     return "jmp\t%P1";
19842   else
19843     return "call\t%P1";
19844 }
19845   [(set_attr "type" "callv")])
19846
19847 (define_insn "*call_value_pop_1"
19848   [(set (match_operand 0 "" "")
19849         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19850               (match_operand:SI 2 "" "")))
19851    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19852                             (match_operand:SI 3 "immediate_operand" "i")))]
19853   "!TARGET_64BIT"
19854 {
19855   if (constant_call_address_operand (operands[1], Pmode))
19856     {
19857       if (SIBLING_CALL_P (insn))
19858         return "jmp\t%P1";
19859       else
19860         return "call\t%P1";
19861     }
19862   if (SIBLING_CALL_P (insn))
19863     return "jmp\t%A1";
19864   else
19865     return "call\t%A1";
19866 }
19867   [(set_attr "type" "callv")])
19868
19869 (define_insn "*call_value_0"
19870   [(set (match_operand 0 "" "")
19871         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19872               (match_operand:SI 2 "" "")))]
19873   "!TARGET_64BIT"
19874 {
19875   if (SIBLING_CALL_P (insn))
19876     return "jmp\t%P1";
19877   else
19878     return "call\t%P1";
19879 }
19880   [(set_attr "type" "callv")])
19881
19882 (define_insn "*call_value_0_rex64"
19883   [(set (match_operand 0 "" "")
19884         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19885               (match_operand:DI 2 "const_int_operand" "")))]
19886   "TARGET_64BIT"
19887 {
19888   if (SIBLING_CALL_P (insn))
19889     return "jmp\t%P1";
19890   else
19891     return "call\t%P1";
19892 }
19893   [(set_attr "type" "callv")])
19894
19895 (define_insn "*call_value_1"
19896   [(set (match_operand 0 "" "")
19897         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19898               (match_operand:SI 2 "" "")))]
19899   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19900 {
19901   if (constant_call_address_operand (operands[1], Pmode))
19902     return "call\t%P1";
19903   return "call\t%*%1";
19904 }
19905   [(set_attr "type" "callv")])
19906
19907 (define_insn "*sibcall_value_1"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19910               (match_operand:SI 2 "" "")))]
19911   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19912 {
19913   if (constant_call_address_operand (operands[1], Pmode))
19914     return "jmp\t%P1";
19915   return "jmp\t%*%1";
19916 }
19917   [(set_attr "type" "callv")])
19918
19919 (define_insn "*call_value_1_rex64"
19920   [(set (match_operand 0 "" "")
19921         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19922               (match_operand:DI 2 "" "")))]
19923   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19924 {
19925   if (constant_call_address_operand (operands[1], Pmode))
19926     return "call\t%P1";
19927   return "call\t%A1";
19928 }
19929   [(set_attr "type" "callv")])
19930
19931 (define_insn "*sibcall_value_1_rex64"
19932   [(set (match_operand 0 "" "")
19933         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19934               (match_operand:DI 2 "" "")))]
19935   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19936   "jmp\t%P1"
19937   [(set_attr "type" "callv")])
19938
19939 (define_insn "*sibcall_value_1_rex64_v"
19940   [(set (match_operand 0 "" "")
19941         (call (mem:QI (reg:DI 40))
19942               (match_operand:DI 1 "" "")))]
19943   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19944   "jmp\t*%%r11"
19945   [(set_attr "type" "callv")])
19946 \f
19947 (define_insn "trap"
19948   [(trap_if (const_int 1) (const_int 5))]
19949   ""
19950   "int\t$5")
19951
19952 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19953 ;;; for the sake of bounds checking.  By emitting bounds checks as
19954 ;;; conditional traps rather than as conditional jumps around
19955 ;;; unconditional traps we avoid introducing spurious basic-block
19956 ;;; boundaries and facilitate elimination of redundant checks.  In
19957 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19958 ;;; interrupt 5.
19959 ;;; 
19960 ;;; FIXME: Static branch prediction rules for ix86 are such that
19961 ;;; forward conditional branches predict as untaken.  As implemented
19962 ;;; below, pseudo conditional traps violate that rule.  We should use
19963 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19964 ;;; section loaded at the end of the text segment and branch forward
19965 ;;; there on bounds-failure, and then jump back immediately (in case
19966 ;;; the system chooses to ignore bounds violations, or to report
19967 ;;; violations and continue execution).
19968
19969 (define_expand "conditional_trap"
19970   [(trap_if (match_operator 0 "comparison_operator"
19971              [(match_dup 2) (const_int 0)])
19972             (match_operand 1 "const_int_operand" ""))]
19973   ""
19974 {
19975   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19976                               ix86_expand_compare (GET_CODE (operands[0]),
19977                                                    NULL, NULL),
19978                               operands[1]));
19979   DONE;
19980 })
19981
19982 (define_insn "*conditional_trap_1"
19983   [(trap_if (match_operator 0 "comparison_operator"
19984              [(reg 17) (const_int 0)])
19985             (match_operand 1 "const_int_operand" ""))]
19986   ""
19987 {
19988   operands[2] = gen_label_rtx ();
19989   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19990   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19991                              CODE_LABEL_NUMBER (operands[2]));
19992   RET;
19993 })
19994
19995         ;; Pentium III SIMD instructions.
19996
19997 ;; Moves for SSE/MMX regs.
19998
19999 (define_insn "movv4sf_internal"
20000   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20001         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
20002   "TARGET_SSE"
20003   "@
20004     xorps\t%0, %0
20005     movaps\t{%1, %0|%0, %1}
20006     movaps\t{%1, %0|%0, %1}"
20007   [(set_attr "type" "ssemov")
20008    (set_attr "mode" "V4SF")])
20009
20010 (define_split
20011   [(set (match_operand:V4SF 0 "register_operand" "")
20012         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
20013   "TARGET_SSE"
20014   [(set (match_dup 0)
20015         (vec_merge:V4SF
20016          (vec_duplicate:V4SF (match_dup 1))
20017          (match_dup 2)
20018          (const_int 1)))]
20019 {
20020   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20021   operands[2] = CONST0_RTX (V4SFmode);
20022 })
20023
20024 (define_insn "movv4si_internal"
20025   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20026         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20027   "TARGET_SSE"
20028 {
20029   switch (which_alternative)
20030     {
20031     case 0:
20032       if (get_attr_mode (insn) == MODE_V4SF)
20033         return "xorps\t%0, %0";
20034       else
20035         return "pxor\t%0, %0";
20036     case 1:
20037     case 2:
20038       if (get_attr_mode (insn) == MODE_V4SF)
20039         return "movaps\t{%1, %0|%0, %1}";
20040       else
20041         return "movdqa\t{%1, %0|%0, %1}";
20042     default:
20043       abort ();
20044     }
20045 }
20046   [(set_attr "type" "ssemov")
20047    (set (attr "mode")
20048         (cond [(eq_attr "alternative" "0,1")
20049                  (if_then_else
20050                    (ne (symbol_ref "optimize_size")
20051                        (const_int 0))
20052                    (const_string "V4SF")
20053                    (const_string "TI"))
20054                (eq_attr "alternative" "2")
20055                  (if_then_else
20056                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20057                             (const_int 0))
20058                         (ne (symbol_ref "optimize_size")
20059                             (const_int 0)))
20060                    (const_string "V4SF")
20061                    (const_string "TI"))]
20062                (const_string "TI")))])
20063
20064 (define_insn "movv2di_internal"
20065   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20066         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20067   "TARGET_SSE"
20068 {
20069   switch (which_alternative)
20070     {
20071     case 0:
20072       if (get_attr_mode (insn) == MODE_V4SF)
20073         return "xorps\t%0, %0";
20074       else
20075         return "pxor\t%0, %0";
20076     case 1:
20077     case 2:
20078       if (get_attr_mode (insn) == MODE_V4SF)
20079         return "movaps\t{%1, %0|%0, %1}";
20080       else
20081         return "movdqa\t{%1, %0|%0, %1}";
20082     default:
20083       abort ();
20084     }
20085 }
20086   [(set_attr "type" "ssemov")
20087    (set (attr "mode")
20088         (cond [(eq_attr "alternative" "0,1")
20089                  (if_then_else
20090                    (ne (symbol_ref "optimize_size")
20091                        (const_int 0))
20092                    (const_string "V4SF")
20093                    (const_string "TI"))
20094                (eq_attr "alternative" "2")
20095                  (if_then_else
20096                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20097                             (const_int 0))
20098                         (ne (symbol_ref "optimize_size")
20099                             (const_int 0)))
20100                    (const_string "V4SF")
20101                    (const_string "TI"))]
20102                (const_string "TI")))])
20103
20104 (define_split
20105   [(set (match_operand:V2DF 0 "register_operand" "")
20106         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20107   "TARGET_SSE2"
20108   [(set (match_dup 0)
20109         (vec_merge:V2DF
20110          (vec_duplicate:V2DF (match_dup 1))
20111          (match_dup 2)
20112          (const_int 1)))]
20113 {
20114   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20115   operands[2] = CONST0_RTX (V2DFmode);
20116 })
20117
20118 (define_insn "movv8qi_internal"
20119   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20120         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20121   "TARGET_MMX
20122    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20123   "@
20124     pxor\t%0, %0
20125     movq\t{%1, %0|%0, %1}
20126     movq\t{%1, %0|%0, %1}
20127     movdq2q\t{%1, %0|%0, %1}
20128     movq2dq\t{%1, %0|%0, %1}
20129     movq\t{%1, %0|%0, %1}
20130     movq\t{%1, %0|%0, %1}"
20131   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20132    (set_attr "mode" "DI")])
20133
20134 (define_insn "movv4hi_internal"
20135   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20136         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20137   "TARGET_MMX
20138    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20139   "@
20140     pxor\t%0, %0
20141     movq\t{%1, %0|%0, %1}
20142     movq\t{%1, %0|%0, %1}
20143     movdq2q\t{%1, %0|%0, %1}
20144     movq2dq\t{%1, %0|%0, %1}
20145     movq\t{%1, %0|%0, %1}
20146     movq\t{%1, %0|%0, %1}"
20147   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20148    (set_attr "mode" "DI")])
20149
20150 (define_insn "*movv2si_internal"
20151   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20152         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20153   "TARGET_MMX
20154    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20155   "@
20156     pxor\t%0, %0
20157     movq\t{%1, %0|%0, %1}
20158     movq\t{%1, %0|%0, %1}
20159     movdq2q\t{%1, %0|%0, %1}
20160     movq2dq\t{%1, %0|%0, %1}
20161     movq\t{%1, %0|%0, %1}
20162     movq\t{%1, %0|%0, %1}"
20163   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20164    (set_attr "mode" "DI")])
20165
20166 (define_insn "movv2sf_internal"
20167   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20168         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20169   "TARGET_3DNOW
20170    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20171   "@
20172     pxor\t%0, %0
20173     movq\t{%1, %0|%0, %1}
20174     movq\t{%1, %0|%0, %1}
20175     movdq2q\t{%1, %0|%0, %1}
20176     movq2dq\t{%1, %0|%0, %1}
20177     movlps\t{%1, %0|%0, %1}
20178     movlps\t{%1, %0|%0, %1}"
20179   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20180    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20181
20182 (define_expand "movti"
20183   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20184         (match_operand:TI 1 "nonimmediate_operand" ""))]
20185   "TARGET_SSE || TARGET_64BIT"
20186 {
20187   if (TARGET_64BIT)
20188     ix86_expand_move (TImode, operands);
20189   else
20190     ix86_expand_vector_move (TImode, operands);
20191   DONE;
20192 })
20193
20194 (define_expand "movtf"
20195   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20196         (match_operand:TF 1 "nonimmediate_operand" ""))]
20197   "TARGET_64BIT"
20198 {
20199   if (TARGET_64BIT)
20200     ix86_expand_move (TFmode, operands);
20201   else
20202     ix86_expand_vector_move (TFmode, operands);
20203   DONE;
20204 })
20205
20206 (define_insn "movv2df_internal"
20207   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20208         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20209   "TARGET_SSE2
20210    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20211 {
20212   switch (which_alternative)
20213     {
20214     case 0:
20215       if (get_attr_mode (insn) == MODE_V4SF)
20216         return "xorps\t%0, %0";
20217       else
20218         return "xorpd\t%0, %0";
20219     case 1:
20220     case 2:
20221       if (get_attr_mode (insn) == MODE_V4SF)
20222         return "movaps\t{%1, %0|%0, %1}";
20223       else
20224         return "movapd\t{%1, %0|%0, %1}";
20225     default:
20226       abort ();
20227     }
20228 }
20229   [(set_attr "type" "ssemov")
20230    (set (attr "mode")
20231         (cond [(eq_attr "alternative" "0,1")
20232                  (if_then_else
20233                    (ne (symbol_ref "optimize_size")
20234                        (const_int 0))
20235                    (const_string "V4SF")
20236                    (const_string "V2DF"))
20237                (eq_attr "alternative" "2")
20238                  (if_then_else
20239                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20240                             (const_int 0))
20241                         (ne (symbol_ref "optimize_size")
20242                             (const_int 0)))
20243                    (const_string "V4SF")
20244                    (const_string "V2DF"))]
20245                (const_string "V2DF")))])
20246
20247 (define_insn "movv8hi_internal"
20248   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20249         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20250   "TARGET_SSE2
20251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20252 {
20253   switch (which_alternative)
20254     {
20255     case 0:
20256       if (get_attr_mode (insn) == MODE_V4SF)
20257         return "xorps\t%0, %0";
20258       else
20259         return "pxor\t%0, %0";
20260     case 1:
20261     case 2:
20262       if (get_attr_mode (insn) == MODE_V4SF)
20263         return "movaps\t{%1, %0|%0, %1}";
20264       else
20265         return "movdqa\t{%1, %0|%0, %1}";
20266     default:
20267       abort ();
20268     }
20269 }
20270   [(set_attr "type" "ssemov")
20271    (set (attr "mode")
20272         (cond [(eq_attr "alternative" "0,1")
20273                  (if_then_else
20274                    (ne (symbol_ref "optimize_size")
20275                        (const_int 0))
20276                    (const_string "V4SF")
20277                    (const_string "TI"))
20278                (eq_attr "alternative" "2")
20279                  (if_then_else
20280                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20281                             (const_int 0))
20282                         (ne (symbol_ref "optimize_size")
20283                             (const_int 0)))
20284                    (const_string "V4SF")
20285                    (const_string "TI"))]
20286                (const_string "TI")))])
20287
20288 (define_insn "movv16qi_internal"
20289   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20290         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20291   "TARGET_SSE2
20292    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20293 {
20294   switch (which_alternative)
20295     {
20296     case 0:
20297       if (get_attr_mode (insn) == MODE_V4SF)
20298         return "xorps\t%0, %0";
20299       else
20300         return "pxor\t%0, %0";
20301     case 1:
20302     case 2:
20303       if (get_attr_mode (insn) == MODE_V4SF)
20304         return "movaps\t{%1, %0|%0, %1}";
20305       else
20306         return "movdqa\t{%1, %0|%0, %1}";
20307     default:
20308       abort ();
20309     }
20310 }
20311   [(set_attr "type" "ssemov")
20312    (set (attr "mode")
20313         (cond [(eq_attr "alternative" "0,1")
20314                  (if_then_else
20315                    (ne (symbol_ref "optimize_size")
20316                        (const_int 0))
20317                    (const_string "V4SF")
20318                    (const_string "TI"))
20319                (eq_attr "alternative" "2")
20320                  (if_then_else
20321                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20322                             (const_int 0))
20323                         (ne (symbol_ref "optimize_size")
20324                             (const_int 0)))
20325                    (const_string "V4SF")
20326                    (const_string "TI"))]
20327                (const_string "TI")))])
20328
20329 (define_expand "movv2df"
20330   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20331         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20332   "TARGET_SSE2"
20333 {
20334   ix86_expand_vector_move (V2DFmode, operands);
20335   DONE;
20336 })
20337
20338 (define_expand "movv8hi"
20339   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20340         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20341   "TARGET_SSE2"
20342 {
20343   ix86_expand_vector_move (V8HImode, operands);
20344   DONE;
20345 })
20346
20347 (define_expand "movv16qi"
20348   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20349         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20350   "TARGET_SSE2"
20351 {
20352   ix86_expand_vector_move (V16QImode, operands);
20353   DONE;
20354 })
20355
20356 (define_expand "movv4sf"
20357   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20358         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20359   "TARGET_SSE"
20360 {
20361   ix86_expand_vector_move (V4SFmode, operands);
20362   DONE;
20363 })
20364
20365 (define_expand "movv4si"
20366   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20367         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20368   "TARGET_SSE"
20369 {
20370   ix86_expand_vector_move (V4SImode, operands);
20371   DONE;
20372 })
20373
20374 (define_expand "movv2di"
20375   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20376         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20377   "TARGET_SSE"
20378 {
20379   ix86_expand_vector_move (V2DImode, operands);
20380   DONE;
20381 })
20382
20383 (define_expand "movv2si"
20384   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20385         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20386   "TARGET_MMX"
20387 {
20388   ix86_expand_vector_move (V2SImode, operands);
20389   DONE;
20390 })
20391
20392 (define_expand "movv4hi"
20393   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20394         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20395   "TARGET_MMX"
20396 {
20397   ix86_expand_vector_move (V4HImode, operands);
20398   DONE;
20399 })
20400
20401 (define_expand "movv8qi"
20402   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20403         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20404   "TARGET_MMX"
20405 {
20406   ix86_expand_vector_move (V8QImode, operands);
20407   DONE;
20408 })
20409
20410 (define_expand "movv2sf"
20411   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20412         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20413    "TARGET_3DNOW"
20414 {
20415   ix86_expand_vector_move (V2SFmode, operands);
20416   DONE;
20417 })
20418
20419 (define_insn "*pushti"
20420   [(set (match_operand:TI 0 "push_operand" "=<")
20421         (match_operand:TI 1 "register_operand" "x"))]
20422   "TARGET_SSE"
20423   "#")
20424
20425 (define_insn "*pushv2df"
20426   [(set (match_operand:V2DF 0 "push_operand" "=<")
20427         (match_operand:V2DF 1 "register_operand" "x"))]
20428   "TARGET_SSE"
20429   "#")
20430
20431 (define_insn "*pushv2di"
20432   [(set (match_operand:V2DI 0 "push_operand" "=<")
20433         (match_operand:V2DI 1 "register_operand" "x"))]
20434   "TARGET_SSE2"
20435   "#")
20436
20437 (define_insn "*pushv8hi"
20438   [(set (match_operand:V8HI 0 "push_operand" "=<")
20439         (match_operand:V8HI 1 "register_operand" "x"))]
20440   "TARGET_SSE2"
20441   "#")
20442
20443 (define_insn "*pushv16qi"
20444   [(set (match_operand:V16QI 0 "push_operand" "=<")
20445         (match_operand:V16QI 1 "register_operand" "x"))]
20446   "TARGET_SSE2"
20447   "#")
20448
20449 (define_insn "*pushv4sf"
20450   [(set (match_operand:V4SF 0 "push_operand" "=<")
20451         (match_operand:V4SF 1 "register_operand" "x"))]
20452   "TARGET_SSE"
20453   "#")
20454
20455 (define_insn "*pushv4si"
20456   [(set (match_operand:V4SI 0 "push_operand" "=<")
20457         (match_operand:V4SI 1 "register_operand" "x"))]
20458   "TARGET_SSE2"
20459   "#")
20460
20461 (define_insn "*pushv2si"
20462   [(set (match_operand:V2SI 0 "push_operand" "=<")
20463         (match_operand:V2SI 1 "register_operand" "y"))]
20464   "TARGET_MMX"
20465   "#")
20466
20467 (define_insn "*pushv4hi"
20468   [(set (match_operand:V4HI 0 "push_operand" "=<")
20469         (match_operand:V4HI 1 "register_operand" "y"))]
20470   "TARGET_MMX"
20471   "#")
20472
20473 (define_insn "*pushv8qi"
20474   [(set (match_operand:V8QI 0 "push_operand" "=<")
20475         (match_operand:V8QI 1 "register_operand" "y"))]
20476   "TARGET_MMX"
20477   "#")
20478
20479 (define_insn "*pushv2sf"
20480   [(set (match_operand:V2SF 0 "push_operand" "=<")
20481         (match_operand:V2SF 1 "register_operand" "y"))]
20482   "TARGET_3DNOW"
20483   "#")
20484
20485 (define_split
20486   [(set (match_operand 0 "push_operand" "")
20487         (match_operand 1 "register_operand" ""))]
20488   "!TARGET_64BIT && reload_completed
20489    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20491    (set (match_dup 2) (match_dup 1))]
20492   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20493                                  stack_pointer_rtx);
20494    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20495
20496 (define_split
20497   [(set (match_operand 0 "push_operand" "")
20498         (match_operand 1 "register_operand" ""))]
20499   "TARGET_64BIT && reload_completed
20500    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20501   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20502    (set (match_dup 2) (match_dup 1))]
20503   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20504                                  stack_pointer_rtx);
20505    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20506
20507
20508 (define_insn "movti_internal"
20509   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20510         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20511   "TARGET_SSE && !TARGET_64BIT
20512    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20513 {
20514   switch (which_alternative)
20515     {
20516     case 0:
20517       if (get_attr_mode (insn) == MODE_V4SF)
20518         return "xorps\t%0, %0";
20519       else
20520         return "pxor\t%0, %0";
20521     case 1:
20522     case 2:
20523       if (get_attr_mode (insn) == MODE_V4SF)
20524         return "movaps\t{%1, %0|%0, %1}";
20525       else
20526         return "movdqa\t{%1, %0|%0, %1}";
20527     default:
20528       abort ();
20529     }
20530 }
20531   [(set_attr "type" "ssemov,ssemov,ssemov")
20532    (set (attr "mode")
20533         (cond [(eq_attr "alternative" "0,1")
20534                  (if_then_else
20535                    (ne (symbol_ref "optimize_size")
20536                        (const_int 0))
20537                    (const_string "V4SF")
20538                    (const_string "TI"))
20539                (eq_attr "alternative" "2")
20540                  (if_then_else
20541                    (ne (symbol_ref "optimize_size")
20542                        (const_int 0))
20543                    (const_string "V4SF")
20544                    (const_string "TI"))]
20545                (const_string "TI")))])
20546
20547 (define_insn "*movti_rex64"
20548   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20549         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20550   "TARGET_64BIT
20551    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20552 {
20553   switch (which_alternative)
20554     {
20555     case 0:
20556     case 1:
20557       return "#";
20558     case 2:
20559       if (get_attr_mode (insn) == MODE_V4SF)
20560         return "xorps\t%0, %0";
20561       else
20562         return "pxor\t%0, %0";
20563     case 3:
20564     case 4:
20565       if (get_attr_mode (insn) == MODE_V4SF)
20566         return "movaps\t{%1, %0|%0, %1}";
20567       else
20568         return "movdqa\t{%1, %0|%0, %1}";
20569     default:
20570       abort ();
20571     }
20572 }
20573   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20574    (set (attr "mode")
20575         (cond [(eq_attr "alternative" "2,3")
20576                  (if_then_else
20577                    (ne (symbol_ref "optimize_size")
20578                        (const_int 0))
20579                    (const_string "V4SF")
20580                    (const_string "TI"))
20581                (eq_attr "alternative" "4")
20582                  (if_then_else
20583                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20584                             (const_int 0))
20585                         (ne (symbol_ref "optimize_size")
20586                             (const_int 0)))
20587                    (const_string "V4SF")
20588                    (const_string "TI"))]
20589                (const_string "DI")))])
20590
20591 (define_insn "*movtf_rex64"
20592   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20593         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20594   "TARGET_64BIT
20595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20596 {
20597   switch (which_alternative)
20598     {
20599     case 0:
20600     case 1:
20601       return "#";
20602     case 2:
20603       if (get_attr_mode (insn) == MODE_V4SF)
20604         return "xorps\t%0, %0";
20605       else
20606         return "pxor\t%0, %0";
20607     case 3:
20608     case 4:
20609       if (get_attr_mode (insn) == MODE_V4SF)
20610         return "movaps\t{%1, %0|%0, %1}";
20611       else
20612         return "movdqa\t{%1, %0|%0, %1}";
20613     default:
20614       abort ();
20615     }
20616 }
20617   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20618    (set (attr "mode")
20619         (cond [(eq_attr "alternative" "2,3")
20620                  (if_then_else
20621                    (ne (symbol_ref "optimize_size")
20622                        (const_int 0))
20623                    (const_string "V4SF")
20624                    (const_string "TI"))
20625                (eq_attr "alternative" "4")
20626                  (if_then_else
20627                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20628                             (const_int 0))
20629                         (ne (symbol_ref "optimize_size")
20630                             (const_int 0)))
20631                    (const_string "V4SF")
20632                    (const_string "TI"))]
20633                (const_string "DI")))])
20634
20635 (define_split
20636   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20637         (match_operand:TI 1 "general_operand" ""))]
20638   "reload_completed && !SSE_REG_P (operands[0])
20639    && !SSE_REG_P (operands[1])"
20640   [(const_int 0)]
20641   "ix86_split_long_move (operands); DONE;")
20642
20643 (define_split
20644   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20645         (match_operand:TF 1 "general_operand" ""))]
20646   "reload_completed && !SSE_REG_P (operands[0])
20647    && !SSE_REG_P (operands[1])"
20648   [(const_int 0)]
20649   "ix86_split_long_move (operands); DONE;")
20650
20651 ;; These two patterns are useful for specifying exactly whether to use
20652 ;; movaps or movups
20653 (define_expand "sse_movaps"
20654   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20655         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20656                      UNSPEC_MOVA))]
20657   "TARGET_SSE"
20658 {
20659   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20660     {
20661       rtx tmp = gen_reg_rtx (V4SFmode);
20662       emit_insn (gen_sse_movaps (tmp, operands[1]));
20663       emit_move_insn (operands[0], tmp);
20664       DONE;
20665     }
20666 })
20667
20668 (define_insn "*sse_movaps_1"
20669   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20670         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20671                      UNSPEC_MOVA))]
20672   "TARGET_SSE
20673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20674   "movaps\t{%1, %0|%0, %1}"
20675   [(set_attr "type" "ssemov,ssemov")
20676    (set_attr "mode" "V4SF")])
20677
20678 (define_expand "sse_movups"
20679   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20680         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20681                      UNSPEC_MOVU))]
20682   "TARGET_SSE"
20683 {
20684   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20685     {
20686       rtx tmp = gen_reg_rtx (V4SFmode);
20687       emit_insn (gen_sse_movups (tmp, operands[1]));
20688       emit_move_insn (operands[0], tmp);
20689       DONE;
20690     }
20691 })
20692
20693 (define_insn "*sse_movups_1"
20694   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20695         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20696                      UNSPEC_MOVU))]
20697   "TARGET_SSE
20698    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20699   "movups\t{%1, %0|%0, %1}"
20700   [(set_attr "type" "ssecvt,ssecvt")
20701    (set_attr "mode" "V4SF")])
20702
20703 ;; SSE Strange Moves.
20704
20705 (define_insn "sse_movmskps"
20706   [(set (match_operand:SI 0 "register_operand" "=r")
20707         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20708                    UNSPEC_MOVMSK))]
20709   "TARGET_SSE"
20710   "movmskps\t{%1, %0|%0, %1}"
20711   [(set_attr "type" "ssecvt")
20712    (set_attr "mode" "V4SF")])
20713
20714 (define_insn "mmx_pmovmskb"
20715   [(set (match_operand:SI 0 "register_operand" "=r")
20716         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20717                    UNSPEC_MOVMSK))]
20718   "TARGET_SSE || TARGET_3DNOW_A"
20719   "pmovmskb\t{%1, %0|%0, %1}"
20720   [(set_attr "type" "ssecvt")
20721    (set_attr "mode" "V4SF")])
20722
20723
20724 (define_insn "mmx_maskmovq"
20725   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20726         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20727                       (match_operand:V8QI 2 "register_operand" "y")]
20728                      UNSPEC_MASKMOV))]
20729   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20730   ;; @@@ check ordering of operands in intel/nonintel syntax
20731   "maskmovq\t{%2, %1|%1, %2}"
20732   [(set_attr "type" "mmxcvt")
20733    (set_attr "mode" "DI")])
20734
20735 (define_insn "mmx_maskmovq_rex"
20736   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20737         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20738                       (match_operand:V8QI 2 "register_operand" "y")]
20739                      UNSPEC_MASKMOV))]
20740   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20741   ;; @@@ check ordering of operands in intel/nonintel syntax
20742   "maskmovq\t{%2, %1|%1, %2}"
20743   [(set_attr "type" "mmxcvt")
20744    (set_attr "mode" "DI")])
20745
20746 (define_insn "sse_movntv4sf"
20747   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20748         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20749                      UNSPEC_MOVNT))]
20750   "TARGET_SSE"
20751   "movntps\t{%1, %0|%0, %1}"
20752   [(set_attr "type" "ssemov")
20753    (set_attr "mode" "V4SF")])
20754
20755 (define_insn "sse_movntdi"
20756   [(set (match_operand:DI 0 "memory_operand" "=m")
20757         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20758                    UNSPEC_MOVNT))]
20759   "TARGET_SSE || TARGET_3DNOW_A"
20760   "movntq\t{%1, %0|%0, %1}"
20761   [(set_attr "type" "mmxmov")
20762    (set_attr "mode" "DI")])
20763
20764 (define_insn "sse_movhlps"
20765   [(set (match_operand:V4SF 0 "register_operand" "=x")
20766         (vec_merge:V4SF
20767          (match_operand:V4SF 1 "register_operand" "0")
20768          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20769                           (parallel [(const_int 2)
20770                                      (const_int 3)
20771                                      (const_int 0)
20772                                      (const_int 1)]))
20773          (const_int 3)))]
20774   "TARGET_SSE"
20775   "movhlps\t{%2, %0|%0, %2}"
20776   [(set_attr "type" "ssecvt")
20777    (set_attr "mode" "V4SF")])
20778
20779 (define_insn "sse_movlhps"
20780   [(set (match_operand:V4SF 0 "register_operand" "=x")
20781         (vec_merge:V4SF
20782          (match_operand:V4SF 1 "register_operand" "0")
20783          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20784                           (parallel [(const_int 2)
20785                                      (const_int 3)
20786                                      (const_int 0)
20787                                      (const_int 1)]))
20788          (const_int 12)))]
20789   "TARGET_SSE"
20790   "movlhps\t{%2, %0|%0, %2}"
20791   [(set_attr "type" "ssecvt")
20792    (set_attr "mode" "V4SF")])
20793
20794 (define_insn "sse_movhps"
20795   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20796         (vec_merge:V4SF
20797          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20798          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20799          (const_int 12)))]
20800   "TARGET_SSE
20801    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20802   "movhps\t{%2, %0|%0, %2}"
20803   [(set_attr "type" "ssecvt")
20804    (set_attr "mode" "V4SF")])
20805
20806 (define_insn "sse_movlps"
20807   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20808         (vec_merge:V4SF
20809          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20810          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20811          (const_int 3)))]
20812   "TARGET_SSE
20813    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20814   "movlps\t{%2, %0|%0, %2}"
20815   [(set_attr "type" "ssecvt")
20816    (set_attr "mode" "V4SF")])
20817
20818 (define_expand "sse_loadss"
20819   [(match_operand:V4SF 0 "register_operand" "")
20820    (match_operand:SF 1 "memory_operand" "")]
20821   "TARGET_SSE"
20822 {
20823   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20824                                CONST0_RTX (V4SFmode)));
20825   DONE;
20826 })
20827
20828 (define_insn "sse_loadss_1"
20829   [(set (match_operand:V4SF 0 "register_operand" "=x")
20830         (vec_merge:V4SF
20831          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20832          (match_operand:V4SF 2 "const0_operand" "X")
20833          (const_int 1)))]
20834   "TARGET_SSE"
20835   "movss\t{%1, %0|%0, %1}"
20836   [(set_attr "type" "ssemov")
20837    (set_attr "mode" "SF")])
20838
20839 (define_insn "sse_movss"
20840   [(set (match_operand:V4SF 0 "register_operand" "=x")
20841         (vec_merge:V4SF
20842          (match_operand:V4SF 1 "register_operand" "0")
20843          (match_operand:V4SF 2 "register_operand" "x")
20844          (const_int 1)))]
20845   "TARGET_SSE"
20846   "movss\t{%2, %0|%0, %2}"
20847   [(set_attr "type" "ssemov")
20848    (set_attr "mode" "SF")])
20849
20850 (define_insn "sse_storess"
20851   [(set (match_operand:SF 0 "memory_operand" "=m")
20852         (vec_select:SF
20853          (match_operand:V4SF 1 "register_operand" "x")
20854          (parallel [(const_int 0)])))]
20855   "TARGET_SSE"
20856   "movss\t{%1, %0|%0, %1}"
20857   [(set_attr "type" "ssemov")
20858    (set_attr "mode" "SF")])
20859
20860 (define_insn "sse_shufps"
20861   [(set (match_operand:V4SF 0 "register_operand" "=x")
20862         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20863                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20864                       (match_operand:SI 3 "immediate_operand" "i")]
20865                      UNSPEC_SHUFFLE))]
20866   "TARGET_SSE"
20867   ;; @@@ check operand order for intel/nonintel syntax
20868   "shufps\t{%3, %2, %0|%0, %2, %3}"
20869   [(set_attr "type" "ssecvt")
20870    (set_attr "mode" "V4SF")])
20871
20872
20873 ;; SSE arithmetic
20874
20875 (define_insn "addv4sf3"
20876   [(set (match_operand:V4SF 0 "register_operand" "=x")
20877         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20878                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20879   "TARGET_SSE"
20880   "addps\t{%2, %0|%0, %2}"
20881   [(set_attr "type" "sseadd")
20882    (set_attr "mode" "V4SF")])
20883
20884 (define_insn "vmaddv4sf3"
20885   [(set (match_operand:V4SF 0 "register_operand" "=x")
20886         (vec_merge:V4SF
20887          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20888                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20889          (match_dup 1)
20890          (const_int 1)))]
20891   "TARGET_SSE"
20892   "addss\t{%2, %0|%0, %2}"
20893   [(set_attr "type" "sseadd")
20894    (set_attr "mode" "SF")])
20895
20896 (define_insn "subv4sf3"
20897   [(set (match_operand:V4SF 0 "register_operand" "=x")
20898         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20899                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20900   "TARGET_SSE"
20901   "subps\t{%2, %0|%0, %2}"
20902   [(set_attr "type" "sseadd")
20903    (set_attr "mode" "V4SF")])
20904
20905 (define_insn "vmsubv4sf3"
20906   [(set (match_operand:V4SF 0 "register_operand" "=x")
20907         (vec_merge:V4SF
20908          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20909                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20910          (match_dup 1)
20911          (const_int 1)))]
20912   "TARGET_SSE"
20913   "subss\t{%2, %0|%0, %2}"
20914   [(set_attr "type" "sseadd")
20915    (set_attr "mode" "SF")])
20916
20917 ;; ??? Should probably be done by generic code instead.
20918 (define_expand "negv4sf2"
20919   [(set (match_operand:V4SF 0 "register_operand" "")
20920         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20921                   (match_dup 2)))]
20922   "TARGET_SSE"
20923 {
20924   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20925   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20926   operands[2] = force_reg (V4SFmode, vm0);
20927 })
20928
20929 (define_insn "mulv4sf3"
20930   [(set (match_operand:V4SF 0 "register_operand" "=x")
20931         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20932                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20933   "TARGET_SSE"
20934   "mulps\t{%2, %0|%0, %2}"
20935   [(set_attr "type" "ssemul")
20936    (set_attr "mode" "V4SF")])
20937
20938 (define_insn "vmmulv4sf3"
20939   [(set (match_operand:V4SF 0 "register_operand" "=x")
20940         (vec_merge:V4SF
20941          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20942                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20943          (match_dup 1)
20944          (const_int 1)))]
20945   "TARGET_SSE"
20946   "mulss\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "ssemul")
20948    (set_attr "mode" "SF")])
20949
20950 (define_insn "divv4sf3"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20953                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20954   "TARGET_SSE"
20955   "divps\t{%2, %0|%0, %2}"
20956   [(set_attr "type" "ssediv")
20957    (set_attr "mode" "V4SF")])
20958
20959 (define_insn "vmdivv4sf3"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (vec_merge:V4SF
20962          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20963                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20964          (match_dup 1)
20965          (const_int 1)))]
20966   "TARGET_SSE"
20967   "divss\t{%2, %0|%0, %2}"
20968   [(set_attr "type" "ssediv")
20969    (set_attr "mode" "SF")])
20970
20971
20972 ;; SSE square root/reciprocal
20973
20974 (define_insn "rcpv4sf2"
20975   [(set (match_operand:V4SF 0 "register_operand" "=x")
20976         (unspec:V4SF
20977          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20978   "TARGET_SSE"
20979   "rcpps\t{%1, %0|%0, %1}"
20980   [(set_attr "type" "sse")
20981    (set_attr "mode" "V4SF")])
20982
20983 (define_insn "vmrcpv4sf2"
20984   [(set (match_operand:V4SF 0 "register_operand" "=x")
20985         (vec_merge:V4SF
20986          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20987                       UNSPEC_RCP)
20988          (match_operand:V4SF 2 "register_operand" "0")
20989          (const_int 1)))]
20990   "TARGET_SSE"
20991   "rcpss\t{%1, %0|%0, %1}"
20992   [(set_attr "type" "sse")
20993    (set_attr "mode" "SF")])
20994
20995 (define_insn "rsqrtv4sf2"
20996   [(set (match_operand:V4SF 0 "register_operand" "=x")
20997         (unspec:V4SF
20998          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20999   "TARGET_SSE"
21000   "rsqrtps\t{%1, %0|%0, %1}"
21001   [(set_attr "type" "sse")
21002    (set_attr "mode" "V4SF")])
21003
21004 (define_insn "vmrsqrtv4sf2"
21005   [(set (match_operand:V4SF 0 "register_operand" "=x")
21006         (vec_merge:V4SF
21007          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21008                       UNSPEC_RSQRT)
21009          (match_operand:V4SF 2 "register_operand" "0")
21010          (const_int 1)))]
21011   "TARGET_SSE"
21012   "rsqrtss\t{%1, %0|%0, %1}"
21013   [(set_attr "type" "sse")
21014    (set_attr "mode" "SF")])
21015
21016 (define_insn "sqrtv4sf2"
21017   [(set (match_operand:V4SF 0 "register_operand" "=x")
21018         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21019   "TARGET_SSE"
21020   "sqrtps\t{%1, %0|%0, %1}"
21021   [(set_attr "type" "sse")
21022    (set_attr "mode" "V4SF")])
21023
21024 (define_insn "vmsqrtv4sf2"
21025   [(set (match_operand:V4SF 0 "register_operand" "=x")
21026         (vec_merge:V4SF
21027          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21028          (match_operand:V4SF 2 "register_operand" "0")
21029          (const_int 1)))]
21030   "TARGET_SSE"
21031   "sqrtss\t{%1, %0|%0, %1}"
21032   [(set_attr "type" "sse")
21033    (set_attr "mode" "SF")])
21034
21035 ;; SSE logical operations.
21036
21037 ;; SSE defines logical operations on floating point values.  This brings
21038 ;; interesting challenge to RTL representation where logicals are only valid
21039 ;; on integral types.  We deal with this by representing the floating point
21040 ;; logical as logical on arguments casted to TImode as this is what hardware
21041 ;; really does.  Unfortunately hardware requires the type information to be
21042 ;; present and thus we must avoid subregs from being simplified and eliminated
21043 ;; in later compilation phases.
21044 ;;
21045 ;; We have following variants from each instruction:
21046 ;; sse_andsf3 - the operation taking V4SF vector operands
21047 ;;              and doing TImode cast on them
21048 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21049 ;;                      TImode, since backend insist on eliminating casts
21050 ;;                      on memory operands
21051 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21052 ;;                   We cannot accept memory operand here as instruction reads
21053 ;;                   whole scalar.  This is generated only post reload by GCC
21054 ;;                   scalar float operations that expands to logicals (fabs)
21055 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21056 ;;                   memory operand.  Eventually combine can be able
21057 ;;                   to synthesize these using splitter.
21058 ;; sse2_anddf3, *sse2_anddf3_memory
21059 ;;              
21060 ;; 
21061 ;; These are not called andti3 etc. because we really really don't want
21062 ;; the compiler to widen DImode ands to TImode ands and then try to move
21063 ;; into DImode subregs of SSE registers, and them together, and move out
21064 ;; of DImode subregs again!
21065 ;; SSE1 single precision floating point logical operation
21066 (define_expand "sse_andv4sf3"
21067   [(set (match_operand:V4SF 0 "register_operand" "")
21068         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21069                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21070   "TARGET_SSE"
21071   "")
21072
21073 (define_insn "*sse_andv4sf3"
21074   [(set (match_operand:V4SF 0 "register_operand" "=x")
21075         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21076                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21077   "TARGET_SSE
21078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21079   "andps\t{%2, %0|%0, %2}"
21080   [(set_attr "type" "sselog")
21081    (set_attr "mode" "V4SF")])
21082
21083 (define_expand "sse_nandv4sf3"
21084   [(set (match_operand:V4SF 0 "register_operand" "")
21085         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21086                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21087   "TARGET_SSE"
21088   "")
21089
21090 (define_insn "*sse_nandv4sf3"
21091   [(set (match_operand:V4SF 0 "register_operand" "=x")
21092         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21093                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21094   "TARGET_SSE"
21095   "andnps\t{%2, %0|%0, %2}"
21096   [(set_attr "type" "sselog")
21097    (set_attr "mode" "V4SF")])
21098
21099 (define_expand "sse_iorv4sf3"
21100   [(set (match_operand:V4SF 0 "register_operand" "")
21101         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21102                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21103   "TARGET_SSE"
21104   "")
21105
21106 (define_insn "*sse_iorv4sf3"
21107   [(set (match_operand:V4SF 0 "register_operand" "=x")
21108         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21109                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21110   "TARGET_SSE
21111    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21112   "orps\t{%2, %0|%0, %2}"
21113   [(set_attr "type" "sselog")
21114    (set_attr "mode" "V4SF")])
21115
21116 (define_expand "sse_xorv4sf3"
21117   [(set (match_operand:V4SF 0 "register_operand" "")
21118         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21119                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21120   "TARGET_SSE"
21121   "")
21122
21123 (define_insn "*sse_xorv4sf3"
21124   [(set (match_operand:V4SF 0 "register_operand" "=x")
21125         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21126                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21127   "TARGET_SSE
21128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21129   "xorps\t{%2, %0|%0, %2}"
21130   [(set_attr "type" "sselog")
21131    (set_attr "mode" "V4SF")])
21132
21133 ;; SSE2 double precision floating point logical operation
21134
21135 (define_expand "sse2_andv2df3"
21136   [(set (match_operand:V2DF 0 "register_operand" "")
21137         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21138                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21139   "TARGET_SSE2"
21140   "")
21141
21142 (define_insn "*sse2_andv2df3"
21143   [(set (match_operand:V2DF 0 "register_operand" "=x")
21144         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21145                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21146   "TARGET_SSE2
21147    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21148   "andpd\t{%2, %0|%0, %2}"
21149   [(set_attr "type" "sselog")
21150    (set_attr "mode" "V2DF")])
21151
21152 (define_expand "sse2_nandv2df3"
21153   [(set (match_operand:V2DF 0 "register_operand" "")
21154         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21155                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21156   "TARGET_SSE2"
21157   "")
21158
21159 (define_insn "*sse2_nandv2df3"
21160   [(set (match_operand:V2DF 0 "register_operand" "=x")
21161         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21162                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21163   "TARGET_SSE2"
21164   "andnpd\t{%2, %0|%0, %2}"
21165   [(set_attr "type" "sselog")
21166    (set_attr "mode" "V2DF")])
21167
21168 (define_expand "sse2_iorv2df3"
21169   [(set (match_operand:V2DF 0 "register_operand" "")
21170         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21171                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21172   "TARGET_SSE2"
21173   "")
21174
21175 (define_insn "*sse2_iorv2df3"
21176   [(set (match_operand:V2DF 0 "register_operand" "=x")
21177         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21178                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21179   "TARGET_SSE2
21180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21181   "orpd\t{%2, %0|%0, %2}"
21182   [(set_attr "type" "sselog")
21183    (set_attr "mode" "V2DF")])
21184
21185 (define_expand "sse2_xorv2df3"
21186   [(set (match_operand:V2DF 0 "register_operand" "")
21187         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21188                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21189   "TARGET_SSE2"
21190   "")
21191
21192 (define_insn "*sse2_xorv2df3"
21193   [(set (match_operand:V2DF 0 "register_operand" "=x")
21194         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21195                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21196   "TARGET_SSE2
21197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21198   "xorpd\t{%2, %0|%0, %2}"
21199   [(set_attr "type" "sselog")
21200    (set_attr "mode" "V2DF")])
21201
21202 ;; SSE2 integral logicals.  These patterns must always come after floating
21203 ;; point ones since we don't want compiler to use integer opcodes on floating
21204 ;; point SSE values to avoid matching of subregs in the match_operand.
21205 (define_insn "*sse2_andti3"
21206   [(set (match_operand:TI 0 "register_operand" "=x")
21207         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21208                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21209   "TARGET_SSE2
21210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21211   "pand\t{%2, %0|%0, %2}"
21212   [(set_attr "type" "sselog")
21213    (set_attr "mode" "TI")])
21214
21215 (define_insn "sse2_andv2di3"
21216   [(set (match_operand:V2DI 0 "register_operand" "=x")
21217         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21218                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21219   "TARGET_SSE2
21220    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21221   "pand\t{%2, %0|%0, %2}"
21222   [(set_attr "type" "sselog")
21223    (set_attr "mode" "TI")])
21224
21225 (define_insn "*sse2_nandti3"
21226   [(set (match_operand:TI 0 "register_operand" "=x")
21227         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21228                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21229   "TARGET_SSE2"
21230   "pandn\t{%2, %0|%0, %2}"
21231   [(set_attr "type" "sselog")
21232    (set_attr "mode" "TI")])
21233
21234 (define_insn "sse2_nandv2di3"
21235   [(set (match_operand:V2DI 0 "register_operand" "=x")
21236         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21237                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21238   "TARGET_SSE2
21239    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21240   "pandn\t{%2, %0|%0, %2}"
21241   [(set_attr "type" "sselog")
21242    (set_attr "mode" "TI")])
21243
21244 (define_insn "*sse2_iorti3"
21245   [(set (match_operand:TI 0 "register_operand" "=x")
21246         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21247                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21248   "TARGET_SSE2
21249    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21250   "por\t{%2, %0|%0, %2}"
21251   [(set_attr "type" "sselog")
21252    (set_attr "mode" "TI")])
21253
21254 (define_insn "sse2_iorv2di3"
21255   [(set (match_operand:V2DI 0 "register_operand" "=x")
21256         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21257                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21258   "TARGET_SSE2
21259    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21260   "por\t{%2, %0|%0, %2}"
21261   [(set_attr "type" "sselog")
21262    (set_attr "mode" "TI")])
21263
21264 (define_insn "*sse2_xorti3"
21265   [(set (match_operand:TI 0 "register_operand" "=x")
21266         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21267                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21268   "TARGET_SSE2
21269    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21270   "pxor\t{%2, %0|%0, %2}"
21271   [(set_attr "type" "sselog")
21272    (set_attr "mode" "TI")])
21273
21274 (define_insn "sse2_xorv2di3"
21275   [(set (match_operand:V2DI 0 "register_operand" "=x")
21276         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21277                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21278   "TARGET_SSE2
21279    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21280   "pxor\t{%2, %0|%0, %2}"
21281   [(set_attr "type" "sselog")
21282    (set_attr "mode" "TI")])
21283
21284 ;; Use xor, but don't show input operands so they aren't live before
21285 ;; this insn.
21286 (define_insn "sse_clrv4sf"
21287   [(set (match_operand:V4SF 0 "register_operand" "=x")
21288         (match_operand:V4SF 1 "const0_operand" "X"))]
21289   "TARGET_SSE"
21290 {
21291   if (get_attr_mode (insn) == MODE_TI)
21292     return "pxor\t{%0, %0|%0, %0}";
21293   else
21294     return "xorps\t{%0, %0|%0, %0}";
21295 }
21296   [(set_attr "type" "sselog")
21297    (set_attr "memory" "none")
21298    (set (attr "mode")
21299         (if_then_else
21300            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21301                          (const_int 0))
21302                      (ne (symbol_ref "TARGET_SSE2")
21303                          (const_int 0)))
21304                 (eq (symbol_ref "optimize_size")
21305                     (const_int 0)))
21306          (const_string "TI")
21307          (const_string "V4SF")))])
21308
21309 ;; Use xor, but don't show input operands so they aren't live before
21310 ;; this insn.
21311 (define_insn "sse_clrv2df"
21312   [(set (match_operand:V2DF 0 "register_operand" "=x")
21313         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21314   "TARGET_SSE2"
21315   "xorpd\t{%0, %0|%0, %0}"
21316   [(set_attr "type" "sselog")
21317    (set_attr "memory" "none")
21318    (set_attr "mode" "V4SF")])
21319
21320 ;; SSE mask-generating compares
21321
21322 (define_insn "maskcmpv4sf3"
21323   [(set (match_operand:V4SI 0 "register_operand" "=x")
21324         (match_operator:V4SI 3 "sse_comparison_operator"
21325                 [(match_operand:V4SF 1 "register_operand" "0")
21326                  (match_operand:V4SF 2 "register_operand" "x")]))]
21327   "TARGET_SSE"
21328   "cmp%D3ps\t{%2, %0|%0, %2}"
21329   [(set_attr "type" "ssecmp")
21330    (set_attr "mode" "V4SF")])
21331
21332 (define_insn "maskncmpv4sf3"
21333   [(set (match_operand:V4SI 0 "register_operand" "=x")
21334         (not:V4SI
21335          (match_operator:V4SI 3 "sse_comparison_operator"
21336                 [(match_operand:V4SF 1 "register_operand" "0")
21337                  (match_operand:V4SF 2 "register_operand" "x")])))]
21338   "TARGET_SSE"
21339 {
21340   if (GET_CODE (operands[3]) == UNORDERED)
21341     return "cmpordps\t{%2, %0|%0, %2}";
21342   else
21343     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21344 }
21345   [(set_attr "type" "ssecmp")
21346    (set_attr "mode" "V4SF")])
21347
21348 (define_insn "vmmaskcmpv4sf3"
21349   [(set (match_operand:V4SI 0 "register_operand" "=x")
21350         (vec_merge:V4SI
21351          (match_operator:V4SI 3 "sse_comparison_operator"
21352                 [(match_operand:V4SF 1 "register_operand" "0")
21353                  (match_operand:V4SF 2 "register_operand" "x")])
21354          (subreg:V4SI (match_dup 1) 0)
21355          (const_int 1)))]
21356   "TARGET_SSE"
21357   "cmp%D3ss\t{%2, %0|%0, %2}"
21358   [(set_attr "type" "ssecmp")
21359    (set_attr "mode" "SF")])
21360
21361 (define_insn "vmmaskncmpv4sf3"
21362   [(set (match_operand:V4SI 0 "register_operand" "=x")
21363         (vec_merge:V4SI
21364          (not:V4SI
21365           (match_operator:V4SI 3 "sse_comparison_operator"
21366                 [(match_operand:V4SF 1 "register_operand" "0")
21367                  (match_operand:V4SF 2 "register_operand" "x")]))
21368          (subreg:V4SI (match_dup 1) 0)
21369          (const_int 1)))]
21370   "TARGET_SSE"
21371 {
21372   if (GET_CODE (operands[3]) == UNORDERED)
21373     return "cmpordss\t{%2, %0|%0, %2}";
21374   else
21375     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21376 }
21377   [(set_attr "type" "ssecmp")
21378    (set_attr "mode" "SF")])
21379
21380 (define_insn "sse_comi"
21381   [(set (reg:CCFP FLAGS_REG)
21382         (compare:CCFP (vec_select:SF
21383                        (match_operand:V4SF 0 "register_operand" "x")
21384                        (parallel [(const_int 0)]))
21385                       (vec_select:SF
21386                        (match_operand:V4SF 1 "register_operand" "x")
21387                        (parallel [(const_int 0)]))))]
21388   "TARGET_SSE"
21389   "comiss\t{%1, %0|%0, %1}"
21390   [(set_attr "type" "ssecomi")
21391    (set_attr "mode" "SF")])
21392
21393 (define_insn "sse_ucomi"
21394   [(set (reg:CCFPU FLAGS_REG)
21395         (compare:CCFPU (vec_select:SF
21396                         (match_operand:V4SF 0 "register_operand" "x")
21397                         (parallel [(const_int 0)]))
21398                        (vec_select:SF
21399                         (match_operand:V4SF 1 "register_operand" "x")
21400                         (parallel [(const_int 0)]))))]
21401   "TARGET_SSE"
21402   "ucomiss\t{%1, %0|%0, %1}"
21403   [(set_attr "type" "ssecomi")
21404    (set_attr "mode" "SF")])
21405
21406
21407 ;; SSE unpack
21408
21409 (define_insn "sse_unpckhps"
21410   [(set (match_operand:V4SF 0 "register_operand" "=x")
21411         (vec_merge:V4SF
21412          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21413                           (parallel [(const_int 2)
21414                                      (const_int 0)
21415                                      (const_int 3)
21416                                      (const_int 1)]))
21417          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21418                           (parallel [(const_int 0)
21419                                      (const_int 2)
21420                                      (const_int 1)
21421                                      (const_int 3)]))
21422          (const_int 5)))]
21423   "TARGET_SSE"
21424   "unpckhps\t{%2, %0|%0, %2}"
21425   [(set_attr "type" "ssecvt")
21426    (set_attr "mode" "V4SF")])
21427
21428 (define_insn "sse_unpcklps"
21429   [(set (match_operand:V4SF 0 "register_operand" "=x")
21430         (vec_merge:V4SF
21431          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21432                           (parallel [(const_int 0)
21433                                      (const_int 2)
21434                                      (const_int 1)
21435                                      (const_int 3)]))
21436          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21437                           (parallel [(const_int 2)
21438                                      (const_int 0)
21439                                      (const_int 3)
21440                                      (const_int 1)]))
21441          (const_int 5)))]
21442   "TARGET_SSE"
21443   "unpcklps\t{%2, %0|%0, %2}"
21444   [(set_attr "type" "ssecvt")
21445    (set_attr "mode" "V4SF")])
21446
21447
21448 ;; SSE min/max
21449
21450 (define_insn "smaxv4sf3"
21451   [(set (match_operand:V4SF 0 "register_operand" "=x")
21452         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21453                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21454   "TARGET_SSE"
21455   "maxps\t{%2, %0|%0, %2}"
21456   [(set_attr "type" "sse")
21457    (set_attr "mode" "V4SF")])
21458
21459 (define_insn "vmsmaxv4sf3"
21460   [(set (match_operand:V4SF 0 "register_operand" "=x")
21461         (vec_merge:V4SF
21462          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21463                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21464          (match_dup 1)
21465          (const_int 1)))]
21466   "TARGET_SSE"
21467   "maxss\t{%2, %0|%0, %2}"
21468   [(set_attr "type" "sse")
21469    (set_attr "mode" "SF")])
21470
21471 (define_insn "sminv4sf3"
21472   [(set (match_operand:V4SF 0 "register_operand" "=x")
21473         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21474                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21475   "TARGET_SSE"
21476   "minps\t{%2, %0|%0, %2}"
21477   [(set_attr "type" "sse")
21478    (set_attr "mode" "V4SF")])
21479
21480 (define_insn "vmsminv4sf3"
21481   [(set (match_operand:V4SF 0 "register_operand" "=x")
21482         (vec_merge:V4SF
21483          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21484                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21485          (match_dup 1)
21486          (const_int 1)))]
21487   "TARGET_SSE"
21488   "minss\t{%2, %0|%0, %2}"
21489   [(set_attr "type" "sse")
21490    (set_attr "mode" "SF")])
21491
21492 ;; SSE <-> integer/MMX conversions
21493
21494 (define_insn "cvtpi2ps"
21495   [(set (match_operand:V4SF 0 "register_operand" "=x")
21496         (vec_merge:V4SF
21497          (match_operand:V4SF 1 "register_operand" "0")
21498          (vec_duplicate:V4SF
21499           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21500          (const_int 12)))]
21501   "TARGET_SSE"
21502   "cvtpi2ps\t{%2, %0|%0, %2}"
21503   [(set_attr "type" "ssecvt")
21504    (set_attr "mode" "V4SF")])
21505
21506 (define_insn "cvtps2pi"
21507   [(set (match_operand:V2SI 0 "register_operand" "=y")
21508         (vec_select:V2SI
21509          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21510          (parallel [(const_int 0) (const_int 1)])))]
21511   "TARGET_SSE"
21512   "cvtps2pi\t{%1, %0|%0, %1}"
21513   [(set_attr "type" "ssecvt")
21514    (set_attr "mode" "V4SF")])
21515
21516 (define_insn "cvttps2pi"
21517   [(set (match_operand:V2SI 0 "register_operand" "=y")
21518         (vec_select:V2SI
21519          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21520                       UNSPEC_FIX)
21521          (parallel [(const_int 0) (const_int 1)])))]
21522   "TARGET_SSE"
21523   "cvttps2pi\t{%1, %0|%0, %1}"
21524   [(set_attr "type" "ssecvt")
21525    (set_attr "mode" "SF")])
21526
21527 (define_insn "cvtsi2ss"
21528   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21529         (vec_merge:V4SF
21530          (match_operand:V4SF 1 "register_operand" "0,0")
21531          (vec_duplicate:V4SF
21532           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21533          (const_int 14)))]
21534   "TARGET_SSE"
21535   "cvtsi2ss\t{%2, %0|%0, %2}"
21536   [(set_attr "type" "sseicvt")
21537    (set_attr "athlon_decode" "vector,double")
21538    (set_attr "mode" "SF")])
21539
21540 (define_insn "cvtsi2ssq"
21541   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21542         (vec_merge:V4SF
21543          (match_operand:V4SF 1 "register_operand" "0,0")
21544          (vec_duplicate:V4SF
21545           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21546          (const_int 14)))]
21547   "TARGET_SSE && TARGET_64BIT"
21548   "cvtsi2ssq\t{%2, %0|%0, %2}"
21549   [(set_attr "type" "sseicvt")
21550    (set_attr "athlon_decode" "vector,double")
21551    (set_attr "mode" "SF")])
21552
21553 (define_insn "cvtss2si"
21554   [(set (match_operand:SI 0 "register_operand" "=r,r")
21555         (vec_select:SI
21556          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21557          (parallel [(const_int 0)])))]
21558   "TARGET_SSE"
21559   "cvtss2si\t{%1, %0|%0, %1}"
21560   [(set_attr "type" "sseicvt")
21561    (set_attr "athlon_decode" "double,vector")
21562    (set_attr "mode" "SI")])
21563
21564 (define_insn "cvtss2siq"
21565   [(set (match_operand:DI 0 "register_operand" "=r,r")
21566         (vec_select:DI
21567          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21568          (parallel [(const_int 0)])))]
21569   "TARGET_SSE"
21570   "cvtss2siq\t{%1, %0|%0, %1}"
21571   [(set_attr "type" "sseicvt")
21572    (set_attr "athlon_decode" "double,vector")
21573    (set_attr "mode" "DI")])
21574
21575 (define_insn "cvttss2si"
21576   [(set (match_operand:SI 0 "register_operand" "=r,r")
21577         (vec_select:SI
21578          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21579                       UNSPEC_FIX)
21580          (parallel [(const_int 0)])))]
21581   "TARGET_SSE"
21582   "cvttss2si\t{%1, %0|%0, %1}"
21583   [(set_attr "type" "sseicvt")
21584    (set_attr "mode" "SF")
21585    (set_attr "athlon_decode" "double,vector")])
21586
21587 (define_insn "cvttss2siq"
21588   [(set (match_operand:DI 0 "register_operand" "=r,r")
21589         (vec_select:DI
21590          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21591                       UNSPEC_FIX)
21592          (parallel [(const_int 0)])))]
21593   "TARGET_SSE && TARGET_64BIT"
21594   "cvttss2siq\t{%1, %0|%0, %1}"
21595   [(set_attr "type" "sseicvt")
21596    (set_attr "mode" "SF")
21597    (set_attr "athlon_decode" "double,vector")])
21598
21599
21600 ;; MMX insns
21601
21602 ;; MMX arithmetic
21603
21604 (define_insn "addv8qi3"
21605   [(set (match_operand:V8QI 0 "register_operand" "=y")
21606         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21607                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21608   "TARGET_MMX"
21609   "paddb\t{%2, %0|%0, %2}"
21610   [(set_attr "type" "mmxadd")
21611    (set_attr "mode" "DI")])
21612
21613 (define_insn "addv4hi3"
21614   [(set (match_operand:V4HI 0 "register_operand" "=y")
21615         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21616                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21617   "TARGET_MMX"
21618   "paddw\t{%2, %0|%0, %2}"
21619   [(set_attr "type" "mmxadd")
21620    (set_attr "mode" "DI")])
21621
21622 (define_insn "addv2si3"
21623   [(set (match_operand:V2SI 0 "register_operand" "=y")
21624         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21625                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21626   "TARGET_MMX"
21627   "paddd\t{%2, %0|%0, %2}"
21628   [(set_attr "type" "mmxadd")
21629    (set_attr "mode" "DI")])
21630
21631 (define_insn "mmx_adddi3"
21632   [(set (match_operand:DI 0 "register_operand" "=y")
21633         (unspec:DI
21634          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21635                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21636          UNSPEC_NOP))]
21637   "TARGET_MMX"
21638   "paddq\t{%2, %0|%0, %2}"
21639   [(set_attr "type" "mmxadd")
21640    (set_attr "mode" "DI")])
21641
21642 (define_insn "ssaddv8qi3"
21643   [(set (match_operand:V8QI 0 "register_operand" "=y")
21644         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21645                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21646   "TARGET_MMX"
21647   "paddsb\t{%2, %0|%0, %2}"
21648   [(set_attr "type" "mmxadd")
21649    (set_attr "mode" "DI")])
21650
21651 (define_insn "ssaddv4hi3"
21652   [(set (match_operand:V4HI 0 "register_operand" "=y")
21653         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21654                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21655   "TARGET_MMX"
21656   "paddsw\t{%2, %0|%0, %2}"
21657   [(set_attr "type" "mmxadd")
21658    (set_attr "mode" "DI")])
21659
21660 (define_insn "usaddv8qi3"
21661   [(set (match_operand:V8QI 0 "register_operand" "=y")
21662         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21663                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21664   "TARGET_MMX"
21665   "paddusb\t{%2, %0|%0, %2}"
21666   [(set_attr "type" "mmxadd")
21667    (set_attr "mode" "DI")])
21668
21669 (define_insn "usaddv4hi3"
21670   [(set (match_operand:V4HI 0 "register_operand" "=y")
21671         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21672                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21673   "TARGET_MMX"
21674   "paddusw\t{%2, %0|%0, %2}"
21675   [(set_attr "type" "mmxadd")
21676    (set_attr "mode" "DI")])
21677
21678 (define_insn "subv8qi3"
21679   [(set (match_operand:V8QI 0 "register_operand" "=y")
21680         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21681                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21682   "TARGET_MMX"
21683   "psubb\t{%2, %0|%0, %2}"
21684   [(set_attr "type" "mmxadd")
21685    (set_attr "mode" "DI")])
21686
21687 (define_insn "subv4hi3"
21688   [(set (match_operand:V4HI 0 "register_operand" "=y")
21689         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21690                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21691   "TARGET_MMX"
21692   "psubw\t{%2, %0|%0, %2}"
21693   [(set_attr "type" "mmxadd")
21694    (set_attr "mode" "DI")])
21695
21696 (define_insn "subv2si3"
21697   [(set (match_operand:V2SI 0 "register_operand" "=y")
21698         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21699                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21700   "TARGET_MMX"
21701   "psubd\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxadd")
21703    (set_attr "mode" "DI")])
21704
21705 (define_insn "mmx_subdi3"
21706   [(set (match_operand:DI 0 "register_operand" "=y")
21707         (unspec:DI
21708          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21709                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21710          UNSPEC_NOP))]
21711   "TARGET_MMX"
21712   "psubq\t{%2, %0|%0, %2}"
21713   [(set_attr "type" "mmxadd")
21714    (set_attr "mode" "DI")])
21715
21716 (define_insn "sssubv8qi3"
21717   [(set (match_operand:V8QI 0 "register_operand" "=y")
21718         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21719                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21720   "TARGET_MMX"
21721   "psubsb\t{%2, %0|%0, %2}"
21722   [(set_attr "type" "mmxadd")
21723    (set_attr "mode" "DI")])
21724
21725 (define_insn "sssubv4hi3"
21726   [(set (match_operand:V4HI 0 "register_operand" "=y")
21727         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21728                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21729   "TARGET_MMX"
21730   "psubsw\t{%2, %0|%0, %2}"
21731   [(set_attr "type" "mmxadd")
21732    (set_attr "mode" "DI")])
21733
21734 (define_insn "ussubv8qi3"
21735   [(set (match_operand:V8QI 0 "register_operand" "=y")
21736         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21737                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21738   "TARGET_MMX"
21739   "psubusb\t{%2, %0|%0, %2}"
21740   [(set_attr "type" "mmxadd")
21741    (set_attr "mode" "DI")])
21742
21743 (define_insn "ussubv4hi3"
21744   [(set (match_operand:V4HI 0 "register_operand" "=y")
21745         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21746                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21747   "TARGET_MMX"
21748   "psubusw\t{%2, %0|%0, %2}"
21749   [(set_attr "type" "mmxadd")
21750    (set_attr "mode" "DI")])
21751
21752 (define_insn "mulv4hi3"
21753   [(set (match_operand:V4HI 0 "register_operand" "=y")
21754         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21755                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21756   "TARGET_MMX"
21757   "pmullw\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxmul")
21759    (set_attr "mode" "DI")])
21760
21761 (define_insn "smulv4hi3_highpart"
21762   [(set (match_operand:V4HI 0 "register_operand" "=y")
21763         (truncate:V4HI
21764          (lshiftrt:V4SI
21765           (mult:V4SI (sign_extend:V4SI
21766                       (match_operand:V4HI 1 "register_operand" "0"))
21767                      (sign_extend:V4SI
21768                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21769           (const_int 16))))]
21770   "TARGET_MMX"
21771   "pmulhw\t{%2, %0|%0, %2}"
21772   [(set_attr "type" "mmxmul")
21773    (set_attr "mode" "DI")])
21774
21775 (define_insn "umulv4hi3_highpart"
21776   [(set (match_operand:V4HI 0 "register_operand" "=y")
21777         (truncate:V4HI
21778          (lshiftrt:V4SI
21779           (mult:V4SI (zero_extend:V4SI
21780                       (match_operand:V4HI 1 "register_operand" "0"))
21781                      (zero_extend:V4SI
21782                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21783           (const_int 16))))]
21784   "TARGET_SSE || TARGET_3DNOW_A"
21785   "pmulhuw\t{%2, %0|%0, %2}"
21786   [(set_attr "type" "mmxmul")
21787    (set_attr "mode" "DI")])
21788
21789 (define_insn "mmx_pmaddwd"
21790   [(set (match_operand:V2SI 0 "register_operand" "=y")
21791         (plus:V2SI
21792          (mult:V2SI
21793           (sign_extend:V2SI
21794            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21795                             (parallel [(const_int 0) (const_int 2)])))
21796           (sign_extend:V2SI
21797            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21798                             (parallel [(const_int 0) (const_int 2)]))))
21799          (mult:V2SI
21800           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21801                                              (parallel [(const_int 1)
21802                                                         (const_int 3)])))
21803           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21804                                              (parallel [(const_int 1)
21805                                                         (const_int 3)]))))))]
21806   "TARGET_MMX"
21807   "pmaddwd\t{%2, %0|%0, %2}"
21808   [(set_attr "type" "mmxmul")
21809    (set_attr "mode" "DI")])
21810
21811
21812 ;; MMX logical operations
21813 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21814 ;; normal code that also wants to use the FPU from getting broken.
21815 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21816 (define_insn "mmx_iordi3"
21817   [(set (match_operand:DI 0 "register_operand" "=y")
21818         (unspec:DI
21819          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21820                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21821          UNSPEC_NOP))]
21822   "TARGET_MMX"
21823   "por\t{%2, %0|%0, %2}"
21824   [(set_attr "type" "mmxadd")
21825    (set_attr "mode" "DI")])
21826
21827 (define_insn "mmx_xordi3"
21828   [(set (match_operand:DI 0 "register_operand" "=y")
21829         (unspec:DI
21830          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21831                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21832          UNSPEC_NOP))]
21833   "TARGET_MMX"
21834   "pxor\t{%2, %0|%0, %2}"
21835   [(set_attr "type" "mmxadd")
21836    (set_attr "mode" "DI")
21837    (set_attr "memory" "none")])
21838
21839 ;; Same as pxor, but don't show input operands so that we don't think
21840 ;; they are live.
21841 (define_insn "mmx_clrdi"
21842   [(set (match_operand:DI 0 "register_operand" "=y")
21843         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21844   "TARGET_MMX"
21845   "pxor\t{%0, %0|%0, %0}"
21846   [(set_attr "type" "mmxadd")
21847    (set_attr "mode" "DI")
21848    (set_attr "memory" "none")])
21849
21850 (define_insn "mmx_anddi3"
21851   [(set (match_operand:DI 0 "register_operand" "=y")
21852         (unspec:DI
21853          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21854                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21855          UNSPEC_NOP))]
21856   "TARGET_MMX"
21857   "pand\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "mmxadd")
21859    (set_attr "mode" "DI")])
21860
21861 (define_insn "mmx_nanddi3"
21862   [(set (match_operand:DI 0 "register_operand" "=y")
21863         (unspec:DI
21864          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21865                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21866          UNSPEC_NOP))]
21867   "TARGET_MMX"
21868   "pandn\t{%2, %0|%0, %2}"
21869   [(set_attr "type" "mmxadd")
21870    (set_attr "mode" "DI")])
21871
21872
21873 ;; MMX unsigned averages/sum of absolute differences
21874
21875 (define_insn "mmx_uavgv8qi3"
21876   [(set (match_operand:V8QI 0 "register_operand" "=y")
21877         (ashiftrt:V8QI
21878          (plus:V8QI (plus:V8QI
21879                      (match_operand:V8QI 1 "register_operand" "0")
21880                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21881                     (const_vector:V8QI [(const_int 1)
21882                                         (const_int 1)
21883                                         (const_int 1)
21884                                         (const_int 1)
21885                                         (const_int 1)
21886                                         (const_int 1)
21887                                         (const_int 1)
21888                                         (const_int 1)]))
21889          (const_int 1)))]
21890   "TARGET_SSE || TARGET_3DNOW_A"
21891   "pavgb\t{%2, %0|%0, %2}"
21892   [(set_attr "type" "mmxshft")
21893    (set_attr "mode" "DI")])
21894
21895 (define_insn "mmx_uavgv4hi3"
21896   [(set (match_operand:V4HI 0 "register_operand" "=y")
21897         (ashiftrt:V4HI
21898          (plus:V4HI (plus:V4HI
21899                      (match_operand:V4HI 1 "register_operand" "0")
21900                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21901                     (const_vector:V4HI [(const_int 1)
21902                                         (const_int 1)
21903                                         (const_int 1)
21904                                         (const_int 1)]))
21905          (const_int 1)))]
21906   "TARGET_SSE || TARGET_3DNOW_A"
21907   "pavgw\t{%2, %0|%0, %2}"
21908   [(set_attr "type" "mmxshft")
21909    (set_attr "mode" "DI")])
21910
21911 (define_insn "mmx_psadbw"
21912   [(set (match_operand:DI 0 "register_operand" "=y")
21913         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21914                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21915                    UNSPEC_PSADBW))]
21916   "TARGET_SSE || TARGET_3DNOW_A"
21917   "psadbw\t{%2, %0|%0, %2}"
21918   [(set_attr "type" "mmxshft")
21919    (set_attr "mode" "DI")])
21920
21921
21922 ;; MMX insert/extract/shuffle
21923
21924 (define_insn "mmx_pinsrw"
21925   [(set (match_operand:V4HI 0 "register_operand" "=y")
21926         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21927                         (vec_duplicate:V4HI
21928                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21929                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21930   "TARGET_SSE || TARGET_3DNOW_A"
21931   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21932   [(set_attr "type" "mmxcvt")
21933    (set_attr "mode" "DI")])
21934
21935 (define_insn "mmx_pextrw"
21936   [(set (match_operand:SI 0 "register_operand" "=r")
21937         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21938                                        (parallel
21939                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21940   "TARGET_SSE || TARGET_3DNOW_A"
21941   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21942   [(set_attr "type" "mmxcvt")
21943    (set_attr "mode" "DI")])
21944
21945 (define_insn "mmx_pshufw"
21946   [(set (match_operand:V4HI 0 "register_operand" "=y")
21947         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21948                       (match_operand:SI 2 "immediate_operand" "i")]
21949                      UNSPEC_SHUFFLE))]
21950   "TARGET_SSE || TARGET_3DNOW_A"
21951   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21952   [(set_attr "type" "mmxcvt")
21953    (set_attr "mode" "DI")])
21954
21955
21956 ;; MMX mask-generating comparisons
21957
21958 (define_insn "eqv8qi3"
21959   [(set (match_operand:V8QI 0 "register_operand" "=y")
21960         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21961                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21962   "TARGET_MMX"
21963   "pcmpeqb\t{%2, %0|%0, %2}"
21964   [(set_attr "type" "mmxcmp")
21965    (set_attr "mode" "DI")])
21966
21967 (define_insn "eqv4hi3"
21968   [(set (match_operand:V4HI 0 "register_operand" "=y")
21969         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21970                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21971   "TARGET_MMX"
21972   "pcmpeqw\t{%2, %0|%0, %2}"
21973   [(set_attr "type" "mmxcmp")
21974    (set_attr "mode" "DI")])
21975
21976 (define_insn "eqv2si3"
21977   [(set (match_operand:V2SI 0 "register_operand" "=y")
21978         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21979                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21980   "TARGET_MMX"
21981   "pcmpeqd\t{%2, %0|%0, %2}"
21982   [(set_attr "type" "mmxcmp")
21983    (set_attr "mode" "DI")])
21984
21985 (define_insn "gtv8qi3"
21986   [(set (match_operand:V8QI 0 "register_operand" "=y")
21987         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21988                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21989   "TARGET_MMX"
21990   "pcmpgtb\t{%2, %0|%0, %2}"
21991   [(set_attr "type" "mmxcmp")
21992    (set_attr "mode" "DI")])
21993
21994 (define_insn "gtv4hi3"
21995   [(set (match_operand:V4HI 0 "register_operand" "=y")
21996         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21997                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21998   "TARGET_MMX"
21999   "pcmpgtw\t{%2, %0|%0, %2}"
22000   [(set_attr "type" "mmxcmp")
22001    (set_attr "mode" "DI")])
22002
22003 (define_insn "gtv2si3"
22004   [(set (match_operand:V2SI 0 "register_operand" "=y")
22005         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22006                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22007   "TARGET_MMX"
22008   "pcmpgtd\t{%2, %0|%0, %2}"
22009   [(set_attr "type" "mmxcmp")
22010    (set_attr "mode" "DI")])
22011
22012
22013 ;; MMX max/min insns
22014
22015 (define_insn "umaxv8qi3"
22016   [(set (match_operand:V8QI 0 "register_operand" "=y")
22017         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22018                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22019   "TARGET_SSE || TARGET_3DNOW_A"
22020   "pmaxub\t{%2, %0|%0, %2}"
22021   [(set_attr "type" "mmxadd")
22022    (set_attr "mode" "DI")])
22023
22024 (define_insn "smaxv4hi3"
22025   [(set (match_operand:V4HI 0 "register_operand" "=y")
22026         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22027                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22028   "TARGET_SSE || TARGET_3DNOW_A"
22029   "pmaxsw\t{%2, %0|%0, %2}"
22030   [(set_attr "type" "mmxadd")
22031    (set_attr "mode" "DI")])
22032
22033 (define_insn "uminv8qi3"
22034   [(set (match_operand:V8QI 0 "register_operand" "=y")
22035         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22036                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22037   "TARGET_SSE || TARGET_3DNOW_A"
22038   "pminub\t{%2, %0|%0, %2}"
22039   [(set_attr "type" "mmxadd")
22040    (set_attr "mode" "DI")])
22041
22042 (define_insn "sminv4hi3"
22043   [(set (match_operand:V4HI 0 "register_operand" "=y")
22044         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22045                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22046   "TARGET_SSE || TARGET_3DNOW_A"
22047   "pminsw\t{%2, %0|%0, %2}"
22048   [(set_attr "type" "mmxadd")
22049    (set_attr "mode" "DI")])
22050
22051
22052 ;; MMX shifts
22053
22054 (define_insn "ashrv4hi3"
22055   [(set (match_operand:V4HI 0 "register_operand" "=y")
22056         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22057                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22058   "TARGET_MMX"
22059   "psraw\t{%2, %0|%0, %2}"
22060   [(set_attr "type" "mmxshft")
22061    (set_attr "mode" "DI")])
22062
22063 (define_insn "ashrv2si3"
22064   [(set (match_operand:V2SI 0 "register_operand" "=y")
22065         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22066                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22067   "TARGET_MMX"
22068   "psrad\t{%2, %0|%0, %2}"
22069   [(set_attr "type" "mmxshft")
22070    (set_attr "mode" "DI")])
22071
22072 (define_insn "lshrv4hi3"
22073   [(set (match_operand:V4HI 0 "register_operand" "=y")
22074         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22075                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22076   "TARGET_MMX"
22077   "psrlw\t{%2, %0|%0, %2}"
22078   [(set_attr "type" "mmxshft")
22079    (set_attr "mode" "DI")])
22080
22081 (define_insn "lshrv2si3"
22082   [(set (match_operand:V2SI 0 "register_operand" "=y")
22083         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22084                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22085   "TARGET_MMX"
22086   "psrld\t{%2, %0|%0, %2}"
22087   [(set_attr "type" "mmxshft")
22088    (set_attr "mode" "DI")])
22089
22090 ;; See logical MMX insns.
22091 (define_insn "mmx_lshrdi3"
22092   [(set (match_operand:DI 0 "register_operand" "=y")
22093         (unspec:DI
22094           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22095                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22096           UNSPEC_NOP))]
22097   "TARGET_MMX"
22098   "psrlq\t{%2, %0|%0, %2}"
22099   [(set_attr "type" "mmxshft")
22100    (set_attr "mode" "DI")])
22101
22102 (define_insn "ashlv4hi3"
22103   [(set (match_operand:V4HI 0 "register_operand" "=y")
22104         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22105                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22106   "TARGET_MMX"
22107   "psllw\t{%2, %0|%0, %2}"
22108   [(set_attr "type" "mmxshft")
22109    (set_attr "mode" "DI")])
22110
22111 (define_insn "ashlv2si3"
22112   [(set (match_operand:V2SI 0 "register_operand" "=y")
22113         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22114                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22115   "TARGET_MMX"
22116   "pslld\t{%2, %0|%0, %2}"
22117   [(set_attr "type" "mmxshft")
22118    (set_attr "mode" "DI")])
22119
22120 ;; See logical MMX insns.
22121 (define_insn "mmx_ashldi3"
22122   [(set (match_operand:DI 0 "register_operand" "=y")
22123         (unspec:DI
22124          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22125                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22126          UNSPEC_NOP))]
22127   "TARGET_MMX"
22128   "psllq\t{%2, %0|%0, %2}"
22129   [(set_attr "type" "mmxshft")
22130    (set_attr "mode" "DI")])
22131
22132
22133 ;; MMX pack/unpack insns.
22134
22135 (define_insn "mmx_packsswb"
22136   [(set (match_operand:V8QI 0 "register_operand" "=y")
22137         (vec_concat:V8QI
22138          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22139          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22140   "TARGET_MMX"
22141   "packsswb\t{%2, %0|%0, %2}"
22142   [(set_attr "type" "mmxshft")
22143    (set_attr "mode" "DI")])
22144
22145 (define_insn "mmx_packssdw"
22146   [(set (match_operand:V4HI 0 "register_operand" "=y")
22147         (vec_concat:V4HI
22148          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22149          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22150   "TARGET_MMX"
22151   "packssdw\t{%2, %0|%0, %2}"
22152   [(set_attr "type" "mmxshft")
22153    (set_attr "mode" "DI")])
22154
22155 (define_insn "mmx_packuswb"
22156   [(set (match_operand:V8QI 0 "register_operand" "=y")
22157         (vec_concat:V8QI
22158          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22159          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22160   "TARGET_MMX"
22161   "packuswb\t{%2, %0|%0, %2}"
22162   [(set_attr "type" "mmxshft")
22163    (set_attr "mode" "DI")])
22164
22165 (define_insn "mmx_punpckhbw"
22166   [(set (match_operand:V8QI 0 "register_operand" "=y")
22167         (vec_merge:V8QI
22168          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22169                           (parallel [(const_int 4)
22170                                      (const_int 0)
22171                                      (const_int 5)
22172                                      (const_int 1)
22173                                      (const_int 6)
22174                                      (const_int 2)
22175                                      (const_int 7)
22176                                      (const_int 3)]))
22177          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22178                           (parallel [(const_int 0)
22179                                      (const_int 4)
22180                                      (const_int 1)
22181                                      (const_int 5)
22182                                      (const_int 2)
22183                                      (const_int 6)
22184                                      (const_int 3)
22185                                      (const_int 7)]))
22186          (const_int 85)))]
22187   "TARGET_MMX"
22188   "punpckhbw\t{%2, %0|%0, %2}"
22189   [(set_attr "type" "mmxcvt")
22190    (set_attr "mode" "DI")])
22191
22192 (define_insn "mmx_punpckhwd"
22193   [(set (match_operand:V4HI 0 "register_operand" "=y")
22194         (vec_merge:V4HI
22195          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22196                           (parallel [(const_int 0)
22197                                      (const_int 2)
22198                                      (const_int 1)
22199                                      (const_int 3)]))
22200          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22201                           (parallel [(const_int 2)
22202                                      (const_int 0)
22203                                      (const_int 3)
22204                                      (const_int 1)]))
22205          (const_int 5)))]
22206   "TARGET_MMX"
22207   "punpckhwd\t{%2, %0|%0, %2}"
22208   [(set_attr "type" "mmxcvt")
22209    (set_attr "mode" "DI")])
22210
22211 (define_insn "mmx_punpckhdq"
22212   [(set (match_operand:V2SI 0 "register_operand" "=y")
22213         (vec_merge:V2SI
22214          (match_operand:V2SI 1 "register_operand" "0")
22215          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22216                           (parallel [(const_int 1)
22217                                      (const_int 0)]))
22218          (const_int 1)))]
22219   "TARGET_MMX"
22220   "punpckhdq\t{%2, %0|%0, %2}"
22221   [(set_attr "type" "mmxcvt")
22222    (set_attr "mode" "DI")])
22223
22224 (define_insn "mmx_punpcklbw"
22225   [(set (match_operand:V8QI 0 "register_operand" "=y")
22226         (vec_merge:V8QI
22227          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22228                           (parallel [(const_int 0)
22229                                      (const_int 4)
22230                                      (const_int 1)
22231                                      (const_int 5)
22232                                      (const_int 2)
22233                                      (const_int 6)
22234                                      (const_int 3)
22235                                      (const_int 7)]))
22236          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22237                           (parallel [(const_int 4)
22238                                      (const_int 0)
22239                                      (const_int 5)
22240                                      (const_int 1)
22241                                      (const_int 6)
22242                                      (const_int 2)
22243                                      (const_int 7)
22244                                      (const_int 3)]))
22245          (const_int 85)))]
22246   "TARGET_MMX"
22247   "punpcklbw\t{%2, %0|%0, %2}"
22248   [(set_attr "type" "mmxcvt")
22249    (set_attr "mode" "DI")])
22250
22251 (define_insn "mmx_punpcklwd"
22252   [(set (match_operand:V4HI 0 "register_operand" "=y")
22253         (vec_merge:V4HI
22254          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22255                           (parallel [(const_int 2)
22256                                      (const_int 0)
22257                                      (const_int 3)
22258                                      (const_int 1)]))
22259          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22260                           (parallel [(const_int 0)
22261                                      (const_int 2)
22262                                      (const_int 1)
22263                                      (const_int 3)]))
22264          (const_int 5)))]
22265   "TARGET_MMX"
22266   "punpcklwd\t{%2, %0|%0, %2}"
22267   [(set_attr "type" "mmxcvt")
22268    (set_attr "mode" "DI")])
22269
22270 (define_insn "mmx_punpckldq"
22271   [(set (match_operand:V2SI 0 "register_operand" "=y")
22272         (vec_merge:V2SI
22273          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22274                            (parallel [(const_int 1)
22275                                       (const_int 0)]))
22276          (match_operand:V2SI 2 "register_operand" "y")
22277          (const_int 1)))]
22278   "TARGET_MMX"
22279   "punpckldq\t{%2, %0|%0, %2}"
22280   [(set_attr "type" "mmxcvt")
22281    (set_attr "mode" "DI")])
22282
22283
22284 ;; Miscellaneous stuff
22285
22286 (define_insn "emms"
22287   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22288    (clobber (reg:XF 8))
22289    (clobber (reg:XF 9))
22290    (clobber (reg:XF 10))
22291    (clobber (reg:XF 11))
22292    (clobber (reg:XF 12))
22293    (clobber (reg:XF 13))
22294    (clobber (reg:XF 14))
22295    (clobber (reg:XF 15))
22296    (clobber (reg:DI 29))
22297    (clobber (reg:DI 30))
22298    (clobber (reg:DI 31))
22299    (clobber (reg:DI 32))
22300    (clobber (reg:DI 33))
22301    (clobber (reg:DI 34))
22302    (clobber (reg:DI 35))
22303    (clobber (reg:DI 36))]
22304   "TARGET_MMX"
22305   "emms"
22306   [(set_attr "type" "mmx")
22307    (set_attr "memory" "unknown")])
22308
22309 (define_insn "ldmxcsr"
22310   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22311                     UNSPECV_LDMXCSR)]
22312   "TARGET_SSE"
22313   "ldmxcsr\t%0"
22314   [(set_attr "type" "sse")
22315    (set_attr "memory" "load")])
22316
22317 (define_insn "stmxcsr"
22318   [(set (match_operand:SI 0 "memory_operand" "=m")
22319         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22320   "TARGET_SSE"
22321   "stmxcsr\t%0"
22322   [(set_attr "type" "sse")
22323    (set_attr "memory" "store")])
22324
22325 (define_expand "sfence"
22326   [(set (match_dup 0)
22327         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22328   "TARGET_SSE || TARGET_3DNOW_A"
22329 {
22330   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22331   MEM_VOLATILE_P (operands[0]) = 1;
22332 })
22333
22334 (define_insn "*sfence_insn"
22335   [(set (match_operand:BLK 0 "" "")
22336         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22337   "TARGET_SSE || TARGET_3DNOW_A"
22338   "sfence"
22339   [(set_attr "type" "sse")
22340    (set_attr "memory" "unknown")])
22341
22342 (define_expand "sse_prologue_save"
22343   [(parallel [(set (match_operand:BLK 0 "" "")
22344                    (unspec:BLK [(reg:DI 21)
22345                                 (reg:DI 22)
22346                                 (reg:DI 23)
22347                                 (reg:DI 24)
22348                                 (reg:DI 25)
22349                                 (reg:DI 26)
22350                                 (reg:DI 27)
22351                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22352               (use (match_operand:DI 1 "register_operand" ""))
22353               (use (match_operand:DI 2 "immediate_operand" ""))
22354               (use (label_ref:DI (match_operand 3 "" "")))])]
22355   "TARGET_64BIT"
22356   "")
22357
22358 (define_insn "*sse_prologue_save_insn"
22359   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22360                           (match_operand:DI 4 "const_int_operand" "n")))
22361         (unspec:BLK [(reg:DI 21)
22362                      (reg:DI 22)
22363                      (reg:DI 23)
22364                      (reg:DI 24)
22365                      (reg:DI 25)
22366                      (reg:DI 26)
22367                      (reg:DI 27)
22368                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22369    (use (match_operand:DI 1 "register_operand" "r"))
22370    (use (match_operand:DI 2 "const_int_operand" "i"))
22371    (use (label_ref:DI (match_operand 3 "" "X")))]
22372   "TARGET_64BIT
22373    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22374    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22375   "*
22376 {
22377   int i;
22378   operands[0] = gen_rtx_MEM (Pmode,
22379                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22380   output_asm_insn (\"jmp\\t%A1\", operands);
22381   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22382     {
22383       operands[4] = adjust_address (operands[0], DImode, i*16);
22384       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22385       PUT_MODE (operands[4], TImode);
22386       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22387         output_asm_insn (\"rex\", operands);
22388       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22389     }
22390   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22391                              CODE_LABEL_NUMBER (operands[3]));
22392   RET;
22393 }
22394   "
22395   [(set_attr "type" "other")
22396    (set_attr "length_immediate" "0")
22397    (set_attr "length_address" "0")
22398    (set_attr "length" "135")
22399    (set_attr "memory" "store")
22400    (set_attr "modrm" "0")
22401    (set_attr "mode" "DI")])
22402
22403 ;; 3Dnow! instructions
22404
22405 (define_insn "addv2sf3"
22406   [(set (match_operand:V2SF 0 "register_operand" "=y")
22407         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22408                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22409   "TARGET_3DNOW"
22410   "pfadd\\t{%2, %0|%0, %2}"
22411   [(set_attr "type" "mmxadd")
22412    (set_attr "mode" "V2SF")])
22413
22414 (define_insn "subv2sf3"
22415   [(set (match_operand:V2SF 0 "register_operand" "=y")
22416         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22417                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22418   "TARGET_3DNOW"
22419   "pfsub\\t{%2, %0|%0, %2}"
22420   [(set_attr "type" "mmxadd")
22421    (set_attr "mode" "V2SF")])
22422
22423 (define_insn "subrv2sf3"
22424   [(set (match_operand:V2SF 0 "register_operand" "=y")
22425         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22426                     (match_operand:V2SF 1 "register_operand" "0")))]
22427   "TARGET_3DNOW"
22428   "pfsubr\\t{%2, %0|%0, %2}"
22429   [(set_attr "type" "mmxadd")
22430    (set_attr "mode" "V2SF")])
22431
22432 (define_insn "gtv2sf3"
22433   [(set (match_operand:V2SI 0 "register_operand" "=y")
22434         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22435                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22436  "TARGET_3DNOW"
22437   "pfcmpgt\\t{%2, %0|%0, %2}"
22438   [(set_attr "type" "mmxcmp")
22439    (set_attr "mode" "V2SF")])
22440
22441 (define_insn "gev2sf3"
22442   [(set (match_operand:V2SI 0 "register_operand" "=y")
22443         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22444                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22445   "TARGET_3DNOW"
22446   "pfcmpge\\t{%2, %0|%0, %2}"
22447   [(set_attr "type" "mmxcmp")
22448    (set_attr "mode" "V2SF")])
22449
22450 (define_insn "eqv2sf3"
22451   [(set (match_operand:V2SI 0 "register_operand" "=y")
22452         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22453                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22454   "TARGET_3DNOW"
22455   "pfcmpeq\\t{%2, %0|%0, %2}"
22456   [(set_attr "type" "mmxcmp")
22457    (set_attr "mode" "V2SF")])
22458
22459 (define_insn "pfmaxv2sf3"
22460   [(set (match_operand:V2SF 0 "register_operand" "=y")
22461         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22462                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22463   "TARGET_3DNOW"
22464   "pfmax\\t{%2, %0|%0, %2}"
22465   [(set_attr "type" "mmxadd")
22466    (set_attr "mode" "V2SF")])
22467
22468 (define_insn "pfminv2sf3"
22469   [(set (match_operand:V2SF 0 "register_operand" "=y")
22470         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22471                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22472   "TARGET_3DNOW"
22473   "pfmin\\t{%2, %0|%0, %2}"
22474   [(set_attr "type" "mmxadd")
22475    (set_attr "mode" "V2SF")])
22476
22477 (define_insn "mulv2sf3"
22478   [(set (match_operand:V2SF 0 "register_operand" "=y")
22479         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22480                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22481   "TARGET_3DNOW"
22482   "pfmul\\t{%2, %0|%0, %2}"
22483   [(set_attr "type" "mmxmul")
22484    (set_attr "mode" "V2SF")])
22485
22486 (define_insn "femms"
22487   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22488    (clobber (reg:XF 8))
22489    (clobber (reg:XF 9))
22490    (clobber (reg:XF 10))
22491    (clobber (reg:XF 11))
22492    (clobber (reg:XF 12))
22493    (clobber (reg:XF 13))
22494    (clobber (reg:XF 14))
22495    (clobber (reg:XF 15))
22496    (clobber (reg:DI 29))
22497    (clobber (reg:DI 30))
22498    (clobber (reg:DI 31))
22499    (clobber (reg:DI 32))
22500    (clobber (reg:DI 33))
22501    (clobber (reg:DI 34))
22502    (clobber (reg:DI 35))
22503    (clobber (reg:DI 36))]
22504   "TARGET_3DNOW"
22505   "femms"
22506   [(set_attr "type" "mmx")
22507    (set_attr "memory" "none")]) 
22508
22509 (define_insn "pf2id"
22510   [(set (match_operand:V2SI 0 "register_operand" "=y")
22511         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22512   "TARGET_3DNOW"
22513   "pf2id\\t{%1, %0|%0, %1}"
22514   [(set_attr "type" "mmxcvt")
22515    (set_attr "mode" "V2SF")])
22516
22517 (define_insn "pf2iw"
22518   [(set (match_operand:V2SI 0 "register_operand" "=y")
22519         (sign_extend:V2SI
22520            (ss_truncate:V2HI
22521               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22522   "TARGET_3DNOW_A"
22523   "pf2iw\\t{%1, %0|%0, %1}"
22524   [(set_attr "type" "mmxcvt")
22525    (set_attr "mode" "V2SF")])
22526
22527 (define_insn "pfacc"
22528   [(set (match_operand:V2SF 0 "register_operand" "=y")
22529         (vec_concat:V2SF
22530            (plus:SF
22531               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22532                              (parallel [(const_int  0)]))
22533               (vec_select:SF (match_dup 1)
22534                              (parallel [(const_int 1)])))
22535            (plus:SF
22536               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22537                              (parallel [(const_int  0)]))
22538               (vec_select:SF (match_dup 2)
22539                              (parallel [(const_int 1)])))))]
22540   "TARGET_3DNOW"
22541   "pfacc\\t{%2, %0|%0, %2}"
22542   [(set_attr "type" "mmxadd")
22543    (set_attr "mode" "V2SF")])
22544
22545 (define_insn "pfnacc"
22546   [(set (match_operand:V2SF 0 "register_operand" "=y")
22547         (vec_concat:V2SF
22548            (minus:SF
22549               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22550                              (parallel [(const_int 0)]))
22551               (vec_select:SF (match_dup 1)
22552                              (parallel [(const_int 1)])))
22553            (minus:SF
22554               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22555                              (parallel [(const_int  0)]))
22556               (vec_select:SF (match_dup 2)
22557                              (parallel [(const_int 1)])))))]
22558   "TARGET_3DNOW_A"
22559   "pfnacc\\t{%2, %0|%0, %2}"
22560   [(set_attr "type" "mmxadd")
22561    (set_attr "mode" "V2SF")])
22562
22563 (define_insn "pfpnacc"
22564   [(set (match_operand:V2SF 0 "register_operand" "=y")
22565         (vec_concat:V2SF
22566            (minus:SF
22567               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22568                              (parallel [(const_int 0)]))
22569               (vec_select:SF (match_dup 1)
22570                              (parallel [(const_int 1)])))
22571            (plus:SF
22572               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22573                              (parallel [(const_int 0)]))
22574               (vec_select:SF (match_dup 2)
22575                              (parallel [(const_int 1)])))))]
22576   "TARGET_3DNOW_A"
22577   "pfpnacc\\t{%2, %0|%0, %2}"
22578   [(set_attr "type" "mmxadd")
22579    (set_attr "mode" "V2SF")])
22580
22581 (define_insn "pi2fw"
22582   [(set (match_operand:V2SF 0 "register_operand" "=y")
22583         (float:V2SF
22584            (vec_concat:V2SI
22585               (sign_extend:SI
22586                  (truncate:HI
22587                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22588                                    (parallel [(const_int 0)]))))
22589               (sign_extend:SI
22590                  (truncate:HI
22591                     (vec_select:SI (match_dup 1)
22592                                    (parallel [(const_int  1)])))))))]
22593   "TARGET_3DNOW_A"
22594   "pi2fw\\t{%1, %0|%0, %1}"
22595   [(set_attr "type" "mmxcvt")
22596    (set_attr "mode" "V2SF")])
22597
22598 (define_insn "floatv2si2"
22599   [(set (match_operand:V2SF 0 "register_operand" "=y")
22600         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22601   "TARGET_3DNOW"
22602   "pi2fd\\t{%1, %0|%0, %1}"
22603   [(set_attr "type" "mmxcvt")
22604    (set_attr "mode" "V2SF")])
22605
22606 ;; This insn is identical to pavgb in operation, but the opcode is
22607 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22608
22609 (define_insn "pavgusb"
22610  [(set (match_operand:V8QI 0 "register_operand" "=y")
22611        (unspec:V8QI
22612           [(match_operand:V8QI 1 "register_operand" "0")
22613            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22614           UNSPEC_PAVGUSB))]
22615   "TARGET_3DNOW"
22616   "pavgusb\\t{%2, %0|%0, %2}"
22617   [(set_attr "type" "mmxshft")
22618    (set_attr "mode" "TI")])
22619
22620 ;; 3DNow reciprocal and sqrt
22621  
22622 (define_insn "pfrcpv2sf2"
22623   [(set (match_operand:V2SF 0 "register_operand" "=y")
22624         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22625         UNSPEC_PFRCP))]
22626   "TARGET_3DNOW"
22627   "pfrcp\\t{%1, %0|%0, %1}"
22628   [(set_attr "type" "mmx")
22629    (set_attr "mode" "TI")])
22630
22631 (define_insn "pfrcpit1v2sf3"
22632   [(set (match_operand:V2SF 0 "register_operand" "=y")
22633         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22634                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22635                      UNSPEC_PFRCPIT1))]
22636   "TARGET_3DNOW"
22637   "pfrcpit1\\t{%2, %0|%0, %2}"
22638   [(set_attr "type" "mmx")
22639    (set_attr "mode" "TI")])
22640
22641 (define_insn "pfrcpit2v2sf3"
22642   [(set (match_operand:V2SF 0 "register_operand" "=y")
22643         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22644                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22645                      UNSPEC_PFRCPIT2))]
22646   "TARGET_3DNOW"
22647   "pfrcpit2\\t{%2, %0|%0, %2}"
22648   [(set_attr "type" "mmx")
22649    (set_attr "mode" "TI")])
22650
22651 (define_insn "pfrsqrtv2sf2"
22652   [(set (match_operand:V2SF 0 "register_operand" "=y")
22653         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22654                      UNSPEC_PFRSQRT))]
22655   "TARGET_3DNOW"
22656   "pfrsqrt\\t{%1, %0|%0, %1}"
22657   [(set_attr "type" "mmx")
22658    (set_attr "mode" "TI")])
22659                 
22660 (define_insn "pfrsqit1v2sf3"
22661   [(set (match_operand:V2SF 0 "register_operand" "=y")
22662         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22663                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22664                      UNSPEC_PFRSQIT1))]
22665   "TARGET_3DNOW"
22666   "pfrsqit1\\t{%2, %0|%0, %2}"
22667   [(set_attr "type" "mmx")
22668    (set_attr "mode" "TI")])
22669
22670 (define_insn "pmulhrwv4hi3"
22671   [(set (match_operand:V4HI 0 "register_operand" "=y")
22672         (truncate:V4HI
22673            (lshiftrt:V4SI
22674               (plus:V4SI
22675                  (mult:V4SI
22676                     (sign_extend:V4SI
22677                        (match_operand:V4HI 1 "register_operand" "0"))
22678                     (sign_extend:V4SI
22679                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22680                  (const_vector:V4SI [(const_int 32768)
22681                                      (const_int 32768)
22682                                      (const_int 32768)
22683                                      (const_int 32768)]))
22684               (const_int 16))))]
22685   "TARGET_3DNOW"
22686   "pmulhrw\\t{%2, %0|%0, %2}"
22687   [(set_attr "type" "mmxmul")
22688    (set_attr "mode" "TI")])
22689
22690 (define_insn "pswapdv2si2"
22691   [(set (match_operand:V2SI 0 "register_operand" "=y")
22692         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22693                          (parallel [(const_int 1) (const_int 0)])))]
22694   "TARGET_3DNOW_A"
22695   "pswapd\\t{%1, %0|%0, %1}"
22696   [(set_attr "type" "mmxcvt")
22697    (set_attr "mode" "TI")])
22698
22699 (define_insn "pswapdv2sf2"
22700   [(set (match_operand:V2SF 0 "register_operand" "=y")
22701         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22702                          (parallel [(const_int 1) (const_int 0)])))]
22703   "TARGET_3DNOW_A"
22704   "pswapd\\t{%1, %0|%0, %1}"
22705   [(set_attr "type" "mmxcvt")
22706    (set_attr "mode" "TI")])
22707
22708 (define_expand "prefetch"
22709   [(prefetch (match_operand 0 "address_operand" "")
22710              (match_operand:SI 1 "const_int_operand" "")
22711              (match_operand:SI 2 "const_int_operand" ""))]
22712   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22713 {
22714   int rw = INTVAL (operands[1]);
22715   int locality = INTVAL (operands[2]);
22716
22717   if (rw != 0 && rw != 1)
22718     abort ();
22719   if (locality < 0 || locality > 3)
22720     abort ();
22721   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22722     abort ();
22723
22724   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22725      suported by SSE counterpart or the SSE prefetch is not available
22726      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22727      of locality.  */
22728   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22729     operands[2] = GEN_INT (3);
22730   else
22731     operands[1] = const0_rtx;
22732 })
22733
22734 (define_insn "*prefetch_sse"
22735   [(prefetch (match_operand:SI 0 "address_operand" "p")
22736              (const_int 0)
22737              (match_operand:SI 1 "const_int_operand" ""))]
22738   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22739 {
22740   static const char * const patterns[4] = {
22741    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22742   };
22743
22744   int locality = INTVAL (operands[1]);
22745   if (locality < 0 || locality > 3)
22746     abort ();
22747
22748   return patterns[locality];  
22749 }
22750   [(set_attr "type" "sse")
22751    (set_attr "memory" "none")])
22752
22753 (define_insn "*prefetch_sse_rex"
22754   [(prefetch (match_operand:DI 0 "address_operand" "p")
22755              (const_int 0)
22756              (match_operand:SI 1 "const_int_operand" ""))]
22757   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22758 {
22759   static const char * const patterns[4] = {
22760    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22761   };
22762
22763   int locality = INTVAL (operands[1]);
22764   if (locality < 0 || locality > 3)
22765     abort ();
22766
22767   return patterns[locality];  
22768 }
22769   [(set_attr "type" "sse")
22770    (set_attr "memory" "none")])
22771
22772 (define_insn "*prefetch_3dnow"
22773   [(prefetch (match_operand:SI 0 "address_operand" "p")
22774              (match_operand:SI 1 "const_int_operand" "n")
22775              (const_int 3))]
22776   "TARGET_3DNOW && !TARGET_64BIT"
22777 {
22778   if (INTVAL (operands[1]) == 0)
22779     return "prefetch\t%a0";
22780   else
22781     return "prefetchw\t%a0";
22782 }
22783   [(set_attr "type" "mmx")
22784    (set_attr "memory" "none")])
22785
22786 (define_insn "*prefetch_3dnow_rex"
22787   [(prefetch (match_operand:DI 0 "address_operand" "p")
22788              (match_operand:SI 1 "const_int_operand" "n")
22789              (const_int 3))]
22790   "TARGET_3DNOW && TARGET_64BIT"
22791 {
22792   if (INTVAL (operands[1]) == 0)
22793     return "prefetch\t%a0";
22794   else
22795     return "prefetchw\t%a0";
22796 }
22797   [(set_attr "type" "mmx")
22798    (set_attr "memory" "none")])
22799
22800 ;; SSE2 support
22801
22802 (define_insn "addv2df3"
22803   [(set (match_operand:V2DF 0 "register_operand" "=x")
22804         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22805                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22806   "TARGET_SSE2"
22807   "addpd\t{%2, %0|%0, %2}"
22808   [(set_attr "type" "sseadd")
22809    (set_attr "mode" "V2DF")])
22810
22811 (define_insn "vmaddv2df3"
22812   [(set (match_operand:V2DF 0 "register_operand" "=x")
22813         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22814                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22815                         (match_dup 1)
22816                         (const_int 1)))]
22817   "TARGET_SSE2"
22818   "addsd\t{%2, %0|%0, %2}"
22819   [(set_attr "type" "sseadd")
22820    (set_attr "mode" "DF")])
22821
22822 (define_insn "subv2df3"
22823   [(set (match_operand:V2DF 0 "register_operand" "=x")
22824         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22825                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22826   "TARGET_SSE2"
22827   "subpd\t{%2, %0|%0, %2}"
22828   [(set_attr "type" "sseadd")
22829    (set_attr "mode" "V2DF")])
22830
22831 (define_insn "vmsubv2df3"
22832   [(set (match_operand:V2DF 0 "register_operand" "=x")
22833         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22834                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22835                         (match_dup 1)
22836                         (const_int 1)))]
22837   "TARGET_SSE2"
22838   "subsd\t{%2, %0|%0, %2}"
22839   [(set_attr "type" "sseadd")
22840    (set_attr "mode" "DF")])
22841
22842 (define_insn "mulv2df3"
22843   [(set (match_operand:V2DF 0 "register_operand" "=x")
22844         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22845                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22846   "TARGET_SSE2"
22847   "mulpd\t{%2, %0|%0, %2}"
22848   [(set_attr "type" "ssemul")
22849    (set_attr "mode" "V2DF")])
22850
22851 (define_insn "vmmulv2df3"
22852   [(set (match_operand:V2DF 0 "register_operand" "=x")
22853         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22854                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22855                         (match_dup 1)
22856                         (const_int 1)))]
22857   "TARGET_SSE2"
22858   "mulsd\t{%2, %0|%0, %2}"
22859   [(set_attr "type" "ssemul")
22860    (set_attr "mode" "DF")])
22861
22862 (define_insn "divv2df3"
22863   [(set (match_operand:V2DF 0 "register_operand" "=x")
22864         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22865                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22866   "TARGET_SSE2"
22867   "divpd\t{%2, %0|%0, %2}"
22868   [(set_attr "type" "ssediv")
22869    (set_attr "mode" "V2DF")])
22870
22871 (define_insn "vmdivv2df3"
22872   [(set (match_operand:V2DF 0 "register_operand" "=x")
22873         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22874                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22875                         (match_dup 1)
22876                         (const_int 1)))]
22877   "TARGET_SSE2"
22878   "divsd\t{%2, %0|%0, %2}"
22879   [(set_attr "type" "ssediv")
22880    (set_attr "mode" "DF")])
22881
22882 ;; SSE min/max
22883
22884 (define_insn "smaxv2df3"
22885   [(set (match_operand:V2DF 0 "register_operand" "=x")
22886         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22887                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22888   "TARGET_SSE2"
22889   "maxpd\t{%2, %0|%0, %2}"
22890   [(set_attr "type" "sseadd")
22891    (set_attr "mode" "V2DF")])
22892
22893 (define_insn "vmsmaxv2df3"
22894   [(set (match_operand:V2DF 0 "register_operand" "=x")
22895         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22896                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22897                         (match_dup 1)
22898                         (const_int 1)))]
22899   "TARGET_SSE2"
22900   "maxsd\t{%2, %0|%0, %2}"
22901   [(set_attr "type" "sseadd")
22902    (set_attr "mode" "DF")])
22903
22904 (define_insn "sminv2df3"
22905   [(set (match_operand:V2DF 0 "register_operand" "=x")
22906         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22907                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22908   "TARGET_SSE2"
22909   "minpd\t{%2, %0|%0, %2}"
22910   [(set_attr "type" "sseadd")
22911    (set_attr "mode" "V2DF")])
22912
22913 (define_insn "vmsminv2df3"
22914   [(set (match_operand:V2DF 0 "register_operand" "=x")
22915         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22916                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22917                         (match_dup 1)
22918                         (const_int 1)))]
22919   "TARGET_SSE2"
22920   "minsd\t{%2, %0|%0, %2}"
22921   [(set_attr "type" "sseadd")
22922    (set_attr "mode" "DF")])
22923 ;; SSE2 square root.  There doesn't appear to be an extension for the
22924 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22925
22926 (define_insn "sqrtv2df2"
22927   [(set (match_operand:V2DF 0 "register_operand" "=x")
22928         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22929   "TARGET_SSE2"
22930   "sqrtpd\t{%1, %0|%0, %1}"
22931   [(set_attr "type" "sse")
22932    (set_attr "mode" "V2DF")])
22933
22934 (define_insn "vmsqrtv2df2"
22935   [(set (match_operand:V2DF 0 "register_operand" "=x")
22936         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22937                         (match_operand:V2DF 2 "register_operand" "0")
22938                         (const_int 1)))]
22939   "TARGET_SSE2"
22940   "sqrtsd\t{%1, %0|%0, %1}"
22941   [(set_attr "type" "sse")
22942    (set_attr "mode" "SF")])
22943
22944 ;; SSE mask-generating compares
22945
22946 (define_insn "maskcmpv2df3"
22947   [(set (match_operand:V2DI 0 "register_operand" "=x")
22948         (match_operator:V2DI 3 "sse_comparison_operator"
22949                              [(match_operand:V2DF 1 "register_operand" "0")
22950                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22951   "TARGET_SSE2"
22952   "cmp%D3pd\t{%2, %0|%0, %2}"
22953   [(set_attr "type" "ssecmp")
22954    (set_attr "mode" "V2DF")])
22955
22956 (define_insn "maskncmpv2df3"
22957   [(set (match_operand:V2DI 0 "register_operand" "=x")
22958         (not:V2DI
22959          (match_operator:V2DI 3 "sse_comparison_operator"
22960                               [(match_operand:V2DF 1 "register_operand" "0")
22961                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22962   "TARGET_SSE2"
22963 {
22964   if (GET_CODE (operands[3]) == UNORDERED)
22965     return "cmpordps\t{%2, %0|%0, %2}";
22966   else
22967     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22968 }
22969   [(set_attr "type" "ssecmp")
22970    (set_attr "mode" "V2DF")])
22971
22972 (define_insn "vmmaskcmpv2df3"
22973   [(set (match_operand:V2DI 0 "register_operand" "=x")
22974         (vec_merge:V2DI
22975          (match_operator:V2DI 3 "sse_comparison_operator"
22976                               [(match_operand:V2DF 1 "register_operand" "0")
22977                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22978          (subreg:V2DI (match_dup 1) 0)
22979          (const_int 1)))]
22980   "TARGET_SSE2"
22981   "cmp%D3sd\t{%2, %0|%0, %2}"
22982   [(set_attr "type" "ssecmp")
22983    (set_attr "mode" "DF")])
22984
22985 (define_insn "vmmaskncmpv2df3"
22986   [(set (match_operand:V2DI 0 "register_operand" "=x")
22987         (vec_merge:V2DI
22988          (not:V2DI
22989           (match_operator:V2DI 3 "sse_comparison_operator"
22990                                [(match_operand:V2DF 1 "register_operand" "0")
22991                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22992          (subreg:V2DI (match_dup 1) 0)
22993          (const_int 1)))]
22994   "TARGET_SSE2"
22995 {
22996   if (GET_CODE (operands[3]) == UNORDERED)
22997     return "cmpordsd\t{%2, %0|%0, %2}";
22998   else
22999     return "cmpn%D3sd\t{%2, %0|%0, %2}";
23000 }
23001   [(set_attr "type" "ssecmp")
23002    (set_attr "mode" "DF")])
23003
23004 (define_insn "sse2_comi"
23005   [(set (reg:CCFP FLAGS_REG)
23006         (compare:CCFP (vec_select:DF
23007                        (match_operand:V2DF 0 "register_operand" "x")
23008                        (parallel [(const_int 0)]))
23009                       (vec_select:DF
23010                        (match_operand:V2DF 1 "register_operand" "x")
23011                        (parallel [(const_int 0)]))))]
23012   "TARGET_SSE2"
23013   "comisd\t{%1, %0|%0, %1}"
23014   [(set_attr "type" "ssecomi")
23015    (set_attr "mode" "DF")])
23016
23017 (define_insn "sse2_ucomi"
23018   [(set (reg:CCFPU FLAGS_REG)
23019         (compare:CCFPU (vec_select:DF
23020                          (match_operand:V2DF 0 "register_operand" "x")
23021                          (parallel [(const_int 0)]))
23022                         (vec_select:DF
23023                          (match_operand:V2DF 1 "register_operand" "x")
23024                          (parallel [(const_int 0)]))))]
23025   "TARGET_SSE2"
23026   "ucomisd\t{%1, %0|%0, %1}"
23027   [(set_attr "type" "ssecomi")
23028    (set_attr "mode" "DF")])
23029
23030 ;; SSE Strange Moves.
23031
23032 (define_insn "sse2_movmskpd"
23033   [(set (match_operand:SI 0 "register_operand" "=r")
23034         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23035                    UNSPEC_MOVMSK))]
23036   "TARGET_SSE2"
23037   "movmskpd\t{%1, %0|%0, %1}"
23038   [(set_attr "type" "ssecvt")
23039    (set_attr "mode" "V2DF")])
23040
23041 (define_insn "sse2_pmovmskb"
23042   [(set (match_operand:SI 0 "register_operand" "=r")
23043         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23044                    UNSPEC_MOVMSK))]
23045   "TARGET_SSE2"
23046   "pmovmskb\t{%1, %0|%0, %1}"
23047   [(set_attr "type" "ssecvt")
23048    (set_attr "mode" "V2DF")])
23049
23050 (define_insn "sse2_maskmovdqu"
23051   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23052         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23053                        (match_operand:V16QI 2 "register_operand" "x")]
23054                       UNSPEC_MASKMOV))]
23055   "TARGET_SSE2"
23056   ;; @@@ check ordering of operands in intel/nonintel syntax
23057   "maskmovdqu\t{%2, %1|%1, %2}"
23058   [(set_attr "type" "ssecvt")
23059    (set_attr "mode" "TI")])
23060
23061 (define_insn "sse2_maskmovdqu_rex64"
23062   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23063         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23064                        (match_operand:V16QI 2 "register_operand" "x")]
23065                       UNSPEC_MASKMOV))]
23066   "TARGET_SSE2"
23067   ;; @@@ check ordering of operands in intel/nonintel syntax
23068   "maskmovdqu\t{%2, %1|%1, %2}"
23069   [(set_attr "type" "ssecvt")
23070    (set_attr "mode" "TI")])
23071
23072 (define_insn "sse2_movntv2df"
23073   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23074         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23075                      UNSPEC_MOVNT))]
23076   "TARGET_SSE2"
23077   "movntpd\t{%1, %0|%0, %1}"
23078   [(set_attr "type" "ssecvt")
23079    (set_attr "mode" "V2DF")])
23080
23081 (define_insn "sse2_movntv2di"
23082   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23083         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23084                      UNSPEC_MOVNT))]
23085   "TARGET_SSE2"
23086   "movntdq\t{%1, %0|%0, %1}"
23087   [(set_attr "type" "ssecvt")
23088    (set_attr "mode" "TI")])
23089
23090 (define_insn "sse2_movntsi"
23091   [(set (match_operand:SI 0 "memory_operand" "=m")
23092         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23093                    UNSPEC_MOVNT))]
23094   "TARGET_SSE2"
23095   "movnti\t{%1, %0|%0, %1}"
23096   [(set_attr "type" "ssecvt")
23097    (set_attr "mode" "V2DF")])
23098
23099 ;; SSE <-> integer/MMX conversions
23100
23101 ;; Conversions between SI and SF
23102
23103 (define_insn "cvtdq2ps"
23104   [(set (match_operand:V4SF 0 "register_operand" "=x")
23105         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23106   "TARGET_SSE2"
23107   "cvtdq2ps\t{%1, %0|%0, %1}"
23108   [(set_attr "type" "ssecvt")
23109    (set_attr "mode" "V2DF")])
23110
23111 (define_insn "cvtps2dq"
23112   [(set (match_operand:V4SI 0 "register_operand" "=x")
23113         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23114   "TARGET_SSE2"
23115   "cvtps2dq\t{%1, %0|%0, %1}"
23116   [(set_attr "type" "ssecvt")
23117    (set_attr "mode" "TI")])
23118
23119 (define_insn "cvttps2dq"
23120   [(set (match_operand:V4SI 0 "register_operand" "=x")
23121         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23122                      UNSPEC_FIX))]
23123   "TARGET_SSE2"
23124   "cvttps2dq\t{%1, %0|%0, %1}"
23125   [(set_attr "type" "ssecvt")
23126    (set_attr "mode" "TI")])
23127
23128 ;; Conversions between SI and DF
23129
23130 (define_insn "cvtdq2pd"
23131   [(set (match_operand:V2DF 0 "register_operand" "=x")
23132         (float:V2DF (vec_select:V2SI
23133                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23134                      (parallel
23135                       [(const_int 0)
23136                        (const_int 1)]))))]
23137   "TARGET_SSE2"
23138   "cvtdq2pd\t{%1, %0|%0, %1}"
23139   [(set_attr "type" "ssecvt")
23140    (set_attr "mode" "V2DF")])
23141
23142 (define_insn "cvtpd2dq"
23143   [(set (match_operand:V4SI 0 "register_operand" "=x")
23144         (vec_concat:V4SI
23145          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23146          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23147   "TARGET_SSE2"
23148   "cvtpd2dq\t{%1, %0|%0, %1}"
23149   [(set_attr "type" "ssecvt")
23150    (set_attr "mode" "TI")])
23151
23152 (define_insn "cvttpd2dq"
23153   [(set (match_operand:V4SI 0 "register_operand" "=x")
23154         (vec_concat:V4SI
23155          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23156                       UNSPEC_FIX)
23157          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23158   "TARGET_SSE2"
23159   "cvttpd2dq\t{%1, %0|%0, %1}"
23160   [(set_attr "type" "ssecvt")
23161    (set_attr "mode" "TI")])
23162
23163 (define_insn "cvtpd2pi"
23164   [(set (match_operand:V2SI 0 "register_operand" "=y")
23165         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23166   "TARGET_SSE2"
23167   "cvtpd2pi\t{%1, %0|%0, %1}"
23168   [(set_attr "type" "ssecvt")
23169    (set_attr "mode" "TI")])
23170
23171 (define_insn "cvttpd2pi"
23172   [(set (match_operand:V2SI 0 "register_operand" "=y")
23173         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23174                      UNSPEC_FIX))]
23175   "TARGET_SSE2"
23176   "cvttpd2pi\t{%1, %0|%0, %1}"
23177   [(set_attr "type" "ssecvt")
23178    (set_attr "mode" "TI")])
23179
23180 (define_insn "cvtpi2pd"
23181   [(set (match_operand:V2DF 0 "register_operand" "=x")
23182         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23183   "TARGET_SSE2"
23184   "cvtpi2pd\t{%1, %0|%0, %1}"
23185   [(set_attr "type" "ssecvt")
23186    (set_attr "mode" "TI")])
23187
23188 ;; Conversions between SI and DF
23189
23190 (define_insn "cvtsd2si"
23191   [(set (match_operand:SI 0 "register_operand" "=r,r")
23192         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23193                                (parallel [(const_int 0)]))))]
23194   "TARGET_SSE2"
23195   "cvtsd2si\t{%1, %0|%0, %1}"
23196   [(set_attr "type" "sseicvt")
23197    (set_attr "athlon_decode" "double,vector")
23198    (set_attr "mode" "SI")])
23199
23200 (define_insn "cvtsd2siq"
23201   [(set (match_operand:DI 0 "register_operand" "=r,r")
23202         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23203                                (parallel [(const_int 0)]))))]
23204   "TARGET_SSE2 && TARGET_64BIT"
23205   "cvtsd2siq\t{%1, %0|%0, %1}"
23206   [(set_attr "type" "sseicvt")
23207    (set_attr "athlon_decode" "double,vector")
23208    (set_attr "mode" "DI")])
23209
23210 (define_insn "cvttsd2si"
23211   [(set (match_operand:SI 0 "register_operand" "=r,r")
23212         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23213                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23214   "TARGET_SSE2"
23215   "cvttsd2si\t{%1, %0|%0, %1}"
23216   [(set_attr "type" "sseicvt")
23217    (set_attr "mode" "SI")
23218    (set_attr "athlon_decode" "double,vector")])
23219
23220 (define_insn "cvttsd2siq"
23221   [(set (match_operand:DI 0 "register_operand" "=r,r")
23222         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23223                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23224   "TARGET_SSE2 && TARGET_64BIT"
23225   "cvttsd2siq\t{%1, %0|%0, %1}"
23226   [(set_attr "type" "sseicvt")
23227    (set_attr "mode" "DI")
23228    (set_attr "athlon_decode" "double,vector")])
23229
23230 (define_insn "cvtsi2sd"
23231   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23232         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23233                         (vec_duplicate:V2DF
23234                           (float:DF
23235                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23236                         (const_int 2)))]
23237   "TARGET_SSE2"
23238   "cvtsi2sd\t{%2, %0|%0, %2}"
23239   [(set_attr "type" "sseicvt")
23240    (set_attr "mode" "DF")
23241    (set_attr "athlon_decode" "double,direct")])
23242
23243 (define_insn "cvtsi2sdq"
23244   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23245         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23246                         (vec_duplicate:V2DF
23247                           (float:DF
23248                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23249                         (const_int 2)))]
23250   "TARGET_SSE2 && TARGET_64BIT"
23251   "cvtsi2sdq\t{%2, %0|%0, %2}"
23252   [(set_attr "type" "sseicvt")
23253    (set_attr "mode" "DF")
23254    (set_attr "athlon_decode" "double,direct")])
23255
23256 ;; Conversions between SF and DF
23257
23258 (define_insn "cvtsd2ss"
23259   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23260         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23261                         (vec_duplicate:V4SF
23262                           (float_truncate:V2SF
23263                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23264                         (const_int 14)))]
23265   "TARGET_SSE2"
23266   "cvtsd2ss\t{%2, %0|%0, %2}"
23267   [(set_attr "type" "ssecvt")
23268    (set_attr "athlon_decode" "vector,double")
23269    (set_attr "mode" "SF")])
23270
23271 (define_insn "cvtss2sd"
23272   [(set (match_operand:V2DF 0 "register_operand" "=x")
23273         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23274                         (float_extend:V2DF
23275                           (vec_select:V2SF
23276                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23277                             (parallel [(const_int 0)
23278                                        (const_int 1)])))
23279                         (const_int 2)))]
23280   "TARGET_SSE2"
23281   "cvtss2sd\t{%2, %0|%0, %2}"
23282   [(set_attr "type" "ssecvt")
23283    (set_attr "mode" "DF")])
23284
23285 (define_insn "cvtpd2ps"
23286   [(set (match_operand:V4SF 0 "register_operand" "=x")
23287         (subreg:V4SF
23288           (vec_concat:V4SI
23289             (subreg:V2SI (float_truncate:V2SF
23290                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23291             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23292   "TARGET_SSE2"
23293   "cvtpd2ps\t{%1, %0|%0, %1}"
23294   [(set_attr "type" "ssecvt")
23295    (set_attr "mode" "V4SF")])
23296
23297 (define_insn "cvtps2pd"
23298   [(set (match_operand:V2DF 0 "register_operand" "=x")
23299         (float_extend:V2DF
23300           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23301                            (parallel [(const_int 0)
23302                                       (const_int 1)]))))]
23303   "TARGET_SSE2"
23304   "cvtps2pd\t{%1, %0|%0, %1}"
23305   [(set_attr "type" "ssecvt")
23306    (set_attr "mode" "V2DF")])
23307
23308 ;; SSE2 variants of MMX insns
23309
23310 ;; MMX arithmetic
23311
23312 (define_insn "addv16qi3"
23313   [(set (match_operand:V16QI 0 "register_operand" "=x")
23314         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23315                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23316   "TARGET_SSE2"
23317   "paddb\t{%2, %0|%0, %2}"
23318   [(set_attr "type" "sseiadd")
23319    (set_attr "mode" "TI")])
23320
23321 (define_insn "addv8hi3"
23322   [(set (match_operand:V8HI 0 "register_operand" "=x")
23323         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23324                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23325   "TARGET_SSE2"
23326   "paddw\t{%2, %0|%0, %2}"
23327   [(set_attr "type" "sseiadd")
23328    (set_attr "mode" "TI")])
23329
23330 (define_insn "addv4si3"
23331   [(set (match_operand:V4SI 0 "register_operand" "=x")
23332         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23333                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23334   "TARGET_SSE2"
23335   "paddd\t{%2, %0|%0, %2}"
23336   [(set_attr "type" "sseiadd")
23337    (set_attr "mode" "TI")])
23338
23339 (define_insn "addv2di3"
23340   [(set (match_operand:V2DI 0 "register_operand" "=x")
23341         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23342                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23343   "TARGET_SSE2"
23344   "paddq\t{%2, %0|%0, %2}"
23345   [(set_attr "type" "sseiadd")
23346    (set_attr "mode" "TI")])
23347
23348 (define_insn "ssaddv16qi3"
23349   [(set (match_operand:V16QI 0 "register_operand" "=x")
23350         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23351                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23352   "TARGET_SSE2"
23353   "paddsb\t{%2, %0|%0, %2}"
23354   [(set_attr "type" "sseiadd")
23355    (set_attr "mode" "TI")])
23356
23357 (define_insn "ssaddv8hi3"
23358   [(set (match_operand:V8HI 0 "register_operand" "=x")
23359         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23360                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23361   "TARGET_SSE2"
23362   "paddsw\t{%2, %0|%0, %2}"
23363   [(set_attr "type" "sseiadd")
23364    (set_attr "mode" "TI")])
23365
23366 (define_insn "usaddv16qi3"
23367   [(set (match_operand:V16QI 0 "register_operand" "=x")
23368         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23369                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23370   "TARGET_SSE2"
23371   "paddusb\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseiadd")
23373    (set_attr "mode" "TI")])
23374
23375 (define_insn "usaddv8hi3"
23376   [(set (match_operand:V8HI 0 "register_operand" "=x")
23377         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23378                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23379   "TARGET_SSE2"
23380   "paddusw\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseiadd")
23382    (set_attr "mode" "TI")])
23383
23384 (define_insn "subv16qi3"
23385   [(set (match_operand:V16QI 0 "register_operand" "=x")
23386         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23387                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23388   "TARGET_SSE2"
23389   "psubb\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseiadd")
23391    (set_attr "mode" "TI")])
23392
23393 (define_insn "subv8hi3"
23394   [(set (match_operand:V8HI 0 "register_operand" "=x")
23395         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23396                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23397   "TARGET_SSE2"
23398   "psubw\t{%2, %0|%0, %2}"
23399   [(set_attr "type" "sseiadd")
23400    (set_attr "mode" "TI")])
23401
23402 (define_insn "subv4si3"
23403   [(set (match_operand:V4SI 0 "register_operand" "=x")
23404         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23405                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23406   "TARGET_SSE2"
23407   "psubd\t{%2, %0|%0, %2}"
23408   [(set_attr "type" "sseiadd")
23409    (set_attr "mode" "TI")])
23410
23411 (define_insn "subv2di3"
23412   [(set (match_operand:V2DI 0 "register_operand" "=x")
23413         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23414                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23415   "TARGET_SSE2"
23416   "psubq\t{%2, %0|%0, %2}"
23417   [(set_attr "type" "sseiadd")
23418    (set_attr "mode" "TI")])
23419
23420 (define_insn "sssubv16qi3"
23421   [(set (match_operand:V16QI 0 "register_operand" "=x")
23422         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23423                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23424   "TARGET_SSE2"
23425   "psubsb\t{%2, %0|%0, %2}"
23426   [(set_attr "type" "sseiadd")
23427    (set_attr "mode" "TI")])
23428
23429 (define_insn "sssubv8hi3"
23430   [(set (match_operand:V8HI 0 "register_operand" "=x")
23431         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23432                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23433   "TARGET_SSE2"
23434   "psubsw\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseiadd")
23436    (set_attr "mode" "TI")])
23437
23438 (define_insn "ussubv16qi3"
23439   [(set (match_operand:V16QI 0 "register_operand" "=x")
23440         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23441                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23442   "TARGET_SSE2"
23443   "psubusb\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseiadd")
23445    (set_attr "mode" "TI")])
23446
23447 (define_insn "ussubv8hi3"
23448   [(set (match_operand:V8HI 0 "register_operand" "=x")
23449         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23450                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23451   "TARGET_SSE2"
23452   "psubusw\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseiadd")
23454    (set_attr "mode" "TI")])
23455
23456 (define_insn "mulv8hi3"
23457   [(set (match_operand:V8HI 0 "register_operand" "=x")
23458         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23459                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23460   "TARGET_SSE2"
23461   "pmullw\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseimul")
23463    (set_attr "mode" "TI")])
23464
23465 (define_insn "smulv8hi3_highpart"
23466   [(set (match_operand:V8HI 0 "register_operand" "=x")
23467         (truncate:V8HI
23468          (lshiftrt:V8SI
23469           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23470                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23471           (const_int 16))))]
23472   "TARGET_SSE2"
23473   "pmulhw\t{%2, %0|%0, %2}"
23474   [(set_attr "type" "sseimul")
23475    (set_attr "mode" "TI")])
23476
23477 (define_insn "umulv8hi3_highpart"
23478   [(set (match_operand:V8HI 0 "register_operand" "=x")
23479         (truncate:V8HI
23480          (lshiftrt:V8SI
23481           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23482                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23483           (const_int 16))))]
23484   "TARGET_SSE2"
23485   "pmulhuw\t{%2, %0|%0, %2}"
23486   [(set_attr "type" "sseimul")
23487    (set_attr "mode" "TI")])
23488
23489 (define_insn "sse2_umulsidi3"
23490   [(set (match_operand:DI 0 "register_operand" "=y")
23491         (mult:DI (zero_extend:DI (vec_select:SI
23492                                   (match_operand:V2SI 1 "register_operand" "0")
23493                                   (parallel [(const_int 0)])))
23494                  (zero_extend:DI (vec_select:SI
23495                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23496                                   (parallel [(const_int 0)])))))]
23497   "TARGET_SSE2"
23498   "pmuludq\t{%2, %0|%0, %2}"
23499   [(set_attr "type" "mmxmul")
23500    (set_attr "mode" "DI")])
23501
23502 (define_insn "sse2_umulv2siv2di3"
23503   [(set (match_operand:V2DI 0 "register_operand" "=x")
23504         (mult:V2DI (zero_extend:V2DI
23505                      (vec_select:V2SI
23506                        (match_operand:V4SI 1 "register_operand" "0")
23507                        (parallel [(const_int 0) (const_int 2)])))
23508                    (zero_extend:V2DI
23509                      (vec_select:V2SI
23510                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23511                        (parallel [(const_int 0) (const_int 2)])))))]
23512   "TARGET_SSE2"
23513   "pmuludq\t{%2, %0|%0, %2}"
23514   [(set_attr "type" "sseimul")
23515    (set_attr "mode" "TI")])
23516
23517 (define_insn "sse2_pmaddwd"
23518   [(set (match_operand:V4SI 0 "register_operand" "=x")
23519         (plus:V4SI
23520          (mult:V4SI
23521           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23522                                              (parallel [(const_int 0)
23523                                                         (const_int 2)
23524                                                         (const_int 4)
23525                                                         (const_int 6)])))
23526           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23527                                              (parallel [(const_int 0)
23528                                                         (const_int 2)
23529                                                         (const_int 4)
23530                                                         (const_int 6)]))))
23531          (mult:V4SI
23532           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23533                                              (parallel [(const_int 1)
23534                                                         (const_int 3)
23535                                                         (const_int 5)
23536                                                         (const_int 7)])))
23537           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23538                                              (parallel [(const_int 1)
23539                                                         (const_int 3)
23540                                                         (const_int 5)
23541                                                         (const_int 7)]))))))]
23542   "TARGET_SSE2"
23543   "pmaddwd\t{%2, %0|%0, %2}"
23544   [(set_attr "type" "sseiadd")
23545    (set_attr "mode" "TI")])
23546
23547 ;; Same as pxor, but don't show input operands so that we don't think
23548 ;; they are live.
23549 (define_insn "sse2_clrti"
23550   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23551   "TARGET_SSE2"
23552 {
23553   if (get_attr_mode (insn) == MODE_TI)
23554     return "pxor\t%0, %0";
23555   else
23556     return "xorps\t%0, %0";
23557 }
23558   [(set_attr "type" "ssemov")
23559    (set_attr "memory" "none")
23560    (set (attr "mode")
23561               (if_then_else
23562                 (ne (symbol_ref "optimize_size")
23563                     (const_int 0))
23564                 (const_string "V4SF")
23565                 (const_string "TI")))])
23566
23567 ;; MMX unsigned averages/sum of absolute differences
23568
23569 (define_insn "sse2_uavgv16qi3"
23570   [(set (match_operand:V16QI 0 "register_operand" "=x")
23571         (ashiftrt:V16QI
23572          (plus:V16QI (plus:V16QI
23573                      (match_operand:V16QI 1 "register_operand" "0")
23574                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23575                      (const_vector:V16QI [(const_int 1) (const_int 1)
23576                                           (const_int 1) (const_int 1)
23577                                           (const_int 1) (const_int 1)
23578                                           (const_int 1) (const_int 1)
23579                                           (const_int 1) (const_int 1)
23580                                           (const_int 1) (const_int 1)
23581                                           (const_int 1) (const_int 1)
23582                                           (const_int 1) (const_int 1)]))
23583          (const_int 1)))]
23584   "TARGET_SSE2"
23585   "pavgb\t{%2, %0|%0, %2}"
23586   [(set_attr "type" "sseiadd")
23587    (set_attr "mode" "TI")])
23588
23589 (define_insn "sse2_uavgv8hi3"
23590   [(set (match_operand:V8HI 0 "register_operand" "=x")
23591         (ashiftrt:V8HI
23592          (plus:V8HI (plus:V8HI
23593                      (match_operand:V8HI 1 "register_operand" "0")
23594                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23595                     (const_vector:V8HI [(const_int 1) (const_int 1)
23596                                         (const_int 1) (const_int 1)
23597                                         (const_int 1) (const_int 1)
23598                                         (const_int 1) (const_int 1)]))
23599          (const_int 1)))]
23600   "TARGET_SSE2"
23601   "pavgw\t{%2, %0|%0, %2}"
23602   [(set_attr "type" "sseiadd")
23603    (set_attr "mode" "TI")])
23604
23605 ;; @@@ this isn't the right representation.
23606 (define_insn "sse2_psadbw"
23607   [(set (match_operand:V2DI 0 "register_operand" "=x")
23608         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23609                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23610                      UNSPEC_PSADBW))]
23611   "TARGET_SSE2"
23612   "psadbw\t{%2, %0|%0, %2}"
23613   [(set_attr "type" "sseiadd")
23614    (set_attr "mode" "TI")])
23615
23616
23617 ;; MMX insert/extract/shuffle
23618
23619 (define_insn "sse2_pinsrw"
23620   [(set (match_operand:V8HI 0 "register_operand" "=x")
23621         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23622                         (vec_duplicate:V8HI
23623                          (truncate:HI
23624                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23625                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23626   "TARGET_SSE2"
23627   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23628   [(set_attr "type" "ssecvt")
23629    (set_attr "mode" "TI")])
23630
23631 (define_insn "sse2_pextrw"
23632   [(set (match_operand:SI 0 "register_operand" "=r")
23633         (zero_extend:SI
23634           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23635                          (parallel
23636                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23637   "TARGET_SSE2"
23638   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23639   [(set_attr "type" "ssecvt")
23640    (set_attr "mode" "TI")])
23641
23642 (define_insn "sse2_pshufd"
23643   [(set (match_operand:V4SI 0 "register_operand" "=x")
23644         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23645                       (match_operand:SI 2 "immediate_operand" "i")]
23646                      UNSPEC_SHUFFLE))]
23647   "TARGET_SSE2"
23648   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23649   [(set_attr "type" "ssecvt")
23650    (set_attr "mode" "TI")])
23651
23652 (define_insn "sse2_pshuflw"
23653   [(set (match_operand:V8HI 0 "register_operand" "=x")
23654         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23655                       (match_operand:SI 2 "immediate_operand" "i")]
23656                      UNSPEC_PSHUFLW))]
23657   "TARGET_SSE2"
23658   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23659   [(set_attr "type" "ssecvt")
23660    (set_attr "mode" "TI")])
23661
23662 (define_insn "sse2_pshufhw"
23663   [(set (match_operand:V8HI 0 "register_operand" "=x")
23664         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23665                       (match_operand:SI 2 "immediate_operand" "i")]
23666                      UNSPEC_PSHUFHW))]
23667   "TARGET_SSE2"
23668   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23669   [(set_attr "type" "ssecvt")
23670    (set_attr "mode" "TI")])
23671
23672 ;; MMX mask-generating comparisons
23673
23674 (define_insn "eqv16qi3"
23675   [(set (match_operand:V16QI 0 "register_operand" "=x")
23676         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23677                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23678   "TARGET_SSE2"
23679   "pcmpeqb\t{%2, %0|%0, %2}"
23680   [(set_attr "type" "ssecmp")
23681    (set_attr "mode" "TI")])
23682
23683 (define_insn "eqv8hi3"
23684   [(set (match_operand:V8HI 0 "register_operand" "=x")
23685         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23686                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23687   "TARGET_SSE2"
23688   "pcmpeqw\t{%2, %0|%0, %2}"
23689   [(set_attr "type" "ssecmp")
23690    (set_attr "mode" "TI")])
23691
23692 (define_insn "eqv4si3"
23693   [(set (match_operand:V4SI 0 "register_operand" "=x")
23694         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23695                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23696   "TARGET_SSE2"
23697   "pcmpeqd\t{%2, %0|%0, %2}"
23698   [(set_attr "type" "ssecmp")
23699    (set_attr "mode" "TI")])
23700
23701 (define_insn "gtv16qi3"
23702   [(set (match_operand:V16QI 0 "register_operand" "=x")
23703         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23704                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23705   "TARGET_SSE2"
23706   "pcmpgtb\t{%2, %0|%0, %2}"
23707   [(set_attr "type" "ssecmp")
23708    (set_attr "mode" "TI")])
23709
23710 (define_insn "gtv8hi3"
23711   [(set (match_operand:V8HI 0 "register_operand" "=x")
23712         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23713                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23714   "TARGET_SSE2"
23715   "pcmpgtw\t{%2, %0|%0, %2}"
23716   [(set_attr "type" "ssecmp")
23717    (set_attr "mode" "TI")])
23718
23719 (define_insn "gtv4si3"
23720   [(set (match_operand:V4SI 0 "register_operand" "=x")
23721         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23722                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23723   "TARGET_SSE2"
23724   "pcmpgtd\t{%2, %0|%0, %2}"
23725   [(set_attr "type" "ssecmp")
23726    (set_attr "mode" "TI")])
23727
23728
23729 ;; MMX max/min insns
23730
23731 (define_insn "umaxv16qi3"
23732   [(set (match_operand:V16QI 0 "register_operand" "=x")
23733         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23734                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23735   "TARGET_SSE2"
23736   "pmaxub\t{%2, %0|%0, %2}"
23737   [(set_attr "type" "sseiadd")
23738    (set_attr "mode" "TI")])
23739
23740 (define_insn "smaxv8hi3"
23741   [(set (match_operand:V8HI 0 "register_operand" "=x")
23742         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23743                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23744   "TARGET_SSE2"
23745   "pmaxsw\t{%2, %0|%0, %2}"
23746   [(set_attr "type" "sseiadd")
23747    (set_attr "mode" "TI")])
23748
23749 (define_insn "uminv16qi3"
23750   [(set (match_operand:V16QI 0 "register_operand" "=x")
23751         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23752                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23753   "TARGET_SSE2"
23754   "pminub\t{%2, %0|%0, %2}"
23755   [(set_attr "type" "sseiadd")
23756    (set_attr "mode" "TI")])
23757
23758 (define_insn "sminv8hi3"
23759   [(set (match_operand:V8HI 0 "register_operand" "=x")
23760         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23761                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23762   "TARGET_SSE2"
23763   "pminsw\t{%2, %0|%0, %2}"
23764   [(set_attr "type" "sseiadd")
23765    (set_attr "mode" "TI")])
23766
23767
23768 ;; MMX shifts
23769
23770 (define_insn "ashrv8hi3"
23771   [(set (match_operand:V8HI 0 "register_operand" "=x")
23772         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23773                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23774   "TARGET_SSE2"
23775   "psraw\t{%2, %0|%0, %2}"
23776   [(set_attr "type" "sseishft")
23777    (set_attr "mode" "TI")])
23778
23779 (define_insn "ashrv4si3"
23780   [(set (match_operand:V4SI 0 "register_operand" "=x")
23781         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23782                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23783   "TARGET_SSE2"
23784   "psrad\t{%2, %0|%0, %2}"
23785   [(set_attr "type" "sseishft")
23786    (set_attr "mode" "TI")])
23787
23788 (define_insn "lshrv8hi3"
23789   [(set (match_operand:V8HI 0 "register_operand" "=x")
23790         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23791                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23792   "TARGET_SSE2"
23793   "psrlw\t{%2, %0|%0, %2}"
23794   [(set_attr "type" "sseishft")
23795    (set_attr "mode" "TI")])
23796
23797 (define_insn "lshrv4si3"
23798   [(set (match_operand:V4SI 0 "register_operand" "=x")
23799         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23800                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23801   "TARGET_SSE2"
23802   "psrld\t{%2, %0|%0, %2}"
23803   [(set_attr "type" "sseishft")
23804    (set_attr "mode" "TI")])
23805
23806 (define_insn "lshrv2di3"
23807   [(set (match_operand:V2DI 0 "register_operand" "=x")
23808         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23809                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23810   "TARGET_SSE2"
23811   "psrlq\t{%2, %0|%0, %2}"
23812   [(set_attr "type" "sseishft")
23813    (set_attr "mode" "TI")])
23814
23815 (define_insn "ashlv8hi3"
23816   [(set (match_operand:V8HI 0 "register_operand" "=x")
23817         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23818                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23819   "TARGET_SSE2"
23820   "psllw\t{%2, %0|%0, %2}"
23821   [(set_attr "type" "sseishft")
23822    (set_attr "mode" "TI")])
23823
23824 (define_insn "ashlv4si3"
23825   [(set (match_operand:V4SI 0 "register_operand" "=x")
23826         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23827                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23828   "TARGET_SSE2"
23829   "pslld\t{%2, %0|%0, %2}"
23830   [(set_attr "type" "sseishft")
23831    (set_attr "mode" "TI")])
23832
23833 (define_insn "ashlv2di3"
23834   [(set (match_operand:V2DI 0 "register_operand" "=x")
23835         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23836                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23837   "TARGET_SSE2"
23838   "psllq\t{%2, %0|%0, %2}"
23839   [(set_attr "type" "sseishft")
23840    (set_attr "mode" "TI")])
23841
23842 (define_insn "ashrv8hi3_ti"
23843   [(set (match_operand:V8HI 0 "register_operand" "=x")
23844         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23845                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23846   "TARGET_SSE2"
23847   "psraw\t{%2, %0|%0, %2}"
23848   [(set_attr "type" "sseishft")
23849    (set_attr "mode" "TI")])
23850
23851 (define_insn "ashrv4si3_ti"
23852   [(set (match_operand:V4SI 0 "register_operand" "=x")
23853         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23854                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23855   "TARGET_SSE2"
23856   "psrad\t{%2, %0|%0, %2}"
23857   [(set_attr "type" "sseishft")
23858    (set_attr "mode" "TI")])
23859
23860 (define_insn "lshrv8hi3_ti"
23861   [(set (match_operand:V8HI 0 "register_operand" "=x")
23862         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23863                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23864   "TARGET_SSE2"
23865   "psrlw\t{%2, %0|%0, %2}"
23866   [(set_attr "type" "sseishft")
23867    (set_attr "mode" "TI")])
23868
23869 (define_insn "lshrv4si3_ti"
23870   [(set (match_operand:V4SI 0 "register_operand" "=x")
23871         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23872                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23873   "TARGET_SSE2"
23874   "psrld\t{%2, %0|%0, %2}"
23875   [(set_attr "type" "sseishft")
23876    (set_attr "mode" "TI")])
23877
23878 (define_insn "lshrv2di3_ti"
23879   [(set (match_operand:V2DI 0 "register_operand" "=x")
23880         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23881                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23882   "TARGET_SSE2"
23883   "psrlq\t{%2, %0|%0, %2}"
23884   [(set_attr "type" "sseishft")
23885    (set_attr "mode" "TI")])
23886
23887 (define_insn "ashlv8hi3_ti"
23888   [(set (match_operand:V8HI 0 "register_operand" "=x")
23889         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23890                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23891   "TARGET_SSE2"
23892   "psllw\t{%2, %0|%0, %2}"
23893   [(set_attr "type" "sseishft")
23894    (set_attr "mode" "TI")])
23895
23896 (define_insn "ashlv4si3_ti"
23897   [(set (match_operand:V4SI 0 "register_operand" "=x")
23898         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23899                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23900   "TARGET_SSE2"
23901   "pslld\t{%2, %0|%0, %2}"
23902   [(set_attr "type" "sseishft")
23903    (set_attr "mode" "TI")])
23904
23905 (define_insn "ashlv2di3_ti"
23906   [(set (match_operand:V2DI 0 "register_operand" "=x")
23907         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23908                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23909   "TARGET_SSE2"
23910   "psllq\t{%2, %0|%0, %2}"
23911   [(set_attr "type" "sseishft")
23912    (set_attr "mode" "TI")])
23913
23914 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23915 ;; we wouldn't need here it since we never generate TImode arithmetic.
23916
23917 ;; There has to be some kind of prize for the weirdest new instruction...
23918 (define_insn "sse2_ashlti3"
23919   [(set (match_operand:TI 0 "register_operand" "=x")
23920         (unspec:TI
23921          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23922                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23923                                (const_int 8)))] UNSPEC_NOP))]
23924   "TARGET_SSE2"
23925   "pslldq\t{%2, %0|%0, %2}"
23926   [(set_attr "type" "sseishft")
23927    (set_attr "mode" "TI")])
23928
23929 (define_insn "sse2_lshrti3"
23930   [(set (match_operand:TI 0 "register_operand" "=x")
23931         (unspec:TI
23932          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23933                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23934                                 (const_int 8)))] UNSPEC_NOP))]
23935   "TARGET_SSE2"
23936   "psrldq\t{%2, %0|%0, %2}"
23937   [(set_attr "type" "sseishft")
23938    (set_attr "mode" "TI")])
23939
23940 ;; SSE unpack
23941
23942 (define_insn "sse2_unpckhpd"
23943   [(set (match_operand:V2DF 0 "register_operand" "=x")
23944         (vec_concat:V2DF
23945          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23946                         (parallel [(const_int 1)]))
23947          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23948                         (parallel [(const_int 1)]))))]
23949   "TARGET_SSE2"
23950   "unpckhpd\t{%2, %0|%0, %2}"
23951   [(set_attr "type" "ssecvt")
23952    (set_attr "mode" "V2DF")])
23953
23954 (define_insn "sse2_unpcklpd"
23955   [(set (match_operand:V2DF 0 "register_operand" "=x")
23956         (vec_concat:V2DF
23957          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23958                         (parallel [(const_int 0)]))
23959          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23960                         (parallel [(const_int 0)]))))]
23961   "TARGET_SSE2"
23962   "unpcklpd\t{%2, %0|%0, %2}"
23963   [(set_attr "type" "ssecvt")
23964    (set_attr "mode" "V2DF")])
23965
23966 ;; MMX pack/unpack insns.
23967
23968 (define_insn "sse2_packsswb"
23969   [(set (match_operand:V16QI 0 "register_operand" "=x")
23970         (vec_concat:V16QI
23971          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23972          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23973   "TARGET_SSE2"
23974   "packsswb\t{%2, %0|%0, %2}"
23975   [(set_attr "type" "ssecvt")
23976    (set_attr "mode" "TI")])
23977
23978 (define_insn "sse2_packssdw"
23979   [(set (match_operand:V8HI 0 "register_operand" "=x")
23980         (vec_concat:V8HI
23981          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23982          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23983   "TARGET_SSE2"
23984   "packssdw\t{%2, %0|%0, %2}"
23985   [(set_attr "type" "ssecvt")
23986    (set_attr "mode" "TI")])
23987
23988 (define_insn "sse2_packuswb"
23989   [(set (match_operand:V16QI 0 "register_operand" "=x")
23990         (vec_concat:V16QI
23991          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23992          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23993   "TARGET_SSE2"
23994   "packuswb\t{%2, %0|%0, %2}"
23995   [(set_attr "type" "ssecvt")
23996    (set_attr "mode" "TI")])
23997
23998 (define_insn "sse2_punpckhbw"
23999   [(set (match_operand:V16QI 0 "register_operand" "=x")
24000         (vec_merge:V16QI
24001          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24002                            (parallel [(const_int 8) (const_int 0)
24003                                       (const_int 9) (const_int 1)
24004                                       (const_int 10) (const_int 2)
24005                                       (const_int 11) (const_int 3)
24006                                       (const_int 12) (const_int 4)
24007                                       (const_int 13) (const_int 5)
24008                                       (const_int 14) (const_int 6)
24009                                       (const_int 15) (const_int 7)]))
24010          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24011                            (parallel [(const_int 0) (const_int 8)
24012                                       (const_int 1) (const_int 9)
24013                                       (const_int 2) (const_int 10)
24014                                       (const_int 3) (const_int 11)
24015                                       (const_int 4) (const_int 12)
24016                                       (const_int 5) (const_int 13)
24017                                       (const_int 6) (const_int 14)
24018                                       (const_int 7) (const_int 15)]))
24019          (const_int 21845)))]
24020   "TARGET_SSE2"
24021   "punpckhbw\t{%2, %0|%0, %2}"
24022   [(set_attr "type" "ssecvt")
24023    (set_attr "mode" "TI")])
24024
24025 (define_insn "sse2_punpckhwd"
24026   [(set (match_operand:V8HI 0 "register_operand" "=x")
24027         (vec_merge:V8HI
24028          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24029                           (parallel [(const_int 4) (const_int 0)
24030                                      (const_int 5) (const_int 1)
24031                                      (const_int 6) (const_int 2)
24032                                      (const_int 7) (const_int 3)]))
24033          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24034                           (parallel [(const_int 0) (const_int 4)
24035                                      (const_int 1) (const_int 5)
24036                                      (const_int 2) (const_int 6)
24037                                      (const_int 3) (const_int 7)]))
24038          (const_int 85)))]
24039   "TARGET_SSE2"
24040   "punpckhwd\t{%2, %0|%0, %2}"
24041   [(set_attr "type" "ssecvt")
24042    (set_attr "mode" "TI")])
24043
24044 (define_insn "sse2_punpckhdq"
24045   [(set (match_operand:V4SI 0 "register_operand" "=x")
24046         (vec_merge:V4SI
24047          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24048                           (parallel [(const_int 2) (const_int 0)
24049                                      (const_int 3) (const_int 1)]))
24050          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24051                           (parallel [(const_int 0) (const_int 2)
24052                                      (const_int 1) (const_int 3)]))
24053          (const_int 5)))]
24054   "TARGET_SSE2"
24055   "punpckhdq\t{%2, %0|%0, %2}"
24056   [(set_attr "type" "ssecvt")
24057    (set_attr "mode" "TI")])
24058
24059 (define_insn "sse2_punpcklbw"
24060   [(set (match_operand:V16QI 0 "register_operand" "=x")
24061         (vec_merge:V16QI
24062          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24063                            (parallel [(const_int 0) (const_int 8)
24064                                       (const_int 1) (const_int 9)
24065                                       (const_int 2) (const_int 10)
24066                                       (const_int 3) (const_int 11)
24067                                       (const_int 4) (const_int 12)
24068                                       (const_int 5) (const_int 13)
24069                                       (const_int 6) (const_int 14)
24070                                       (const_int 7) (const_int 15)]))
24071          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24072                            (parallel [(const_int 8) (const_int 0)
24073                                       (const_int 9) (const_int 1)
24074                                       (const_int 10) (const_int 2)
24075                                       (const_int 11) (const_int 3)
24076                                       (const_int 12) (const_int 4)
24077                                       (const_int 13) (const_int 5)
24078                                       (const_int 14) (const_int 6)
24079                                       (const_int 15) (const_int 7)]))
24080          (const_int 21845)))]
24081   "TARGET_SSE2"
24082   "punpcklbw\t{%2, %0|%0, %2}"
24083   [(set_attr "type" "ssecvt")
24084    (set_attr "mode" "TI")])
24085
24086 (define_insn "sse2_punpcklwd"
24087   [(set (match_operand:V8HI 0 "register_operand" "=x")
24088         (vec_merge:V8HI
24089          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24090                           (parallel [(const_int 0) (const_int 4)
24091                                      (const_int 1) (const_int 5)
24092                                      (const_int 2) (const_int 6)
24093                                      (const_int 3) (const_int 7)]))
24094          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24095                           (parallel [(const_int 4) (const_int 0)
24096                                      (const_int 5) (const_int 1)
24097                                      (const_int 6) (const_int 2)
24098                                      (const_int 7) (const_int 3)]))
24099          (const_int 85)))]
24100   "TARGET_SSE2"
24101   "punpcklwd\t{%2, %0|%0, %2}"
24102   [(set_attr "type" "ssecvt")
24103    (set_attr "mode" "TI")])
24104
24105 (define_insn "sse2_punpckldq"
24106   [(set (match_operand:V4SI 0 "register_operand" "=x")
24107         (vec_merge:V4SI
24108          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24109                           (parallel [(const_int 0) (const_int 2)
24110                                      (const_int 1) (const_int 3)]))
24111          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24112                           (parallel [(const_int 2) (const_int 0)
24113                                      (const_int 3) (const_int 1)]))
24114          (const_int 5)))]
24115   "TARGET_SSE2"
24116   "punpckldq\t{%2, %0|%0, %2}"
24117   [(set_attr "type" "ssecvt")
24118    (set_attr "mode" "TI")])
24119
24120 (define_insn "sse2_punpcklqdq"
24121   [(set (match_operand:V2DI 0 "register_operand" "=x")
24122         (vec_merge:V2DI
24123          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24124                           (parallel [(const_int 1)
24125                                      (const_int 0)]))
24126          (match_operand:V2DI 1 "register_operand" "0")
24127          (const_int 1)))]
24128   "TARGET_SSE2"
24129   "punpcklqdq\t{%2, %0|%0, %2}"
24130   [(set_attr "type" "ssecvt")
24131    (set_attr "mode" "TI")])
24132
24133 (define_insn "sse2_punpckhqdq"
24134   [(set (match_operand:V2DI 0 "register_operand" "=x")
24135         (vec_merge:V2DI
24136          (match_operand:V2DI 1 "register_operand" "0")
24137          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24138                           (parallel [(const_int 1)
24139                                      (const_int 0)]))
24140          (const_int 1)))]
24141   "TARGET_SSE2"
24142   "punpckhqdq\t{%2, %0|%0, %2}"
24143   [(set_attr "type" "ssecvt")
24144    (set_attr "mode" "TI")])
24145
24146 ;; SSE2 moves
24147
24148 (define_insn "sse2_movapd"
24149   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24150         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24151                      UNSPEC_MOVA))]
24152   "TARGET_SSE2
24153    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24154   "movapd\t{%1, %0|%0, %1}"
24155   [(set_attr "type" "ssemov")
24156    (set_attr "mode" "V2DF")])
24157
24158 (define_insn "sse2_movupd"
24159   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24160         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24161                      UNSPEC_MOVU))]
24162   "TARGET_SSE2
24163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24164   "movupd\t{%1, %0|%0, %1}"
24165   [(set_attr "type" "ssecvt")
24166    (set_attr "mode" "V2DF")])
24167
24168 (define_insn "sse2_movdqa"
24169   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24170         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24171                        UNSPEC_MOVA))]
24172   "TARGET_SSE2
24173    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24174   "movdqa\t{%1, %0|%0, %1}"
24175   [(set_attr "type" "ssemov")
24176    (set_attr "mode" "TI")])
24177
24178 (define_insn "sse2_movdqu"
24179   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24180         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24181                        UNSPEC_MOVU))]
24182   "TARGET_SSE2
24183    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24184   "movdqu\t{%1, %0|%0, %1}"
24185   [(set_attr "type" "ssecvt")
24186    (set_attr "mode" "TI")])
24187
24188 (define_insn "sse2_movdq2q"
24189   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24190         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24191                        (parallel [(const_int 0)])))]
24192   "TARGET_SSE2 && !TARGET_64BIT"
24193   "@
24194    movq\t{%1, %0|%0, %1}
24195    movdq2q\t{%1, %0|%0, %1}"
24196   [(set_attr "type" "ssecvt")
24197    (set_attr "mode" "TI")])
24198
24199 (define_insn "sse2_movdq2q_rex64"
24200   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24201         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24202                        (parallel [(const_int 0)])))]
24203   "TARGET_SSE2 && TARGET_64BIT"
24204   "@
24205    movq\t{%1, %0|%0, %1}
24206    movdq2q\t{%1, %0|%0, %1}
24207    movd\t{%1, %0|%0, %1}"
24208   [(set_attr "type" "ssecvt")
24209    (set_attr "mode" "TI")])
24210
24211 (define_insn "sse2_movq2dq"
24212   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24213         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24214                          (const_int 0)))]
24215   "TARGET_SSE2 && !TARGET_64BIT"
24216   "@
24217    movq\t{%1, %0|%0, %1}
24218    movq2dq\t{%1, %0|%0, %1}"
24219   [(set_attr "type" "ssecvt,ssemov")
24220    (set_attr "mode" "TI")])
24221
24222 (define_insn "sse2_movq2dq_rex64"
24223   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24224         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24225                          (const_int 0)))]
24226   "TARGET_SSE2 && TARGET_64BIT"
24227   "@
24228    movq\t{%1, %0|%0, %1}
24229    movq2dq\t{%1, %0|%0, %1}
24230    movd\t{%1, %0|%0, %1}"
24231   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24232    (set_attr "mode" "TI")])
24233
24234 (define_insn "sse2_movq"
24235   [(set (match_operand:V2DI 0 "register_operand" "=x")
24236         (vec_concat:V2DI (vec_select:DI
24237                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24238                           (parallel [(const_int 0)]))
24239                          (const_int 0)))]
24240   "TARGET_SSE2"
24241   "movq\t{%1, %0|%0, %1}"
24242   [(set_attr "type" "ssemov")
24243    (set_attr "mode" "TI")])
24244
24245 (define_insn "sse2_loadd"
24246   [(set (match_operand:V4SI 0 "register_operand" "=x")
24247         (vec_merge:V4SI
24248          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24249          (const_vector:V4SI [(const_int 0)
24250                              (const_int 0)
24251                              (const_int 0)
24252                              (const_int 0)])
24253          (const_int 1)))]
24254   "TARGET_SSE2"
24255   "movd\t{%1, %0|%0, %1}"
24256   [(set_attr "type" "ssemov")
24257    (set_attr "mode" "TI")])
24258
24259 (define_insn "sse2_stored"
24260   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24261         (vec_select:SI
24262          (match_operand:V4SI 1 "register_operand" "x")
24263          (parallel [(const_int 0)])))]
24264   "TARGET_SSE2"
24265   "movd\t{%1, %0|%0, %1}"
24266   [(set_attr "type" "ssemov")
24267    (set_attr "mode" "TI")])
24268
24269 (define_insn "sse2_movhpd"
24270   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24271         (vec_merge:V2DF
24272          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24273          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24274          (const_int 2)))]
24275   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24276   "movhpd\t{%2, %0|%0, %2}"
24277   [(set_attr "type" "ssecvt")
24278    (set_attr "mode" "V2DF")])
24279
24280 (define_expand "sse2_loadsd"
24281   [(match_operand:V2DF 0 "register_operand" "")
24282    (match_operand:DF 1 "memory_operand" "")]
24283   "TARGET_SSE2"
24284 {
24285   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24286                                 CONST0_RTX (V2DFmode)));
24287   DONE;
24288 })
24289
24290 (define_insn "sse2_loadsd_1"
24291   [(set (match_operand:V2DF 0 "register_operand" "=x")
24292         (vec_merge:V2DF
24293          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24294          (match_operand:V2DF 2 "const0_operand" "X")
24295          (const_int 1)))]
24296   "TARGET_SSE2"
24297   "movsd\t{%1, %0|%0, %1}"
24298   [(set_attr "type" "ssecvt")
24299    (set_attr "mode" "DF")])
24300
24301 (define_insn "sse2_movsd"
24302   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24303         (vec_merge:V2DF
24304          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24305          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24306          (const_int 1)))]
24307   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24308   "@movsd\t{%2, %0|%0, %2}
24309     movlpd\t{%2, %0|%0, %2}
24310     movlpd\t{%2, %0|%0, %2}"
24311   [(set_attr "type" "ssecvt")
24312    (set_attr "mode" "DF,V2DF,V2DF")])
24313
24314 (define_insn "sse2_storesd"
24315   [(set (match_operand:DF 0 "memory_operand" "=m")
24316         (vec_select:DF
24317          (match_operand:V2DF 1 "register_operand" "x")
24318          (parallel [(const_int 0)])))]
24319   "TARGET_SSE2"
24320   "movsd\t{%1, %0|%0, %1}"
24321   [(set_attr "type" "ssecvt")
24322    (set_attr "mode" "DF")])
24323
24324 (define_insn "sse2_shufpd"
24325   [(set (match_operand:V2DF 0 "register_operand" "=x")
24326         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24327                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24328                       (match_operand:SI 3 "immediate_operand" "i")]
24329                      UNSPEC_SHUFFLE))]
24330   "TARGET_SSE2"
24331   ;; @@@ check operand order for intel/nonintel syntax
24332   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24333   [(set_attr "type" "ssecvt")
24334    (set_attr "mode" "V2DF")])
24335
24336 (define_insn "sse2_clflush"
24337   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24338                     UNSPECV_CLFLUSH)]
24339   "TARGET_SSE2"
24340   "clflush\t%a0"
24341   [(set_attr "type" "sse")
24342    (set_attr "memory" "unknown")])
24343
24344 (define_expand "sse2_mfence"
24345   [(set (match_dup 0)
24346         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24347   "TARGET_SSE2"
24348 {
24349   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24350   MEM_VOLATILE_P (operands[0]) = 1;
24351 })
24352
24353 (define_insn "*mfence_insn"
24354   [(set (match_operand:BLK 0 "" "")
24355         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24356   "TARGET_SSE2"
24357   "mfence"
24358   [(set_attr "type" "sse")
24359    (set_attr "memory" "unknown")])
24360
24361 (define_expand "sse2_lfence"
24362   [(set (match_dup 0)
24363         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24364   "TARGET_SSE2"
24365 {
24366   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24367   MEM_VOLATILE_P (operands[0]) = 1;
24368 })
24369
24370 (define_insn "*lfence_insn"
24371   [(set (match_operand:BLK 0 "" "")
24372         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24373   "TARGET_SSE2"
24374   "lfence"
24375   [(set_attr "type" "sse")
24376    (set_attr "memory" "unknown")])
24377
24378 ;; SSE3
24379
24380 (define_insn "mwait"
24381   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24382                      (match_operand:SI 1 "register_operand" "c")]
24383                     UNSPECV_MWAIT)]
24384   "TARGET_SSE3"
24385   "mwait\t%0, %1"
24386   [(set_attr "length" "3")])
24387
24388 (define_insn "monitor"
24389   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24390                      (match_operand:SI 1 "register_operand" "c")
24391                      (match_operand:SI 2 "register_operand" "d")]
24392                     UNSPECV_MONITOR)]
24393   "TARGET_SSE3"
24394   "monitor\t%0, %1, %2"
24395   [(set_attr "length" "3")])
24396
24397 ;; SSE3 arithmetic
24398
24399 (define_insn "addsubv4sf3"
24400   [(set (match_operand:V4SF 0 "register_operand" "=x")
24401         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24402                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24403                      UNSPEC_ADDSUB))]
24404   "TARGET_SSE3"
24405   "addsubps\t{%2, %0|%0, %2}"
24406   [(set_attr "type" "sseadd")
24407    (set_attr "mode" "V4SF")])
24408
24409 (define_insn "addsubv2df3"
24410   [(set (match_operand:V2DF 0 "register_operand" "=x")
24411         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24412                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24413                      UNSPEC_ADDSUB))]
24414   "TARGET_SSE3"
24415   "addsubpd\t{%2, %0|%0, %2}"
24416   [(set_attr "type" "sseadd")
24417    (set_attr "mode" "V2DF")])
24418
24419 (define_insn "haddv4sf3"
24420   [(set (match_operand:V4SF 0 "register_operand" "=x")
24421         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24422                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24423                      UNSPEC_HADD))]
24424   "TARGET_SSE3"
24425   "haddps\t{%2, %0|%0, %2}"
24426   [(set_attr "type" "sseadd")
24427    (set_attr "mode" "V4SF")])
24428
24429 (define_insn "haddv2df3"
24430   [(set (match_operand:V2DF 0 "register_operand" "=x")
24431         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24432                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24433                      UNSPEC_HADD))]
24434   "TARGET_SSE3"
24435   "haddpd\t{%2, %0|%0, %2}"
24436   [(set_attr "type" "sseadd")
24437    (set_attr "mode" "V2DF")])
24438
24439 (define_insn "hsubv4sf3"
24440   [(set (match_operand:V4SF 0 "register_operand" "=x")
24441         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24442                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24443                      UNSPEC_HSUB))]
24444   "TARGET_SSE3"
24445   "hsubps\t{%2, %0|%0, %2}"
24446   [(set_attr "type" "sseadd")
24447    (set_attr "mode" "V4SF")])
24448
24449 (define_insn "hsubv2df3"
24450   [(set (match_operand:V2DF 0 "register_operand" "=x")
24451         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24452                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24453                      UNSPEC_HSUB))]
24454   "TARGET_SSE3"
24455   "hsubpd\t{%2, %0|%0, %2}"
24456   [(set_attr "type" "sseadd")
24457    (set_attr "mode" "V2DF")])
24458
24459 (define_insn "movshdup"
24460   [(set (match_operand:V4SF 0 "register_operand" "=x")
24461         (unspec:V4SF
24462          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24463   "TARGET_SSE3"
24464   "movshdup\t{%1, %0|%0, %1}"
24465   [(set_attr "type" "sse")
24466    (set_attr "mode" "V4SF")])
24467
24468 (define_insn "movsldup"
24469   [(set (match_operand:V4SF 0 "register_operand" "=x")
24470         (unspec:V4SF
24471          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24472   "TARGET_SSE3"
24473   "movsldup\t{%1, %0|%0, %1}"
24474   [(set_attr "type" "sse")
24475    (set_attr "mode" "V4SF")])
24476
24477 (define_insn "lddqu"
24478   [(set (match_operand:V16QI 0 "register_operand" "=x")
24479         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24480                        UNSPEC_LDQQU))]
24481   "TARGET_SSE3"
24482   "lddqu\t{%1, %0|%0, %1}"
24483   [(set_attr "type" "ssecvt")
24484    (set_attr "mode" "TI")])
24485
24486 (define_insn "loadddup"
24487   [(set (match_operand:V2DF 0 "register_operand" "=x")
24488         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24489   "TARGET_SSE3"
24490   "movddup\t{%1, %0|%0, %1}"
24491   [(set_attr "type" "ssecvt")
24492    (set_attr "mode" "DF")])
24493
24494 (define_insn "movddup"
24495   [(set (match_operand:V2DF 0 "register_operand" "=x")
24496         (vec_duplicate:V2DF
24497          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24498                         (parallel [(const_int 0)]))))]
24499   "TARGET_SSE3"
24500   "movddup\t{%1, %0|%0, %1}"
24501   [(set_attr "type" "ssecvt")
24502    (set_attr "mode" "DF")])