OSDN Git Service

2004-09-04 Uros Bizjak <uros@kss-loka.si>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg 17)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg 17)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg 17)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg 17)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg 17)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg 17)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg 17)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg 17)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg 17)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg 17)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg 17)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg 17)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg 17)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg 17)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg 17)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg 17)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg 17)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg 17)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
801 ;; and that fp moves clobber the condition codes, and that there is
802 ;; currently no way to describe this fact to reg-stack.  So there are
803 ;; no splitters yet for this.
804
805 ;; %%% YIKES!  This scheme does not retain a strong connection between 
806 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
807 ;; work!  Only allow tos/mem with tos in op 0.
808 ;;
809 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
810 ;; things aren't as bad as they sound...
811
812 (define_insn "*cmpfp_0"
813   [(set (match_operand:HI 0 "register_operand" "=a")
814         (unspec:HI
815           [(compare:CCFP (match_operand 1 "register_operand" "f")
816                          (match_operand 2 "const0_operand" "X"))]
817           UNSPEC_FNSTSW))]
818   "TARGET_80387
819    && FLOAT_MODE_P (GET_MODE (operands[1]))
820    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
821 {
822   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
823     return "ftst\;fnstsw\t%0\;fstp\t%y0";
824   else
825     return "ftst\;fnstsw\t%0";
826 }
827   [(set_attr "type" "multi")
828    (set (attr "mode")
829      (cond [(match_operand:SF 1 "" "")
830               (const_string "SF")
831             (match_operand:DF 1 "" "")
832               (const_string "DF")
833            ]
834            (const_string "XF")))])
835
836 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
837 ;; used to manage the reg stack popping would not be preserved.
838
839 (define_insn "*cmpfp_2_sf"
840   [(set (reg:CCFP FPSR_REG)
841         (compare:CCFP
842           (match_operand:SF 0 "register_operand" "f")
843           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
844   "TARGET_80387"
845   "* return output_fp_compare (insn, operands, 0, 0);"
846   [(set_attr "type" "fcmp")
847    (set_attr "mode" "SF")])
848
849 (define_insn "*cmpfp_2_sf_1"
850   [(set (match_operand:HI 0 "register_operand" "=a")
851         (unspec:HI
852           [(compare:CCFP
853              (match_operand:SF 1 "register_operand" "f")
854              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
855           UNSPEC_FNSTSW))]
856   "TARGET_80387"
857   "* return output_fp_compare (insn, operands, 2, 0);"
858   [(set_attr "type" "fcmp")
859    (set_attr "mode" "SF")])
860
861 (define_insn "*cmpfp_2_df"
862   [(set (reg:CCFP FPSR_REG)
863         (compare:CCFP
864           (match_operand:DF 0 "register_operand" "f")
865           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
866   "TARGET_80387"
867   "* return output_fp_compare (insn, operands, 0, 0);"
868   [(set_attr "type" "fcmp")
869    (set_attr "mode" "DF")])
870
871 (define_insn "*cmpfp_2_df_1"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand:DF 1 "register_operand" "f")
876              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
877           UNSPEC_FNSTSW))]
878   "TARGET_80387"
879   "* return output_fp_compare (insn, operands, 2, 0);"
880   [(set_attr "type" "multi")
881    (set_attr "mode" "DF")])
882
883 (define_insn "*cmpfp_2_xf"
884   [(set (reg:CCFP FPSR_REG)
885         (compare:CCFP
886           (match_operand:XF 0 "register_operand" "f")
887           (match_operand:XF 1 "register_operand" "f")))]
888   "TARGET_80387"
889   "* return output_fp_compare (insn, operands, 0, 0);"
890   [(set_attr "type" "fcmp")
891    (set_attr "mode" "XF")])
892
893 (define_insn "*cmpfp_2_xf_1"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:XF 1 "register_operand" "f")
898              (match_operand:XF 2 "register_operand" "f"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 2, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "mode" "XF")])
904
905 (define_insn "*cmpfp_2u"
906   [(set (reg:CCFPU FPSR_REG)
907         (compare:CCFPU
908           (match_operand 0 "register_operand" "f")
909           (match_operand 1 "register_operand" "f")))]
910   "TARGET_80387
911    && FLOAT_MODE_P (GET_MODE (operands[0]))
912    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
913   "* return output_fp_compare (insn, operands, 0, 1);"
914   [(set_attr "type" "fcmp")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
922
923 (define_insn "*cmpfp_2u_1"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFPU
927              (match_operand 1 "register_operand" "f")
928              (match_operand 2 "register_operand" "f"))]
929           UNSPEC_FNSTSW))]
930   "TARGET_80387
931    && FLOAT_MODE_P (GET_MODE (operands[1]))
932    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
933   "* return output_fp_compare (insn, operands, 2, 1);"
934   [(set_attr "type" "multi")
935    (set (attr "mode")
936      (cond [(match_operand:SF 1 "" "")
937               (const_string "SF")
938             (match_operand:DF 1 "" "")
939               (const_string "DF")
940            ]
941            (const_string "XF")))])
942
943 ;; Patterns to match the SImode-in-memory ficom instructions.
944 ;;
945 ;; %%% Play games with accepting gp registers, as otherwise we have to
946 ;; force them to memory during rtl generation, which is no good.  We
947 ;; can get rid of this once we teach reload to do memory input reloads 
948 ;; via pushes.
949
950 (define_insn "*ficom_1"
951   [(set (reg:CCFP FPSR_REG)
952         (compare:CCFP
953           (match_operand 0 "register_operand" "f,f")
954           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
955   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
956    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
957   "#")
958
959 ;; Split the not-really-implemented gp register case into a
960 ;; push-op-pop sequence.
961 ;;
962 ;; %%% This is most efficient, but am I gonna get in trouble
963 ;; for separating cc0_setter and cc0_user?
964
965 (define_split
966   [(set (reg:CCFP FPSR_REG)
967         (compare:CCFP
968           (match_operand:SF 0 "register_operand" "")
969           (float (match_operand:SI 1 "register_operand" ""))))]
970   "0 && TARGET_80387 && reload_completed"
971   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
972    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
973    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
974               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
975   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
976    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
977
978 ;; FP compares, step 2
979 ;; Move the fpsw to ax.
980
981 (define_insn "x86_fnstsw_1"
982   [(set (match_operand:HI 0 "register_operand" "=a")
983         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
984   "TARGET_80387"
985   "fnstsw\t%0"
986   [(set_attr "length" "2")
987    (set_attr "mode" "SI")
988    (set_attr "unit" "i387")])
989
990 ;; FP compares, step 3
991 ;; Get ax into flags, general case.
992
993 (define_insn "x86_sahf_1"
994   [(set (reg:CC FLAGS_REG)
995         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
996   "!TARGET_64BIT"
997   "sahf"
998   [(set_attr "length" "1")
999    (set_attr "athlon_decode" "vector")
1000    (set_attr "mode" "SI")])
1001
1002 ;; Pentium Pro can do steps 1 through 3 in one go.
1003
1004 (define_insn "*cmpfp_i"
1005   [(set (reg:CCFP FLAGS_REG)
1006         (compare:CCFP (match_operand 0 "register_operand" "f")
1007                       (match_operand 1 "register_operand" "f")))]
1008   "TARGET_80387 && TARGET_CMOVE
1009    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1012   "* return output_fp_compare (insn, operands, 1, 0);"
1013   [(set_attr "type" "fcmp")
1014    (set (attr "mode")
1015      (cond [(match_operand:SF 1 "" "")
1016               (const_string "SF")
1017             (match_operand:DF 1 "" "")
1018               (const_string "DF")
1019            ]
1020            (const_string "XF")))
1021    (set_attr "athlon_decode" "vector")])
1022
1023 (define_insn "*cmpfp_i_sse"
1024   [(set (reg:CCFP FLAGS_REG)
1025         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1026                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1027   "TARGET_80387
1028    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1029    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1030   "* return output_fp_compare (insn, operands, 1, 0);"
1031   [(set_attr "type" "fcmp,ssecomi")
1032    (set (attr "mode")
1033      (if_then_else (match_operand:SF 1 "" "")
1034         (const_string "SF")
1035         (const_string "DF")))
1036    (set_attr "athlon_decode" "vector")])
1037
1038 (define_insn "*cmpfp_i_sse_only"
1039   [(set (reg:CCFP FLAGS_REG)
1040         (compare:CCFP (match_operand 0 "register_operand" "x")
1041                       (match_operand 1 "nonimmediate_operand" "xm")))]
1042   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1043    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1044   "* return output_fp_compare (insn, operands, 1, 0);"
1045   [(set_attr "type" "ssecomi")
1046    (set (attr "mode")
1047      (if_then_else (match_operand:SF 1 "" "")
1048         (const_string "SF")
1049         (const_string "DF")))
1050    (set_attr "athlon_decode" "vector")])
1051
1052 (define_insn "*cmpfp_iu"
1053   [(set (reg:CCFPU FLAGS_REG)
1054         (compare:CCFPU (match_operand 0 "register_operand" "f")
1055                        (match_operand 1 "register_operand" "f")))]
1056   "TARGET_80387 && TARGET_CMOVE
1057    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058    && FLOAT_MODE_P (GET_MODE (operands[0]))
1059    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1060   "* return output_fp_compare (insn, operands, 1, 1);"
1061   [(set_attr "type" "fcmp")
1062    (set (attr "mode")
1063      (cond [(match_operand:SF 1 "" "")
1064               (const_string "SF")
1065             (match_operand:DF 1 "" "")
1066               (const_string "DF")
1067            ]
1068            (const_string "XF")))
1069    (set_attr "athlon_decode" "vector")])
1070
1071 (define_insn "*cmpfp_iu_sse"
1072   [(set (reg:CCFPU FLAGS_REG)
1073         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1074                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1075   "TARGET_80387
1076    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1077    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1078   "* return output_fp_compare (insn, operands, 1, 1);"
1079   [(set_attr "type" "fcmp,ssecomi")
1080    (set (attr "mode")
1081      (if_then_else (match_operand:SF 1 "" "")
1082         (const_string "SF")
1083         (const_string "DF")))
1084    (set_attr "athlon_decode" "vector")])
1085
1086 (define_insn "*cmpfp_iu_sse_only"
1087   [(set (reg:CCFPU FLAGS_REG)
1088         (compare:CCFPU (match_operand 0 "register_operand" "x")
1089                        (match_operand 1 "nonimmediate_operand" "xm")))]
1090   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1091    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1092   "* return output_fp_compare (insn, operands, 1, 1);"
1093   [(set_attr "type" "ssecomi")
1094    (set (attr "mode")
1095      (if_then_else (match_operand:SF 1 "" "")
1096         (const_string "SF")
1097         (const_string "DF")))
1098    (set_attr "athlon_decode" "vector")])
1099 \f
1100 ;; Move instructions.
1101
1102 ;; General case of fullword move.
1103
1104 (define_expand "movsi"
1105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1106         (match_operand:SI 1 "general_operand" ""))]
1107   ""
1108   "ix86_expand_move (SImode, operands); DONE;")
1109
1110 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1111 ;; general_operand.
1112 ;;
1113 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1114 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1115 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1116 ;; targets without our curiosities, and it is just as easy to represent
1117 ;; this differently.
1118
1119 (define_insn "*pushsi2"
1120   [(set (match_operand:SI 0 "push_operand" "=<")
1121         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1126
1127 ;; For 64BIT abi we always round up to 8 bytes.
1128 (define_insn "*pushsi2_rex64"
1129   [(set (match_operand:SI 0 "push_operand" "=X")
1130         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1131   "TARGET_64BIT"
1132   "push{q}\t%q1"
1133   [(set_attr "type" "push")
1134    (set_attr "mode" "SI")])
1135
1136 (define_insn "*pushsi2_prologue"
1137   [(set (match_operand:SI 0 "push_operand" "=<")
1138         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1139    (clobber (mem:BLK (scratch)))]
1140   "!TARGET_64BIT"
1141   "push{l}\t%1"
1142   [(set_attr "type" "push")
1143    (set_attr "mode" "SI")])
1144
1145 (define_insn "*popsi1_epilogue"
1146   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1147         (mem:SI (reg:SI SP_REG)))
1148    (set (reg:SI SP_REG)
1149         (plus:SI (reg:SI SP_REG) (const_int 4)))
1150    (clobber (mem:BLK (scratch)))]
1151   "!TARGET_64BIT"
1152   "pop{l}\t%0"
1153   [(set_attr "type" "pop")
1154    (set_attr "mode" "SI")])
1155
1156 (define_insn "popsi1"
1157   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1158         (mem:SI (reg:SI SP_REG)))
1159    (set (reg:SI SP_REG)
1160         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1161   "!TARGET_64BIT"
1162   "pop{l}\t%0"
1163   [(set_attr "type" "pop")
1164    (set_attr "mode" "SI")])
1165
1166 (define_insn "*movsi_xor"
1167   [(set (match_operand:SI 0 "register_operand" "=r")
1168         (match_operand:SI 1 "const0_operand" "i"))
1169    (clobber (reg:CC FLAGS_REG))]
1170   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1171   "xor{l}\t{%0, %0|%0, %0}"
1172   [(set_attr "type" "alu1")
1173    (set_attr "mode" "SI")
1174    (set_attr "length_immediate" "0")])
1175  
1176 (define_insn "*movsi_or"
1177   [(set (match_operand:SI 0 "register_operand" "=r")
1178         (match_operand:SI 1 "immediate_operand" "i"))
1179    (clobber (reg:CC FLAGS_REG))]
1180   "reload_completed
1181    && operands[1] == constm1_rtx
1182    && (TARGET_PENTIUM || optimize_size)"
1183 {
1184   operands[1] = constm1_rtx;
1185   return "or{l}\t{%1, %0|%0, %1}";
1186 }
1187   [(set_attr "type" "alu1")
1188    (set_attr "mode" "SI")
1189    (set_attr "length_immediate" "1")])
1190
1191 (define_insn "*movsi_1"
1192   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1193         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1196 {
1197   switch (get_attr_type (insn))
1198     {
1199     case TYPE_SSEMOV:
1200       if (get_attr_mode (insn) == MODE_TI)
1201         return "movdqa\t{%1, %0|%0, %1}";
1202       return "movd\t{%1, %0|%0, %1}";
1203
1204     case TYPE_MMXMOV:
1205       if (get_attr_mode (insn) == MODE_DI)
1206         return "movq\t{%1, %0|%0, %1}";
1207       return "movd\t{%1, %0|%0, %1}";
1208
1209     case TYPE_LEA:
1210       return "lea{l}\t{%1, %0|%0, %1}";
1211
1212     default:
1213       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1214         abort();
1215       return "mov{l}\t{%1, %0|%0, %1}";
1216     }
1217 }
1218   [(set (attr "type")
1219      (cond [(eq_attr "alternative" "2,3,4")
1220               (const_string "mmxmov")
1221             (eq_attr "alternative" "5,6,7")
1222               (const_string "ssemov")
1223             (and (ne (symbol_ref "flag_pic") (const_int 0))
1224                  (match_operand:SI 1 "symbolic_operand" ""))
1225               (const_string "lea")
1226            ]
1227            (const_string "imov")))
1228    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1229
1230 (define_insn "*movsi_1_nointernunit"
1231   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1232         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1233   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1234    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1235 {
1236   switch (get_attr_type (insn))
1237     {
1238     case TYPE_SSEMOV:
1239       if (get_attr_mode (insn) == MODE_TI)
1240         return "movdqa\t{%1, %0|%0, %1}";
1241       return "movd\t{%1, %0|%0, %1}";
1242
1243     case TYPE_MMXMOV:
1244       if (get_attr_mode (insn) == MODE_DI)
1245         return "movq\t{%1, %0|%0, %1}";
1246       return "movd\t{%1, %0|%0, %1}";
1247
1248     case TYPE_LEA:
1249       return "lea{l}\t{%1, %0|%0, %1}";
1250
1251     default:
1252       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1253         abort();
1254       return "mov{l}\t{%1, %0|%0, %1}";
1255     }
1256 }
1257   [(set (attr "type")
1258      (cond [(eq_attr "alternative" "2,3,4")
1259               (const_string "mmxmov")
1260             (eq_attr "alternative" "5,6,7")
1261               (const_string "ssemov")
1262             (and (ne (symbol_ref "flag_pic") (const_int 0))
1263                  (match_operand:SI 1 "symbolic_operand" ""))
1264               (const_string "lea")
1265            ]
1266            (const_string "imov")))
1267    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1268
1269 ;; Stores and loads of ax to arbitrary constant address.
1270 ;; We fake an second form of instruction to force reload to load address
1271 ;; into register when rax is not available
1272 (define_insn "*movabssi_1_rex64"
1273   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1274         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1275   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1276   "@
1277    movabs{l}\t{%1, %P0|%P0, %1}
1278    mov{l}\t{%1, %a0|%a0, %1}"
1279   [(set_attr "type" "imov")
1280    (set_attr "modrm" "0,*")
1281    (set_attr "length_address" "8,0")
1282    (set_attr "length_immediate" "0,*")
1283    (set_attr "memory" "store")
1284    (set_attr "mode" "SI")])
1285
1286 (define_insn "*movabssi_2_rex64"
1287   [(set (match_operand:SI 0 "register_operand" "=a,r")
1288         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1289   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1290   "@
1291    movabs{l}\t{%P1, %0|%0, %P1}
1292    mov{l}\t{%a1, %0|%0, %a1}"
1293   [(set_attr "type" "imov")
1294    (set_attr "modrm" "0,*")
1295    (set_attr "length_address" "8,0")
1296    (set_attr "length_immediate" "0")
1297    (set_attr "memory" "load")
1298    (set_attr "mode" "SI")])
1299
1300 (define_insn "*swapsi"
1301   [(set (match_operand:SI 0 "register_operand" "+r")
1302         (match_operand:SI 1 "register_operand" "+r"))
1303    (set (match_dup 1)
1304         (match_dup 0))]
1305   ""
1306   "xchg{l}\t%1, %0"
1307   [(set_attr "type" "imov")
1308    (set_attr "pent_pair" "np")
1309    (set_attr "athlon_decode" "vector")
1310    (set_attr "mode" "SI")
1311    (set_attr "modrm" "0")])
1312
1313 (define_expand "movhi"
1314   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1315         (match_operand:HI 1 "general_operand" ""))]
1316   ""
1317   "ix86_expand_move (HImode, operands); DONE;")
1318
1319 (define_insn "*pushhi2"
1320   [(set (match_operand:HI 0 "push_operand" "=<,<")
1321         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1322   "!TARGET_64BIT"
1323   "@
1324    push{w}\t{|WORD PTR }%1
1325    push{w}\t%1"
1326   [(set_attr "type" "push")
1327    (set_attr "mode" "HI")])
1328
1329 ;; For 64BIT abi we always round up to 8 bytes.
1330 (define_insn "*pushhi2_rex64"
1331   [(set (match_operand:HI 0 "push_operand" "=X")
1332         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1333   "TARGET_64BIT"
1334   "push{q}\t%q1"
1335   [(set_attr "type" "push")
1336    (set_attr "mode" "QI")])
1337
1338 (define_insn "*movhi_1"
1339   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1340         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1341   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1342 {
1343   switch (get_attr_type (insn))
1344     {
1345     case TYPE_IMOVX:
1346       /* movzwl is faster than movw on p2 due to partial word stalls,
1347          though not as fast as an aligned movl.  */
1348       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1349     default:
1350       if (get_attr_mode (insn) == MODE_SI)
1351         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1352       else
1353         return "mov{w}\t{%1, %0|%0, %1}";
1354     }
1355 }
1356   [(set (attr "type")
1357      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1358               (const_string "imov")
1359             (and (eq_attr "alternative" "0")
1360                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1361                           (const_int 0))
1362                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1363                           (const_int 0))))
1364               (const_string "imov")
1365             (and (eq_attr "alternative" "1,2")
1366                  (match_operand:HI 1 "aligned_operand" ""))
1367               (const_string "imov")
1368             (and (ne (symbol_ref "TARGET_MOVX")
1369                      (const_int 0))
1370                  (eq_attr "alternative" "0,2"))
1371               (const_string "imovx")
1372            ]
1373            (const_string "imov")))
1374     (set (attr "mode")
1375       (cond [(eq_attr "type" "imovx")
1376                (const_string "SI")
1377              (and (eq_attr "alternative" "1,2")
1378                   (match_operand:HI 1 "aligned_operand" ""))
1379                (const_string "SI")
1380              (and (eq_attr "alternative" "0")
1381                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1382                            (const_int 0))
1383                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1384                            (const_int 0))))
1385                (const_string "SI")
1386             ]
1387             (const_string "HI")))])
1388
1389 ;; Stores and loads of ax to arbitrary constant address.
1390 ;; We fake an second form of instruction to force reload to load address
1391 ;; into register when rax is not available
1392 (define_insn "*movabshi_1_rex64"
1393   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1394         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1395   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1396   "@
1397    movabs{w}\t{%1, %P0|%P0, %1}
1398    mov{w}\t{%1, %a0|%a0, %1}"
1399   [(set_attr "type" "imov")
1400    (set_attr "modrm" "0,*")
1401    (set_attr "length_address" "8,0")
1402    (set_attr "length_immediate" "0,*")
1403    (set_attr "memory" "store")
1404    (set_attr "mode" "HI")])
1405
1406 (define_insn "*movabshi_2_rex64"
1407   [(set (match_operand:HI 0 "register_operand" "=a,r")
1408         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1409   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1410   "@
1411    movabs{w}\t{%P1, %0|%0, %P1}
1412    mov{w}\t{%a1, %0|%0, %a1}"
1413   [(set_attr "type" "imov")
1414    (set_attr "modrm" "0,*")
1415    (set_attr "length_address" "8,0")
1416    (set_attr "length_immediate" "0")
1417    (set_attr "memory" "load")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*swaphi_1"
1421   [(set (match_operand:HI 0 "register_operand" "+r")
1422         (match_operand:HI 1 "register_operand" "+r"))
1423    (set (match_dup 1)
1424         (match_dup 0))]
1425   "TARGET_PARTIAL_REG_STALL"
1426   "xchg{w}\t%1, %0"
1427   [(set_attr "type" "imov")
1428    (set_attr "pent_pair" "np")
1429    (set_attr "mode" "HI")
1430    (set_attr "modrm" "0")])
1431
1432 (define_insn "*swaphi_2"
1433   [(set (match_operand:HI 0 "register_operand" "+r")
1434         (match_operand:HI 1 "register_operand" "+r"))
1435    (set (match_dup 1)
1436         (match_dup 0))]
1437   "! TARGET_PARTIAL_REG_STALL"
1438   "xchg{l}\t%k1, %k0"
1439   [(set_attr "type" "imov")
1440    (set_attr "pent_pair" "np")
1441    (set_attr "mode" "SI")
1442    (set_attr "modrm" "0")])
1443
1444 (define_expand "movstricthi"
1445   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1446         (match_operand:HI 1 "general_operand" ""))]
1447   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1448 {
1449   /* Don't generate memory->memory moves, go through a register */
1450   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1451     operands[1] = force_reg (HImode, operands[1]);
1452 })
1453
1454 (define_insn "*movstricthi_1"
1455   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1456         (match_operand:HI 1 "general_operand" "rn,m"))]
1457   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1458    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1459   "mov{w}\t{%1, %0|%0, %1}"
1460   [(set_attr "type" "imov")
1461    (set_attr "mode" "HI")])
1462
1463 (define_insn "*movstricthi_xor"
1464   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1465         (match_operand:HI 1 "const0_operand" "i"))
1466    (clobber (reg:CC FLAGS_REG))]
1467   "reload_completed
1468    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1469   "xor{w}\t{%0, %0|%0, %0}"
1470   [(set_attr "type" "alu1")
1471    (set_attr "mode" "HI")
1472    (set_attr "length_immediate" "0")])
1473
1474 (define_expand "movqi"
1475   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1476         (match_operand:QI 1 "general_operand" ""))]
1477   ""
1478   "ix86_expand_move (QImode, operands); DONE;")
1479
1480 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1481 ;; "push a byte".  But actually we use pushw, which has the effect
1482 ;; of rounding the amount pushed up to a halfword.
1483
1484 (define_insn "*pushqi2"
1485   [(set (match_operand:QI 0 "push_operand" "=X,X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1487   "!TARGET_64BIT"
1488   "@
1489    push{w}\t{|word ptr }%1
1490    push{w}\t%w1"
1491   [(set_attr "type" "push")
1492    (set_attr "mode" "HI")])
1493
1494 ;; For 64BIT abi we always round up to 8 bytes.
1495 (define_insn "*pushqi2_rex64"
1496   [(set (match_operand:QI 0 "push_operand" "=X")
1497         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1498   "TARGET_64BIT"
1499   "push{q}\t%q1"
1500   [(set_attr "type" "push")
1501    (set_attr "mode" "QI")])
1502
1503 ;; Situation is quite tricky about when to choose full sized (SImode) move
1504 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1505 ;; partial register dependency machines (such as AMD Athlon), where QImode
1506 ;; moves issue extra dependency and for partial register stalls machines
1507 ;; that don't use QImode patterns (and QImode move cause stall on the next
1508 ;; instruction).
1509 ;;
1510 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1511 ;; register stall machines with, where we use QImode instructions, since
1512 ;; partial register stall can be caused there.  Then we use movzx.
1513 (define_insn "*movqi_1"
1514   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1515         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1516   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1517 {
1518   switch (get_attr_type (insn))
1519     {
1520     case TYPE_IMOVX:
1521       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1522         abort ();
1523       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1524     default:
1525       if (get_attr_mode (insn) == MODE_SI)
1526         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1527       else
1528         return "mov{b}\t{%1, %0|%0, %1}";
1529     }
1530 }
1531   [(set (attr "type")
1532      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1533               (const_string "imov")
1534             (and (eq_attr "alternative" "3")
1535                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1536                           (const_int 0))
1537                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1538                           (const_int 0))))
1539               (const_string "imov")
1540             (eq_attr "alternative" "3,5")
1541               (const_string "imovx")
1542             (and (ne (symbol_ref "TARGET_MOVX")
1543                      (const_int 0))
1544                  (eq_attr "alternative" "2"))
1545               (const_string "imovx")
1546            ]
1547            (const_string "imov")))
1548    (set (attr "mode")
1549       (cond [(eq_attr "alternative" "3,4,5")
1550                (const_string "SI")
1551              (eq_attr "alternative" "6")
1552                (const_string "QI")
1553              (eq_attr "type" "imovx")
1554                (const_string "SI")
1555              (and (eq_attr "type" "imov")
1556                   (and (eq_attr "alternative" "0,1,2")
1557                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1558                            (const_int 0))))
1559                (const_string "SI")
1560              ;; Avoid partial register stalls when not using QImode arithmetic
1561              (and (eq_attr "type" "imov")
1562                   (and (eq_attr "alternative" "0,1,2")
1563                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1564                                 (const_int 0))
1565                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1566                                 (const_int 0)))))
1567                (const_string "SI")
1568            ]
1569            (const_string "QI")))])
1570
1571 (define_expand "reload_outqi"
1572   [(parallel [(match_operand:QI 0 "" "=m")
1573               (match_operand:QI 1 "register_operand" "r")
1574               (match_operand:QI 2 "register_operand" "=&q")])]
1575   ""
1576 {
1577   rtx op0, op1, op2;
1578   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1579
1580   if (reg_overlap_mentioned_p (op2, op0))
1581     abort ();
1582   if (! q_regs_operand (op1, QImode))
1583     {
1584       emit_insn (gen_movqi (op2, op1));
1585       op1 = op2;
1586     }
1587   emit_insn (gen_movqi (op0, op1));
1588   DONE;
1589 })
1590
1591 (define_insn "*swapqi"
1592   [(set (match_operand:QI 0 "register_operand" "+r")
1593         (match_operand:QI 1 "register_operand" "+r"))
1594    (set (match_dup 1)
1595         (match_dup 0))]
1596   ""
1597   "xchg{b}\t%1, %0"
1598   [(set_attr "type" "imov")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "mode" "QI")
1601    (set_attr "modrm" "0")])
1602
1603 (define_expand "movstrictqi"
1604   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1605         (match_operand:QI 1 "general_operand" ""))]
1606   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1607 {
1608   /* Don't generate memory->memory moves, go through a register.  */
1609   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1610     operands[1] = force_reg (QImode, operands[1]);
1611 })
1612
1613 (define_insn "*movstrictqi_1"
1614   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1615         (match_operand:QI 1 "general_operand" "*qn,m"))]
1616   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1617    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1618   "mov{b}\t{%1, %0|%0, %1}"
1619   [(set_attr "type" "imov")
1620    (set_attr "mode" "QI")])
1621
1622 (define_insn "*movstrictqi_xor"
1623   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1624         (match_operand:QI 1 "const0_operand" "i"))
1625    (clobber (reg:CC FLAGS_REG))]
1626   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1627   "xor{b}\t{%0, %0|%0, %0}"
1628   [(set_attr "type" "alu1")
1629    (set_attr "mode" "QI")
1630    (set_attr "length_immediate" "0")])
1631
1632 (define_insn "*movsi_extv_1"
1633   [(set (match_operand:SI 0 "register_operand" "=R")
1634         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1635                          (const_int 8)
1636                          (const_int 8)))]
1637   ""
1638   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1639   [(set_attr "type" "imovx")
1640    (set_attr "mode" "SI")])
1641
1642 (define_insn "*movhi_extv_1"
1643   [(set (match_operand:HI 0 "register_operand" "=R")
1644         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1645                          (const_int 8)
1646                          (const_int 8)))]
1647   ""
1648   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1649   [(set_attr "type" "imovx")
1650    (set_attr "mode" "SI")])
1651
1652 (define_insn "*movqi_extv_1"
1653   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "!TARGET_64BIT"
1658 {
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1666 }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1678
1679 (define_insn "*movqi_extv_1_rex64"
1680   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1681         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1682                          (const_int 8)
1683                          (const_int 8)))]
1684   "TARGET_64BIT"
1685 {
1686   switch (get_attr_type (insn))
1687     {
1688     case TYPE_IMOVX:
1689       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1690     default:
1691       return "mov{b}\t{%h1, %0|%0, %h1}";
1692     }
1693 }
1694   [(set (attr "type")
1695      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1696                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1697                              (ne (symbol_ref "TARGET_MOVX")
1698                                  (const_int 0))))
1699         (const_string "imovx")
1700         (const_string "imov")))
1701    (set (attr "mode")
1702      (if_then_else (eq_attr "type" "imovx")
1703         (const_string "SI")
1704         (const_string "QI")))])
1705
1706 ;; Stores and loads of ax to arbitrary constant address.
1707 ;; We fake an second form of instruction to force reload to load address
1708 ;; into register when rax is not available
1709 (define_insn "*movabsqi_1_rex64"
1710   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1711         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1712   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1713   "@
1714    movabs{b}\t{%1, %P0|%P0, %1}
1715    mov{b}\t{%1, %a0|%a0, %1}"
1716   [(set_attr "type" "imov")
1717    (set_attr "modrm" "0,*")
1718    (set_attr "length_address" "8,0")
1719    (set_attr "length_immediate" "0,*")
1720    (set_attr "memory" "store")
1721    (set_attr "mode" "QI")])
1722
1723 (define_insn "*movabsqi_2_rex64"
1724   [(set (match_operand:QI 0 "register_operand" "=a,r")
1725         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1726   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1727   "@
1728    movabs{b}\t{%P1, %0|%0, %P1}
1729    mov{b}\t{%a1, %0|%0, %a1}"
1730   [(set_attr "type" "imov")
1731    (set_attr "modrm" "0,*")
1732    (set_attr "length_address" "8,0")
1733    (set_attr "length_immediate" "0")
1734    (set_attr "memory" "load")
1735    (set_attr "mode" "QI")])
1736
1737 (define_insn "*movsi_extzv_1"
1738   [(set (match_operand:SI 0 "register_operand" "=R")
1739         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1740                          (const_int 8)
1741                          (const_int 8)))]
1742   ""
1743   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1744   [(set_attr "type" "imovx")
1745    (set_attr "mode" "SI")])
1746
1747 (define_insn "*movqi_extzv_2"
1748   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1749         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1750                                     (const_int 8)
1751                                     (const_int 8)) 0))]
1752   "!TARGET_64BIT"
1753 {
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758     default:
1759       return "mov{b}\t{%h1, %0|%0, %h1}";
1760     }
1761 }
1762   [(set (attr "type")
1763      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1764                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1765                              (ne (symbol_ref "TARGET_MOVX")
1766                                  (const_int 0))))
1767         (const_string "imovx")
1768         (const_string "imov")))
1769    (set (attr "mode")
1770      (if_then_else (eq_attr "type" "imovx")
1771         (const_string "SI")
1772         (const_string "QI")))])
1773
1774 (define_insn "*movqi_extzv_2_rex64"
1775   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1776         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1777                                     (const_int 8)
1778                                     (const_int 8)) 0))]
1779   "TARGET_64BIT"
1780 {
1781   switch (get_attr_type (insn))
1782     {
1783     case TYPE_IMOVX:
1784       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1785     default:
1786       return "mov{b}\t{%h1, %0|%0, %h1}";
1787     }
1788 }
1789   [(set (attr "type")
1790      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1791                         (ne (symbol_ref "TARGET_MOVX")
1792                             (const_int 0)))
1793         (const_string "imovx")
1794         (const_string "imov")))
1795    (set (attr "mode")
1796      (if_then_else (eq_attr "type" "imovx")
1797         (const_string "SI")
1798         (const_string "QI")))])
1799
1800 (define_insn "movsi_insv_1"
1801   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802                          (const_int 8)
1803                          (const_int 8))
1804         (match_operand:SI 1 "general_operand" "Qmn"))]
1805   "!TARGET_64BIT"
1806   "mov{b}\t{%b1, %h0|%h0, %b1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1809
1810 (define_insn "movdi_insv_1_rex64"
1811   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1812                          (const_int 8)
1813                          (const_int 8))
1814         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1815   "TARGET_64BIT"
1816   "mov{b}\t{%b1, %h0|%h0, %b1}"
1817   [(set_attr "type" "imov")
1818    (set_attr "mode" "QI")])
1819
1820 (define_insn "*movqi_insv_2"
1821   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822                          (const_int 8)
1823                          (const_int 8))
1824         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1825                      (const_int 8)))]
1826   ""
1827   "mov{b}\t{%h1, %h0|%h0, %h1}"
1828   [(set_attr "type" "imov")
1829    (set_attr "mode" "QI")])
1830
1831 (define_expand "movdi"
1832   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1833         (match_operand:DI 1 "general_operand" ""))]
1834   ""
1835   "ix86_expand_move (DImode, operands); DONE;")
1836
1837 (define_insn "*pushdi"
1838   [(set (match_operand:DI 0 "push_operand" "=<")
1839         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1840   "!TARGET_64BIT"
1841   "#")
1842
1843 (define_insn "pushdi2_rex64"
1844   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1845         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1846   "TARGET_64BIT"
1847   "@
1848    push{q}\t%1
1849    #"
1850   [(set_attr "type" "push,multi")
1851    (set_attr "mode" "DI")])
1852
1853 ;; Convert impossible pushes of immediate to existing instructions.
1854 ;; First try to get scratch register and go through it.  In case this
1855 ;; fails, push sign extended lower part first and then overwrite
1856 ;; upper part by 32bit move.
1857 (define_peephole2
1858   [(match_scratch:DI 2 "r")
1859    (set (match_operand:DI 0 "push_operand" "")
1860         (match_operand:DI 1 "immediate_operand" ""))]
1861   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1862    && !x86_64_immediate_operand (operands[1], DImode)"
1863   [(set (match_dup 2) (match_dup 1))
1864    (set (match_dup 0) (match_dup 2))]
1865   "")
1866
1867 ;; We need to define this as both peepholer and splitter for case
1868 ;; peephole2 pass is not run.
1869 (define_peephole2
1870   [(set (match_operand:DI 0 "push_operand" "")
1871         (match_operand:DI 1 "immediate_operand" ""))]
1872   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1873    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1874   [(set (match_dup 0) (match_dup 1))
1875    (set (match_dup 2) (match_dup 3))]
1876   "split_di (operands + 1, 1, operands + 2, operands + 3);
1877    operands[1] = gen_lowpart (DImode, operands[2]);
1878    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1879                                                     GEN_INT (4)));
1880   ")
1881
1882 (define_split
1883   [(set (match_operand:DI 0 "push_operand" "")
1884         (match_operand:DI 1 "immediate_operand" ""))]
1885   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1886    && !symbolic_operand (operands[1], DImode)
1887    && !x86_64_immediate_operand (operands[1], DImode)"
1888   [(set (match_dup 0) (match_dup 1))
1889    (set (match_dup 2) (match_dup 3))]
1890   "split_di (operands + 1, 1, operands + 2, operands + 3);
1891    operands[1] = gen_lowpart (DImode, operands[2]);
1892    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893                                                     GEN_INT (4)));
1894   ")
1895
1896 (define_insn "*pushdi2_prologue_rex64"
1897   [(set (match_operand:DI 0 "push_operand" "=<")
1898         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899    (clobber (mem:BLK (scratch)))]
1900   "TARGET_64BIT"
1901   "push{q}\t%1"
1902   [(set_attr "type" "push")
1903    (set_attr "mode" "DI")])
1904
1905 (define_insn "*popdi1_epilogue_rex64"
1906   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907         (mem:DI (reg:DI SP_REG)))
1908    (set (reg:DI SP_REG)
1909         (plus:DI (reg:DI SP_REG) (const_int 8)))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "pop{q}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "DI")])
1915
1916 (define_insn "popdi1"
1917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918         (mem:DI (reg:DI SP_REG)))
1919    (set (reg:DI SP_REG)
1920         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1921   "TARGET_64BIT"
1922   "pop{q}\t%0"
1923   [(set_attr "type" "pop")
1924    (set_attr "mode" "DI")])
1925
1926 (define_insn "*movdi_xor_rex64"
1927   [(set (match_operand:DI 0 "register_operand" "=r")
1928         (match_operand:DI 1 "const0_operand" "i"))
1929    (clobber (reg:CC FLAGS_REG))]
1930   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931    && reload_completed"
1932   "xor{l}\t{%k0, %k0|%k0, %k0}"
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "SI")
1935    (set_attr "length_immediate" "0")])
1936
1937 (define_insn "*movdi_or_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const_int_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1942    && reload_completed
1943    && operands[1] == constm1_rtx"
1944 {
1945   operands[1] = constm1_rtx;
1946   return "or{q}\t{%1, %0|%0, %1}";
1947 }
1948   [(set_attr "type" "alu1")
1949    (set_attr "mode" "DI")
1950    (set_attr "length_immediate" "1")])
1951
1952 (define_insn "*movdi_2"
1953   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1954         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1955   "!TARGET_64BIT
1956    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1957   "@
1958    #
1959    #
1960    movq\t{%1, %0|%0, %1}
1961    movq\t{%1, %0|%0, %1}
1962    movq\t{%1, %0|%0, %1}
1963    movdqa\t{%1, %0|%0, %1}
1964    movq\t{%1, %0|%0, %1}"
1965   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1966    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1967
1968 (define_split
1969   [(set (match_operand:DI 0 "push_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973   [(const_int 0)]
1974   "ix86_split_long_move (operands); DONE;")
1975
1976 ;; %%% This multiword shite has got to go.
1977 (define_split
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979         (match_operand:DI 1 "general_operand" ""))]
1980   "!TARGET_64BIT && reload_completed
1981    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1983   [(const_int 0)]
1984   "ix86_split_long_move (operands); DONE;")
1985
1986 (define_insn "*movdi_1_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1988         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1989   "TARGET_64BIT
1990    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1991    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1992 {
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (which_alternative == 11)
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000     case TYPE_SSEMOV:
2001       if (get_attr_mode (insn) == MODE_TI)
2002           return "movdqa\t{%1, %0|%0, %1}";
2003       /* FALLTHRU */
2004     case TYPE_MMXMOV:
2005       /* Moves from and into integer register is done using movd opcode with
2006          REX prefix.  */
2007       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008           return "movd\t{%1, %0|%0, %1}";
2009       return "movq\t{%1, %0|%0, %1}";
2010     case TYPE_MULTI:
2011       return "#";
2012     case TYPE_LEA:
2013       return "lea{q}\t{%a1, %0|%0, %a1}";
2014     default:
2015       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2016         abort ();
2017       if (get_attr_mode (insn) == MODE_SI)
2018         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019       else if (which_alternative == 2)
2020         return "movabs{q}\t{%1, %0|%0, %1}";
2021       else
2022         return "mov{q}\t{%1, %0|%0, %1}";
2023     }
2024 }
2025   [(set (attr "type")
2026      (cond [(eq_attr "alternative" "5,6,7")
2027               (const_string "mmxmov")
2028             (eq_attr "alternative" "8,9,10")
2029               (const_string "ssemov")
2030             (eq_attr "alternative" "11,12")
2031               (const_string "ssecvt")
2032             (eq_attr "alternative" "4")
2033               (const_string "multi")
2034             (and (ne (symbol_ref "flag_pic") (const_int 0))
2035                  (match_operand:DI 1 "symbolic_operand" ""))
2036               (const_string "lea")
2037            ]
2038            (const_string "imov")))
2039    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2040    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2041    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2042
2043 (define_insn "*movdi_1_rex64_nointerunit"
2044   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2045         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2046   "TARGET_64BIT
2047    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2048    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2049 {
2050   switch (get_attr_type (insn))
2051     {
2052     case TYPE_SSEMOV:
2053       if (get_attr_mode (insn) == MODE_TI)
2054           return "movdqa\t{%1, %0|%0, %1}";
2055       /* FALLTHRU */
2056     case TYPE_MMXMOV:
2057       return "movq\t{%1, %0|%0, %1}";
2058     case TYPE_MULTI:
2059       return "#";
2060     case TYPE_LEA:
2061       return "lea{q}\t{%a1, %0|%0, %a1}";
2062     default:
2063       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2064         abort ();
2065       if (get_attr_mode (insn) == MODE_SI)
2066         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2067       else if (which_alternative == 2)
2068         return "movabs{q}\t{%1, %0|%0, %1}";
2069       else
2070         return "mov{q}\t{%1, %0|%0, %1}";
2071     }
2072 }
2073   [(set (attr "type")
2074      (cond [(eq_attr "alternative" "5,6,7")
2075               (const_string "mmxmov")
2076             (eq_attr "alternative" "8,9,10")
2077               (const_string "ssemov")
2078             (eq_attr "alternative" "4")
2079               (const_string "multi")
2080             (and (ne (symbol_ref "flag_pic") (const_int 0))
2081                  (match_operand:DI 1 "symbolic_operand" ""))
2082               (const_string "lea")
2083            ]
2084            (const_string "imov")))
2085    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2086    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2087    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2088
2089 ;; Stores and loads of ax to arbitrary constant address.
2090 ;; We fake an second form of instruction to force reload to load address
2091 ;; into register when rax is not available
2092 (define_insn "*movabsdi_1_rex64"
2093   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2094         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2095   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2096   "@
2097    movabs{q}\t{%1, %P0|%P0, %1}
2098    mov{q}\t{%1, %a0|%a0, %1}"
2099   [(set_attr "type" "imov")
2100    (set_attr "modrm" "0,*")
2101    (set_attr "length_address" "8,0")
2102    (set_attr "length_immediate" "0,*")
2103    (set_attr "memory" "store")
2104    (set_attr "mode" "DI")])
2105
2106 (define_insn "*movabsdi_2_rex64"
2107   [(set (match_operand:DI 0 "register_operand" "=a,r")
2108         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2109   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2110   "@
2111    movabs{q}\t{%P1, %0|%0, %P1}
2112    mov{q}\t{%a1, %0|%0, %a1}"
2113   [(set_attr "type" "imov")
2114    (set_attr "modrm" "0,*")
2115    (set_attr "length_address" "8,0")
2116    (set_attr "length_immediate" "0")
2117    (set_attr "memory" "load")
2118    (set_attr "mode" "DI")])
2119
2120 ;; Convert impossible stores of immediate to existing instructions.
2121 ;; First try to get scratch register and go through it.  In case this
2122 ;; fails, move by 32bit parts.
2123 (define_peephole2
2124   [(match_scratch:DI 2 "r")
2125    (set (match_operand:DI 0 "memory_operand" "")
2126         (match_operand:DI 1 "immediate_operand" ""))]
2127   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 1))
2130    (set (match_dup 0) (match_dup 2))]
2131   "")
2132
2133 ;; We need to define this as both peepholer and splitter for case
2134 ;; peephole2 pass is not run.
2135 (define_peephole2
2136   [(set (match_operand:DI 0 "memory_operand" "")
2137         (match_operand:DI 1 "immediate_operand" ""))]
2138   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2139    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2140   [(set (match_dup 2) (match_dup 3))
2141    (set (match_dup 4) (match_dup 5))]
2142   "split_di (operands, 2, operands + 2, operands + 4);")
2143
2144 (define_split
2145   [(set (match_operand:DI 0 "memory_operand" "")
2146         (match_operand:DI 1 "immediate_operand" ""))]
2147   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2148    && !symbolic_operand (operands[1], DImode)
2149    && !x86_64_immediate_operand (operands[1], DImode)"
2150   [(set (match_dup 2) (match_dup 3))
2151    (set (match_dup 4) (match_dup 5))]
2152   "split_di (operands, 2, operands + 2, operands + 4);")
2153
2154 (define_insn "*swapdi_rex64"
2155   [(set (match_operand:DI 0 "register_operand" "+r")
2156         (match_operand:DI 1 "register_operand" "+r"))
2157    (set (match_dup 1)
2158         (match_dup 0))]
2159   "TARGET_64BIT"
2160   "xchg{q}\t%1, %0"
2161   [(set_attr "type" "imov")
2162    (set_attr "pent_pair" "np")
2163    (set_attr "athlon_decode" "vector")
2164    (set_attr "mode" "DI")
2165    (set_attr "modrm" "0")])
2166
2167   
2168 (define_expand "movsf"
2169   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2170         (match_operand:SF 1 "general_operand" ""))]
2171   ""
2172   "ix86_expand_move (SFmode, operands); DONE;")
2173
2174 (define_insn "*pushsf"
2175   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2176         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2177   "!TARGET_64BIT"
2178 {
2179   switch (which_alternative)
2180     {
2181     case 1:
2182       return "push{l}\t%1";
2183
2184     default:
2185       /* This insn should be already split before reg-stack.  */
2186       abort ();
2187     }
2188 }
2189   [(set_attr "type" "multi,push,multi")
2190    (set_attr "mode" "SF,SI,SF")])
2191
2192 (define_insn "*pushsf_rex64"
2193   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2194         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2195   "TARGET_64BIT"
2196 {
2197   switch (which_alternative)
2198     {
2199     case 1:
2200       return "push{q}\t%q1";
2201
2202     default:
2203       /* This insn should be already split before reg-stack.  */
2204       abort ();
2205     }
2206 }
2207   [(set_attr "type" "multi,push,multi")
2208    (set_attr "mode" "SF,DI,SF")])
2209
2210 (define_split
2211   [(set (match_operand:SF 0 "push_operand" "")
2212         (match_operand:SF 1 "memory_operand" ""))]
2213   "reload_completed
2214    && GET_CODE (operands[1]) == MEM
2215    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2216    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2217   [(set (match_dup 0)
2218         (match_dup 1))]
2219   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2220
2221
2222 ;; %%% Kill this when call knows how to work this out.
2223 (define_split
2224   [(set (match_operand:SF 0 "push_operand" "")
2225         (match_operand:SF 1 "any_fp_register_operand" ""))]
2226   "!TARGET_64BIT"
2227   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2228    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2229
2230 (define_split
2231   [(set (match_operand:SF 0 "push_operand" "")
2232         (match_operand:SF 1 "any_fp_register_operand" ""))]
2233   "TARGET_64BIT"
2234   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2235    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2236
2237 (define_insn "*movsf_1"
2238   [(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")
2239         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2240   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2241    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2242    && (reload_in_progress || reload_completed
2243        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2244        || GET_CODE (operands[1]) != CONST_DOUBLE
2245        || memory_operand (operands[0], SFmode))" 
2246 {
2247   switch (which_alternative)
2248     {
2249     case 0:
2250       return output_387_reg_move (insn, operands);
2251
2252     case 1:
2253       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2254         return "fstp%z0\t%y0";
2255       else
2256         return "fst%z0\t%y0";
2257
2258     case 2:
2259       return standard_80387_constant_opcode (operands[1]);
2260
2261     case 3:
2262     case 4:
2263       return "mov{l}\t{%1, %0|%0, %1}";
2264     case 5:
2265       if (get_attr_mode (insn) == MODE_TI)
2266         return "pxor\t%0, %0";
2267       else
2268         return "xorps\t%0, %0";
2269     case 6:
2270       if (get_attr_mode (insn) == MODE_V4SF)
2271         return "movaps\t{%1, %0|%0, %1}";
2272       else
2273         return "movss\t{%1, %0|%0, %1}";
2274     case 7:
2275     case 8:
2276       return "movss\t{%1, %0|%0, %1}";
2277
2278     case 9:
2279     case 10:
2280       return "movd\t{%1, %0|%0, %1}";
2281
2282     case 11:
2283       return "movq\t{%1, %0|%0, %1}";
2284
2285     default:
2286       abort();
2287     }
2288 }
2289   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2290    (set (attr "mode")
2291         (cond [(eq_attr "alternative" "3,4,9,10")
2292                  (const_string "SI")
2293                (eq_attr "alternative" "5")
2294                  (if_then_else
2295                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2296                                  (const_int 0))
2297                              (ne (symbol_ref "TARGET_SSE2")
2298                                  (const_int 0)))
2299                         (eq (symbol_ref "optimize_size")
2300                             (const_int 0)))
2301                    (const_string "TI")
2302                    (const_string "V4SF"))
2303                /* For architectures resolving dependencies on
2304                   whole SSE registers use APS move to break dependency
2305                   chains, otherwise use short move to avoid extra work. 
2306
2307                   Do the same for architectures resolving dependencies on
2308                   the parts.  While in DF mode it is better to always handle
2309                   just register parts, the SF mode is different due to lack
2310                   of instructions to load just part of the register.  It is
2311                   better to maintain the whole registers in single format
2312                   to avoid problems on using packed logical operations.  */
2313                (eq_attr "alternative" "6")
2314                  (if_then_else
2315                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2316                             (const_int 0))
2317                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2318                             (const_int 0)))
2319                    (const_string "V4SF")
2320                    (const_string "SF"))
2321                (eq_attr "alternative" "11")
2322                  (const_string "DI")]
2323                (const_string "SF")))])
2324
2325 (define_insn "*movsf_1_nointerunit"
2326   [(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")
2327         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2328   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2329    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2330    && (reload_in_progress || reload_completed
2331        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2332        || GET_CODE (operands[1]) != CONST_DOUBLE
2333        || memory_operand (operands[0], SFmode))" 
2334 {
2335   switch (which_alternative)
2336     {
2337     case 0:
2338       return output_387_reg_move (insn, operands);
2339
2340     case 1:
2341       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2342         return "fstp%z0\t%y0";
2343       else
2344         return "fst%z0\t%y0";
2345
2346     case 2:
2347       return standard_80387_constant_opcode (operands[1]);
2348
2349     case 3:
2350     case 4:
2351       return "mov{l}\t{%1, %0|%0, %1}";
2352     case 5:
2353       if (get_attr_mode (insn) == MODE_TI)
2354         return "pxor\t%0, %0";
2355       else
2356         return "xorps\t%0, %0";
2357     case 6:
2358       if (get_attr_mode (insn) == MODE_V4SF)
2359         return "movaps\t{%1, %0|%0, %1}";
2360       else
2361         return "movss\t{%1, %0|%0, %1}";
2362     case 7:
2363     case 8:
2364       return "movss\t{%1, %0|%0, %1}";
2365
2366     case 9:
2367     case 10:
2368       return "movd\t{%1, %0|%0, %1}";
2369
2370     case 11:
2371       return "movq\t{%1, %0|%0, %1}";
2372
2373     default:
2374       abort();
2375     }
2376 }
2377   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2378    (set (attr "mode")
2379         (cond [(eq_attr "alternative" "3,4,9,10")
2380                  (const_string "SI")
2381                (eq_attr "alternative" "5")
2382                  (if_then_else
2383                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2384                                  (const_int 0))
2385                              (ne (symbol_ref "TARGET_SSE2")
2386                                  (const_int 0)))
2387                         (eq (symbol_ref "optimize_size")
2388                             (const_int 0)))
2389                    (const_string "TI")
2390                    (const_string "V4SF"))
2391                /* For architectures resolving dependencies on
2392                   whole SSE registers use APS move to break dependency
2393                   chains, otherwise use short move to avoid extra work. 
2394
2395                   Do the same for architectures resolving dependencies on
2396                   the parts.  While in DF mode it is better to always handle
2397                   just register parts, the SF mode is different due to lack
2398                   of instructions to load just part of the register.  It is
2399                   better to maintain the whole registers in single format
2400                   to avoid problems on using packed logical operations.  */
2401                (eq_attr "alternative" "6")
2402                  (if_then_else
2403                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2404                             (const_int 0))
2405                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2406                             (const_int 0)))
2407                    (const_string "V4SF")
2408                    (const_string "SF"))
2409                (eq_attr "alternative" "11")
2410                  (const_string "DI")]
2411                (const_string "SF")))])
2412
2413 (define_insn "*swapsf"
2414   [(set (match_operand:SF 0 "register_operand" "+f")
2415         (match_operand:SF 1 "register_operand" "+f"))
2416    (set (match_dup 1)
2417         (match_dup 0))]
2418   "reload_completed || !TARGET_SSE"
2419 {
2420   if (STACK_TOP_P (operands[0]))
2421     return "fxch\t%1";
2422   else
2423     return "fxch\t%0";
2424 }
2425   [(set_attr "type" "fxch")
2426    (set_attr "mode" "SF")])
2427
2428 (define_expand "movdf"
2429   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2430         (match_operand:DF 1 "general_operand" ""))]
2431   ""
2432   "ix86_expand_move (DFmode, operands); DONE;")
2433
2434 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2435 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2436 ;; On the average, pushdf using integers can be still shorter.  Allow this
2437 ;; pattern for optimize_size too.
2438
2439 (define_insn "*pushdf_nointeger"
2440   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2441         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2442   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2443 {
2444   /* This insn should be already split before reg-stack.  */
2445   abort ();
2446 }
2447   [(set_attr "type" "multi")
2448    (set_attr "mode" "DF,SI,SI,DF")])
2449
2450 (define_insn "*pushdf_integer"
2451   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2452         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2453   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2454 {
2455   /* This insn should be already split before reg-stack.  */
2456   abort ();
2457 }
2458   [(set_attr "type" "multi")
2459    (set_attr "mode" "DF,SI,DF")])
2460
2461 ;; %%% Kill this when call knows how to work this out.
2462 (define_split
2463   [(set (match_operand:DF 0 "push_operand" "")
2464         (match_operand:DF 1 "any_fp_register_operand" ""))]
2465   "!TARGET_64BIT && reload_completed"
2466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2467    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2468   "")
2469
2470 (define_split
2471   [(set (match_operand:DF 0 "push_operand" "")
2472         (match_operand:DF 1 "any_fp_register_operand" ""))]
2473   "TARGET_64BIT && reload_completed"
2474   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2475    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2476   "")
2477
2478 (define_split
2479   [(set (match_operand:DF 0 "push_operand" "")
2480         (match_operand:DF 1 "general_operand" ""))]
2481   "reload_completed"
2482   [(const_int 0)]
2483   "ix86_split_long_move (operands); DONE;")
2484
2485 ;; Moving is usually shorter when only FP registers are used. This separate
2486 ;; movdf pattern avoids the use of integer registers for FP operations
2487 ;; when optimizing for size.
2488
2489 (define_insn "*movdf_nointeger"
2490   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2491         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2492   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2493    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2494    && (reload_in_progress || reload_completed
2495        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2496        || GET_CODE (operands[1]) != CONST_DOUBLE
2497        || memory_operand (operands[0], DFmode))" 
2498 {
2499   switch (which_alternative)
2500     {
2501     case 0:
2502       return output_387_reg_move (insn, operands);
2503
2504     case 1:
2505       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2506         return "fstp%z0\t%y0";
2507       else
2508         return "fst%z0\t%y0";
2509
2510     case 2:
2511       return standard_80387_constant_opcode (operands[1]);
2512
2513     case 3:
2514     case 4:
2515       return "#";
2516     case 5:
2517       switch (get_attr_mode (insn))
2518         {
2519         case MODE_V4SF:
2520           return "xorps\t%0, %0";
2521         case MODE_V2DF:
2522           return "xorpd\t%0, %0";
2523         case MODE_TI:
2524           return "pxor\t%0, %0";
2525         default:
2526           abort ();
2527         }
2528     case 6:
2529       switch (get_attr_mode (insn))
2530         {
2531         case MODE_V4SF:
2532           return "movaps\t{%1, %0|%0, %1}";
2533         case MODE_V2DF:
2534           return "movapd\t{%1, %0|%0, %1}";
2535         case MODE_DF:
2536           return "movsd\t{%1, %0|%0, %1}";
2537         default:
2538           abort ();
2539         }
2540     case 7:
2541       if (get_attr_mode (insn) == MODE_V2DF)
2542         return "movlpd\t{%1, %0|%0, %1}";
2543       else
2544         return "movsd\t{%1, %0|%0, %1}";
2545     case 8:
2546       return "movsd\t{%1, %0|%0, %1}";
2547
2548     default:
2549       abort();
2550     }
2551 }
2552   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2553    (set (attr "mode")
2554         (cond [(eq_attr "alternative" "3,4")
2555                  (const_string "SI")
2556                /* xorps is one byte shorter.  */
2557                (eq_attr "alternative" "5")
2558                  (cond [(ne (symbol_ref "optimize_size")
2559                             (const_int 0))
2560                           (const_string "V4SF")
2561                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2562                             (const_int 0))
2563                           (const_string "TI")]
2564                        (const_string "V2DF"))
2565                /* For architectures resolving dependencies on
2566                   whole SSE registers use APD move to break dependency
2567                   chains, otherwise use short move to avoid extra work.
2568
2569                   movaps encodes one byte shorter.  */
2570                (eq_attr "alternative" "6")
2571                  (cond
2572                   [(ne (symbol_ref "optimize_size")
2573                        (const_int 0))
2574                      (const_string "V4SF")
2575                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2576                        (const_int 0))
2577                      (const_string "V2DF")]
2578                    (const_string "DF"))
2579                /* For architectures resolving dependencies on register
2580                   parts we may avoid extra work to zero out upper part
2581                   of register.  */
2582                (eq_attr "alternative" "7")
2583                  (if_then_else
2584                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2585                        (const_int 0))
2586                    (const_string "V2DF")
2587                    (const_string "DF"))]
2588                (const_string "DF")))])
2589
2590 (define_insn "*movdf_integer"
2591   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2592         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2593   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2594    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2595    && (reload_in_progress || reload_completed
2596        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2597        || GET_CODE (operands[1]) != CONST_DOUBLE
2598        || memory_operand (operands[0], DFmode))" 
2599 {
2600   switch (which_alternative)
2601     {
2602     case 0:
2603       return output_387_reg_move (insn, operands);
2604
2605     case 1:
2606       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2607         return "fstp%z0\t%y0";
2608       else
2609         return "fst%z0\t%y0";
2610
2611     case 2:
2612       return standard_80387_constant_opcode (operands[1]);
2613
2614     case 3:
2615     case 4:
2616       return "#";
2617
2618     case 5:
2619       switch (get_attr_mode (insn))
2620         {
2621         case MODE_V4SF:
2622           return "xorps\t%0, %0";
2623         case MODE_V2DF:
2624           return "xorpd\t%0, %0";
2625         case MODE_TI:
2626           return "pxor\t%0, %0";
2627         default:
2628           abort ();
2629         }
2630     case 6:
2631       switch (get_attr_mode (insn))
2632         {
2633         case MODE_V4SF:
2634           return "movaps\t{%1, %0|%0, %1}";
2635         case MODE_V2DF:
2636           return "movapd\t{%1, %0|%0, %1}";
2637         case MODE_DF:
2638           return "movsd\t{%1, %0|%0, %1}";
2639         default:
2640           abort ();
2641         }
2642     case 7:
2643       if (get_attr_mode (insn) == MODE_V2DF)
2644         return "movlpd\t{%1, %0|%0, %1}";
2645       else
2646         return "movsd\t{%1, %0|%0, %1}";
2647     case 8:
2648       return "movsd\t{%1, %0|%0, %1}";
2649
2650     default:
2651       abort();
2652     }
2653 }
2654   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2655    (set (attr "mode")
2656         (cond [(eq_attr "alternative" "3,4")
2657                  (const_string "SI")
2658                /* xorps is one byte shorter.  */
2659                (eq_attr "alternative" "5")
2660                  (cond [(ne (symbol_ref "optimize_size")
2661                             (const_int 0))
2662                           (const_string "V4SF")
2663                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2664                             (const_int 0))
2665                           (const_string "TI")]
2666                        (const_string "V2DF"))
2667                /* For architectures resolving dependencies on
2668                   whole SSE registers use APD move to break dependency
2669                   chains, otherwise use short move to avoid extra work.  
2670
2671                   movaps encodes one byte shorter.  */
2672                (eq_attr "alternative" "6")
2673                  (cond
2674                   [(ne (symbol_ref "optimize_size")
2675                        (const_int 0))
2676                      (const_string "V4SF")
2677                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2678                        (const_int 0))
2679                      (const_string "V2DF")]
2680                    (const_string "DF"))
2681                /* For architectures resolving dependencies on register
2682                   parts we may avoid extra work to zero out upper part
2683                   of register.  */
2684                (eq_attr "alternative" "7")
2685                  (if_then_else
2686                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2687                        (const_int 0))
2688                    (const_string "V2DF")
2689                    (const_string "DF"))]
2690                (const_string "DF")))])
2691
2692 (define_split
2693   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2694         (match_operand:DF 1 "general_operand" ""))]
2695   "reload_completed
2696    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2697    && ! (ANY_FP_REG_P (operands[0]) || 
2698          (GET_CODE (operands[0]) == SUBREG
2699           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2700    && ! (ANY_FP_REG_P (operands[1]) || 
2701          (GET_CODE (operands[1]) == SUBREG
2702           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2703   [(const_int 0)]
2704   "ix86_split_long_move (operands); DONE;")
2705
2706 (define_insn "*swapdf"
2707   [(set (match_operand:DF 0 "register_operand" "+f")
2708         (match_operand:DF 1 "register_operand" "+f"))
2709    (set (match_dup 1)
2710         (match_dup 0))]
2711   "reload_completed || !TARGET_SSE2"
2712 {
2713   if (STACK_TOP_P (operands[0]))
2714     return "fxch\t%1";
2715   else
2716     return "fxch\t%0";
2717 }
2718   [(set_attr "type" "fxch")
2719    (set_attr "mode" "DF")])
2720
2721 (define_expand "movxf"
2722   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2723         (match_operand:XF 1 "general_operand" ""))]
2724   ""
2725   "ix86_expand_move (XFmode, operands); DONE;")
2726
2727 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2728 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2729 ;; Pushing using integer instructions is longer except for constants
2730 ;; and direct memory references.
2731 ;; (assuming that any given constant is pushed only once, but this ought to be
2732 ;;  handled elsewhere).
2733
2734 (define_insn "*pushxf_nointeger"
2735   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2736         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2737   "optimize_size"
2738 {
2739   /* This insn should be already split before reg-stack.  */
2740   abort ();
2741 }
2742   [(set_attr "type" "multi")
2743    (set_attr "mode" "XF,SI,SI")])
2744
2745 (define_insn "*pushxf_integer"
2746   [(set (match_operand:XF 0 "push_operand" "=<,<")
2747         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2748   "!optimize_size"
2749 {
2750   /* This insn should be already split before reg-stack.  */
2751   abort ();
2752 }
2753   [(set_attr "type" "multi")
2754    (set_attr "mode" "XF,SI")])
2755
2756 (define_split
2757   [(set (match_operand 0 "push_operand" "")
2758         (match_operand 1 "general_operand" ""))]
2759   "reload_completed
2760    && (GET_MODE (operands[0]) == XFmode
2761        || GET_MODE (operands[0]) == DFmode)
2762    && !ANY_FP_REG_P (operands[1])"
2763   [(const_int 0)]
2764   "ix86_split_long_move (operands); DONE;")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "!TARGET_64BIT"
2770   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 (define_split
2775   [(set (match_operand:XF 0 "push_operand" "")
2776         (match_operand:XF 1 "any_fp_register_operand" ""))]
2777   "TARGET_64BIT"
2778   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2779    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2780   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2781
2782 ;; Do not use integer registers when optimizing for size
2783 (define_insn "*movxf_nointeger"
2784   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2785         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2786   "optimize_size
2787    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2788    && (reload_in_progress || reload_completed
2789        || GET_CODE (operands[1]) != CONST_DOUBLE
2790        || memory_operand (operands[0], XFmode))" 
2791 {
2792   switch (which_alternative)
2793     {
2794     case 0:
2795       return output_387_reg_move (insn, operands);
2796
2797     case 1:
2798       /* There is no non-popping store to memory for XFmode.  So if
2799          we need one, follow the store with a load.  */
2800       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2801         return "fstp%z0\t%y0\;fld%z0\t%y0";
2802       else
2803         return "fstp%z0\t%y0";
2804
2805     case 2:
2806       return standard_80387_constant_opcode (operands[1]);
2807
2808     case 3: case 4:
2809       return "#";
2810     }
2811   abort();
2812 }
2813   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814    (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816 (define_insn "*movxf_integer"
2817   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2818         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2819   "!optimize_size
2820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821    && (reload_in_progress || reload_completed
2822        || GET_CODE (operands[1]) != CONST_DOUBLE
2823        || memory_operand (operands[0], XFmode))" 
2824 {
2825   switch (which_alternative)
2826     {
2827     case 0:
2828       return output_387_reg_move (insn, operands);
2829
2830     case 1:
2831       /* There is no non-popping store to memory for XFmode.  So if
2832          we need one, follow the store with a load.  */
2833       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834         return "fstp%z0\t%y0\;fld%z0\t%y0";
2835       else
2836         return "fstp%z0\t%y0";
2837
2838     case 2:
2839       return standard_80387_constant_opcode (operands[1]);
2840
2841     case 3: case 4:
2842       return "#";
2843     }
2844   abort();
2845 }
2846   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2847    (set_attr "mode" "XF,XF,XF,SI,SI")])
2848
2849 (define_split
2850   [(set (match_operand 0 "nonimmediate_operand" "")
2851         (match_operand 1 "general_operand" ""))]
2852   "reload_completed
2853    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854    && GET_MODE (operands[0]) == XFmode
2855    && ! (ANY_FP_REG_P (operands[0]) || 
2856          (GET_CODE (operands[0]) == SUBREG
2857           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2858    && ! (ANY_FP_REG_P (operands[1]) || 
2859          (GET_CODE (operands[1]) == SUBREG
2860           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2861   [(const_int 0)]
2862   "ix86_split_long_move (operands); DONE;")
2863
2864 (define_split
2865   [(set (match_operand 0 "register_operand" "")
2866         (match_operand 1 "memory_operand" ""))]
2867   "reload_completed
2868    && GET_CODE (operands[1]) == MEM
2869    && (GET_MODE (operands[0]) == XFmode
2870        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2871    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2872    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2873   [(set (match_dup 0) (match_dup 1))]
2874 {
2875   rtx c = get_pool_constant (XEXP (operands[1], 0));
2876   rtx r = operands[0];
2877
2878   if (GET_CODE (r) == SUBREG)
2879     r = SUBREG_REG (r);
2880
2881   if (SSE_REG_P (r))
2882     {
2883       if (!standard_sse_constant_p (c))
2884         FAIL;
2885     }
2886   else if (FP_REG_P (r))
2887     {
2888       if (!standard_80387_constant_p (c))
2889         FAIL;
2890     }
2891   else if (MMX_REG_P (r))
2892     FAIL;
2893
2894   operands[1] = c;
2895 })
2896
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   ""
2903 {
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2908 }
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2911 \f
2912 ;; Zero extension instructions
2913
2914 (define_expand "zero_extendhisi2"
2915   [(set (match_operand:SI 0 "register_operand" "")
2916      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2917   ""
2918 {
2919   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2920     {
2921       operands[1] = force_reg (HImode, operands[1]);
2922       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2923       DONE;
2924     }
2925 })
2926
2927 (define_insn "zero_extendhisi2_and"
2928   [(set (match_operand:SI 0 "register_operand" "=r")
2929      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2930    (clobber (reg:CC FLAGS_REG))]
2931   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2932   "#"
2933   [(set_attr "type" "alu1")
2934    (set_attr "mode" "SI")])
2935
2936 (define_split
2937   [(set (match_operand:SI 0 "register_operand" "")
2938         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2939    (clobber (reg:CC FLAGS_REG))]
2940   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2941   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2942               (clobber (reg:CC FLAGS_REG))])]
2943   "")
2944
2945 (define_insn "*zero_extendhisi2_movzwl"
2946   [(set (match_operand:SI 0 "register_operand" "=r")
2947      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2948   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2949   "movz{wl|x}\t{%1, %0|%0, %1}"
2950   [(set_attr "type" "imovx")
2951    (set_attr "mode" "SI")])
2952
2953 (define_expand "zero_extendqihi2"
2954   [(parallel
2955     [(set (match_operand:HI 0 "register_operand" "")
2956        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2957      (clobber (reg:CC FLAGS_REG))])]
2958   ""
2959   "")
2960
2961 (define_insn "*zero_extendqihi2_and"
2962   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2963      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2964    (clobber (reg:CC FLAGS_REG))]
2965   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2966   "#"
2967   [(set_attr "type" "alu1")
2968    (set_attr "mode" "HI")])
2969
2970 (define_insn "*zero_extendqihi2_movzbw_and"
2971   [(set (match_operand:HI 0 "register_operand" "=r,r")
2972      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2973    (clobber (reg:CC FLAGS_REG))]
2974   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2975   "#"
2976   [(set_attr "type" "imovx,alu1")
2977    (set_attr "mode" "HI")])
2978
2979 (define_insn "*zero_extendqihi2_movzbw"
2980   [(set (match_operand:HI 0 "register_operand" "=r")
2981      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2982   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2983   "movz{bw|x}\t{%1, %0|%0, %1}"
2984   [(set_attr "type" "imovx")
2985    (set_attr "mode" "HI")])
2986
2987 ;; For the movzbw case strip only the clobber
2988 (define_split
2989   [(set (match_operand:HI 0 "register_operand" "")
2990         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "reload_completed 
2993    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2994    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2995   [(set (match_operand:HI 0 "register_operand" "")
2996         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2997
2998 ;; When source and destination does not overlap, clear destination
2999 ;; first and then do the movb
3000 (define_split
3001   [(set (match_operand:HI 0 "register_operand" "")
3002         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3003    (clobber (reg:CC FLAGS_REG))]
3004   "reload_completed
3005    && ANY_QI_REG_P (operands[0])
3006    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3007    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3008   [(set (match_dup 0) (const_int 0))
3009    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3010   "operands[2] = gen_lowpart (QImode, operands[0]);")
3011
3012 ;; Rest is handled by single and.
3013 (define_split
3014   [(set (match_operand:HI 0 "register_operand" "")
3015         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "reload_completed
3018    && true_regnum (operands[0]) == true_regnum (operands[1])"
3019   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3020               (clobber (reg:CC FLAGS_REG))])]
3021   "")
3022
3023 (define_expand "zero_extendqisi2"
3024   [(parallel
3025     [(set (match_operand:SI 0 "register_operand" "")
3026        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3027      (clobber (reg:CC FLAGS_REG))])]
3028   ""
3029   "")
3030
3031 (define_insn "*zero_extendqisi2_and"
3032   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3033      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3036   "#"
3037   [(set_attr "type" "alu1")
3038    (set_attr "mode" "SI")])
3039
3040 (define_insn "*zero_extendqisi2_movzbw_and"
3041   [(set (match_operand:SI 0 "register_operand" "=r,r")
3042      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3045   "#"
3046   [(set_attr "type" "imovx,alu1")
3047    (set_attr "mode" "SI")])
3048
3049 (define_insn "*zero_extendqisi2_movzbw"
3050   [(set (match_operand:SI 0 "register_operand" "=r")
3051      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3052   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3053   "movz{bl|x}\t{%1, %0|%0, %1}"
3054   [(set_attr "type" "imovx")
3055    (set_attr "mode" "SI")])
3056
3057 ;; For the movzbl case strip only the clobber
3058 (define_split
3059   [(set (match_operand:SI 0 "register_operand" "")
3060         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3061    (clobber (reg:CC FLAGS_REG))]
3062   "reload_completed 
3063    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3064    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3065   [(set (match_dup 0)
3066         (zero_extend:SI (match_dup 1)))])
3067
3068 ;; When source and destination does not overlap, clear destination
3069 ;; first and then do the movb
3070 (define_split
3071   [(set (match_operand:SI 0 "register_operand" "")
3072         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && ANY_QI_REG_P (operands[0])
3076    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3077    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3078    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3079   [(set (match_dup 0) (const_int 0))
3080    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3081   "operands[2] = gen_lowpart (QImode, operands[0]);")
3082
3083 ;; Rest is handled by single and.
3084 (define_split
3085   [(set (match_operand:SI 0 "register_operand" "")
3086         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "reload_completed
3089    && true_regnum (operands[0]) == true_regnum (operands[1])"
3090   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3091               (clobber (reg:CC FLAGS_REG))])]
3092   "")
3093
3094 ;; %%% Kill me once multi-word ops are sane.
3095 (define_expand "zero_extendsidi2"
3096   [(set (match_operand:DI 0 "register_operand" "=r")
3097      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3098   ""
3099   "if (!TARGET_64BIT)
3100      {
3101        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3102        DONE;
3103      }
3104   ")
3105
3106 (define_insn "zero_extendsidi2_32"
3107   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3108         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3109    (clobber (reg:CC FLAGS_REG))]
3110   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3111   "@
3112    #
3113    #
3114    #
3115    movd\t{%1, %0|%0, %1}
3116    movd\t{%1, %0|%0, %1}"
3117   [(set_attr "mode" "SI,SI,SI,DI,TI")
3118    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3119
3120 (define_insn "*zero_extendsidi2_32_1"
3121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3122         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3125   "@
3126    #
3127    #
3128    #
3129    movd\t{%1, %0|%0, %1}
3130    movd\t{%1, %0|%0, %1}"
3131   [(set_attr "mode" "SI,SI,SI,DI,TI")
3132    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3133
3134 (define_insn "zero_extendsidi2_rex64"
3135   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3136      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3137   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3138   "@
3139    mov\t{%k1, %k0|%k0, %k1}
3140    #
3141    movd\t{%1, %0|%0, %1}
3142    movd\t{%1, %0|%0, %1}"
3143   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3144    (set_attr "mode" "SI,DI,DI,TI")])
3145
3146 (define_insn "*zero_extendsidi2_rex64_1"
3147   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3148      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3149   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3150   "@
3151    mov\t{%k1, %k0|%k0, %k1}
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3156    (set_attr "mode" "SI,DI,SI,SI")])
3157
3158 (define_split
3159   [(set (match_operand:DI 0 "memory_operand" "")
3160      (zero_extend:DI (match_dup 0)))]
3161   "TARGET_64BIT"
3162   [(set (match_dup 4) (const_int 0))]
3163   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3164
3165 (define_split 
3166   [(set (match_operand:DI 0 "register_operand" "")
3167         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3168    (clobber (reg:CC FLAGS_REG))]
3169   "!TARGET_64BIT && reload_completed
3170    && true_regnum (operands[0]) == true_regnum (operands[1])"
3171   [(set (match_dup 4) (const_int 0))]
3172   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3173
3174 (define_split 
3175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3176         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3177    (clobber (reg:CC FLAGS_REG))]
3178   "!TARGET_64BIT && reload_completed
3179    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3180   [(set (match_dup 3) (match_dup 1))
3181    (set (match_dup 4) (const_int 0))]
3182   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3183
3184 (define_insn "zero_extendhidi2"
3185   [(set (match_operand:DI 0 "register_operand" "=r,r")
3186      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3187   "TARGET_64BIT"
3188   "@
3189    movz{wl|x}\t{%1, %k0|%k0, %1}
3190    movz{wq|x}\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx")
3192    (set_attr "mode" "SI,DI")])
3193
3194 (define_insn "zero_extendqidi2"
3195   [(set (match_operand:DI 0 "register_operand" "=r,r")
3196      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3197   "TARGET_64BIT"
3198   "@
3199    movz{bl|x}\t{%1, %k0|%k0, %1}
3200    movz{bq|x}\t{%1, %0|%0, %1}"
3201   [(set_attr "type" "imovx")
3202    (set_attr "mode" "SI,DI")])
3203 \f
3204 ;; Sign extension instructions
3205
3206 (define_expand "extendsidi2"
3207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3208                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3209               (clobber (reg:CC FLAGS_REG))
3210               (clobber (match_scratch:SI 2 ""))])]
3211   ""
3212 {
3213   if (TARGET_64BIT)
3214     {
3215       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3216       DONE;
3217     }
3218 })
3219
3220 (define_insn "*extendsidi2_1"
3221   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3222         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3223    (clobber (reg:CC FLAGS_REG))
3224    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3225   "!TARGET_64BIT"
3226   "#")
3227
3228 (define_insn "extendsidi2_rex64"
3229   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3230         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3231   "TARGET_64BIT"
3232   "@
3233    {cltq|cdqe}
3234    movs{lq|x}\t{%1,%0|%0, %1}"
3235   [(set_attr "type" "imovx")
3236    (set_attr "mode" "DI")
3237    (set_attr "prefix_0f" "0")
3238    (set_attr "modrm" "0,1")])
3239
3240 (define_insn "extendhidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "TARGET_64BIT"
3244   "movs{wq|x}\t{%1,%0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "DI")])
3247
3248 (define_insn "extendqidi2"
3249   [(set (match_operand:DI 0 "register_operand" "=r")
3250         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3251   "TARGET_64BIT"
3252   "movs{bq|x}\t{%1,%0|%0, %1}"
3253    [(set_attr "type" "imovx")
3254     (set_attr "mode" "DI")])
3255
3256 ;; Extend to memory case when source register does die.
3257 (define_split 
3258   [(set (match_operand:DI 0 "memory_operand" "")
3259         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260    (clobber (reg:CC FLAGS_REG))
3261    (clobber (match_operand:SI 2 "register_operand" ""))]
3262   "(reload_completed
3263     && dead_or_set_p (insn, operands[1])
3264     && !reg_mentioned_p (operands[1], operands[0]))"
3265   [(set (match_dup 3) (match_dup 1))
3266    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3267               (clobber (reg:CC FLAGS_REG))])
3268    (set (match_dup 4) (match_dup 1))]
3269   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3270
3271 ;; Extend to memory case when source register does not die.
3272 (define_split 
3273   [(set (match_operand:DI 0 "memory_operand" "")
3274         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3275    (clobber (reg:CC FLAGS_REG))
3276    (clobber (match_operand:SI 2 "register_operand" ""))]
3277   "reload_completed"
3278   [(const_int 0)]
3279 {
3280   split_di (&operands[0], 1, &operands[3], &operands[4]);
3281
3282   emit_move_insn (operands[3], operands[1]);
3283
3284   /* Generate a cltd if possible and doing so it profitable.  */
3285   if (true_regnum (operands[1]) == 0
3286       && true_regnum (operands[2]) == 1
3287       && (optimize_size || TARGET_USE_CLTD))
3288     {
3289       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3290     }
3291   else
3292     {
3293       emit_move_insn (operands[2], operands[1]);
3294       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3295     }
3296   emit_move_insn (operands[4], operands[2]);
3297   DONE;
3298 })
3299
3300 ;; Extend to register case.  Optimize case where source and destination
3301 ;; registers match and cases where we can use cltd.
3302 (define_split 
3303   [(set (match_operand:DI 0 "register_operand" "")
3304         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305    (clobber (reg:CC FLAGS_REG))
3306    (clobber (match_scratch:SI 2 ""))]
3307   "reload_completed"
3308   [(const_int 0)]
3309 {
3310   split_di (&operands[0], 1, &operands[3], &operands[4]);
3311
3312   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3313     emit_move_insn (operands[3], operands[1]);
3314
3315   /* Generate a cltd if possible and doing so it profitable.  */
3316   if (true_regnum (operands[3]) == 0
3317       && (optimize_size || TARGET_USE_CLTD))
3318     {
3319       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3320       DONE;
3321     }
3322
3323   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3324     emit_move_insn (operands[4], operands[1]);
3325
3326   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3327   DONE;
3328 })
3329
3330 (define_insn "extendhisi2"
3331   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3332         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3333   ""
3334 {
3335   switch (get_attr_prefix_0f (insn))
3336     {
3337     case 0:
3338       return "{cwtl|cwde}";
3339     default:
3340       return "movs{wl|x}\t{%1,%0|%0, %1}";
3341     }
3342 }
3343   [(set_attr "type" "imovx")
3344    (set_attr "mode" "SI")
3345    (set (attr "prefix_0f")
3346      ;; movsx is short decodable while cwtl is vector decoded.
3347      (if_then_else (and (eq_attr "cpu" "!k6")
3348                         (eq_attr "alternative" "0"))
3349         (const_string "0")
3350         (const_string "1")))
3351    (set (attr "modrm")
3352      (if_then_else (eq_attr "prefix_0f" "0")
3353         (const_string "0")
3354         (const_string "1")))])
3355
3356 (define_insn "*extendhisi2_zext"
3357   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358         (zero_extend:DI
3359           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3360   "TARGET_64BIT"
3361 {
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3368     }
3369 }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3382
3383 (define_insn "extendqihi2"
3384   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3385         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3386   ""
3387 {
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cbtw|cbw}";
3392     default:
3393       return "movs{bw|x}\t{%1,%0|%0, %1}";
3394     }
3395 }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "HI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3408
3409 (define_insn "extendqisi2"
3410   [(set (match_operand:SI 0 "register_operand" "=r")
3411         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3412   ""
3413   "movs{bl|x}\t{%1,%0|%0, %1}"
3414    [(set_attr "type" "imovx")
3415     (set_attr "mode" "SI")])
3416
3417 (define_insn "*extendqisi2_zext"
3418   [(set (match_operand:DI 0 "register_operand" "=r")
3419         (zero_extend:DI
3420           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3421   "TARGET_64BIT"
3422   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3423    [(set_attr "type" "imovx")
3424     (set_attr "mode" "SI")])
3425 \f
3426 ;; Conversions between float and double.
3427
3428 ;; These are all no-ops in the model used for the 80387.  So just
3429 ;; emit moves.
3430
3431 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3432 (define_insn "*dummy_extendsfdf2"
3433   [(set (match_operand:DF 0 "push_operand" "=<")
3434         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3435   "0"
3436   "#")
3437
3438 (define_split
3439   [(set (match_operand:DF 0 "push_operand" "")
3440         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3441   "!TARGET_64BIT"
3442   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3443    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3444
3445 (define_split
3446   [(set (match_operand:DF 0 "push_operand" "")
3447         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "TARGET_64BIT"
3449   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3450    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3451
3452 (define_insn "*dummy_extendsfxf2"
3453   [(set (match_operand:XF 0 "push_operand" "=<")
3454         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3455   "0"
3456   "#")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   ""
3462   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3463    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469   "TARGET_64BIT"
3470   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   ""
3478   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3479    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485   "TARGET_64BIT"
3486   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3487    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_expand "extendsfdf2"
3491   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3493   "TARGET_80387 || TARGET_SSE2"
3494 {
3495   /* ??? Needed for compress_float_constant since all fp constants
3496      are LEGITIMATE_CONSTANT_P.  */
3497   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3498     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3499   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3500     operands[1] = force_reg (SFmode, operands[1]);
3501 })
3502
3503 (define_insn "*extendsfdf2_1"
3504   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3505         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3506   "(TARGET_80387 || TARGET_SSE2)
3507    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3508 {
3509   switch (which_alternative)
3510     {
3511     case 0:
3512       return output_387_reg_move (insn, operands);
3513
3514     case 1:
3515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3516         return "fstp%z0\t%y0";
3517       else
3518         return "fst%z0\t%y0";
3519
3520     case 2:
3521       return "cvtss2sd\t{%1, %0|%0, %1}";
3522
3523     default:
3524       abort ();
3525     }
3526 }
3527   [(set_attr "type" "fmov,fmov,ssecvt")
3528    (set_attr "mode" "SF,XF,DF")])
3529
3530 (define_insn "*extendsfdf2_1_sse_only"
3531   [(set (match_operand:DF 0 "register_operand" "=Y")
3532         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3533   "!TARGET_80387 && TARGET_SSE2
3534    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3535   "cvtss2sd\t{%1, %0|%0, %1}"
3536   [(set_attr "type" "ssecvt")
3537    (set_attr "mode" "DF")])
3538
3539 (define_expand "extendsfxf2"
3540   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3541         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3542   "TARGET_80387"
3543 {
3544   /* ??? Needed for compress_float_constant since all fp constants
3545      are LEGITIMATE_CONSTANT_P.  */
3546   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3547     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3549     operands[1] = force_reg (SFmode, operands[1]);
3550 })
3551
3552 (define_insn "*extendsfxf2_1"
3553   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3554         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3555   "TARGET_80387
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 {
3558   switch (which_alternative)
3559     {
3560     case 0:
3561       return output_387_reg_move (insn, operands);
3562
3563     case 1:
3564       /* There is no non-popping store to memory for XFmode.  So if
3565          we need one, follow the store with a load.  */
3566       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3567         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3568       else
3569         return "fstp%z0\t%y0";
3570
3571     default:
3572       abort ();
3573     }
3574 }
3575   [(set_attr "type" "fmov")
3576    (set_attr "mode" "SF,XF")])
3577
3578 (define_expand "extenddfxf2"
3579   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3580         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3581   "TARGET_80387"
3582 {
3583   /* ??? Needed for compress_float_constant since all fp constants
3584      are LEGITIMATE_CONSTANT_P.  */
3585   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3586     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3587   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3588     operands[1] = force_reg (DFmode, operands[1]);
3589 })
3590
3591 (define_insn "*extenddfxf2_1"
3592   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3593         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3594   "TARGET_80387
3595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3596 {
3597   switch (which_alternative)
3598     {
3599     case 0:
3600       return output_387_reg_move (insn, operands);
3601
3602     case 1:
3603       /* There is no non-popping store to memory for XFmode.  So if
3604          we need one, follow the store with a load.  */
3605       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3606         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3607       else
3608         return "fstp%z0\t%y0";
3609
3610     default:
3611       abort ();
3612     }
3613 }
3614   [(set_attr "type" "fmov")
3615    (set_attr "mode" "DF,XF")])
3616
3617 ;; %%% This seems bad bad news.
3618 ;; This cannot output into an f-reg because there is no way to be sure
3619 ;; of truncating in that case.  Otherwise this is just like a simple move
3620 ;; insn.  So we pretend we can output to a reg in order to get better
3621 ;; register preferencing, but we really use a stack slot.
3622
3623 (define_expand "truncdfsf2"
3624   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3625                    (float_truncate:SF
3626                     (match_operand:DF 1 "register_operand" "")))
3627               (clobber (match_dup 2))])]
3628   "TARGET_80387 || TARGET_SSE2"
3629   "
3630    if (!TARGET_80387)
3631      {
3632         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3633         DONE;
3634      }
3635    else if (flag_unsafe_math_optimizations)
3636      {
3637         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3638         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3639         if (reg != operands[0])
3640           emit_move_insn (operands[0], reg);
3641         DONE;
3642      }
3643    else
3644      operands[2] = assign_386_stack_local (SFmode, 0);
3645 ")
3646
3647 (define_insn "truncdfsf2_noop"
3648   [(set (match_operand:SF 0 "register_operand" "=f")
3649         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3650   "TARGET_80387 && flag_unsafe_math_optimizations"
3651 {
3652   return output_387_reg_move (insn, operands);
3653 }
3654   [(set_attr "type" "fmov")
3655    (set_attr "mode" "SF")])
3656
3657 (define_insn "*truncdfsf2_1"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3659         (float_truncate:SF
3660          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3661    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3662   "TARGET_80387 && !TARGET_SSE2"
3663 {
3664   switch (which_alternative)
3665     {
3666     case 0:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671     default:
3672       abort ();
3673     }
3674 }
3675   [(set_attr "type" "fmov,multi,multi,multi")
3676    (set_attr "mode" "SF,SF,SF,SF")])
3677
3678 (define_insn "*truncdfsf2_1_sse"
3679   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3680         (float_truncate:SF
3681          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3682    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3683   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3684 {
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689         return "fstp%z0\t%y0";
3690       else
3691         return "fst%z0\t%y0";
3692     case 4:
3693       return "#";
3694     default:
3695       abort ();
3696     }
3697 }
3698   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3699    (set_attr "mode" "SF,SF,SF,SF,DF")])
3700
3701 (define_insn "*truncdfsf2_1_sse_nooverlap"
3702   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3703         (float_truncate:SF
3704          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3705    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3706   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3707 {
3708   switch (which_alternative)
3709     {
3710     case 0:
3711       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0";
3713       else
3714         return "fst%z0\t%y0";
3715     case 4:
3716       return "#";
3717     default:
3718       abort ();
3719     }
3720 }
3721   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3722    (set_attr "mode" "SF,SF,SF,SF,DF")])
3723
3724 (define_insn "*truncdfsf2_2"
3725   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3726         (float_truncate:SF
3727          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3728   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3729    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3730 {
3731   switch (which_alternative)
3732     {
3733     case 0:
3734     case 1:
3735       return "cvtsd2ss\t{%1, %0|%0, %1}";
3736     case 2:
3737       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738         return "fstp%z0\t%y0";
3739       else
3740         return "fst%z0\t%y0";
3741     default:
3742       abort ();
3743     }
3744 }
3745   [(set_attr "type" "ssecvt,ssecvt,fmov")
3746    (set_attr "athlon_decode" "vector,double,*")
3747    (set_attr "mode" "SF,SF,SF")])
3748
3749 (define_insn "*truncdfsf2_2_nooverlap"
3750   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3751         (float_truncate:SF
3752          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3753   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3755 {
3756   switch (which_alternative)
3757     {
3758     case 0:
3759       return "#";
3760     case 1:
3761       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762         return "fstp%z0\t%y0";
3763       else
3764         return "fst%z0\t%y0";
3765     default:
3766       abort ();
3767     }
3768 }
3769   [(set_attr "type" "ssecvt,fmov")
3770    (set_attr "mode" "DF,SF")])
3771
3772 (define_insn "*truncdfsf2_3"
3773   [(set (match_operand:SF 0 "memory_operand" "=m")
3774         (float_truncate:SF
3775          (match_operand:DF 1 "register_operand" "f")))]
3776   "TARGET_80387"
3777 {
3778   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779     return "fstp%z0\t%y0";
3780   else
3781     return "fst%z0\t%y0";
3782 }
3783   [(set_attr "type" "fmov")
3784    (set_attr "mode" "SF")])
3785
3786 (define_insn "truncdfsf2_sse_only"
3787   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3788         (float_truncate:SF
3789          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3790   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3791   "cvtsd2ss\t{%1, %0|%0, %1}"
3792   [(set_attr "type" "ssecvt")
3793    (set_attr "athlon_decode" "vector,double")
3794    (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_sse_only_nooverlap"
3797   [(set (match_operand:SF 0 "register_operand" "=&Y")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3800   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3801   "#"
3802   [(set_attr "type" "ssecvt")
3803    (set_attr "mode" "DF")])
3804
3805 (define_split
3806   [(set (match_operand:SF 0 "memory_operand" "")
3807         (float_truncate:SF
3808          (match_operand:DF 1 "register_operand" "")))
3809    (clobber (match_operand:SF 2 "memory_operand" ""))]
3810   "TARGET_80387"
3811   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3812   "")
3813
3814 ; Avoid possible reformatting penalty on the destination by first
3815 ; zeroing it out
3816 (define_split
3817   [(set (match_operand:SF 0 "register_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "nonimmediate_operand" "")))
3820    (clobber (match_operand 2 "" ""))]
3821   "TARGET_80387 && reload_completed
3822    && SSE_REG_P (operands[0])
3823    && !STACK_REG_P (operands[1])"
3824   [(const_int 0)]
3825 {
3826   rtx src, dest;
3827   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3828     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3829   else
3830     {
3831       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3832       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3833       /* simplify_gen_subreg refuses to widen memory references.  */
3834       if (GET_CODE (src) == SUBREG)
3835         alter_subreg (&src);
3836       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3837         abort ();
3838       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3839       emit_insn (gen_cvtsd2ss (dest, dest, src));
3840     }
3841   DONE;
3842 })
3843
3844 (define_split
3845   [(set (match_operand:SF 0 "register_operand" "")
3846         (float_truncate:SF
3847          (match_operand:DF 1 "nonimmediate_operand" "")))]
3848   "TARGET_80387 && reload_completed
3849    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3850   [(const_int 0)]
3851 {
3852   rtx src, dest;
3853   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3854   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3855   /* simplify_gen_subreg refuses to widen memory references.  */
3856   if (GET_CODE (src) == SUBREG)
3857     alter_subreg (&src);
3858   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3859     abort ();
3860   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3861   emit_insn (gen_cvtsd2ss (dest, dest, src));
3862   DONE;
3863 })
3864
3865 (define_split
3866   [(set (match_operand:SF 0 "register_operand" "")
3867         (float_truncate:SF
3868          (match_operand:DF 1 "fp_register_operand" "")))
3869    (clobber (match_operand:SF 2 "memory_operand" ""))]
3870   "TARGET_80387 && reload_completed"
3871   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3872    (set (match_dup 0) (match_dup 2))]
3873   "")
3874
3875 (define_expand "truncxfsf2"
3876   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3877                    (float_truncate:SF
3878                     (match_operand:XF 1 "register_operand" "")))
3879               (clobber (match_dup 2))])]
3880   "TARGET_80387"
3881   "
3882   if (flag_unsafe_math_optimizations)
3883     {
3884       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3885       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3886       if (reg != operands[0])
3887         emit_move_insn (operands[0], reg);
3888       DONE;
3889     }
3890   else
3891     operands[2] = assign_386_stack_local (SFmode, 0);
3892   ")
3893
3894 (define_insn "truncxfsf2_noop"
3895   [(set (match_operand:SF 0 "register_operand" "=f")
3896         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3897   "TARGET_80387 && flag_unsafe_math_optimizations"
3898 {
3899   return output_387_reg_move (insn, operands);
3900 }
3901   [(set_attr "type" "fmov")
3902    (set_attr "mode" "SF")])
3903
3904 (define_insn "*truncxfsf2_1"
3905   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3908    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909   "TARGET_80387"
3910 {
3911   switch (which_alternative)
3912     {
3913     case 0:
3914       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3915         return "fstp%z0\t%y0";
3916       else
3917         return "fst%z0\t%y0";
3918     default:
3919       abort();
3920     }
3921 }
3922   [(set_attr "type" "fmov,multi,multi,multi")
3923    (set_attr "mode" "SF")])
3924
3925 (define_insn "*truncxfsf2_2"
3926   [(set (match_operand:SF 0 "memory_operand" "=m")
3927         (float_truncate:SF
3928          (match_operand:XF 1 "register_operand" "f")))]
3929   "TARGET_80387"
3930 {
3931   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932     return "fstp%z0\t%y0";
3933   else
3934     return "fst%z0\t%y0";
3935 }
3936   [(set_attr "type" "fmov")
3937    (set_attr "mode" "SF")])
3938
3939 (define_split
3940   [(set (match_operand:SF 0 "memory_operand" "")
3941         (float_truncate:SF
3942          (match_operand:XF 1 "register_operand" "")))
3943    (clobber (match_operand:SF 2 "memory_operand" ""))]
3944   "TARGET_80387"
3945   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3946   "")
3947
3948 (define_split
3949   [(set (match_operand:SF 0 "register_operand" "")
3950         (float_truncate:SF
3951          (match_operand:XF 1 "register_operand" "")))
3952    (clobber (match_operand:SF 2 "memory_operand" ""))]
3953   "TARGET_80387 && reload_completed"
3954   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955    (set (match_dup 0) (match_dup 2))]
3956   "")
3957
3958 (define_expand "truncxfdf2"
3959   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3960                    (float_truncate:DF
3961                     (match_operand:XF 1 "register_operand" "")))
3962               (clobber (match_dup 2))])]
3963   "TARGET_80387"
3964   "
3965   if (flag_unsafe_math_optimizations)
3966     {
3967       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3968       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3969       if (reg != operands[0])
3970         emit_move_insn (operands[0], reg);
3971       DONE;
3972     }
3973   else
3974     operands[2] = assign_386_stack_local (DFmode, 0);
3975   ")
3976
3977 (define_insn "truncxfdf2_noop"
3978   [(set (match_operand:DF 0 "register_operand" "=f")
3979         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3980   "TARGET_80387 && flag_unsafe_math_optimizations"
3981 {
3982   return output_387_reg_move (insn, operands);
3983 }
3984   [(set_attr "type" "fmov")
3985    (set_attr "mode" "DF")])
3986
3987 (define_insn "*truncxfdf2_1"
3988   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3989         (float_truncate:DF
3990          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3991    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3992   "TARGET_80387"
3993 {
3994   switch (which_alternative)
3995     {
3996     case 0:
3997       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3998         return "fstp%z0\t%y0";
3999       else
4000         return "fst%z0\t%y0";
4001     default:
4002       abort();
4003     }
4004   abort ();
4005 }
4006   [(set_attr "type" "fmov,multi,multi,multi")
4007    (set_attr "mode" "DF")])
4008
4009 (define_insn "*truncxfdf2_2"
4010   [(set (match_operand:DF 0 "memory_operand" "=m")
4011         (float_truncate:DF
4012           (match_operand:XF 1 "register_operand" "f")))]
4013   "TARGET_80387"
4014 {
4015   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4016     return "fstp%z0\t%y0";
4017   else
4018     return "fst%z0\t%y0";
4019 }
4020   [(set_attr "type" "fmov")
4021    (set_attr "mode" "DF")])
4022
4023 (define_split
4024   [(set (match_operand:DF 0 "memory_operand" "")
4025         (float_truncate:DF
4026          (match_operand:XF 1 "register_operand" "")))
4027    (clobber (match_operand:DF 2 "memory_operand" ""))]
4028   "TARGET_80387"
4029   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4030   "")
4031
4032 (define_split
4033   [(set (match_operand:DF 0 "register_operand" "")
4034         (float_truncate:DF
4035          (match_operand:XF 1 "register_operand" "")))
4036    (clobber (match_operand:DF 2 "memory_operand" ""))]
4037   "TARGET_80387 && reload_completed"
4038   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4039    (set (match_dup 0) (match_dup 2))]
4040   "")
4041
4042 \f
4043 ;; %%% Break up all these bad boys.
4044
4045 ;; Signed conversion to DImode.
4046
4047 (define_expand "fix_truncxfdi2"
4048   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4049                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4050               (clobber (reg:CC FLAGS_REG))])]
4051   "TARGET_80387"
4052   "")
4053
4054 (define_expand "fix_truncdfdi2"
4055   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4056                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4057               (clobber (reg:CC FLAGS_REG))])]
4058   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4059 {
4060   if (TARGET_64BIT && TARGET_SSE2)
4061    {
4062      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4063      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4064      if (out != operands[0])
4065         emit_move_insn (operands[0], out);
4066      DONE;
4067    }
4068 })
4069
4070 (define_expand "fix_truncsfdi2"
4071   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])] 
4074   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4075 {
4076   if (TARGET_SSE && TARGET_64BIT)
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4084 })
4085
4086 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4087 ;; of the machinery.
4088 (define_insn_and_split "*fix_truncdi_1"
4089   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4090         (fix:DI (match_operand 1 "register_operand" "f,f")))
4091    (clobber (reg:CC FLAGS_REG))]
4092   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4093    && !reload_completed && !reload_in_progress
4094    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4095   "#"
4096   "&& 1"
4097   [(const_int 0)]
4098 {
4099   ix86_optimize_mode_switching = 1;
4100   operands[2] = assign_386_stack_local (HImode, 1);
4101   operands[3] = assign_386_stack_local (HImode, 2);
4102   if (memory_operand (operands[0], VOIDmode))
4103     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4104                                        operands[2], operands[3]));
4105   else
4106     {
4107       operands[4] = assign_386_stack_local (DImode, 0);
4108       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4109                                            operands[2], operands[3],
4110                                            operands[4]));
4111     }
4112   DONE;
4113 }
4114   [(set_attr "type" "fistp")
4115    (set_attr "i387_cw" "trunc")
4116    (set_attr "mode" "DI")])
4117
4118 (define_insn "fix_truncdi_nomemory"
4119   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4120         (fix:DI (match_operand 1 "register_operand" "f,f")))
4121    (use (match_operand:HI 2 "memory_operand" "m,m"))
4122    (use (match_operand:HI 3 "memory_operand" "m,m"))
4123    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4124    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4125   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4126    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4127   "#"
4128   [(set_attr "type" "fistp")
4129    (set_attr "i387_cw" "trunc")
4130    (set_attr "mode" "DI")])
4131
4132 (define_insn "fix_truncdi_memory"
4133   [(set (match_operand:DI 0 "memory_operand" "=m")
4134         (fix:DI (match_operand 1 "register_operand" "f")))
4135    (use (match_operand:HI 2 "memory_operand" "m"))
4136    (use (match_operand:HI 3 "memory_operand" "m"))
4137    (clobber (match_scratch:DF 4 "=&1f"))]
4138   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4139    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4140   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4141   [(set_attr "type" "fistp")
4142    (set_attr "i387_cw" "trunc")
4143    (set_attr "mode" "DI")])
4144
4145 (define_split 
4146   [(set (match_operand:DI 0 "register_operand" "")
4147         (fix:DI (match_operand 1 "register_operand" "")))
4148    (use (match_operand:HI 2 "memory_operand" ""))
4149    (use (match_operand:HI 3 "memory_operand" ""))
4150    (clobber (match_operand:DI 4 "memory_operand" ""))
4151    (clobber (match_scratch 5 ""))]
4152   "reload_completed"
4153   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4154               (use (match_dup 2))
4155               (use (match_dup 3))
4156               (clobber (match_dup 5))])
4157    (set (match_dup 0) (match_dup 4))]
4158   "")
4159
4160 (define_split 
4161   [(set (match_operand:DI 0 "memory_operand" "")
4162         (fix:DI (match_operand 1 "register_operand" "")))
4163    (use (match_operand:HI 2 "memory_operand" ""))
4164    (use (match_operand:HI 3 "memory_operand" ""))
4165    (clobber (match_operand:DI 4 "memory_operand" ""))
4166    (clobber (match_scratch 5 ""))]
4167   "reload_completed"
4168   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4169               (use (match_dup 2))
4170               (use (match_dup 3))
4171               (clobber (match_dup 5))])]
4172   "")
4173
4174 ;; When SSE available, it is always faster to use it!
4175 (define_insn "fix_truncsfdi_sse"
4176   [(set (match_operand:DI 0 "register_operand" "=r,r")
4177         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4178   "TARGET_64BIT && TARGET_SSE"
4179   "cvttss2si{q}\t{%1, %0|%0, %1}"
4180   [(set_attr "type" "sseicvt")
4181    (set_attr "mode" "SF")
4182    (set_attr "athlon_decode" "double,vector")])
4183
4184 ;; Avoid vector decoded form of the instruction.
4185 (define_peephole2
4186   [(match_scratch:SF 2 "x")
4187    (set (match_operand:DI 0 "register_operand" "")
4188         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4189   "TARGET_K8 && !optimize_size"
4190   [(set (match_dup 2) (match_dup 1))
4191    (set (match_dup 0) (fix:DI (match_dup 2)))]
4192   "")
4193
4194 (define_insn "fix_truncdfdi_sse"
4195   [(set (match_operand:DI 0 "register_operand" "=r,r")
4196         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4197   "TARGET_64BIT && TARGET_SSE2"
4198   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4199   [(set_attr "type" "sseicvt,sseicvt")
4200    (set_attr "mode" "DF")
4201    (set_attr "athlon_decode" "double,vector")])
4202
4203 ;; Avoid vector decoded form of the instruction.
4204 (define_peephole2
4205   [(match_scratch:DF 2 "Y")
4206    (set (match_operand:DI 0 "register_operand" "")
4207         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4208   "TARGET_K8 && !optimize_size"
4209   [(set (match_dup 2) (match_dup 1))
4210    (set (match_dup 0) (fix:DI (match_dup 2)))]
4211   "")
4212
4213 ;; Signed conversion to SImode.
4214
4215 (define_expand "fix_truncxfsi2"
4216   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4217                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4218               (clobber (reg:CC FLAGS_REG))])]
4219   "TARGET_80387"
4220   "")
4221
4222 (define_expand "fix_truncdfsi2"
4223   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4224                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4225               (clobber (reg:CC FLAGS_REG))])]
4226   "TARGET_80387 || TARGET_SSE2"
4227 {
4228   if (TARGET_SSE2)
4229    {
4230      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4231      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4232      if (out != operands[0])
4233         emit_move_insn (operands[0], out);
4234      DONE;
4235    }
4236 })
4237
4238 (define_expand "fix_truncsfsi2"
4239   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4240                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4241               (clobber (reg:CC FLAGS_REG))])] 
4242   "TARGET_80387 || TARGET_SSE"
4243 {
4244   if (TARGET_SSE)
4245    {
4246      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4247      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4248      if (out != operands[0])
4249         emit_move_insn (operands[0], out);
4250      DONE;
4251    }
4252 })
4253
4254 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4255 ;; of the machinery.
4256 (define_insn_and_split "*fix_truncsi_1"
4257   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4258         (fix:SI (match_operand 1 "register_operand" "f,f")))
4259    (clobber (reg:CC FLAGS_REG))]
4260   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261    && !reload_completed && !reload_in_progress
4262    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4263   "#"
4264   "&& 1"
4265   [(const_int 0)]
4266 {
4267   ix86_optimize_mode_switching = 1;
4268   operands[2] = assign_386_stack_local (HImode, 1);
4269   operands[3] = assign_386_stack_local (HImode, 2);
4270   if (memory_operand (operands[0], VOIDmode))
4271     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4272                                        operands[2], operands[3]));
4273   else
4274     {
4275       operands[4] = assign_386_stack_local (SImode, 0);
4276       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4277                                            operands[2], operands[3],
4278                                            operands[4]));
4279     }
4280   DONE;
4281 }
4282   [(set_attr "type" "fistp")
4283    (set_attr "i387_cw" "trunc")
4284    (set_attr "mode" "SI")])
4285
4286 (define_insn "fix_truncsi_nomemory"
4287   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4288         (fix:SI (match_operand 1 "register_operand" "f,f")))
4289    (use (match_operand:HI 2 "memory_operand" "m,m"))
4290    (use (match_operand:HI 3 "memory_operand" "m,m"))
4291    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4292   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4293    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4294   "#"
4295   [(set_attr "type" "fistp")
4296    (set_attr "i387_cw" "trunc")
4297    (set_attr "mode" "SI")])
4298
4299 (define_insn "fix_truncsi_memory"
4300   [(set (match_operand:SI 0 "memory_operand" "=m")
4301         (fix:SI (match_operand 1 "register_operand" "f")))
4302    (use (match_operand:HI 2 "memory_operand" "m"))
4303    (use (match_operand:HI 3 "memory_operand" "m"))]
4304   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4305    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4306   "* return output_fix_trunc (insn, operands);"
4307   [(set_attr "type" "fistp")
4308    (set_attr "i387_cw" "trunc")
4309    (set_attr "mode" "SI")])
4310
4311 ;; When SSE available, it is always faster to use it!
4312 (define_insn "fix_truncsfsi_sse"
4313   [(set (match_operand:SI 0 "register_operand" "=r,r")
4314         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4315   "TARGET_SSE"
4316   "cvttss2si\t{%1, %0|%0, %1}"
4317   [(set_attr "type" "sseicvt")
4318    (set_attr "mode" "DF")
4319    (set_attr "athlon_decode" "double,vector")])
4320
4321 ;; Avoid vector decoded form of the instruction.
4322 (define_peephole2
4323   [(match_scratch:SF 2 "x")
4324    (set (match_operand:SI 0 "register_operand" "")
4325         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4326   "TARGET_K8 && !optimize_size"
4327   [(set (match_dup 2) (match_dup 1))
4328    (set (match_dup 0) (fix:SI (match_dup 2)))]
4329   "")
4330
4331 (define_insn "fix_truncdfsi_sse"
4332   [(set (match_operand:SI 0 "register_operand" "=r,r")
4333         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4334   "TARGET_SSE2"
4335   "cvttsd2si\t{%1, %0|%0, %1}"
4336   [(set_attr "type" "sseicvt")
4337    (set_attr "mode" "DF")
4338    (set_attr "athlon_decode" "double,vector")])
4339
4340 ;; Avoid vector decoded form of the instruction.
4341 (define_peephole2
4342   [(match_scratch:DF 2 "Y")
4343    (set (match_operand:SI 0 "register_operand" "")
4344         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4345   "TARGET_K8 && !optimize_size"
4346   [(set (match_dup 2) (match_dup 1))
4347    (set (match_dup 0) (fix:SI (match_dup 2)))]
4348   "")
4349
4350 (define_split 
4351   [(set (match_operand:SI 0 "register_operand" "")
4352         (fix:SI (match_operand 1 "register_operand" "")))
4353    (use (match_operand:HI 2 "memory_operand" ""))
4354    (use (match_operand:HI 3 "memory_operand" ""))
4355    (clobber (match_operand:SI 4 "memory_operand" ""))]
4356   "reload_completed"
4357   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4358               (use (match_dup 2))
4359               (use (match_dup 3))])
4360    (set (match_dup 0) (match_dup 4))]
4361   "")
4362
4363 (define_split 
4364   [(set (match_operand:SI 0 "memory_operand" "")
4365         (fix:SI (match_operand 1 "register_operand" "")))
4366    (use (match_operand:HI 2 "memory_operand" ""))
4367    (use (match_operand:HI 3 "memory_operand" ""))
4368    (clobber (match_operand:SI 4 "memory_operand" ""))]
4369   "reload_completed"
4370   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4371               (use (match_dup 2))
4372               (use (match_dup 3))])]
4373   "")
4374
4375 ;; Signed conversion to HImode.
4376
4377 (define_expand "fix_truncxfhi2"
4378   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4379                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4380               (clobber (reg:CC FLAGS_REG))])] 
4381   "TARGET_80387"
4382   "")
4383
4384 (define_expand "fix_truncdfhi2"
4385   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4386                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4387               (clobber (reg:CC FLAGS_REG))])]
4388   "TARGET_80387 && !TARGET_SSE2"
4389   "")
4390
4391 (define_expand "fix_truncsfhi2"
4392   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4393                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4394                (clobber (reg:CC FLAGS_REG))])]
4395   "TARGET_80387 && !TARGET_SSE"
4396   "")
4397
4398 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4399 ;; of the machinery.
4400 (define_insn_and_split "*fix_trunchi_1"
4401   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4402         (fix:HI (match_operand 1 "register_operand" "f,f")))
4403    (clobber (reg:CC FLAGS_REG))]
4404   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4405    && !reload_completed && !reload_in_progress
4406    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4407   "#"
4408   ""
4409   [(const_int 0)]
4410 {
4411   ix86_optimize_mode_switching = 1;
4412   operands[2] = assign_386_stack_local (HImode, 1);
4413   operands[3] = assign_386_stack_local (HImode, 2);
4414   if (memory_operand (operands[0], VOIDmode))
4415     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4416                                        operands[2], operands[3]));
4417   else
4418     {
4419       operands[4] = assign_386_stack_local (HImode, 0);
4420       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4421                                            operands[2], operands[3],
4422                                            operands[4]));
4423     }
4424   DONE;
4425 }
4426   [(set_attr "type" "fistp")
4427    (set_attr "i387_cw" "trunc")
4428    (set_attr "mode" "HI")])
4429
4430 (define_insn "fix_trunchi_nomemory"
4431   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4432         (fix:HI (match_operand 1 "register_operand" "f,f")))
4433    (use (match_operand:HI 2 "memory_operand" "m,m"))
4434    (use (match_operand:HI 3 "memory_operand" "m,m"))
4435    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4436   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4437    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4438   "#"
4439   [(set_attr "type" "fistp")
4440    (set_attr "i387_cw" "trunc")
4441    (set_attr "mode" "HI")])
4442
4443 (define_insn "fix_trunchi_memory"
4444   [(set (match_operand:HI 0 "memory_operand" "=m")
4445         (fix:HI (match_operand 1 "register_operand" "f")))
4446    (use (match_operand:HI 2 "memory_operand" "m"))
4447    (use (match_operand:HI 3 "memory_operand" "m"))]
4448   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4449    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4450   "* return output_fix_trunc (insn, operands);"
4451   [(set_attr "type" "fistp")
4452    (set_attr "i387_cw" "trunc")
4453    (set_attr "mode" "HI")])
4454
4455 (define_split 
4456   [(set (match_operand:HI 0 "memory_operand" "")
4457         (fix:HI (match_operand 1 "register_operand" "")))
4458    (use (match_operand:HI 2 "memory_operand" ""))
4459    (use (match_operand:HI 3 "memory_operand" ""))
4460    (clobber (match_operand:HI 4 "memory_operand" ""))]
4461   "reload_completed"
4462   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4463               (use (match_dup 2))
4464               (use (match_dup 3))])]
4465   "")
4466
4467 (define_split 
4468   [(set (match_operand:HI 0 "register_operand" "")
4469         (fix:HI (match_operand 1 "register_operand" "")))
4470    (use (match_operand:HI 2 "memory_operand" ""))
4471    (use (match_operand:HI 3 "memory_operand" ""))
4472    (clobber (match_operand:HI 4 "memory_operand" ""))]
4473   "reload_completed"
4474   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4475               (use (match_dup 2))
4476               (use (match_dup 3))
4477               (clobber (match_dup 4))])
4478    (set (match_dup 0) (match_dup 4))]
4479   "")
4480
4481 (define_insn "x86_fnstcw_1"
4482   [(set (match_operand:HI 0 "memory_operand" "=m")
4483         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4484   "TARGET_80387"
4485   "fnstcw\t%0"
4486   [(set_attr "length" "2")
4487    (set_attr "mode" "HI")
4488    (set_attr "unit" "i387")])
4489
4490 (define_insn "x86_fldcw_1"
4491   [(set (reg:HI FPSR_REG)
4492         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4493   "TARGET_80387"
4494   "fldcw\t%0"
4495   [(set_attr "length" "2")
4496    (set_attr "mode" "HI")
4497    (set_attr "unit" "i387")
4498    (set_attr "athlon_decode" "vector")])
4499 \f
4500 ;; Conversion between fixed point and floating point.
4501
4502 ;; Even though we only accept memory inputs, the backend _really_
4503 ;; wants to be able to do this between registers.
4504
4505 (define_expand "floathisf2"
4506   [(set (match_operand:SF 0 "register_operand" "")
4507         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508   "TARGET_SSE || TARGET_80387"
4509 {
4510   if (TARGET_SSE && TARGET_SSE_MATH)
4511     {
4512       emit_insn (gen_floatsisf2 (operands[0],
4513                                  convert_to_mode (SImode, operands[1], 0)));
4514       DONE;
4515     }
4516 })
4517
4518 (define_insn "*floathisf2_1"
4519   [(set (match_operand:SF 0 "register_operand" "=f,f")
4520         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4521   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "SF")
4527    (set_attr "fp_int_src" "true")])
4528
4529 (define_expand "floatsisf2"
4530   [(set (match_operand:SF 0 "register_operand" "")
4531         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4532   "TARGET_SSE || TARGET_80387"
4533   "")
4534
4535 (define_insn "*floatsisf2_i387"
4536   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4537         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4538   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4539   "@
4540    fild%z1\t%1
4541    #
4542    cvtsi2ss\t{%1, %0|%0, %1}
4543    cvtsi2ss\t{%1, %0|%0, %1}"
4544   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4545    (set_attr "mode" "SF")
4546    (set_attr "athlon_decode" "*,*,vector,double")
4547    (set_attr "fp_int_src" "true")])
4548
4549 (define_insn "*floatsisf2_sse"
4550   [(set (match_operand:SF 0 "register_operand" "=x,x")
4551         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4552   "TARGET_SSE"
4553   "cvtsi2ss\t{%1, %0|%0, %1}"
4554   [(set_attr "type" "sseicvt")
4555    (set_attr "mode" "SF")
4556    (set_attr "athlon_decode" "vector,double")
4557    (set_attr "fp_int_src" "true")])
4558
4559 ; Avoid possible reformatting penalty on the destination by first
4560 ; zeroing it out
4561 (define_split
4562   [(set (match_operand:SF 0 "register_operand" "")
4563         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4564   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4565    && SSE_REG_P (operands[0])"
4566   [(const_int 0)]
4567 {
4568   rtx dest;
4569   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4570   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4571   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4572   DONE;
4573 })
4574
4575 (define_expand "floatdisf2"
4576   [(set (match_operand:SF 0 "register_operand" "")
4577         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4578   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4579   "")
4580
4581 (define_insn "*floatdisf2_i387_only"
4582   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4583         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4584   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4585   "@
4586    fild%z1\t%1
4587    #"
4588   [(set_attr "type" "fmov,multi")
4589    (set_attr "mode" "SF")
4590    (set_attr "fp_int_src" "true")])
4591
4592 (define_insn "*floatdisf2_i387"
4593   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4594         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4595   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4596   "@
4597    fild%z1\t%1
4598    #
4599    cvtsi2ss{q}\t{%1, %0|%0, %1}
4600    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4601   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4602    (set_attr "mode" "SF")
4603    (set_attr "athlon_decode" "*,*,vector,double")
4604    (set_attr "fp_int_src" "true")])
4605
4606 (define_insn "*floatdisf2_sse"
4607   [(set (match_operand:SF 0 "register_operand" "=x,x")
4608         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4609   "TARGET_64BIT && TARGET_SSE"
4610   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "sseicvt")
4612    (set_attr "mode" "SF")
4613    (set_attr "athlon_decode" "vector,double")
4614    (set_attr "fp_int_src" "true")])
4615
4616 ; Avoid possible reformatting penalty on the destination by first
4617 ; zeroing it out
4618 (define_split
4619   [(set (match_operand:SF 0 "register_operand" "")
4620         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4622    && SSE_REG_P (operands[0])"
4623   [(const_int 0)]
4624 {
4625   rtx dest;
4626   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4627   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4628   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4629   DONE;
4630 })
4631
4632 (define_expand "floathidf2"
4633   [(set (match_operand:DF 0 "register_operand" "")
4634         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4635   "TARGET_SSE2 || TARGET_80387"
4636 {
4637   if (TARGET_SSE && TARGET_SSE_MATH)
4638     {
4639       emit_insn (gen_floatsidf2 (operands[0],
4640                                  convert_to_mode (SImode, operands[1], 0)));
4641       DONE;
4642     }
4643 })
4644
4645 (define_insn "*floathidf2_1"
4646   [(set (match_operand:DF 0 "register_operand" "=f,f")
4647         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4648   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4649   "@
4650    fild%z1\t%1
4651    #"
4652   [(set_attr "type" "fmov,multi")
4653    (set_attr "mode" "DF")
4654    (set_attr "fp_int_src" "true")])
4655
4656 (define_expand "floatsidf2"
4657   [(set (match_operand:DF 0 "register_operand" "")
4658         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4659   "TARGET_80387 || TARGET_SSE2"
4660   "")
4661
4662 (define_insn "*floatsidf2_i387"
4663   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4664         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4665   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4666   "@
4667    fild%z1\t%1
4668    #
4669    cvtsi2sd\t{%1, %0|%0, %1}
4670    cvtsi2sd\t{%1, %0|%0, %1}"
4671   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4672    (set_attr "mode" "DF")
4673    (set_attr "athlon_decode" "*,*,double,direct")
4674    (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "*floatsidf2_sse"
4677   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4678         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4679   "TARGET_SSE2"
4680   "cvtsi2sd\t{%1, %0|%0, %1}"
4681   [(set_attr "type" "sseicvt")
4682    (set_attr "mode" "DF")
4683    (set_attr "athlon_decode" "double,direct")
4684    (set_attr "fp_int_src" "true")])
4685
4686 (define_expand "floatdidf2"
4687   [(set (match_operand:DF 0 "register_operand" "")
4688         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4689   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4690   "")
4691
4692 (define_insn "*floatdidf2_i387_only"
4693   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4694         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4695   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "DF")
4701    (set_attr "fp_int_src" "true")])
4702
4703 (define_insn "*floatdidf2_i387"
4704   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4705         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4706   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4707   "@
4708    fild%z1\t%1
4709    #
4710    cvtsi2sd{q}\t{%1, %0|%0, %1}
4711    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4712   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4713    (set_attr "mode" "DF")
4714    (set_attr "athlon_decode" "*,*,double,direct")
4715    (set_attr "fp_int_src" "true")])
4716
4717 (define_insn "*floatdidf2_sse"
4718   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4719         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4720   "TARGET_SSE2"
4721   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4722   [(set_attr "type" "sseicvt")
4723    (set_attr "mode" "DF")
4724    (set_attr "athlon_decode" "double,direct")
4725    (set_attr "fp_int_src" "true")])
4726
4727 (define_insn "floathixf2"
4728   [(set (match_operand:XF 0 "register_operand" "=f,f")
4729         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4730   "TARGET_80387"
4731   "@
4732    fild%z1\t%1
4733    #"
4734   [(set_attr "type" "fmov,multi")
4735    (set_attr "mode" "XF")
4736    (set_attr "fp_int_src" "true")])
4737
4738 (define_insn "floatsixf2"
4739   [(set (match_operand:XF 0 "register_operand" "=f,f")
4740         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4741   "TARGET_80387"
4742   "@
4743    fild%z1\t%1
4744    #"
4745   [(set_attr "type" "fmov,multi")
4746    (set_attr "mode" "XF")
4747    (set_attr "fp_int_src" "true")])
4748
4749 (define_insn "floatdixf2"
4750   [(set (match_operand:XF 0 "register_operand" "=f,f")
4751         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4752   "TARGET_80387"
4753   "@
4754    fild%z1\t%1
4755    #"
4756   [(set_attr "type" "fmov,multi")
4757    (set_attr "mode" "XF")
4758    (set_attr "fp_int_src" "true")])
4759
4760 ;; %%% Kill these when reload knows how to do it.
4761 (define_split
4762   [(set (match_operand 0 "fp_register_operand" "")
4763         (float (match_operand 1 "register_operand" "")))]
4764   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4765   [(const_int 0)]
4766 {
4767   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4768   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4769   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4770   ix86_free_from_memory (GET_MODE (operands[1]));
4771   DONE;
4772 })
4773
4774 (define_expand "floatunssisf2"
4775   [(use (match_operand:SF 0 "register_operand" ""))
4776    (use (match_operand:SI 1 "register_operand" ""))]
4777   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4778   "x86_emit_floatuns (operands); DONE;")
4779
4780 (define_expand "floatunsdisf2"
4781   [(use (match_operand:SF 0 "register_operand" ""))
4782    (use (match_operand:DI 1 "register_operand" ""))]
4783   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4784   "x86_emit_floatuns (operands); DONE;")
4785
4786 (define_expand "floatunsdidf2"
4787   [(use (match_operand:DF 0 "register_operand" ""))
4788    (use (match_operand:DI 1 "register_operand" ""))]
4789   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4790   "x86_emit_floatuns (operands); DONE;")
4791 \f
4792 ;; SSE extract/set expanders
4793
4794 (define_expand "vec_setv2df"
4795   [(match_operand:V2DF 0 "register_operand" "")
4796    (match_operand:DF 1 "register_operand" "")
4797    (match_operand 2 "const_int_operand" "")]
4798   "TARGET_SSE2"
4799 {
4800   switch (INTVAL (operands[2]))
4801     {
4802     case 0:
4803       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4804                                  simplify_gen_subreg (V2DFmode, operands[1],
4805                                                       DFmode, 0)));
4806       break;
4807     case 1:
4808       {
4809         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4810
4811         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4812       }
4813       break;
4814     default:
4815       abort ();
4816     }
4817   DONE;
4818 })
4819
4820 (define_expand "vec_extractv2df"
4821   [(match_operand:DF 0 "register_operand" "")
4822    (match_operand:V2DF 1 "register_operand" "")
4823    (match_operand 2 "const_int_operand" "")]
4824   "TARGET_SSE2"
4825 {
4826   switch (INTVAL (operands[2]))
4827     {
4828     case 0:
4829       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4830       break;
4831     case 1:
4832       {
4833         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4834
4835         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4836       }
4837       break;
4838     default:
4839       abort ();
4840     }
4841   DONE;
4842 })
4843
4844 (define_expand "vec_initv2df"
4845   [(match_operand:V2DF 0 "register_operand" "")
4846    (match_operand 1 "" "")]
4847   "TARGET_SSE2"
4848 {
4849   ix86_expand_vector_init (operands[0], operands[1]);
4850   DONE;
4851 })
4852
4853 (define_expand "vec_setv4sf"
4854   [(match_operand:V4SF 0 "register_operand" "")
4855    (match_operand:SF 1 "register_operand" "")
4856    (match_operand 2 "const_int_operand" "")]
4857   "TARGET_SSE"
4858 {
4859   switch (INTVAL (operands[2]))
4860     {
4861     case 0:
4862       emit_insn (gen_sse_movss (operands[0], operands[0],
4863                                 simplify_gen_subreg (V4SFmode, operands[1],
4864                                                      SFmode, 0)));
4865       break;
4866     case 1:
4867       {
4868         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4869         rtx tmp = gen_reg_rtx (V4SFmode);
4870  
4871         emit_move_insn (tmp, operands[0]);
4872         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4873         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4874         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4875                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4876       }
4877       break;
4878     case 2:
4879       {
4880         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881         rtx tmp = gen_reg_rtx (V4SFmode);
4882
4883         emit_move_insn (tmp, operands[0]);
4884         emit_insn (gen_sse_movss (tmp, tmp, op1));
4885         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4886                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4887       }
4888       break;
4889     case 3:
4890       {
4891         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4892         rtx tmp = gen_reg_rtx (V4SFmode);
4893
4894         emit_move_insn (tmp, operands[0]);
4895         emit_insn (gen_sse_movss (tmp, tmp, op1));
4896         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4897                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4898       }
4899       break;
4900     default:
4901       abort ();
4902     }
4903   DONE;
4904 })
4905
4906 (define_expand "vec_extractv4sf"
4907   [(match_operand:SF 0 "register_operand" "")
4908    (match_operand:V4SF 1 "register_operand" "")
4909    (match_operand 2 "const_int_operand" "")]
4910   "TARGET_SSE"
4911 {
4912   switch (INTVAL (operands[2]))
4913     {
4914     case 0:
4915       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4916       break;
4917     case 1:
4918       {
4919         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4920         rtx tmp = gen_reg_rtx (V4SFmode);
4921  
4922         emit_move_insn (tmp, operands[1]);
4923         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4924                                    const1_rtx));
4925       }
4926       break;
4927     case 2:
4928       {
4929         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4930         rtx tmp = gen_reg_rtx (V4SFmode);
4931  
4932         emit_move_insn (tmp, operands[1]);
4933         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4934       }
4935       break;
4936     case 3:
4937       {
4938         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4939         rtx tmp = gen_reg_rtx (V4SFmode);
4940  
4941         emit_move_insn (tmp, operands[1]);
4942         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4943                                    GEN_INT (3)));
4944       }
4945       break;
4946     default:
4947       abort ();
4948     }
4949   DONE;
4950 })
4951
4952 (define_expand "vec_initv4sf"
4953   [(match_operand:V4SF 0 "register_operand" "")
4954    (match_operand 1 "" "")]
4955   "TARGET_SSE"
4956 {
4957   ix86_expand_vector_init (operands[0], operands[1]);
4958   DONE;
4959 })
4960 \f
4961 ;; Add instructions
4962
4963 ;; %%% splits for addsidi3
4964 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4965 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4966 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4967
4968 (define_expand "adddi3"
4969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4970         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4971                  (match_operand:DI 2 "x86_64_general_operand" "")))
4972    (clobber (reg:CC FLAGS_REG))]
4973   ""
4974   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4975
4976 (define_insn "*adddi3_1"
4977   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4978         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4979                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4980    (clobber (reg:CC FLAGS_REG))]
4981   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4982   "#")
4983
4984 (define_split
4985   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4986         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4987                  (match_operand:DI 2 "general_operand" "")))
4988    (clobber (reg:CC FLAGS_REG))]
4989   "!TARGET_64BIT && reload_completed"
4990   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4991                                           UNSPEC_ADD_CARRY))
4992               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4993    (parallel [(set (match_dup 3)
4994                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4995                                      (match_dup 4))
4996                             (match_dup 5)))
4997               (clobber (reg:CC FLAGS_REG))])]
4998   "split_di (operands+0, 1, operands+0, operands+3);
4999    split_di (operands+1, 1, operands+1, operands+4);
5000    split_di (operands+2, 1, operands+2, operands+5);")
5001
5002 (define_insn "adddi3_carry_rex64"
5003   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5004           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5005                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5006                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5007    (clobber (reg:CC FLAGS_REG))]
5008   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5009   "adc{q}\t{%2, %0|%0, %2}"
5010   [(set_attr "type" "alu")
5011    (set_attr "pent_pair" "pu")
5012    (set_attr "mode" "DI")])
5013
5014 (define_insn "*adddi3_cc_rex64"
5015   [(set (reg:CC FLAGS_REG)
5016         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5017                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5018                    UNSPEC_ADD_CARRY))
5019    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5020         (plus:DI (match_dup 1) (match_dup 2)))]
5021   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5022   "add{q}\t{%2, %0|%0, %2}"
5023   [(set_attr "type" "alu")
5024    (set_attr "mode" "DI")])
5025
5026 (define_insn "addqi3_carry"
5027   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5028           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5029                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5030                    (match_operand:QI 2 "general_operand" "qi,qm")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5033   "adc{b}\t{%2, %0|%0, %2}"
5034   [(set_attr "type" "alu")
5035    (set_attr "pent_pair" "pu")
5036    (set_attr "mode" "QI")])
5037
5038 (define_insn "addhi3_carry"
5039   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5040           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5041                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5042                    (match_operand:HI 2 "general_operand" "ri,rm")))
5043    (clobber (reg:CC FLAGS_REG))]
5044   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5045   "adc{w}\t{%2, %0|%0, %2}"
5046   [(set_attr "type" "alu")
5047    (set_attr "pent_pair" "pu")
5048    (set_attr "mode" "HI")])
5049
5050 (define_insn "addsi3_carry"
5051   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5052           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5053                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5054                    (match_operand:SI 2 "general_operand" "ri,rm")))
5055    (clobber (reg:CC FLAGS_REG))]
5056   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5057   "adc{l}\t{%2, %0|%0, %2}"
5058   [(set_attr "type" "alu")
5059    (set_attr "pent_pair" "pu")
5060    (set_attr "mode" "SI")])
5061
5062 (define_insn "*addsi3_carry_zext"
5063   [(set (match_operand:DI 0 "register_operand" "=r")
5064           (zero_extend:DI 
5065             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5066                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5067                      (match_operand:SI 2 "general_operand" "rim"))))
5068    (clobber (reg:CC FLAGS_REG))]
5069   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5070   "adc{l}\t{%2, %k0|%k0, %2}"
5071   [(set_attr "type" "alu")
5072    (set_attr "pent_pair" "pu")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn "*addsi3_cc"
5076   [(set (reg:CC FLAGS_REG)
5077         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5078                     (match_operand:SI 2 "general_operand" "ri,rm")]
5079                    UNSPEC_ADD_CARRY))
5080    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5081         (plus:SI (match_dup 1) (match_dup 2)))]
5082   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5083   "add{l}\t{%2, %0|%0, %2}"
5084   [(set_attr "type" "alu")
5085    (set_attr "mode" "SI")])
5086
5087 (define_insn "addqi3_cc"
5088   [(set (reg:CC FLAGS_REG)
5089         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5090                     (match_operand:QI 2 "general_operand" "qi,qm")]
5091                    UNSPEC_ADD_CARRY))
5092    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5093         (plus:QI (match_dup 1) (match_dup 2)))]
5094   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5095   "add{b}\t{%2, %0|%0, %2}"
5096   [(set_attr "type" "alu")
5097    (set_attr "mode" "QI")])
5098
5099 (define_expand "addsi3"
5100   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5101                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5102                             (match_operand:SI 2 "general_operand" "")))
5103               (clobber (reg:CC FLAGS_REG))])]
5104   ""
5105   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5106
5107 (define_insn "*lea_1"
5108   [(set (match_operand:SI 0 "register_operand" "=r")
5109         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5110   "!TARGET_64BIT"
5111   "lea{l}\t{%a1, %0|%0, %a1}"
5112   [(set_attr "type" "lea")
5113    (set_attr "mode" "SI")])
5114
5115 (define_insn "*lea_1_rex64"
5116   [(set (match_operand:SI 0 "register_operand" "=r")
5117         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5118   "TARGET_64BIT"
5119   "lea{l}\t{%a1, %0|%0, %a1}"
5120   [(set_attr "type" "lea")
5121    (set_attr "mode" "SI")])
5122
5123 (define_insn "*lea_1_zext"
5124   [(set (match_operand:DI 0 "register_operand" "=r")
5125         (zero_extend:DI
5126          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5127   "TARGET_64BIT"
5128   "lea{l}\t{%a1, %k0|%k0, %a1}"
5129   [(set_attr "type" "lea")
5130    (set_attr "mode" "SI")])
5131
5132 (define_insn "*lea_2_rex64"
5133   [(set (match_operand:DI 0 "register_operand" "=r")
5134         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5135   "TARGET_64BIT"
5136   "lea{q}\t{%a1, %0|%0, %a1}"
5137   [(set_attr "type" "lea")
5138    (set_attr "mode" "DI")])
5139
5140 ;; The lea patterns for non-Pmodes needs to be matched by several
5141 ;; insns converted to real lea by splitters.
5142
5143 (define_insn_and_split "*lea_general_1"
5144   [(set (match_operand 0 "register_operand" "=r")
5145         (plus (plus (match_operand 1 "index_register_operand" "r")
5146                     (match_operand 2 "register_operand" "r"))
5147               (match_operand 3 "immediate_operand" "i")))]
5148   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5149     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5150    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5151    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5152    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5153    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5154        || GET_MODE (operands[3]) == VOIDmode)"
5155   "#"
5156   "&& reload_completed"
5157   [(const_int 0)]
5158 {
5159   rtx pat;
5160   operands[0] = gen_lowpart (SImode, operands[0]);
5161   operands[1] = gen_lowpart (Pmode, operands[1]);
5162   operands[2] = gen_lowpart (Pmode, operands[2]);
5163   operands[3] = gen_lowpart (Pmode, operands[3]);
5164   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5165                       operands[3]);
5166   if (Pmode != SImode)
5167     pat = gen_rtx_SUBREG (SImode, pat, 0);
5168   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5169   DONE;
5170 }
5171   [(set_attr "type" "lea")
5172    (set_attr "mode" "SI")])
5173
5174 (define_insn_and_split "*lea_general_1_zext"
5175   [(set (match_operand:DI 0 "register_operand" "=r")
5176         (zero_extend:DI
5177           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5178                             (match_operand:SI 2 "register_operand" "r"))
5179                    (match_operand:SI 3 "immediate_operand" "i"))))]
5180   "TARGET_64BIT"
5181   "#"
5182   "&& reload_completed"
5183   [(set (match_dup 0)
5184         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5185                                                      (match_dup 2))
5186                                             (match_dup 3)) 0)))]
5187 {
5188   operands[1] = gen_lowpart (Pmode, operands[1]);
5189   operands[2] = gen_lowpart (Pmode, operands[2]);
5190   operands[3] = gen_lowpart (Pmode, operands[3]);
5191 }
5192   [(set_attr "type" "lea")
5193    (set_attr "mode" "SI")])
5194
5195 (define_insn_and_split "*lea_general_2"
5196   [(set (match_operand 0 "register_operand" "=r")
5197         (plus (mult (match_operand 1 "index_register_operand" "r")
5198                     (match_operand 2 "const248_operand" "i"))
5199               (match_operand 3 "nonmemory_operand" "ri")))]
5200   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5201     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5202    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5203    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5204    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5205        || GET_MODE (operands[3]) == VOIDmode)"
5206   "#"
5207   "&& reload_completed"
5208   [(const_int 0)]
5209 {
5210   rtx pat;
5211   operands[0] = gen_lowpart (SImode, operands[0]);
5212   operands[1] = gen_lowpart (Pmode, operands[1]);
5213   operands[3] = gen_lowpart (Pmode, operands[3]);
5214   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5215                       operands[3]);
5216   if (Pmode != SImode)
5217     pat = gen_rtx_SUBREG (SImode, pat, 0);
5218   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5219   DONE;
5220 }
5221   [(set_attr "type" "lea")
5222    (set_attr "mode" "SI")])
5223
5224 (define_insn_and_split "*lea_general_2_zext"
5225   [(set (match_operand:DI 0 "register_operand" "=r")
5226         (zero_extend:DI
5227           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5228                             (match_operand:SI 2 "const248_operand" "n"))
5229                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5230   "TARGET_64BIT"
5231   "#"
5232   "&& reload_completed"
5233   [(set (match_dup 0)
5234         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5235                                                      (match_dup 2))
5236                                             (match_dup 3)) 0)))]
5237 {
5238   operands[1] = gen_lowpart (Pmode, operands[1]);
5239   operands[3] = gen_lowpart (Pmode, operands[3]);
5240 }
5241   [(set_attr "type" "lea")
5242    (set_attr "mode" "SI")])
5243
5244 (define_insn_and_split "*lea_general_3"
5245   [(set (match_operand 0 "register_operand" "=r")
5246         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5247                           (match_operand 2 "const248_operand" "i"))
5248                     (match_operand 3 "register_operand" "r"))
5249               (match_operand 4 "immediate_operand" "i")))]
5250   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5251     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5252    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5253    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5254    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5255   "#"
5256   "&& reload_completed"
5257   [(const_int 0)]
5258 {
5259   rtx pat;
5260   operands[0] = gen_lowpart (SImode, operands[0]);
5261   operands[1] = gen_lowpart (Pmode, operands[1]);
5262   operands[3] = gen_lowpart (Pmode, operands[3]);
5263   operands[4] = gen_lowpart (Pmode, operands[4]);
5264   pat = gen_rtx_PLUS (Pmode,
5265                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5266                                                          operands[2]),
5267                                     operands[3]),
5268                       operands[4]);
5269   if (Pmode != SImode)
5270     pat = gen_rtx_SUBREG (SImode, pat, 0);
5271   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5272   DONE;
5273 }
5274   [(set_attr "type" "lea")
5275    (set_attr "mode" "SI")])
5276
5277 (define_insn_and_split "*lea_general_3_zext"
5278   [(set (match_operand:DI 0 "register_operand" "=r")
5279         (zero_extend:DI
5280           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5281                                      (match_operand:SI 2 "const248_operand" "n"))
5282                             (match_operand:SI 3 "register_operand" "r"))
5283                    (match_operand:SI 4 "immediate_operand" "i"))))]
5284   "TARGET_64BIT"
5285   "#"
5286   "&& reload_completed"
5287   [(set (match_dup 0)
5288         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5289                                                               (match_dup 2))
5290                                                      (match_dup 3))
5291                                             (match_dup 4)) 0)))]
5292 {
5293   operands[1] = gen_lowpart (Pmode, operands[1]);
5294   operands[3] = gen_lowpart (Pmode, operands[3]);
5295   operands[4] = gen_lowpart (Pmode, operands[4]);
5296 }
5297   [(set_attr "type" "lea")
5298    (set_attr "mode" "SI")])
5299
5300 (define_insn "*adddi_1_rex64"
5301   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5302         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5303                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5304    (clobber (reg:CC FLAGS_REG))]
5305   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5306 {
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_LEA:
5310       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5311       return "lea{q}\t{%a2, %0|%0, %a2}";
5312
5313     case TYPE_INCDEC:
5314       if (! rtx_equal_p (operands[0], operands[1]))
5315         abort ();
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else if (operands[2] == constm1_rtx)
5319         return "dec{q}\t%0";
5320       else
5321         abort ();
5322
5323     default:
5324       if (! rtx_equal_p (operands[0], operands[1]))
5325         abort ();
5326
5327       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5328          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5329       if (GET_CODE (operands[2]) == CONST_INT
5330           /* Avoid overflows.  */
5331           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5332           && (INTVAL (operands[2]) == 128
5333               || (INTVAL (operands[2]) < 0
5334                   && INTVAL (operands[2]) != -128)))
5335         {
5336           operands[2] = GEN_INT (-INTVAL (operands[2]));
5337           return "sub{q}\t{%2, %0|%0, %2}";
5338         }
5339       return "add{q}\t{%2, %0|%0, %2}";
5340     }
5341 }
5342   [(set (attr "type")
5343      (cond [(eq_attr "alternative" "2")
5344               (const_string "lea")
5345             ; Current assemblers are broken and do not allow @GOTOFF in
5346             ; ought but a memory context.
5347             (match_operand:DI 2 "pic_symbolic_operand" "")
5348               (const_string "lea")
5349             (match_operand:DI 2 "incdec_operand" "")
5350               (const_string "incdec")
5351            ]
5352            (const_string "alu")))
5353    (set_attr "mode" "DI")])
5354
5355 ;; Convert lea to the lea pattern to avoid flags dependency.
5356 (define_split
5357   [(set (match_operand:DI 0 "register_operand" "")
5358         (plus:DI (match_operand:DI 1 "register_operand" "")
5359                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5360    (clobber (reg:CC FLAGS_REG))]
5361   "TARGET_64BIT && reload_completed
5362    && true_regnum (operands[0]) != true_regnum (operands[1])"
5363   [(set (match_dup 0)
5364         (plus:DI (match_dup 1)
5365                  (match_dup 2)))]
5366   "")
5367
5368 (define_insn "*adddi_2_rex64"
5369   [(set (reg 17)
5370         (compare
5371           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5372                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5373           (const_int 0)))                       
5374    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5375         (plus:DI (match_dup 1) (match_dup 2)))]
5376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5377    && ix86_binary_operator_ok (PLUS, DImode, operands)
5378    /* Current assemblers are broken and do not allow @GOTOFF in
5379       ought but a memory context.  */
5380    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5381 {
5382   switch (get_attr_type (insn))
5383     {
5384     case TYPE_INCDEC:
5385       if (! rtx_equal_p (operands[0], operands[1]))
5386         abort ();
5387       if (operands[2] == const1_rtx)
5388         return "inc{q}\t%0";
5389       else if (operands[2] == constm1_rtx)
5390         return "dec{q}\t%0";
5391       else
5392         abort ();
5393
5394     default:
5395       if (! rtx_equal_p (operands[0], operands[1]))
5396         abort ();
5397       /* ???? We ought to handle there the 32bit case too
5398          - do we need new constraint?  */
5399       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5400          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5401       if (GET_CODE (operands[2]) == CONST_INT
5402           /* Avoid overflows.  */
5403           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5404           && (INTVAL (operands[2]) == 128
5405               || (INTVAL (operands[2]) < 0
5406                   && INTVAL (operands[2]) != -128)))
5407         {
5408           operands[2] = GEN_INT (-INTVAL (operands[2]));
5409           return "sub{q}\t{%2, %0|%0, %2}";
5410         }
5411       return "add{q}\t{%2, %0|%0, %2}";
5412     }
5413 }
5414   [(set (attr "type")
5415      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5416         (const_string "incdec")
5417         (const_string "alu")))
5418    (set_attr "mode" "DI")])
5419
5420 (define_insn "*adddi_3_rex64"
5421   [(set (reg 17)
5422         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5423                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5424    (clobber (match_scratch:DI 0 "=r"))]
5425   "TARGET_64BIT
5426    && ix86_match_ccmode (insn, CCZmode)
5427    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5428    /* Current assemblers are broken and do not allow @GOTOFF in
5429       ought but a memory context.  */
5430    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5431 {
5432   switch (get_attr_type (insn))
5433     {
5434     case TYPE_INCDEC:
5435       if (! rtx_equal_p (operands[0], operands[1]))
5436         abort ();
5437       if (operands[2] == const1_rtx)
5438         return "inc{q}\t%0";
5439       else if (operands[2] == constm1_rtx)
5440         return "dec{q}\t%0";
5441       else
5442         abort ();
5443
5444     default:
5445       if (! rtx_equal_p (operands[0], operands[1]))
5446         abort ();
5447       /* ???? We ought to handle there the 32bit case too
5448          - do we need new constraint?  */
5449       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5450          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5451       if (GET_CODE (operands[2]) == CONST_INT
5452           /* Avoid overflows.  */
5453           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{q}\t{%2, %0|%0, %2}";
5460         }
5461       return "add{q}\t{%2, %0|%0, %2}";
5462     }
5463 }
5464   [(set (attr "type")
5465      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5466         (const_string "incdec")
5467         (const_string "alu")))
5468    (set_attr "mode" "DI")])
5469
5470 ; For comparisons against 1, -1 and 128, we may generate better code
5471 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5472 ; is matched then.  We can't accept general immediate, because for
5473 ; case of overflows,  the result is messed up.
5474 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5475 ; when negated.
5476 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5477 ; only for comparisons not depending on it.
5478 (define_insn "*adddi_4_rex64"
5479   [(set (reg 17)
5480         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5481                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5482    (clobber (match_scratch:DI 0 "=rm"))]
5483   "TARGET_64BIT
5484    &&  ix86_match_ccmode (insn, CCGCmode)"
5485 {
5486   switch (get_attr_type (insn))
5487     {
5488     case TYPE_INCDEC:
5489       if (operands[2] == constm1_rtx)
5490         return "inc{q}\t%0";
5491       else if (operands[2] == const1_rtx)
5492         return "dec{q}\t%0";
5493       else
5494         abort();
5495
5496     default:
5497       if (! rtx_equal_p (operands[0], operands[1]))
5498         abort ();
5499       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5501       if ((INTVAL (operands[2]) == -128
5502            || (INTVAL (operands[2]) > 0
5503                && INTVAL (operands[2]) != 128))
5504           /* Avoid overflows.  */
5505           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5506         return "sub{q}\t{%2, %0|%0, %2}";
5507       operands[2] = GEN_INT (-INTVAL (operands[2]));
5508       return "add{q}\t{%2, %0|%0, %2}";
5509     }
5510 }
5511   [(set (attr "type")
5512      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513         (const_string "incdec")
5514         (const_string "alu")))
5515    (set_attr "mode" "DI")])
5516
5517 (define_insn "*adddi_5_rex64"
5518   [(set (reg 17)
5519         (compare
5520           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5521                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5522           (const_int 0)))                       
5523    (clobber (match_scratch:DI 0 "=r"))]
5524   "TARGET_64BIT
5525    && ix86_match_ccmode (insn, CCGOCmode)
5526    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5527    /* Current assemblers are broken and do not allow @GOTOFF in
5528       ought but a memory context.  */
5529    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5530 {
5531   switch (get_attr_type (insn))
5532     {
5533     case TYPE_INCDEC:
5534       if (! rtx_equal_p (operands[0], operands[1]))
5535         abort ();
5536       if (operands[2] == const1_rtx)
5537         return "inc{q}\t%0";
5538       else if (operands[2] == constm1_rtx)
5539         return "dec{q}\t%0";
5540       else
5541         abort();
5542
5543     default:
5544       if (! rtx_equal_p (operands[0], operands[1]))
5545         abort ();
5546       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5547          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5548       if (GET_CODE (operands[2]) == CONST_INT
5549           /* Avoid overflows.  */
5550           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5551           && (INTVAL (operands[2]) == 128
5552               || (INTVAL (operands[2]) < 0
5553                   && INTVAL (operands[2]) != -128)))
5554         {
5555           operands[2] = GEN_INT (-INTVAL (operands[2]));
5556           return "sub{q}\t{%2, %0|%0, %2}";
5557         }
5558       return "add{q}\t{%2, %0|%0, %2}";
5559     }
5560 }
5561   [(set (attr "type")
5562      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5563         (const_string "incdec")
5564         (const_string "alu")))
5565    (set_attr "mode" "DI")])
5566
5567
5568 (define_insn "*addsi_1"
5569   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5570         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5571                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5572    (clobber (reg:CC FLAGS_REG))]
5573   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5574 {
5575   switch (get_attr_type (insn))
5576     {
5577     case TYPE_LEA:
5578       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5579       return "lea{l}\t{%a2, %0|%0, %a2}";
5580
5581     case TYPE_INCDEC:
5582       if (! rtx_equal_p (operands[0], operands[1]))
5583         abort ();
5584       if (operands[2] == const1_rtx)
5585         return "inc{l}\t%0";
5586       else if (operands[2] == constm1_rtx)
5587         return "dec{l}\t%0";
5588       else
5589         abort();
5590
5591     default:
5592       if (! rtx_equal_p (operands[0], operands[1]))
5593         abort ();
5594
5595       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5597       if (GET_CODE (operands[2]) == CONST_INT
5598           && (INTVAL (operands[2]) == 128
5599               || (INTVAL (operands[2]) < 0
5600                   && INTVAL (operands[2]) != -128)))
5601         {
5602           operands[2] = GEN_INT (-INTVAL (operands[2]));
5603           return "sub{l}\t{%2, %0|%0, %2}";
5604         }
5605       return "add{l}\t{%2, %0|%0, %2}";
5606     }
5607 }
5608   [(set (attr "type")
5609      (cond [(eq_attr "alternative" "2")
5610               (const_string "lea")
5611             ; Current assemblers are broken and do not allow @GOTOFF in
5612             ; ought but a memory context.
5613             (match_operand:SI 2 "pic_symbolic_operand" "")
5614               (const_string "lea")
5615             (match_operand:SI 2 "incdec_operand" "")
5616               (const_string "incdec")
5617            ]
5618            (const_string "alu")))
5619    (set_attr "mode" "SI")])
5620
5621 ;; Convert lea to the lea pattern to avoid flags dependency.
5622 (define_split
5623   [(set (match_operand 0 "register_operand" "")
5624         (plus (match_operand 1 "register_operand" "")
5625               (match_operand 2 "nonmemory_operand" "")))
5626    (clobber (reg:CC FLAGS_REG))]
5627   "reload_completed
5628    && true_regnum (operands[0]) != true_regnum (operands[1])"
5629   [(const_int 0)]
5630 {
5631   rtx pat;
5632   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5633      may confuse gen_lowpart.  */
5634   if (GET_MODE (operands[0]) != Pmode)
5635     {
5636       operands[1] = gen_lowpart (Pmode, operands[1]);
5637       operands[2] = gen_lowpart (Pmode, operands[2]);
5638     }
5639   operands[0] = gen_lowpart (SImode, operands[0]);
5640   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5641   if (Pmode != SImode)
5642     pat = gen_rtx_SUBREG (SImode, pat, 0);
5643   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5644   DONE;
5645 })
5646
5647 ;; It may seem that nonimmediate operand is proper one for operand 1.
5648 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5649 ;; we take care in ix86_binary_operator_ok to not allow two memory
5650 ;; operands so proper swapping will be done in reload.  This allow
5651 ;; patterns constructed from addsi_1 to match.
5652 (define_insn "addsi_1_zext"
5653   [(set (match_operand:DI 0 "register_operand" "=r,r")
5654         (zero_extend:DI
5655           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5656                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5657    (clobber (reg:CC FLAGS_REG))]
5658   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5659 {
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_LEA:
5663       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5664       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5665
5666     case TYPE_INCDEC:
5667       if (operands[2] == const1_rtx)
5668         return "inc{l}\t%k0";
5669       else if (operands[2] == constm1_rtx)
5670         return "dec{l}\t%k0";
5671       else
5672         abort();
5673
5674     default:
5675       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5676          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5677       if (GET_CODE (operands[2]) == CONST_INT
5678           && (INTVAL (operands[2]) == 128
5679               || (INTVAL (operands[2]) < 0
5680                   && INTVAL (operands[2]) != -128)))
5681         {
5682           operands[2] = GEN_INT (-INTVAL (operands[2]));
5683           return "sub{l}\t{%2, %k0|%k0, %2}";
5684         }
5685       return "add{l}\t{%2, %k0|%k0, %2}";
5686     }
5687 }
5688   [(set (attr "type")
5689      (cond [(eq_attr "alternative" "1")
5690               (const_string "lea")
5691             ; Current assemblers are broken and do not allow @GOTOFF in
5692             ; ought but a memory context.
5693             (match_operand:SI 2 "pic_symbolic_operand" "")
5694               (const_string "lea")
5695             (match_operand:SI 2 "incdec_operand" "")
5696               (const_string "incdec")
5697            ]
5698            (const_string "alu")))
5699    (set_attr "mode" "SI")])
5700
5701 ;; Convert lea to the lea pattern to avoid flags dependency.
5702 (define_split
5703   [(set (match_operand:DI 0 "register_operand" "")
5704         (zero_extend:DI
5705           (plus:SI (match_operand:SI 1 "register_operand" "")
5706                    (match_operand:SI 2 "nonmemory_operand" ""))))
5707    (clobber (reg:CC FLAGS_REG))]
5708   "TARGET_64BIT && reload_completed
5709    && true_regnum (operands[0]) != true_regnum (operands[1])"
5710   [(set (match_dup 0)
5711         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5712 {
5713   operands[1] = gen_lowpart (Pmode, operands[1]);
5714   operands[2] = gen_lowpart (Pmode, operands[2]);
5715 })
5716
5717 (define_insn "*addsi_2"
5718   [(set (reg 17)
5719         (compare
5720           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5721                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5722           (const_int 0)))                       
5723    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5724         (plus:SI (match_dup 1) (match_dup 2)))]
5725   "ix86_match_ccmode (insn, CCGOCmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 {
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (! rtx_equal_p (operands[0], operands[1]))
5735         abort ();
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else if (operands[2] == constm1_rtx)
5739         return "dec{l}\t%0";
5740       else
5741         abort();
5742
5743     default:
5744       if (! rtx_equal_p (operands[0], operands[1]))
5745         abort ();
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5758 }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5764
5765 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5766 (define_insn "*addsi_2_zext"
5767   [(set (reg 17)
5768         (compare
5769           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5770                    (match_operand:SI 2 "general_operand" "rmni"))
5771           (const_int 0)))                       
5772    (set (match_operand:DI 0 "register_operand" "=r")
5773         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5774   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5775    && ix86_binary_operator_ok (PLUS, SImode, operands)
5776    /* Current assemblers are broken and do not allow @GOTOFF in
5777       ought but a memory context.  */
5778    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5779 {
5780   switch (get_attr_type (insn))
5781     {
5782     case TYPE_INCDEC:
5783       if (operands[2] == const1_rtx)
5784         return "inc{l}\t%k0";
5785       else if (operands[2] == constm1_rtx)
5786         return "dec{l}\t%k0";
5787       else
5788         abort();
5789
5790     default:
5791       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5793       if (GET_CODE (operands[2]) == CONST_INT
5794           && (INTVAL (operands[2]) == 128
5795               || (INTVAL (operands[2]) < 0
5796                   && INTVAL (operands[2]) != -128)))
5797         {
5798           operands[2] = GEN_INT (-INTVAL (operands[2]));
5799           return "sub{l}\t{%2, %k0|%k0, %2}";
5800         }
5801       return "add{l}\t{%2, %k0|%k0, %2}";
5802     }
5803 }
5804   [(set (attr "type")
5805      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5806         (const_string "incdec")
5807         (const_string "alu")))
5808    (set_attr "mode" "SI")])
5809
5810 (define_insn "*addsi_3"
5811   [(set (reg 17)
5812         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5813                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5814    (clobber (match_scratch:SI 0 "=r"))]
5815   "ix86_match_ccmode (insn, CCZmode)
5816    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5817    /* Current assemblers are broken and do not allow @GOTOFF in
5818       ought but a memory context.  */
5819    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5820 {
5821   switch (get_attr_type (insn))
5822     {
5823     case TYPE_INCDEC:
5824       if (! rtx_equal_p (operands[0], operands[1]))
5825         abort ();
5826       if (operands[2] == const1_rtx)
5827         return "inc{l}\t%0";
5828       else if (operands[2] == constm1_rtx)
5829         return "dec{l}\t%0";
5830       else
5831         abort();
5832
5833     default:
5834       if (! rtx_equal_p (operands[0], operands[1]))
5835         abort ();
5836       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5837          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5838       if (GET_CODE (operands[2]) == CONST_INT
5839           && (INTVAL (operands[2]) == 128
5840               || (INTVAL (operands[2]) < 0
5841                   && INTVAL (operands[2]) != -128)))
5842         {
5843           operands[2] = GEN_INT (-INTVAL (operands[2]));
5844           return "sub{l}\t{%2, %0|%0, %2}";
5845         }
5846       return "add{l}\t{%2, %0|%0, %2}";
5847     }
5848 }
5849   [(set (attr "type")
5850      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set_attr "mode" "SI")])
5854
5855 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5856 (define_insn "*addsi_3_zext"
5857   [(set (reg 17)
5858         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5859                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5860    (set (match_operand:DI 0 "register_operand" "=r")
5861         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5862   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5863    && ix86_binary_operator_ok (PLUS, SImode, operands)
5864    /* Current assemblers are broken and do not allow @GOTOFF in
5865       ought but a memory context.  */
5866    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5867 {
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{l}\t%k0";
5873       else if (operands[2] == constm1_rtx)
5874         return "dec{l}\t%k0";
5875       else
5876         abort();
5877
5878     default:
5879       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881       if (GET_CODE (operands[2]) == CONST_INT
5882           && (INTVAL (operands[2]) == 128
5883               || (INTVAL (operands[2]) < 0
5884                   && INTVAL (operands[2]) != -128)))
5885         {
5886           operands[2] = GEN_INT (-INTVAL (operands[2]));
5887           return "sub{l}\t{%2, %k0|%k0, %2}";
5888         }
5889       return "add{l}\t{%2, %k0|%k0, %2}";
5890     }
5891 }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set_attr "mode" "SI")])
5897
5898 ; For comparisons against 1, -1 and 128, we may generate better code
5899 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5900 ; is matched then.  We can't accept general immediate, because for
5901 ; case of overflows,  the result is messed up.
5902 ; This pattern also don't hold of 0x80000000, since the value overflows
5903 ; when negated.
5904 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5905 ; only for comparisons not depending on it.
5906 (define_insn "*addsi_4"
5907   [(set (reg 17)
5908         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5909                  (match_operand:SI 2 "const_int_operand" "n")))
5910    (clobber (match_scratch:SI 0 "=rm"))]
5911   "ix86_match_ccmode (insn, CCGCmode)
5912    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5913 {
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_INCDEC:
5917       if (operands[2] == constm1_rtx)
5918         return "inc{l}\t%0";
5919       else if (operands[2] == const1_rtx)
5920         return "dec{l}\t%0";
5921       else
5922         abort();
5923
5924     default:
5925       if (! rtx_equal_p (operands[0], operands[1]))
5926         abort ();
5927       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5929       if ((INTVAL (operands[2]) == -128
5930            || (INTVAL (operands[2]) > 0
5931                && INTVAL (operands[2]) != 128)))
5932         return "sub{l}\t{%2, %0|%0, %2}";
5933       operands[2] = GEN_INT (-INTVAL (operands[2]));
5934       return "add{l}\t{%2, %0|%0, %2}";
5935     }
5936 }
5937   [(set (attr "type")
5938      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5939         (const_string "incdec")
5940         (const_string "alu")))
5941    (set_attr "mode" "SI")])
5942
5943 (define_insn "*addsi_5"
5944   [(set (reg 17)
5945         (compare
5946           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5947                    (match_operand:SI 2 "general_operand" "rmni"))
5948           (const_int 0)))                       
5949    (clobber (match_scratch:SI 0 "=r"))]
5950   "ix86_match_ccmode (insn, CCGOCmode)
5951    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5952    /* Current assemblers are broken and do not allow @GOTOFF in
5953       ought but a memory context.  */
5954    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5955 {
5956   switch (get_attr_type (insn))
5957     {
5958     case TYPE_INCDEC:
5959       if (! rtx_equal_p (operands[0], operands[1]))
5960         abort ();
5961       if (operands[2] == const1_rtx)
5962         return "inc{l}\t%0";
5963       else if (operands[2] == constm1_rtx)
5964         return "dec{l}\t%0";
5965       else
5966         abort();
5967
5968     default:
5969       if (! rtx_equal_p (operands[0], operands[1]))
5970         abort ();
5971       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5973       if (GET_CODE (operands[2]) == CONST_INT
5974           && (INTVAL (operands[2]) == 128
5975               || (INTVAL (operands[2]) < 0
5976                   && INTVAL (operands[2]) != -128)))
5977         {
5978           operands[2] = GEN_INT (-INTVAL (operands[2]));
5979           return "sub{l}\t{%2, %0|%0, %2}";
5980         }
5981       return "add{l}\t{%2, %0|%0, %2}";
5982     }
5983 }
5984   [(set (attr "type")
5985      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5986         (const_string "incdec")
5987         (const_string "alu")))
5988    (set_attr "mode" "SI")])
5989
5990 (define_expand "addhi3"
5991   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5992                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5993                             (match_operand:HI 2 "general_operand" "")))
5994               (clobber (reg:CC FLAGS_REG))])]
5995   "TARGET_HIMODE_MATH"
5996   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5997
5998 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5999 ;; type optimizations enabled by define-splits.  This is not important
6000 ;; for PII, and in fact harmful because of partial register stalls.
6001
6002 (define_insn "*addhi_1_lea"
6003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6004         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6005                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6006    (clobber (reg:CC FLAGS_REG))]
6007   "!TARGET_PARTIAL_REG_STALL
6008    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6009 {
6010   switch (get_attr_type (insn))
6011     {
6012     case TYPE_LEA:
6013       return "#";
6014     case TYPE_INCDEC:
6015       if (operands[2] == const1_rtx)
6016         return "inc{w}\t%0";
6017       else if (operands[2] == constm1_rtx)
6018         return "dec{w}\t%0";
6019       abort();
6020
6021     default:
6022       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6024       if (GET_CODE (operands[2]) == CONST_INT
6025           && (INTVAL (operands[2]) == 128
6026               || (INTVAL (operands[2]) < 0
6027                   && INTVAL (operands[2]) != -128)))
6028         {
6029           operands[2] = GEN_INT (-INTVAL (operands[2]));
6030           return "sub{w}\t{%2, %0|%0, %2}";
6031         }
6032       return "add{w}\t{%2, %0|%0, %2}";
6033     }
6034 }
6035   [(set (attr "type")
6036      (if_then_else (eq_attr "alternative" "2")
6037         (const_string "lea")
6038         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6039            (const_string "incdec")
6040            (const_string "alu"))))
6041    (set_attr "mode" "HI,HI,SI")])
6042
6043 (define_insn "*addhi_1"
6044   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6045         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046                  (match_operand:HI 2 "general_operand" "ri,rm")))
6047    (clobber (reg:CC FLAGS_REG))]
6048   "TARGET_PARTIAL_REG_STALL
6049    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6050 {
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       if (operands[2] == const1_rtx)
6055         return "inc{w}\t%0";
6056       else if (operands[2] == constm1_rtx)
6057         return "dec{w}\t%0";
6058       abort();
6059
6060     default:
6061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6063       if (GET_CODE (operands[2]) == CONST_INT
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           return "sub{w}\t{%2, %0|%0, %2}";
6070         }
6071       return "add{w}\t{%2, %0|%0, %2}";
6072     }
6073 }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set_attr "mode" "HI")])
6079
6080 (define_insn "*addhi_2"
6081   [(set (reg 17)
6082         (compare
6083           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6084                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6085           (const_int 0)))                       
6086    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6087         (plus:HI (match_dup 1) (match_dup 2)))]
6088   "ix86_match_ccmode (insn, CCGOCmode)
6089    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6090 {
6091   switch (get_attr_type (insn))
6092     {
6093     case TYPE_INCDEC:
6094       if (operands[2] == const1_rtx)
6095         return "inc{w}\t%0";
6096       else if (operands[2] == constm1_rtx)
6097         return "dec{w}\t%0";
6098       abort();
6099
6100     default:
6101       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6102          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6103       if (GET_CODE (operands[2]) == CONST_INT
6104           && (INTVAL (operands[2]) == 128
6105               || (INTVAL (operands[2]) < 0
6106                   && INTVAL (operands[2]) != -128)))
6107         {
6108           operands[2] = GEN_INT (-INTVAL (operands[2]));
6109           return "sub{w}\t{%2, %0|%0, %2}";
6110         }
6111       return "add{w}\t{%2, %0|%0, %2}";
6112     }
6113 }
6114   [(set (attr "type")
6115      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6116         (const_string "incdec")
6117         (const_string "alu")))
6118    (set_attr "mode" "HI")])
6119
6120 (define_insn "*addhi_3"
6121   [(set (reg 17)
6122         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6123                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6124    (clobber (match_scratch:HI 0 "=r"))]
6125   "ix86_match_ccmode (insn, CCZmode)
6126    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6127 {
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return "inc{w}\t%0";
6133       else if (operands[2] == constm1_rtx)
6134         return "dec{w}\t%0";
6135       abort();
6136
6137     default:
6138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6140       if (GET_CODE (operands[2]) == CONST_INT
6141           && (INTVAL (operands[2]) == 128
6142               || (INTVAL (operands[2]) < 0
6143                   && INTVAL (operands[2]) != -128)))
6144         {
6145           operands[2] = GEN_INT (-INTVAL (operands[2]));
6146           return "sub{w}\t{%2, %0|%0, %2}";
6147         }
6148       return "add{w}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "HI")])
6156
6157 ; See comments above addsi_3_imm for details.
6158 (define_insn "*addhi_4"
6159   [(set (reg 17)
6160         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6161                  (match_operand:HI 2 "const_int_operand" "n")))
6162    (clobber (match_scratch:HI 0 "=rm"))]
6163   "ix86_match_ccmode (insn, CCGCmode)
6164    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == constm1_rtx)
6170         return "inc{w}\t%0";
6171       else if (operands[2] == const1_rtx)
6172         return "dec{w}\t%0";
6173       else
6174         abort();
6175
6176     default:
6177       if (! rtx_equal_p (operands[0], operands[1]))
6178         abort ();
6179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6181       if ((INTVAL (operands[2]) == -128
6182            || (INTVAL (operands[2]) > 0
6183                && INTVAL (operands[2]) != 128)))
6184         return "sub{w}\t{%2, %0|%0, %2}";
6185       operands[2] = GEN_INT (-INTVAL (operands[2]));
6186       return "add{w}\t{%2, %0|%0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "SI")])
6194
6195
6196 (define_insn "*addhi_5"
6197   [(set (reg 17)
6198         (compare
6199           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6200                    (match_operand:HI 2 "general_operand" "rmni"))
6201           (const_int 0)))                       
6202    (clobber (match_scratch:HI 0 "=r"))]
6203   "ix86_match_ccmode (insn, CCGOCmode)
6204    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6205 {
6206   switch (get_attr_type (insn))
6207     {
6208     case TYPE_INCDEC:
6209       if (operands[2] == const1_rtx)
6210         return "inc{w}\t%0";
6211       else if (operands[2] == constm1_rtx)
6212         return "dec{w}\t%0";
6213       abort();
6214
6215     default:
6216       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6217          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6218       if (GET_CODE (operands[2]) == CONST_INT
6219           && (INTVAL (operands[2]) == 128
6220               || (INTVAL (operands[2]) < 0
6221                   && INTVAL (operands[2]) != -128)))
6222         {
6223           operands[2] = GEN_INT (-INTVAL (operands[2]));
6224           return "sub{w}\t{%2, %0|%0, %2}";
6225         }
6226       return "add{w}\t{%2, %0|%0, %2}";
6227     }
6228 }
6229   [(set (attr "type")
6230      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6231         (const_string "incdec")
6232         (const_string "alu")))
6233    (set_attr "mode" "HI")])
6234
6235 (define_expand "addqi3"
6236   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6237                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6238                             (match_operand:QI 2 "general_operand" "")))
6239               (clobber (reg:CC FLAGS_REG))])]
6240   "TARGET_QIMODE_MATH"
6241   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6242
6243 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6244 (define_insn "*addqi_1_lea"
6245   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6246         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6247                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6248    (clobber (reg:CC FLAGS_REG))]
6249   "!TARGET_PARTIAL_REG_STALL
6250    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6251 {
6252   int widen = (which_alternative == 2);
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_LEA:
6256       return "#";
6257     case TYPE_INCDEC:
6258       if (operands[2] == const1_rtx)
6259         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6260       else if (operands[2] == constm1_rtx)
6261         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6262       abort();
6263
6264     default:
6265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6267       if (GET_CODE (operands[2]) == CONST_INT
6268           && (INTVAL (operands[2]) == 128
6269               || (INTVAL (operands[2]) < 0
6270                   && INTVAL (operands[2]) != -128)))
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           if (widen)
6274             return "sub{l}\t{%2, %k0|%k0, %2}";
6275           else
6276             return "sub{b}\t{%2, %0|%0, %2}";
6277         }
6278       if (widen)
6279         return "add{l}\t{%k2, %k0|%k0, %k2}";
6280       else
6281         return "add{b}\t{%2, %0|%0, %2}";
6282     }
6283 }
6284   [(set (attr "type")
6285      (if_then_else (eq_attr "alternative" "3")
6286         (const_string "lea")
6287         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288            (const_string "incdec")
6289            (const_string "alu"))))
6290    (set_attr "mode" "QI,QI,SI,SI")])
6291
6292 (define_insn "*addqi_1"
6293   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6294         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6295                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6296    (clobber (reg:CC FLAGS_REG))]
6297   "TARGET_PARTIAL_REG_STALL
6298    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6299 {
6300   int widen = (which_alternative == 2);
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == const1_rtx)
6305         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6306       else if (operands[2] == constm1_rtx)
6307         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6308       abort();
6309
6310     default:
6311       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6313       if (GET_CODE (operands[2]) == CONST_INT
6314           && (INTVAL (operands[2]) == 128
6315               || (INTVAL (operands[2]) < 0
6316                   && INTVAL (operands[2]) != -128)))
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           if (widen)
6320             return "sub{l}\t{%2, %k0|%k0, %2}";
6321           else
6322             return "sub{b}\t{%2, %0|%0, %2}";
6323         }
6324       if (widen)
6325         return "add{l}\t{%k2, %k0|%k0, %k2}";
6326       else
6327         return "add{b}\t{%2, %0|%0, %2}";
6328     }
6329 }
6330   [(set (attr "type")
6331      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6332         (const_string "incdec")
6333         (const_string "alu")))
6334    (set_attr "mode" "QI,QI,SI")])
6335
6336 (define_insn "*addqi_1_slp"
6337   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6338         (plus:QI (match_dup 0)
6339                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6340    (clobber (reg:CC FLAGS_REG))]
6341   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6342    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6343 {
6344   switch (get_attr_type (insn))
6345     {
6346     case TYPE_INCDEC:
6347       if (operands[1] == const1_rtx)
6348         return "inc{b}\t%0";
6349       else if (operands[1] == constm1_rtx)
6350         return "dec{b}\t%0";
6351       abort();
6352
6353     default:
6354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6355       if (GET_CODE (operands[1]) == CONST_INT
6356           && INTVAL (operands[1]) < 0)
6357         {
6358           operands[1] = GEN_INT (-INTVAL (operands[1]));
6359           return "sub{b}\t{%1, %0|%0, %1}";
6360         }
6361       return "add{b}\t{%1, %0|%0, %1}";
6362     }
6363 }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu1")))
6368    (set_attr "mode" "QI")])
6369
6370 (define_insn "*addqi_2"
6371   [(set (reg 17)
6372         (compare
6373           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6374                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6375           (const_int 0)))
6376    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6377         (plus:QI (match_dup 1) (match_dup 2)))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%0";
6386       else if (operands[2] == constm1_rtx
6387                || (GET_CODE (operands[2]) == CONST_INT
6388                    && INTVAL (operands[2]) == 255))
6389         return "dec{b}\t%0";
6390       abort();
6391
6392     default:
6393       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6394       if (GET_CODE (operands[2]) == CONST_INT
6395           && INTVAL (operands[2]) < 0)
6396         {
6397           operands[2] = GEN_INT (-INTVAL (operands[2]));
6398           return "sub{b}\t{%2, %0|%0, %2}";
6399         }
6400       return "add{b}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set_attr "mode" "QI")])
6408
6409 (define_insn "*addqi_3"
6410   [(set (reg 17)
6411         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6412                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6413    (clobber (match_scratch:QI 0 "=q"))]
6414   "ix86_match_ccmode (insn, CCZmode)
6415    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6416 {
6417   switch (get_attr_type (insn))
6418     {
6419     case TYPE_INCDEC:
6420       if (operands[2] == const1_rtx)
6421         return "inc{b}\t%0";
6422       else if (operands[2] == constm1_rtx
6423                || (GET_CODE (operands[2]) == CONST_INT
6424                    && INTVAL (operands[2]) == 255))
6425         return "dec{b}\t%0";
6426       abort();
6427
6428     default:
6429       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6430       if (GET_CODE (operands[2]) == CONST_INT
6431           && INTVAL (operands[2]) < 0)
6432         {
6433           operands[2] = GEN_INT (-INTVAL (operands[2]));
6434           return "sub{b}\t{%2, %0|%0, %2}";
6435         }
6436       return "add{b}\t{%2, %0|%0, %2}";
6437     }
6438 }
6439   [(set (attr "type")
6440      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6441         (const_string "incdec")
6442         (const_string "alu")))
6443    (set_attr "mode" "QI")])
6444
6445 ; See comments above addsi_3_imm for details.
6446 (define_insn "*addqi_4"
6447   [(set (reg 17)
6448         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6449                  (match_operand:QI 2 "const_int_operand" "n")))
6450    (clobber (match_scratch:QI 0 "=qm"))]
6451   "ix86_match_ccmode (insn, CCGCmode)
6452    && (INTVAL (operands[2]) & 0xff) != 0x80"
6453 {
6454   switch (get_attr_type (insn))
6455     {
6456     case TYPE_INCDEC:
6457       if (operands[2] == constm1_rtx
6458           || (GET_CODE (operands[2]) == CONST_INT
6459               && INTVAL (operands[2]) == 255))
6460         return "inc{b}\t%0";
6461       else if (operands[2] == const1_rtx)
6462         return "dec{b}\t%0";
6463       else
6464         abort();
6465
6466     default:
6467       if (! rtx_equal_p (operands[0], operands[1]))
6468         abort ();
6469       if (INTVAL (operands[2]) < 0)
6470         {
6471           operands[2] = GEN_INT (-INTVAL (operands[2]));
6472           return "add{b}\t{%2, %0|%0, %2}";
6473         }
6474       return "sub{b}\t{%2, %0|%0, %2}";
6475     }
6476 }
6477   [(set (attr "type")
6478      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6479         (const_string "incdec")
6480         (const_string "alu")))
6481    (set_attr "mode" "QI")])
6482
6483
6484 (define_insn "*addqi_5"
6485   [(set (reg 17)
6486         (compare
6487           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6488                    (match_operand:QI 2 "general_operand" "qmni"))
6489           (const_int 0)))
6490    (clobber (match_scratch:QI 0 "=q"))]
6491   "ix86_match_ccmode (insn, CCGOCmode)
6492    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6493 {
6494   switch (get_attr_type (insn))
6495     {
6496     case TYPE_INCDEC:
6497       if (operands[2] == const1_rtx)
6498         return "inc{b}\t%0";
6499       else if (operands[2] == constm1_rtx
6500                || (GET_CODE (operands[2]) == CONST_INT
6501                    && INTVAL (operands[2]) == 255))
6502         return "dec{b}\t%0";
6503       abort();
6504
6505     default:
6506       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6507       if (GET_CODE (operands[2]) == CONST_INT
6508           && INTVAL (operands[2]) < 0)
6509         {
6510           operands[2] = GEN_INT (-INTVAL (operands[2]));
6511           return "sub{b}\t{%2, %0|%0, %2}";
6512         }
6513       return "add{b}\t{%2, %0|%0, %2}";
6514     }
6515 }
6516   [(set (attr "type")
6517      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6518         (const_string "incdec")
6519         (const_string "alu")))
6520    (set_attr "mode" "QI")])
6521
6522
6523 (define_insn "addqi_ext_1"
6524   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525                          (const_int 8)
6526                          (const_int 8))
6527         (plus:SI
6528           (zero_extract:SI
6529             (match_operand 1 "ext_register_operand" "0")
6530             (const_int 8)
6531             (const_int 8))
6532           (match_operand:QI 2 "general_operand" "Qmn")))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "!TARGET_64BIT"
6535 {
6536   switch (get_attr_type (insn))
6537     {
6538     case TYPE_INCDEC:
6539       if (operands[2] == const1_rtx)
6540         return "inc{b}\t%h0";
6541       else if (operands[2] == constm1_rtx
6542                || (GET_CODE (operands[2]) == CONST_INT
6543                    && INTVAL (operands[2]) == 255))
6544         return "dec{b}\t%h0";
6545       abort();
6546
6547     default:
6548       return "add{b}\t{%2, %h0|%h0, %2}";
6549     }
6550 }
6551   [(set (attr "type")
6552      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6553         (const_string "incdec")
6554         (const_string "alu")))
6555    (set_attr "mode" "QI")])
6556
6557 (define_insn "*addqi_ext_1_rex64"
6558   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6559                          (const_int 8)
6560                          (const_int 8))
6561         (plus:SI
6562           (zero_extract:SI
6563             (match_operand 1 "ext_register_operand" "0")
6564             (const_int 8)
6565             (const_int 8))
6566           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "TARGET_64BIT"
6569 {
6570   switch (get_attr_type (insn))
6571     {
6572     case TYPE_INCDEC:
6573       if (operands[2] == const1_rtx)
6574         return "inc{b}\t%h0";
6575       else if (operands[2] == constm1_rtx
6576                || (GET_CODE (operands[2]) == CONST_INT
6577                    && INTVAL (operands[2]) == 255))
6578         return "dec{b}\t%h0";
6579       abort();
6580
6581     default:
6582       return "add{b}\t{%2, %h0|%h0, %2}";
6583     }
6584 }
6585   [(set (attr "type")
6586      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6587         (const_string "incdec")
6588         (const_string "alu")))
6589    (set_attr "mode" "QI")])
6590
6591 (define_insn "*addqi_ext_2"
6592   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6593                          (const_int 8)
6594                          (const_int 8))
6595         (plus:SI
6596           (zero_extract:SI
6597             (match_operand 1 "ext_register_operand" "%0")
6598             (const_int 8)
6599             (const_int 8))
6600           (zero_extract:SI
6601             (match_operand 2 "ext_register_operand" "Q")
6602             (const_int 8)
6603             (const_int 8))))
6604    (clobber (reg:CC FLAGS_REG))]
6605   ""
6606   "add{b}\t{%h2, %h0|%h0, %h2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "QI")])
6609
6610 ;; The patterns that match these are at the end of this file.
6611
6612 (define_expand "addxf3"
6613   [(set (match_operand:XF 0 "register_operand" "")
6614         (plus:XF (match_operand:XF 1 "register_operand" "")
6615                  (match_operand:XF 2 "register_operand" "")))]
6616   "TARGET_80387"
6617   "")
6618
6619 (define_expand "adddf3"
6620   [(set (match_operand:DF 0 "register_operand" "")
6621         (plus:DF (match_operand:DF 1 "register_operand" "")
6622                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6623   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6624   "")
6625
6626 (define_expand "addsf3"
6627   [(set (match_operand:SF 0 "register_operand" "")
6628         (plus:SF (match_operand:SF 1 "register_operand" "")
6629                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6630   "TARGET_80387 || TARGET_SSE_MATH"
6631   "")
6632 \f
6633 ;; Subtract instructions
6634
6635 ;; %%% splits for subsidi3
6636
6637 (define_expand "subdi3"
6638   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6639                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6640                              (match_operand:DI 2 "x86_64_general_operand" "")))
6641               (clobber (reg:CC FLAGS_REG))])]
6642   ""
6643   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6644
6645 (define_insn "*subdi3_1"
6646   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6647         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6648                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6651   "#")
6652
6653 (define_split
6654   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6655         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6656                   (match_operand:DI 2 "general_operand" "")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "!TARGET_64BIT && reload_completed"
6659   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6660               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6661    (parallel [(set (match_dup 3)
6662                    (minus:SI (match_dup 4)
6663                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6664                                       (match_dup 5))))
6665               (clobber (reg:CC FLAGS_REG))])]
6666   "split_di (operands+0, 1, operands+0, operands+3);
6667    split_di (operands+1, 1, operands+1, operands+4);
6668    split_di (operands+2, 1, operands+2, operands+5);")
6669
6670 (define_insn "subdi3_carry_rex64"
6671   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6672           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6673             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6674                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6675    (clobber (reg:CC FLAGS_REG))]
6676   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6677   "sbb{q}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "pent_pair" "pu")
6680    (set_attr "mode" "DI")])
6681
6682 (define_insn "*subdi_1_rex64"
6683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6684         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6685                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6686    (clobber (reg:CC FLAGS_REG))]
6687   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6691
6692 (define_insn "*subdi_2_rex64"
6693   [(set (reg 17)
6694         (compare
6695           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6696                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6697           (const_int 0)))
6698    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6699         (minus:DI (match_dup 1) (match_dup 2)))]
6700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6702   "sub{q}\t{%2, %0|%0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "DI")])
6705
6706 (define_insn "*subdi_3_rex63"
6707   [(set (reg 17)
6708         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6709                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6710    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6711         (minus:DI (match_dup 1) (match_dup 2)))]
6712   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714   "sub{q}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "DI")])
6717
6718 (define_insn "subqi3_carry"
6719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6720           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6721             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6722                (match_operand:QI 2 "general_operand" "qi,qm"))))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6725   "sbb{b}\t{%2, %0|%0, %2}"
6726   [(set_attr "type" "alu")
6727    (set_attr "pent_pair" "pu")
6728    (set_attr "mode" "QI")])
6729
6730 (define_insn "subhi3_carry"
6731   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6732           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6733             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6734                (match_operand:HI 2 "general_operand" "ri,rm"))))
6735    (clobber (reg:CC FLAGS_REG))]
6736   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6737   "sbb{w}\t{%2, %0|%0, %2}"
6738   [(set_attr "type" "alu")
6739    (set_attr "pent_pair" "pu")
6740    (set_attr "mode" "HI")])
6741
6742 (define_insn "subsi3_carry"
6743   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6745             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6746                (match_operand:SI 2 "general_operand" "ri,rm"))))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6749   "sbb{l}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "pent_pair" "pu")
6752    (set_attr "mode" "SI")])
6753
6754 (define_insn "subsi3_carry_zext"
6755   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6756           (zero_extend:DI
6757             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6758               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6759                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762   "sbb{l}\t{%2, %k0|%k0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "pent_pair" "pu")
6765    (set_attr "mode" "SI")])
6766
6767 (define_expand "subsi3"
6768   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6769                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6770                              (match_operand:SI 2 "general_operand" "")))
6771               (clobber (reg:CC FLAGS_REG))])]
6772   ""
6773   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6774
6775 (define_insn "*subsi_1"
6776   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6777         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6778                   (match_operand:SI 2 "general_operand" "ri,rm")))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6781   "sub{l}\t{%2, %0|%0, %2}"
6782   [(set_attr "type" "alu")
6783    (set_attr "mode" "SI")])
6784
6785 (define_insn "*subsi_1_zext"
6786   [(set (match_operand:DI 0 "register_operand" "=r")
6787         (zero_extend:DI
6788           (minus:SI (match_operand:SI 1 "register_operand" "0")
6789                     (match_operand:SI 2 "general_operand" "rim"))))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6792   "sub{l}\t{%2, %k0|%k0, %2}"
6793   [(set_attr "type" "alu")
6794    (set_attr "mode" "SI")])
6795
6796 (define_insn "*subsi_2"
6797   [(set (reg 17)
6798         (compare
6799           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800                     (match_operand:SI 2 "general_operand" "ri,rm"))
6801           (const_int 0)))
6802    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6803         (minus:SI (match_dup 1) (match_dup 2)))]
6804   "ix86_match_ccmode (insn, CCGOCmode)
6805    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6806   "sub{l}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "SI")])
6809
6810 (define_insn "*subsi_2_zext"
6811   [(set (reg 17)
6812         (compare
6813           (minus:SI (match_operand:SI 1 "register_operand" "0")
6814                     (match_operand:SI 2 "general_operand" "rim"))
6815           (const_int 0)))
6816    (set (match_operand:DI 0 "register_operand" "=r")
6817         (zero_extend:DI
6818           (minus:SI (match_dup 1)
6819                     (match_dup 2))))]
6820   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6821    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6822   "sub{l}\t{%2, %k0|%k0, %2}"
6823   [(set_attr "type" "alu")
6824    (set_attr "mode" "SI")])
6825
6826 (define_insn "*subsi_3"
6827   [(set (reg 17)
6828         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6829                  (match_operand:SI 2 "general_operand" "ri,rm")))
6830    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6831         (minus:SI (match_dup 1) (match_dup 2)))]
6832   "ix86_match_ccmode (insn, CCmode)
6833    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6834   "sub{l}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "alu")
6836    (set_attr "mode" "SI")])
6837
6838 (define_insn "*subsi_3_zext"
6839   [(set (reg 17)
6840         (compare (match_operand:SI 1 "register_operand" "0")
6841                  (match_operand:SI 2 "general_operand" "rim")))
6842    (set (match_operand:DI 0 "register_operand" "=r")
6843         (zero_extend:DI
6844           (minus:SI (match_dup 1)
6845                     (match_dup 2))))]
6846   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6847    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6848   "sub{q}\t{%2, %0|%0, %2}"
6849   [(set_attr "type" "alu")
6850    (set_attr "mode" "DI")])
6851
6852 (define_expand "subhi3"
6853   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6854                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6855                              (match_operand:HI 2 "general_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   "TARGET_HIMODE_MATH"
6858   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6859
6860 (define_insn "*subhi_1"
6861   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6862         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6863                   (match_operand:HI 2 "general_operand" "ri,rm")))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6866   "sub{w}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "alu")
6868    (set_attr "mode" "HI")])
6869
6870 (define_insn "*subhi_2"
6871   [(set (reg 17)
6872         (compare
6873           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6874                     (match_operand:HI 2 "general_operand" "ri,rm"))
6875           (const_int 0)))
6876    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6877         (minus:HI (match_dup 1) (match_dup 2)))]
6878   "ix86_match_ccmode (insn, CCGOCmode)
6879    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6880   "sub{w}\t{%2, %0|%0, %2}"
6881   [(set_attr "type" "alu")
6882    (set_attr "mode" "HI")])
6883
6884 (define_insn "*subhi_3"
6885   [(set (reg 17)
6886         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6887                  (match_operand:HI 2 "general_operand" "ri,rm")))
6888    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6889         (minus:HI (match_dup 1) (match_dup 2)))]
6890   "ix86_match_ccmode (insn, CCmode)
6891    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6892   "sub{w}\t{%2, %0|%0, %2}"
6893   [(set_attr "type" "alu")
6894    (set_attr "mode" "HI")])
6895
6896 (define_expand "subqi3"
6897   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6898                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6899                              (match_operand:QI 2 "general_operand" "")))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   "TARGET_QIMODE_MATH"
6902   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6903
6904 (define_insn "*subqi_1"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6910   "sub{b}\t{%2, %0|%0, %2}"
6911   [(set_attr "type" "alu")
6912    (set_attr "mode" "QI")])
6913
6914 (define_insn "*subqi_1_slp"
6915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6916         (minus:QI (match_dup 0)
6917                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6918    (clobber (reg:CC FLAGS_REG))]
6919   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6921   "sub{b}\t{%1, %0|%0, %1}"
6922   [(set_attr "type" "alu1")
6923    (set_attr "mode" "QI")])
6924
6925 (define_insn "*subqi_2"
6926   [(set (reg 17)
6927         (compare
6928           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6929                     (match_operand:QI 2 "general_operand" "qi,qm"))
6930           (const_int 0)))
6931    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6932         (minus:HI (match_dup 1) (match_dup 2)))]
6933   "ix86_match_ccmode (insn, CCGOCmode)
6934    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6935   "sub{b}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "mode" "QI")])
6938
6939 (define_insn "*subqi_3"
6940   [(set (reg 17)
6941         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6942                  (match_operand:QI 2 "general_operand" "qi,qm")))
6943    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6944         (minus:HI (match_dup 1) (match_dup 2)))]
6945   "ix86_match_ccmode (insn, CCmode)
6946    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6947   "sub{b}\t{%2, %0|%0, %2}"
6948   [(set_attr "type" "alu")
6949    (set_attr "mode" "QI")])
6950
6951 ;; The patterns that match these are at the end of this file.
6952
6953 (define_expand "subxf3"
6954   [(set (match_operand:XF 0 "register_operand" "")
6955         (minus:XF (match_operand:XF 1 "register_operand" "")
6956                   (match_operand:XF 2 "register_operand" "")))]
6957   "TARGET_80387"
6958   "")
6959
6960 (define_expand "subdf3"
6961   [(set (match_operand:DF 0 "register_operand" "")
6962         (minus:DF (match_operand:DF 1 "register_operand" "")
6963                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6964   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6965   "")
6966
6967 (define_expand "subsf3"
6968   [(set (match_operand:SF 0 "register_operand" "")
6969         (minus:SF (match_operand:SF 1 "register_operand" "")
6970                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6971   "TARGET_80387 || TARGET_SSE_MATH"
6972   "")
6973 \f
6974 ;; Multiply instructions
6975
6976 (define_expand "muldi3"
6977   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6978                    (mult:DI (match_operand:DI 1 "register_operand" "")
6979                             (match_operand:DI 2 "x86_64_general_operand" "")))
6980               (clobber (reg:CC FLAGS_REG))])]
6981   "TARGET_64BIT"
6982   "")
6983
6984 (define_insn "*muldi3_1_rex64"
6985   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6986         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6987                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "TARGET_64BIT
6990    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6991   "@
6992    imul{q}\t{%2, %1, %0|%0, %1, %2}
6993    imul{q}\t{%2, %1, %0|%0, %1, %2}
6994    imul{q}\t{%2, %0|%0, %2}"
6995   [(set_attr "type" "imul")
6996    (set_attr "prefix_0f" "0,0,1")
6997    (set (attr "athlon_decode")
6998         (cond [(eq_attr "cpu" "athlon")
6999                   (const_string "vector")
7000                (eq_attr "alternative" "1")
7001                   (const_string "vector")
7002                (and (eq_attr "alternative" "2")
7003                     (match_operand 1 "memory_operand" ""))
7004                   (const_string "vector")]
7005               (const_string "direct")))
7006    (set_attr "mode" "DI")])
7007
7008 (define_expand "mulsi3"
7009   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7010                    (mult:SI (match_operand:SI 1 "register_operand" "")
7011                             (match_operand:SI 2 "general_operand" "")))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   ""
7014   "")
7015
7016 (define_insn "*mulsi3_1"
7017   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7018         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7019                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7022   "@
7023    imul{l}\t{%2, %1, %0|%0, %1, %2}
7024    imul{l}\t{%2, %1, %0|%0, %1, %2}
7025    imul{l}\t{%2, %0|%0, %2}"
7026   [(set_attr "type" "imul")
7027    (set_attr "prefix_0f" "0,0,1")
7028    (set (attr "athlon_decode")
7029         (cond [(eq_attr "cpu" "athlon")
7030                   (const_string "vector")
7031                (eq_attr "alternative" "1")
7032                   (const_string "vector")
7033                (and (eq_attr "alternative" "2")
7034                     (match_operand 1 "memory_operand" ""))
7035                   (const_string "vector")]
7036               (const_string "direct")))
7037    (set_attr "mode" "SI")])
7038
7039 (define_insn "*mulsi3_1_zext"
7040   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7041         (zero_extend:DI
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   "TARGET_64BIT
7046    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7047   "@
7048    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7049    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7050    imul{l}\t{%2, %k0|%k0, %2}"
7051   [(set_attr "type" "imul")
7052    (set_attr "prefix_0f" "0,0,1")
7053    (set (attr "athlon_decode")
7054         (cond [(eq_attr "cpu" "athlon")
7055                   (const_string "vector")
7056                (eq_attr "alternative" "1")
7057                   (const_string "vector")
7058                (and (eq_attr "alternative" "2")
7059                     (match_operand 1 "memory_operand" ""))
7060                   (const_string "vector")]
7061               (const_string "direct")))
7062    (set_attr "mode" "SI")])
7063
7064 (define_expand "mulhi3"
7065   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7066                    (mult:HI (match_operand:HI 1 "register_operand" "")
7067                             (match_operand:HI 2 "general_operand" "")))
7068               (clobber (reg:CC FLAGS_REG))])]
7069   "TARGET_HIMODE_MATH"
7070   "")
7071
7072 (define_insn "*mulhi3_1"
7073   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7074         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7075                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7076    (clobber (reg:CC FLAGS_REG))]
7077   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7078   "@
7079    imul{w}\t{%2, %1, %0|%0, %1, %2}
7080    imul{w}\t{%2, %1, %0|%0, %1, %2}
7081    imul{w}\t{%2, %0|%0, %2}"
7082   [(set_attr "type" "imul")
7083    (set_attr "prefix_0f" "0,0,1")
7084    (set (attr "athlon_decode")
7085         (cond [(eq_attr "cpu" "athlon")
7086                   (const_string "vector")
7087                (eq_attr "alternative" "1,2")
7088                   (const_string "vector")]
7089               (const_string "direct")))
7090    (set_attr "mode" "HI")])
7091
7092 (define_expand "mulqi3"
7093   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7094                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7095                             (match_operand:QI 2 "register_operand" "")))
7096               (clobber (reg:CC FLAGS_REG))])]
7097   "TARGET_QIMODE_MATH"
7098   "")
7099
7100 (define_insn "*mulqi3_1"
7101   [(set (match_operand:QI 0 "register_operand" "=a")
7102         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7103                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "TARGET_QIMODE_MATH
7106    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107   "mul{b}\t%2"
7108   [(set_attr "type" "imul")
7109    (set_attr "length_immediate" "0")
7110    (set (attr "athlon_decode")
7111      (if_then_else (eq_attr "cpu" "athlon")
7112         (const_string "vector")
7113         (const_string "direct")))
7114    (set_attr "mode" "QI")])
7115
7116 (define_expand "umulqihi3"
7117   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7118                    (mult:HI (zero_extend:HI
7119                               (match_operand:QI 1 "nonimmediate_operand" ""))
7120                             (zero_extend:HI
7121                               (match_operand:QI 2 "register_operand" ""))))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_QIMODE_MATH"
7124   "")
7125
7126 (define_insn "*umulqihi3_1"
7127   [(set (match_operand:HI 0 "register_operand" "=a")
7128         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7129                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_QIMODE_MATH
7132    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7133   "mul{b}\t%2"
7134   [(set_attr "type" "imul")
7135    (set_attr "length_immediate" "0")
7136    (set (attr "athlon_decode")
7137      (if_then_else (eq_attr "cpu" "athlon")
7138         (const_string "vector")
7139         (const_string "direct")))
7140    (set_attr "mode" "QI")])
7141
7142 (define_expand "mulqihi3"
7143   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7144                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7145                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7146               (clobber (reg:CC FLAGS_REG))])]
7147   "TARGET_QIMODE_MATH"
7148   "")
7149
7150 (define_insn "*mulqihi3_insn"
7151   [(set (match_operand:HI 0 "register_operand" "=a")
7152         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153                  (sign_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   "imul{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 "umulditi3"
7167   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7168                    (mult:TI (zero_extend:TI
7169                               (match_operand:DI 1 "nonimmediate_operand" ""))
7170                             (zero_extend:TI
7171                               (match_operand:DI 2 "register_operand" ""))))
7172               (clobber (reg:CC FLAGS_REG))])]
7173   "TARGET_64BIT"
7174   "")
7175
7176 (define_insn "*umulditi3_insn"
7177   [(set (match_operand:TI 0 "register_operand" "=A")
7178         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7179                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "TARGET_64BIT
7182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7183   "mul{q}\t%2"
7184   [(set_attr "type" "imul")
7185    (set_attr "length_immediate" "0")
7186    (set (attr "athlon_decode")
7187      (if_then_else (eq_attr "cpu" "athlon")
7188         (const_string "vector")
7189         (const_string "double")))
7190    (set_attr "mode" "DI")])
7191
7192 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7193 (define_expand "umulsidi3"
7194   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7195                    (mult:DI (zero_extend:DI
7196                               (match_operand:SI 1 "nonimmediate_operand" ""))
7197                             (zero_extend:DI
7198                               (match_operand:SI 2 "register_operand" ""))))
7199               (clobber (reg:CC FLAGS_REG))])]
7200   "!TARGET_64BIT"
7201   "")
7202
7203 (define_insn "*umulsidi3_insn"
7204   [(set (match_operand:DI 0 "register_operand" "=A")
7205         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7206                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "!TARGET_64BIT
7209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7210   "mul{l}\t%2"
7211   [(set_attr "type" "imul")
7212    (set_attr "length_immediate" "0")
7213    (set (attr "athlon_decode")
7214      (if_then_else (eq_attr "cpu" "athlon")
7215         (const_string "vector")
7216         (const_string "double")))
7217    (set_attr "mode" "SI")])
7218
7219 (define_expand "mulditi3"
7220   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7221                    (mult:TI (sign_extend:TI
7222                               (match_operand:DI 1 "nonimmediate_operand" ""))
7223                             (sign_extend:TI
7224                               (match_operand:DI 2 "register_operand" ""))))
7225               (clobber (reg:CC FLAGS_REG))])]
7226   "TARGET_64BIT"
7227   "")
7228
7229 (define_insn "*mulditi3_insn"
7230   [(set (match_operand:TI 0 "register_operand" "=A")
7231         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7232                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7233    (clobber (reg:CC FLAGS_REG))]
7234   "TARGET_64BIT
7235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7236   "imul{q}\t%2"
7237   [(set_attr "type" "imul")
7238    (set_attr "length_immediate" "0")
7239    (set (attr "athlon_decode")
7240      (if_then_else (eq_attr "cpu" "athlon")
7241         (const_string "vector")
7242         (const_string "double")))
7243    (set_attr "mode" "DI")])
7244
7245 (define_expand "mulsidi3"
7246   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7247                    (mult:DI (sign_extend:DI
7248                               (match_operand:SI 1 "nonimmediate_operand" ""))
7249                             (sign_extend:DI
7250                               (match_operand:SI 2 "register_operand" ""))))
7251               (clobber (reg:CC FLAGS_REG))])]
7252   "!TARGET_64BIT"
7253   "")
7254
7255 (define_insn "*mulsidi3_insn"
7256   [(set (match_operand:DI 0 "register_operand" "=A")
7257         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7258                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "!TARGET_64BIT
7261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7262   "imul{l}\t%2"
7263   [(set_attr "type" "imul")
7264    (set_attr "length_immediate" "0")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "SI")])
7270
7271 (define_expand "umuldi3_highpart"
7272   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7273                    (truncate:DI
7274                      (lshiftrt:TI
7275                        (mult:TI (zero_extend:TI
7276                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7277                                 (zero_extend:TI
7278                                   (match_operand:DI 2 "register_operand" "")))
7279                        (const_int 64))))
7280               (clobber (match_scratch:DI 3 ""))
7281               (clobber (reg:CC FLAGS_REG))])]
7282   "TARGET_64BIT"
7283   "")
7284
7285 (define_insn "*umuldi3_highpart_rex64"
7286   [(set (match_operand:DI 0 "register_operand" "=d")
7287         (truncate:DI
7288           (lshiftrt:TI
7289             (mult:TI (zero_extend:TI
7290                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7291                      (zero_extend:TI
7292                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7293             (const_int 64))))
7294    (clobber (match_scratch:DI 3 "=1"))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "TARGET_64BIT
7297    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7298   "mul{q}\t%2"
7299   [(set_attr "type" "imul")
7300    (set_attr "length_immediate" "0")
7301    (set (attr "athlon_decode")
7302      (if_then_else (eq_attr "cpu" "athlon")
7303         (const_string "vector")
7304         (const_string "double")))
7305    (set_attr "mode" "DI")])
7306
7307 (define_expand "umulsi3_highpart"
7308   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7309                    (truncate:SI
7310                      (lshiftrt:DI
7311                        (mult:DI (zero_extend:DI
7312                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7313                                 (zero_extend:DI
7314                                   (match_operand:SI 2 "register_operand" "")))
7315                        (const_int 32))))
7316               (clobber (match_scratch:SI 3 ""))
7317               (clobber (reg:CC FLAGS_REG))])]
7318   ""
7319   "")
7320
7321 (define_insn "*umulsi3_highpart_insn"
7322   [(set (match_operand:SI 0 "register_operand" "=d")
7323         (truncate:SI
7324           (lshiftrt:DI
7325             (mult:DI (zero_extend:DI
7326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7327                      (zero_extend:DI
7328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7329             (const_int 32))))
7330    (clobber (match_scratch:SI 3 "=1"))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7333   "mul{l}\t%2"
7334   [(set_attr "type" "imul")
7335    (set_attr "length_immediate" "0")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7341
7342 (define_insn "*umulsi3_highpart_zext"
7343   [(set (match_operand:DI 0 "register_operand" "=d")
7344         (zero_extend:DI (truncate:SI
7345           (lshiftrt:DI
7346             (mult:DI (zero_extend:DI
7347                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7348                      (zero_extend:DI
7349                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7350             (const_int 32)))))
7351    (clobber (match_scratch:SI 3 "=1"))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_64BIT
7354    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7355   "mul{l}\t%2"
7356   [(set_attr "type" "imul")
7357    (set_attr "length_immediate" "0")
7358    (set (attr "athlon_decode")
7359      (if_then_else (eq_attr "cpu" "athlon")
7360         (const_string "vector")
7361         (const_string "double")))
7362    (set_attr "mode" "SI")])
7363
7364 (define_expand "smuldi3_highpart"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7366                    (truncate:DI
7367                      (lshiftrt:TI
7368                        (mult:TI (sign_extend:TI
7369                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7370                                 (sign_extend:TI
7371                                   (match_operand:DI 2 "register_operand" "")))
7372                        (const_int 64))))
7373               (clobber (match_scratch:DI 3 ""))
7374               (clobber (reg:CC FLAGS_REG))])]
7375   "TARGET_64BIT"
7376   "")
7377
7378 (define_insn "*smuldi3_highpart_rex64"
7379   [(set (match_operand:DI 0 "register_operand" "=d")
7380         (truncate:DI
7381           (lshiftrt:TI
7382             (mult:TI (sign_extend:TI
7383                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7384                      (sign_extend:TI
7385                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7386             (const_int 64))))
7387    (clobber (match_scratch:DI 3 "=1"))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7391   "imul{q}\t%2"
7392   [(set_attr "type" "imul")
7393    (set (attr "athlon_decode")
7394      (if_then_else (eq_attr "cpu" "athlon")
7395         (const_string "vector")
7396         (const_string "double")))
7397    (set_attr "mode" "DI")])
7398
7399 (define_expand "smulsi3_highpart"
7400   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7401                    (truncate:SI
7402                      (lshiftrt:DI
7403                        (mult:DI (sign_extend:DI
7404                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7405                                 (sign_extend:DI
7406                                   (match_operand:SI 2 "register_operand" "")))
7407                        (const_int 32))))
7408               (clobber (match_scratch:SI 3 ""))
7409               (clobber (reg:CC FLAGS_REG))])]
7410   ""
7411   "")
7412
7413 (define_insn "*smulsi3_highpart_insn"
7414   [(set (match_operand:SI 0 "register_operand" "=d")
7415         (truncate:SI
7416           (lshiftrt:DI
7417             (mult:DI (sign_extend:DI
7418                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7419                      (sign_extend:DI
7420                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7421             (const_int 32))))
7422    (clobber (match_scratch:SI 3 "=1"))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7425   "imul{l}\t%2"
7426   [(set_attr "type" "imul")
7427    (set (attr "athlon_decode")
7428      (if_then_else (eq_attr "cpu" "athlon")
7429         (const_string "vector")
7430         (const_string "double")))
7431    (set_attr "mode" "SI")])
7432
7433 (define_insn "*smulsi3_highpart_zext"
7434   [(set (match_operand:DI 0 "register_operand" "=d")
7435         (zero_extend:DI (truncate:SI
7436           (lshiftrt:DI
7437             (mult:DI (sign_extend:DI
7438                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7439                      (sign_extend:DI
7440                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7441             (const_int 32)))))
7442    (clobber (match_scratch:SI 3 "=1"))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_64BIT
7445    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7446   "imul{l}\t%2"
7447   [(set_attr "type" "imul")
7448    (set (attr "athlon_decode")
7449      (if_then_else (eq_attr "cpu" "athlon")
7450         (const_string "vector")
7451         (const_string "double")))
7452    (set_attr "mode" "SI")])
7453
7454 ;; The patterns that match these are at the end of this file.
7455
7456 (define_expand "mulxf3"
7457   [(set (match_operand:XF 0 "register_operand" "")
7458         (mult:XF (match_operand:XF 1 "register_operand" "")
7459                  (match_operand:XF 2 "register_operand" "")))]
7460   "TARGET_80387"
7461   "")
7462
7463 (define_expand "muldf3"
7464   [(set (match_operand:DF 0 "register_operand" "")
7465         (mult:DF (match_operand:DF 1 "register_operand" "")
7466                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7467   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7468   "")
7469
7470 (define_expand "mulsf3"
7471   [(set (match_operand:SF 0 "register_operand" "")
7472         (mult:SF (match_operand:SF 1 "register_operand" "")
7473                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7474   "TARGET_80387 || TARGET_SSE_MATH"
7475   "")
7476 \f
7477 ;; Divide instructions
7478
7479 (define_insn "divqi3"
7480   [(set (match_operand:QI 0 "register_operand" "=a")
7481         (div:QI (match_operand:HI 1 "register_operand" "0")
7482                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7483    (clobber (reg:CC FLAGS_REG))]
7484   "TARGET_QIMODE_MATH"
7485   "idiv{b}\t%2"
7486   [(set_attr "type" "idiv")
7487    (set_attr "mode" "QI")])
7488
7489 (define_insn "udivqi3"
7490   [(set (match_operand:QI 0 "register_operand" "=a")
7491         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7492                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7493    (clobber (reg:CC FLAGS_REG))]
7494   "TARGET_QIMODE_MATH"
7495   "div{b}\t%2"
7496   [(set_attr "type" "idiv")
7497    (set_attr "mode" "QI")])
7498
7499 ;; The patterns that match these are at the end of this file.
7500
7501 (define_expand "divxf3"
7502   [(set (match_operand:XF 0 "register_operand" "")
7503         (div:XF (match_operand:XF 1 "register_operand" "")
7504                 (match_operand:XF 2 "register_operand" "")))]
7505   "TARGET_80387"
7506   "")
7507
7508 (define_expand "divdf3"
7509   [(set (match_operand:DF 0 "register_operand" "")
7510         (div:DF (match_operand:DF 1 "register_operand" "")
7511                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7512    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7513    "")
7514  
7515 (define_expand "divsf3"
7516   [(set (match_operand:SF 0 "register_operand" "")
7517         (div:SF (match_operand:SF 1 "register_operand" "")
7518                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7519   "TARGET_80387 || TARGET_SSE_MATH"
7520   "")
7521 \f
7522 ;; Remainder instructions.
7523
7524 (define_expand "divmoddi4"
7525   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7526                    (div:DI (match_operand:DI 1 "register_operand" "")
7527                            (match_operand:DI 2 "nonimmediate_operand" "")))
7528               (set (match_operand:DI 3 "register_operand" "")
7529                    (mod:DI (match_dup 1) (match_dup 2)))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   "TARGET_64BIT"
7532   "")
7533
7534 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7535 ;; Penalize eax case slightly because it results in worse scheduling
7536 ;; of code.
7537 (define_insn "*divmoddi4_nocltd_rex64"
7538   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7539         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7540                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7541    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7542         (mod:DI (match_dup 2) (match_dup 3)))
7543    (clobber (reg:CC FLAGS_REG))]
7544   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7545   "#"
7546   [(set_attr "type" "multi")])
7547
7548 (define_insn "*divmoddi4_cltd_rex64"
7549   [(set (match_operand:DI 0 "register_operand" "=a")
7550         (div:DI (match_operand:DI 2 "register_operand" "a")
7551                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7552    (set (match_operand:DI 1 "register_operand" "=&d")
7553         (mod:DI (match_dup 2) (match_dup 3)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7556   "#"
7557   [(set_attr "type" "multi")])
7558
7559 (define_insn "*divmoddi_noext_rex64"
7560   [(set (match_operand:DI 0 "register_operand" "=a")
7561         (div:DI (match_operand:DI 1 "register_operand" "0")
7562                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563    (set (match_operand:DI 3 "register_operand" "=d")
7564         (mod:DI (match_dup 1) (match_dup 2)))
7565    (use (match_operand:DI 4 "register_operand" "3"))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT"
7568   "idiv{q}\t%2"
7569   [(set_attr "type" "idiv")
7570    (set_attr "mode" "DI")])
7571
7572 (define_split
7573   [(set (match_operand:DI 0 "register_operand" "")
7574         (div:DI (match_operand:DI 1 "register_operand" "")
7575                 (match_operand:DI 2 "nonimmediate_operand" "")))
7576    (set (match_operand:DI 3 "register_operand" "")
7577         (mod:DI (match_dup 1) (match_dup 2)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && reload_completed"
7580   [(parallel [(set (match_dup 3)
7581                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7582               (clobber (reg:CC FLAGS_REG))])
7583    (parallel [(set (match_dup 0)
7584                    (div:DI (reg:DI 0) (match_dup 2)))
7585               (set (match_dup 3)
7586                    (mod:DI (reg:DI 0) (match_dup 2)))
7587               (use (match_dup 3))
7588               (clobber (reg:CC FLAGS_REG))])]
7589 {
7590   /* Avoid use of cltd in favor of a mov+shift.  */
7591   if (!TARGET_USE_CLTD && !optimize_size)
7592     {
7593       if (true_regnum (operands[1]))
7594         emit_move_insn (operands[0], operands[1]);
7595       else
7596         emit_move_insn (operands[3], operands[1]);
7597       operands[4] = operands[3];
7598     }
7599   else
7600     {
7601       if (true_regnum (operands[1]))
7602         abort();
7603       operands[4] = operands[1];
7604     }
7605 })
7606
7607
7608 (define_expand "divmodsi4"
7609   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7610                    (div:SI (match_operand:SI 1 "register_operand" "")
7611                            (match_operand:SI 2 "nonimmediate_operand" "")))
7612               (set (match_operand:SI 3 "register_operand" "")
7613                    (mod:SI (match_dup 1) (match_dup 2)))
7614               (clobber (reg:CC FLAGS_REG))])]
7615   ""
7616   "")
7617
7618 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7619 ;; Penalize eax case slightly because it results in worse scheduling
7620 ;; of code.
7621 (define_insn "*divmodsi4_nocltd"
7622   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7623         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7624                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7625    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7626         (mod:SI (match_dup 2) (match_dup 3)))
7627    (clobber (reg:CC FLAGS_REG))]
7628   "!optimize_size && !TARGET_USE_CLTD"
7629   "#"
7630   [(set_attr "type" "multi")])
7631
7632 (define_insn "*divmodsi4_cltd"
7633   [(set (match_operand:SI 0 "register_operand" "=a")
7634         (div:SI (match_operand:SI 2 "register_operand" "a")
7635                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7636    (set (match_operand:SI 1 "register_operand" "=&d")
7637         (mod:SI (match_dup 2) (match_dup 3)))
7638    (clobber (reg:CC FLAGS_REG))]
7639   "optimize_size || TARGET_USE_CLTD"
7640   "#"
7641   [(set_attr "type" "multi")])
7642
7643 (define_insn "*divmodsi_noext"
7644   [(set (match_operand:SI 0 "register_operand" "=a")
7645         (div:SI (match_operand:SI 1 "register_operand" "0")
7646                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7647    (set (match_operand:SI 3 "register_operand" "=d")
7648         (mod:SI (match_dup 1) (match_dup 2)))
7649    (use (match_operand:SI 4 "register_operand" "3"))
7650    (clobber (reg:CC FLAGS_REG))]
7651   ""
7652   "idiv{l}\t%2"
7653   [(set_attr "type" "idiv")
7654    (set_attr "mode" "SI")])
7655
7656 (define_split
7657   [(set (match_operand:SI 0 "register_operand" "")
7658         (div:SI (match_operand:SI 1 "register_operand" "")
7659                 (match_operand:SI 2 "nonimmediate_operand" "")))
7660    (set (match_operand:SI 3 "register_operand" "")
7661         (mod:SI (match_dup 1) (match_dup 2)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "reload_completed"
7664   [(parallel [(set (match_dup 3)
7665                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7666               (clobber (reg:CC FLAGS_REG))])
7667    (parallel [(set (match_dup 0)
7668                    (div:SI (reg:SI 0) (match_dup 2)))
7669               (set (match_dup 3)
7670                    (mod:SI (reg:SI 0) (match_dup 2)))
7671               (use (match_dup 3))
7672               (clobber (reg:CC FLAGS_REG))])]
7673 {
7674   /* Avoid use of cltd in favor of a mov+shift.  */
7675   if (!TARGET_USE_CLTD && !optimize_size)
7676     {
7677       if (true_regnum (operands[1]))
7678         emit_move_insn (operands[0], operands[1]);
7679       else
7680         emit_move_insn (operands[3], operands[1]);
7681       operands[4] = operands[3];
7682     }
7683   else
7684     {
7685       if (true_regnum (operands[1]))
7686         abort();
7687       operands[4] = operands[1];
7688     }
7689 })
7690 ;; %%% Split me.
7691 (define_insn "divmodhi4"
7692   [(set (match_operand:HI 0 "register_operand" "=a")
7693         (div:HI (match_operand:HI 1 "register_operand" "0")
7694                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7695    (set (match_operand:HI 3 "register_operand" "=&d")
7696         (mod:HI (match_dup 1) (match_dup 2)))
7697    (clobber (reg:CC FLAGS_REG))]
7698   "TARGET_HIMODE_MATH"
7699   "cwtd\;idiv{w}\t%2"
7700   [(set_attr "type" "multi")
7701    (set_attr "length_immediate" "0")
7702    (set_attr "mode" "SI")])
7703
7704 (define_insn "udivmoddi4"
7705   [(set (match_operand:DI 0 "register_operand" "=a")
7706         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7707                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7708    (set (match_operand:DI 3 "register_operand" "=&d")
7709         (umod:DI (match_dup 1) (match_dup 2)))
7710    (clobber (reg:CC FLAGS_REG))]
7711   "TARGET_64BIT"
7712   "xor{q}\t%3, %3\;div{q}\t%2"
7713   [(set_attr "type" "multi")
7714    (set_attr "length_immediate" "0")
7715    (set_attr "mode" "DI")])
7716
7717 (define_insn "*udivmoddi4_noext"
7718   [(set (match_operand:DI 0 "register_operand" "=a")
7719         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7720                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7721    (set (match_operand:DI 3 "register_operand" "=d")
7722         (umod:DI (match_dup 1) (match_dup 2)))
7723    (use (match_dup 3))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "TARGET_64BIT"
7726   "div{q}\t%2"
7727   [(set_attr "type" "idiv")
7728    (set_attr "mode" "DI")])
7729
7730 (define_split
7731   [(set (match_operand:DI 0 "register_operand" "")
7732         (udiv:DI (match_operand:DI 1 "register_operand" "")
7733                  (match_operand:DI 2 "nonimmediate_operand" "")))
7734    (set (match_operand:DI 3 "register_operand" "")
7735         (umod:DI (match_dup 1) (match_dup 2)))
7736    (clobber (reg:CC FLAGS_REG))]
7737   "TARGET_64BIT && reload_completed"
7738   [(set (match_dup 3) (const_int 0))
7739    (parallel [(set (match_dup 0)
7740                    (udiv:DI (match_dup 1) (match_dup 2)))
7741               (set (match_dup 3)
7742                    (umod:DI (match_dup 1) (match_dup 2)))
7743               (use (match_dup 3))
7744               (clobber (reg:CC FLAGS_REG))])]
7745   "")
7746
7747 (define_insn "udivmodsi4"
7748   [(set (match_operand:SI 0 "register_operand" "=a")
7749         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7750                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7751    (set (match_operand:SI 3 "register_operand" "=&d")
7752         (umod:SI (match_dup 1) (match_dup 2)))
7753    (clobber (reg:CC FLAGS_REG))]
7754   ""
7755   "xor{l}\t%3, %3\;div{l}\t%2"
7756   [(set_attr "type" "multi")
7757    (set_attr "length_immediate" "0")
7758    (set_attr "mode" "SI")])
7759
7760 (define_insn "*udivmodsi4_noext"
7761   [(set (match_operand:SI 0 "register_operand" "=a")
7762         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7763                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7764    (set (match_operand:SI 3 "register_operand" "=d")
7765         (umod:SI (match_dup 1) (match_dup 2)))
7766    (use (match_dup 3))
7767    (clobber (reg:CC FLAGS_REG))]
7768   ""
7769   "div{l}\t%2"
7770   [(set_attr "type" "idiv")
7771    (set_attr "mode" "SI")])
7772
7773 (define_split
7774   [(set (match_operand:SI 0 "register_operand" "")
7775         (udiv:SI (match_operand:SI 1 "register_operand" "")
7776                  (match_operand:SI 2 "nonimmediate_operand" "")))
7777    (set (match_operand:SI 3 "register_operand" "")
7778         (umod:SI (match_dup 1) (match_dup 2)))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "reload_completed"
7781   [(set (match_dup 3) (const_int 0))
7782    (parallel [(set (match_dup 0)
7783                    (udiv:SI (match_dup 1) (match_dup 2)))
7784               (set (match_dup 3)
7785                    (umod:SI (match_dup 1) (match_dup 2)))
7786               (use (match_dup 3))
7787               (clobber (reg:CC FLAGS_REG))])]
7788   "")
7789
7790 (define_expand "udivmodhi4"
7791   [(set (match_dup 4) (const_int 0))
7792    (parallel [(set (match_operand:HI 0 "register_operand" "")
7793                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7794                             (match_operand:HI 2 "nonimmediate_operand" "")))
7795               (set (match_operand:HI 3 "register_operand" "")
7796                    (umod:HI (match_dup 1) (match_dup 2)))
7797               (use (match_dup 4))
7798               (clobber (reg:CC FLAGS_REG))])]
7799   "TARGET_HIMODE_MATH"
7800   "operands[4] = gen_reg_rtx (HImode);")
7801
7802 (define_insn "*udivmodhi_noext"
7803   [(set (match_operand:HI 0 "register_operand" "=a")
7804         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7805                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7806    (set (match_operand:HI 3 "register_operand" "=d")
7807         (umod:HI (match_dup 1) (match_dup 2)))
7808    (use (match_operand:HI 4 "register_operand" "3"))
7809    (clobber (reg:CC FLAGS_REG))]
7810   ""
7811   "div{w}\t%2"
7812   [(set_attr "type" "idiv")
7813    (set_attr "mode" "HI")])
7814
7815 ;; We cannot use div/idiv for double division, because it causes
7816 ;; "division by zero" on the overflow and that's not what we expect
7817 ;; from truncate.  Because true (non truncating) double division is
7818 ;; never generated, we can't create this insn anyway.
7819 ;
7820 ;(define_insn ""
7821 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7822 ;       (truncate:SI
7823 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7824 ;                  (zero_extend:DI
7825 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7826 ;   (set (match_operand:SI 3 "register_operand" "=d")
7827 ;       (truncate:SI
7828 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7829 ;   (clobber (reg:CC FLAGS_REG))]
7830 ;  ""
7831 ;  "div{l}\t{%2, %0|%0, %2}"
7832 ;  [(set_attr "type" "idiv")])
7833 \f
7834 ;;- Logical AND instructions
7835
7836 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7837 ;; Note that this excludes ah.
7838
7839 (define_insn "*testdi_1_rex64"
7840   [(set (reg 17)
7841         (compare
7842           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7843                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7844           (const_int 0)))]
7845   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7847   "@
7848    test{l}\t{%k1, %k0|%k0, %k1}
7849    test{l}\t{%k1, %k0|%k0, %k1}
7850    test{q}\t{%1, %0|%0, %1}
7851    test{q}\t{%1, %0|%0, %1}
7852    test{q}\t{%1, %0|%0, %1}"
7853   [(set_attr "type" "test")
7854    (set_attr "modrm" "0,1,0,1,1")
7855    (set_attr "mode" "SI,SI,DI,DI,DI")
7856    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7857
7858 (define_insn "testsi_1"
7859   [(set (reg 17)
7860         (compare
7861           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7862                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7863           (const_int 0)))]
7864   "ix86_match_ccmode (insn, CCNOmode)
7865    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7866   "test{l}\t{%1, %0|%0, %1}"
7867   [(set_attr "type" "test")
7868    (set_attr "modrm" "0,1,1")
7869    (set_attr "mode" "SI")
7870    (set_attr "pent_pair" "uv,np,uv")])
7871
7872 (define_expand "testsi_ccno_1"
7873   [(set (reg:CCNO FLAGS_REG)
7874         (compare:CCNO
7875           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7876                   (match_operand:SI 1 "nonmemory_operand" ""))
7877           (const_int 0)))]
7878   ""
7879   "")
7880
7881 (define_insn "*testhi_1"
7882   [(set (reg 17)
7883         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7884                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7885                  (const_int 0)))]
7886   "ix86_match_ccmode (insn, CCNOmode)
7887    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7888   "test{w}\t{%1, %0|%0, %1}"
7889   [(set_attr "type" "test")
7890    (set_attr "modrm" "0,1,1")
7891    (set_attr "mode" "HI")
7892    (set_attr "pent_pair" "uv,np,uv")])
7893
7894 (define_expand "testqi_ccz_1"
7895   [(set (reg:CCZ FLAGS_REG)
7896         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7897                              (match_operand:QI 1 "nonmemory_operand" ""))
7898                  (const_int 0)))]
7899   ""
7900   "")
7901
7902 (define_insn "*testqi_1"
7903   [(set (reg 17)
7904         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7905                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7906                  (const_int 0)))]
7907   "ix86_match_ccmode (insn, CCNOmode)
7908    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7909 {
7910   if (which_alternative == 3)
7911     {
7912       if (GET_CODE (operands[1]) == CONST_INT
7913           && (INTVAL (operands[1]) & 0xffffff00))
7914         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7915       return "test{l}\t{%1, %k0|%k0, %1}";
7916     }
7917   return "test{b}\t{%1, %0|%0, %1}";
7918 }
7919   [(set_attr "type" "test")
7920    (set_attr "modrm" "0,1,1,1")
7921    (set_attr "mode" "QI,QI,QI,SI")
7922    (set_attr "pent_pair" "uv,np,uv,np")])
7923
7924 (define_expand "testqi_ext_ccno_0"
7925   [(set (reg:CCNO FLAGS_REG)
7926         (compare:CCNO
7927           (and:SI
7928             (zero_extract:SI
7929               (match_operand 0 "ext_register_operand" "")
7930               (const_int 8)
7931               (const_int 8))
7932             (match_operand 1 "const_int_operand" ""))
7933           (const_int 0)))]
7934   ""
7935   "")
7936
7937 (define_insn "*testqi_ext_0"
7938   [(set (reg 17)
7939         (compare
7940           (and:SI
7941             (zero_extract:SI
7942               (match_operand 0 "ext_register_operand" "Q")
7943               (const_int 8)
7944               (const_int 8))
7945             (match_operand 1 "const_int_operand" "n"))
7946           (const_int 0)))]
7947   "ix86_match_ccmode (insn, CCNOmode)"
7948   "test{b}\t{%1, %h0|%h0, %1}"
7949   [(set_attr "type" "test")
7950    (set_attr "mode" "QI")
7951    (set_attr "length_immediate" "1")
7952    (set_attr "pent_pair" "np")])
7953
7954 (define_insn "*testqi_ext_1"
7955   [(set (reg 17)
7956         (compare
7957           (and:SI
7958             (zero_extract:SI
7959               (match_operand 0 "ext_register_operand" "Q")
7960               (const_int 8)
7961               (const_int 8))
7962             (zero_extend:SI
7963               (match_operand:QI 1 "general_operand" "Qm")))
7964           (const_int 0)))]
7965   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7966    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7967   "test{b}\t{%1, %h0|%h0, %1}"
7968   [(set_attr "type" "test")
7969    (set_attr "mode" "QI")])
7970
7971 (define_insn "*testqi_ext_1_rex64"
7972   [(set (reg 17)
7973         (compare
7974           (and:SI
7975             (zero_extract:SI
7976               (match_operand 0 "ext_register_operand" "Q")
7977               (const_int 8)
7978               (const_int 8))
7979             (zero_extend:SI
7980               (match_operand:QI 1 "register_operand" "Q")))
7981           (const_int 0)))]
7982   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7983   "test{b}\t{%1, %h0|%h0, %1}"
7984   [(set_attr "type" "test")
7985    (set_attr "mode" "QI")])
7986
7987 (define_insn "*testqi_ext_2"
7988   [(set (reg 17)
7989         (compare
7990           (and:SI
7991             (zero_extract:SI
7992               (match_operand 0 "ext_register_operand" "Q")
7993               (const_int 8)
7994               (const_int 8))
7995             (zero_extract:SI
7996               (match_operand 1 "ext_register_operand" "Q")
7997               (const_int 8)
7998               (const_int 8)))
7999           (const_int 0)))]
8000   "ix86_match_ccmode (insn, CCNOmode)"
8001   "test{b}\t{%h1, %h0|%h0, %h1}"
8002   [(set_attr "type" "test")
8003    (set_attr "mode" "QI")])
8004
8005 ;; Combine likes to form bit extractions for some tests.  Humor it.
8006 (define_insn "*testqi_ext_3"
8007   [(set (reg 17)
8008         (compare (zero_extract:SI
8009                    (match_operand 0 "nonimmediate_operand" "rm")
8010                    (match_operand:SI 1 "const_int_operand" "")
8011                    (match_operand:SI 2 "const_int_operand" ""))
8012                  (const_int 0)))]
8013   "ix86_match_ccmode (insn, CCNOmode)
8014    && (GET_MODE (operands[0]) == SImode
8015        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8016        || GET_MODE (operands[0]) == HImode
8017        || GET_MODE (operands[0]) == QImode)"
8018   "#")
8019
8020 (define_insn "*testqi_ext_3_rex64"
8021   [(set (reg 17)
8022         (compare (zero_extract:DI
8023                    (match_operand 0 "nonimmediate_operand" "rm")
8024                    (match_operand:DI 1 "const_int_operand" "")
8025                    (match_operand:DI 2 "const_int_operand" ""))
8026                  (const_int 0)))]
8027   "TARGET_64BIT
8028    && ix86_match_ccmode (insn, CCNOmode)
8029    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8030    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8031    /* Ensure that resulting mask is zero or sign extended operand.  */
8032    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8033        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8034            && INTVAL (operands[1]) > 32))
8035    && (GET_MODE (operands[0]) == SImode
8036        || GET_MODE (operands[0]) == DImode
8037        || GET_MODE (operands[0]) == HImode
8038        || GET_MODE (operands[0]) == QImode)"
8039   "#")
8040
8041 (define_split
8042   [(set (reg 17)
8043         (compare (zero_extract
8044                    (match_operand 0 "nonimmediate_operand" "")
8045                    (match_operand 1 "const_int_operand" "")
8046                    (match_operand 2 "const_int_operand" ""))
8047                  (const_int 0)))]
8048   "ix86_match_ccmode (insn, CCNOmode)"
8049   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8050 {
8051   HOST_WIDE_INT len = INTVAL (operands[1]);
8052   HOST_WIDE_INT pos = INTVAL (operands[2]);
8053   HOST_WIDE_INT mask;
8054   enum machine_mode mode, submode;
8055
8056   mode = GET_MODE (operands[0]);
8057   if (GET_CODE (operands[0]) == MEM)
8058     {
8059       /* ??? Combine likes to put non-volatile mem extractions in QImode
8060          no matter the size of the test.  So find a mode that works.  */
8061       if (! MEM_VOLATILE_P (operands[0]))
8062         {
8063           mode = smallest_mode_for_size (pos + len, MODE_INT);
8064           operands[0] = adjust_address (operands[0], mode, 0);
8065         }
8066     }
8067   else if (GET_CODE (operands[0]) == SUBREG
8068            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8069                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8070            && pos + len <= GET_MODE_BITSIZE (submode))
8071     {
8072       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8073       mode = submode;
8074       operands[0] = SUBREG_REG (operands[0]);
8075     }
8076   else if (mode == HImode && pos + len <= 8)
8077     {
8078       /* Small HImode tests can be converted to QImode.  */
8079       mode = QImode;
8080       operands[0] = gen_lowpart (QImode, operands[0]);
8081     }
8082
8083   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8084   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8085
8086   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8087 })
8088
8089 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8090 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8091 ;; this is relatively important trick.
8092 ;; Do the conversion only post-reload to avoid limiting of the register class
8093 ;; to QI regs.
8094 (define_split
8095   [(set (reg 17)
8096         (compare
8097           (and (match_operand 0 "register_operand" "")
8098                (match_operand 1 "const_int_operand" ""))
8099           (const_int 0)))]
8100    "reload_completed
8101     && QI_REG_P (operands[0])
8102     && ((ix86_match_ccmode (insn, CCZmode)
8103          && !(INTVAL (operands[1]) & ~(255 << 8)))
8104         || (ix86_match_ccmode (insn, CCNOmode)
8105             && !(INTVAL (operands[1]) & ~(127 << 8))))
8106     && GET_MODE (operands[0]) != QImode"
8107   [(set (reg:CCNO FLAGS_REG)
8108         (compare:CCNO
8109           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8110                   (match_dup 1))
8111           (const_int 0)))]
8112   "operands[0] = gen_lowpart (SImode, operands[0]);
8113    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8114
8115 (define_split
8116   [(set (reg 17)
8117         (compare
8118           (and (match_operand 0 "nonimmediate_operand" "")
8119                (match_operand 1 "const_int_operand" ""))
8120           (const_int 0)))]
8121    "reload_completed
8122     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8123     && ((ix86_match_ccmode (insn, CCZmode)
8124          && !(INTVAL (operands[1]) & ~255))
8125         || (ix86_match_ccmode (insn, CCNOmode)
8126             && !(INTVAL (operands[1]) & ~127)))
8127     && GET_MODE (operands[0]) != QImode"
8128   [(set (reg:CCNO FLAGS_REG)
8129         (compare:CCNO
8130           (and:QI (match_dup 0)
8131                   (match_dup 1))
8132           (const_int 0)))]
8133   "operands[0] = gen_lowpart (QImode, operands[0]);
8134    operands[1] = gen_lowpart (QImode, operands[1]);")
8135
8136
8137 ;; %%% This used to optimize known byte-wide and operations to memory,
8138 ;; and sometimes to QImode registers.  If this is considered useful,
8139 ;; it should be done with splitters.
8140
8141 (define_expand "anddi3"
8142   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8143         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8144                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8145    (clobber (reg:CC FLAGS_REG))]
8146   "TARGET_64BIT"
8147   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8148
8149 (define_insn "*anddi_1_rex64"
8150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8151         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8152                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8155 {
8156   switch (get_attr_type (insn))
8157     {
8158     case TYPE_IMOVX:
8159       {
8160         enum machine_mode mode;
8161
8162         if (GET_CODE (operands[2]) != CONST_INT)
8163           abort ();
8164         if (INTVAL (operands[2]) == 0xff)
8165           mode = QImode;
8166         else if (INTVAL (operands[2]) == 0xffff)
8167           mode = HImode;
8168         else
8169           abort ();
8170         
8171         operands[1] = gen_lowpart (mode, operands[1]);
8172         if (mode == QImode)
8173           return "movz{bq|x}\t{%1,%0|%0, %1}";
8174         else
8175           return "movz{wq|x}\t{%1,%0|%0, %1}";
8176       }
8177
8178     default:
8179       if (! rtx_equal_p (operands[0], operands[1]))
8180         abort ();
8181       if (get_attr_mode (insn) == MODE_SI)
8182         return "and{l}\t{%k2, %k0|%k0, %k2}";
8183       else
8184         return "and{q}\t{%2, %0|%0, %2}";
8185     }
8186 }
8187   [(set_attr "type" "alu,alu,alu,imovx")
8188    (set_attr "length_immediate" "*,*,*,0")
8189    (set_attr "mode" "SI,DI,DI,DI")])
8190
8191 (define_insn "*anddi_2"
8192   [(set (reg 17)
8193         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8194                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8195                  (const_int 0)))
8196    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8197         (and:DI (match_dup 1) (match_dup 2)))]
8198   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8199    && ix86_binary_operator_ok (AND, DImode, operands)"
8200   "@
8201    and{l}\t{%k2, %k0|%k0, %k2}
8202    and{q}\t{%2, %0|%0, %2}
8203    and{q}\t{%2, %0|%0, %2}"
8204   [(set_attr "type" "alu")
8205    (set_attr "mode" "SI,DI,DI")])
8206
8207 (define_expand "andsi3"
8208   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8209         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8210                 (match_operand:SI 2 "general_operand" "")))
8211    (clobber (reg:CC FLAGS_REG))]
8212   ""
8213   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8214
8215 (define_insn "*andsi_1"
8216   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8217         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8218                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "ix86_binary_operator_ok (AND, SImode, operands)"
8221 {
8222   switch (get_attr_type (insn))
8223     {
8224     case TYPE_IMOVX:
8225       {
8226         enum machine_mode mode;
8227
8228         if (GET_CODE (operands[2]) != CONST_INT)
8229           abort ();
8230         if (INTVAL (operands[2]) == 0xff)
8231           mode = QImode;
8232         else if (INTVAL (operands[2]) == 0xffff)
8233           mode = HImode;
8234         else
8235           abort ();
8236         
8237         operands[1] = gen_lowpart (mode, operands[1]);
8238         if (mode == QImode)
8239           return "movz{bl|x}\t{%1,%0|%0, %1}";
8240         else
8241           return "movz{wl|x}\t{%1,%0|%0, %1}";
8242       }
8243
8244     default:
8245       if (! rtx_equal_p (operands[0], operands[1]))
8246         abort ();
8247       return "and{l}\t{%2, %0|%0, %2}";
8248     }
8249 }
8250   [(set_attr "type" "alu,alu,imovx")
8251    (set_attr "length_immediate" "*,*,0")
8252    (set_attr "mode" "SI")])
8253
8254 (define_split
8255   [(set (match_operand 0 "register_operand" "")
8256         (and (match_dup 0)
8257              (const_int -65536)))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8260   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8261   "operands[1] = gen_lowpart (HImode, operands[0]);")
8262
8263 (define_split
8264   [(set (match_operand 0 "ext_register_operand" "")
8265         (and (match_dup 0)
8266              (const_int -256)))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8269   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8270   "operands[1] = gen_lowpart (QImode, operands[0]);")
8271
8272 (define_split
8273   [(set (match_operand 0 "ext_register_operand" "")
8274         (and (match_dup 0)
8275              (const_int -65281)))
8276    (clobber (reg:CC FLAGS_REG))]
8277   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8278   [(parallel [(set (zero_extract:SI (match_dup 0)
8279                                     (const_int 8)
8280                                     (const_int 8))
8281                    (xor:SI 
8282                      (zero_extract:SI (match_dup 0)
8283                                       (const_int 8)
8284                                       (const_int 8))
8285                      (zero_extract:SI (match_dup 0)
8286                                       (const_int 8)
8287                                       (const_int 8))))
8288               (clobber (reg:CC FLAGS_REG))])]
8289   "operands[0] = gen_lowpart (SImode, operands[0]);")
8290
8291 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8292 (define_insn "*andsi_1_zext"
8293   [(set (match_operand:DI 0 "register_operand" "=r")
8294         (zero_extend:DI
8295           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8296                   (match_operand:SI 2 "general_operand" "rim"))))
8297    (clobber (reg:CC FLAGS_REG))]
8298   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8299   "and{l}\t{%2, %k0|%k0, %2}"
8300   [(set_attr "type" "alu")
8301    (set_attr "mode" "SI")])
8302
8303 (define_insn "*andsi_2"
8304   [(set (reg 17)
8305         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8306                          (match_operand:SI 2 "general_operand" "rim,ri"))
8307                  (const_int 0)))
8308    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8309         (and:SI (match_dup 1) (match_dup 2)))]
8310   "ix86_match_ccmode (insn, CCNOmode)
8311    && ix86_binary_operator_ok (AND, SImode, operands)"
8312   "and{l}\t{%2, %0|%0, %2}"
8313   [(set_attr "type" "alu")
8314    (set_attr "mode" "SI")])
8315
8316 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8317 (define_insn "*andsi_2_zext"
8318   [(set (reg 17)
8319         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8320                          (match_operand:SI 2 "general_operand" "rim"))
8321                  (const_int 0)))
8322    (set (match_operand:DI 0 "register_operand" "=r")
8323         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8324   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8325    && ix86_binary_operator_ok (AND, SImode, operands)"
8326   "and{l}\t{%2, %k0|%k0, %2}"
8327   [(set_attr "type" "alu")
8328    (set_attr "mode" "SI")])
8329
8330 (define_expand "andhi3"
8331   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8332         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8333                 (match_operand:HI 2 "general_operand" "")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "TARGET_HIMODE_MATH"
8336   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8337
8338 (define_insn "*andhi_1"
8339   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8340         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8341                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "ix86_binary_operator_ok (AND, HImode, operands)"
8344 {
8345   switch (get_attr_type (insn))
8346     {
8347     case TYPE_IMOVX:
8348       if (GET_CODE (operands[2]) != CONST_INT)
8349         abort ();
8350       if (INTVAL (operands[2]) == 0xff)
8351         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8352       abort ();
8353
8354     default:
8355       if (! rtx_equal_p (operands[0], operands[1]))
8356         abort ();
8357
8358       return "and{w}\t{%2, %0|%0, %2}";
8359     }
8360 }
8361   [(set_attr "type" "alu,alu,imovx")
8362    (set_attr "length_immediate" "*,*,0")
8363    (set_attr "mode" "HI,HI,SI")])
8364
8365 (define_insn "*andhi_2"
8366   [(set (reg 17)
8367         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8368                          (match_operand:HI 2 "general_operand" "rim,ri"))
8369                  (const_int 0)))
8370    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8371         (and:HI (match_dup 1) (match_dup 2)))]
8372   "ix86_match_ccmode (insn, CCNOmode)
8373    && ix86_binary_operator_ok (AND, HImode, operands)"
8374   "and{w}\t{%2, %0|%0, %2}"
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "HI")])
8377
8378 (define_expand "andqi3"
8379   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8380         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8381                 (match_operand:QI 2 "general_operand" "")))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "TARGET_QIMODE_MATH"
8384   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8385
8386 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8387 (define_insn "*andqi_1"
8388   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8389         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8390                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8391    (clobber (reg:CC FLAGS_REG))]
8392   "ix86_binary_operator_ok (AND, QImode, operands)"
8393   "@
8394    and{b}\t{%2, %0|%0, %2}
8395    and{b}\t{%2, %0|%0, %2}
8396    and{l}\t{%k2, %k0|%k0, %k2}"
8397   [(set_attr "type" "alu")
8398    (set_attr "mode" "QI,QI,SI")])
8399
8400 (define_insn "*andqi_1_slp"
8401   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8402         (and:QI (match_dup 0)
8403                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8404    (clobber (reg:CC FLAGS_REG))]
8405   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8406    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8407   "and{b}\t{%1, %0|%0, %1}"
8408   [(set_attr "type" "alu1")
8409    (set_attr "mode" "QI")])
8410
8411 (define_insn "*andqi_2"
8412   [(set (reg 17)
8413         (compare (and:QI
8414                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8415                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8416                  (const_int 0)))
8417    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8418         (and:QI (match_dup 1) (match_dup 2)))]
8419   "ix86_match_ccmode (insn, CCNOmode)
8420    && ix86_binary_operator_ok (AND, QImode, operands)"
8421 {
8422   if (which_alternative == 2)
8423     {
8424       if (GET_CODE (operands[2]) == CONST_INT
8425           && (INTVAL (operands[2]) & 0xffffff00))
8426         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8427       return "and{l}\t{%2, %k0|%k0, %2}";
8428     }
8429   return "and{b}\t{%2, %0|%0, %2}";
8430 }
8431   [(set_attr "type" "alu")
8432    (set_attr "mode" "QI,QI,SI")])
8433
8434 (define_insn "*andqi_2_slp"
8435   [(set (reg 17)
8436         (compare (and:QI
8437                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8438                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8439                  (const_int 0)))
8440    (set (strict_low_part (match_dup 0))
8441         (and:QI (match_dup 0) (match_dup 1)))]
8442   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8443    && ix86_match_ccmode (insn, CCNOmode)
8444    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8445   "and{b}\t{%1, %0|%0, %1}"
8446   [(set_attr "type" "alu1")
8447    (set_attr "mode" "QI")])
8448
8449 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8450 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8451 ;; for a QImode operand, which of course failed.
8452
8453 (define_insn "andqi_ext_0"
8454   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455                          (const_int 8)
8456                          (const_int 8))
8457         (and:SI 
8458           (zero_extract:SI
8459             (match_operand 1 "ext_register_operand" "0")
8460             (const_int 8)
8461             (const_int 8))
8462           (match_operand 2 "const_int_operand" "n")))
8463    (clobber (reg:CC FLAGS_REG))]
8464   ""
8465   "and{b}\t{%2, %h0|%h0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "length_immediate" "1")
8468    (set_attr "mode" "QI")])
8469
8470 ;; Generated by peephole translating test to and.  This shows up
8471 ;; often in fp comparisons.
8472
8473 (define_insn "*andqi_ext_0_cc"
8474   [(set (reg 17)
8475         (compare
8476           (and:SI
8477             (zero_extract:SI
8478               (match_operand 1 "ext_register_operand" "0")
8479               (const_int 8)
8480               (const_int 8))
8481             (match_operand 2 "const_int_operand" "n"))
8482           (const_int 0)))
8483    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (and:SI 
8487           (zero_extract:SI
8488             (match_dup 1)
8489             (const_int 8)
8490             (const_int 8))
8491           (match_dup 2)))]
8492   "ix86_match_ccmode (insn, CCNOmode)"
8493   "and{b}\t{%2, %h0|%h0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "length_immediate" "1")
8496    (set_attr "mode" "QI")])
8497
8498 (define_insn "*andqi_ext_1"
8499   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500                          (const_int 8)
8501                          (const_int 8))
8502         (and:SI 
8503           (zero_extract:SI
8504             (match_operand 1 "ext_register_operand" "0")
8505             (const_int 8)
8506             (const_int 8))
8507           (zero_extend:SI
8508             (match_operand:QI 2 "general_operand" "Qm"))))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "!TARGET_64BIT"
8511   "and{b}\t{%2, %h0|%h0, %2}"
8512   [(set_attr "type" "alu")
8513    (set_attr "length_immediate" "0")
8514    (set_attr "mode" "QI")])
8515
8516 (define_insn "*andqi_ext_1_rex64"
8517   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8518                          (const_int 8)
8519                          (const_int 8))
8520         (and:SI 
8521           (zero_extract:SI
8522             (match_operand 1 "ext_register_operand" "0")
8523             (const_int 8)
8524             (const_int 8))
8525           (zero_extend:SI
8526             (match_operand 2 "ext_register_operand" "Q"))))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT"
8529   "and{b}\t{%2, %h0|%h0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "length_immediate" "0")
8532    (set_attr "mode" "QI")])
8533
8534 (define_insn "*andqi_ext_2"
8535   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8536                          (const_int 8)
8537                          (const_int 8))
8538         (and:SI
8539           (zero_extract:SI
8540             (match_operand 1 "ext_register_operand" "%0")
8541             (const_int 8)
8542             (const_int 8))
8543           (zero_extract:SI
8544             (match_operand 2 "ext_register_operand" "Q")
8545             (const_int 8)
8546             (const_int 8))))
8547    (clobber (reg:CC FLAGS_REG))]
8548   ""
8549   "and{b}\t{%h2, %h0|%h0, %h2}"
8550   [(set_attr "type" "alu")
8551    (set_attr "length_immediate" "0")
8552    (set_attr "mode" "QI")])
8553
8554 ;; Convert wide AND instructions with immediate operand to shorter QImode
8555 ;; equivalents when possible.
8556 ;; Don't do the splitting with memory operands, since it introduces risk
8557 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8558 ;; for size, but that can (should?) be handled by generic code instead.
8559 (define_split
8560   [(set (match_operand 0 "register_operand" "")
8561         (and (match_operand 1 "register_operand" "")
8562              (match_operand 2 "const_int_operand" "")))
8563    (clobber (reg:CC FLAGS_REG))]
8564    "reload_completed
8565     && QI_REG_P (operands[0])
8566     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8567     && !(~INTVAL (operands[2]) & ~(255 << 8))
8568     && GET_MODE (operands[0]) != QImode"
8569   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8570                    (and:SI (zero_extract:SI (match_dup 1)
8571                                             (const_int 8) (const_int 8))
8572                            (match_dup 2)))
8573               (clobber (reg:CC FLAGS_REG))])]
8574   "operands[0] = gen_lowpart (SImode, operands[0]);
8575    operands[1] = gen_lowpart (SImode, operands[1]);
8576    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8577
8578 ;; Since AND can be encoded with sign extended immediate, this is only
8579 ;; profitable when 7th bit is not set.
8580 (define_split
8581   [(set (match_operand 0 "register_operand" "")
8582         (and (match_operand 1 "general_operand" "")
8583              (match_operand 2 "const_int_operand" "")))
8584    (clobber (reg:CC FLAGS_REG))]
8585    "reload_completed
8586     && ANY_QI_REG_P (operands[0])
8587     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8588     && !(~INTVAL (operands[2]) & ~255)
8589     && !(INTVAL (operands[2]) & 128)
8590     && GET_MODE (operands[0]) != QImode"
8591   [(parallel [(set (strict_low_part (match_dup 0))
8592                    (and:QI (match_dup 1)
8593                            (match_dup 2)))
8594               (clobber (reg:CC FLAGS_REG))])]
8595   "operands[0] = gen_lowpart (QImode, operands[0]);
8596    operands[1] = gen_lowpart (QImode, operands[1]);
8597    operands[2] = gen_lowpart (QImode, operands[2]);")
8598 \f
8599 ;; Logical inclusive OR instructions
8600
8601 ;; %%% This used to optimize known byte-wide and operations to memory.
8602 ;; If this is considered useful, it should be done with splitters.
8603
8604 (define_expand "iordi3"
8605   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8606         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8607                 (match_operand:DI 2 "x86_64_general_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "TARGET_64BIT"
8610   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8611
8612 (define_insn "*iordi_1_rex64"
8613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8614         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8615                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8616    (clobber (reg:CC FLAGS_REG))]
8617   "TARGET_64BIT
8618    && ix86_binary_operator_ok (IOR, DImode, operands)"
8619   "or{q}\t{%2, %0|%0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "DI")])
8622
8623 (define_insn "*iordi_2_rex64"
8624   [(set (reg 17)
8625         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8626                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8627                  (const_int 0)))
8628    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8629         (ior:DI (match_dup 1) (match_dup 2)))]
8630   "TARGET_64BIT
8631    && ix86_match_ccmode (insn, CCNOmode)
8632    && ix86_binary_operator_ok (IOR, DImode, operands)"
8633   "or{q}\t{%2, %0|%0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "DI")])
8636
8637 (define_insn "*iordi_3_rex64"
8638   [(set (reg 17)
8639         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8640                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8641                  (const_int 0)))
8642    (clobber (match_scratch:DI 0 "=r"))]
8643   "TARGET_64BIT
8644    && ix86_match_ccmode (insn, CCNOmode)
8645    && ix86_binary_operator_ok (IOR, DImode, operands)"
8646   "or{q}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "DI")])
8649
8650
8651 (define_expand "iorsi3"
8652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8653         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8654                 (match_operand:SI 2 "general_operand" "")))
8655    (clobber (reg:CC FLAGS_REG))]
8656   ""
8657   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8658
8659 (define_insn "*iorsi_1"
8660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8661         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8662                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "ix86_binary_operator_ok (IOR, SImode, operands)"
8665   "or{l}\t{%2, %0|%0, %2}"
8666   [(set_attr "type" "alu")
8667    (set_attr "mode" "SI")])
8668
8669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8670 (define_insn "*iorsi_1_zext"
8671   [(set (match_operand:DI 0 "register_operand" "=rm")
8672         (zero_extend:DI
8673           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8674                   (match_operand:SI 2 "general_operand" "rim"))))
8675    (clobber (reg:CC FLAGS_REG))]
8676   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8677   "or{l}\t{%2, %k0|%k0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "mode" "SI")])
8680
8681 (define_insn "*iorsi_1_zext_imm"
8682   [(set (match_operand:DI 0 "register_operand" "=rm")
8683         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8684                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8685    (clobber (reg:CC FLAGS_REG))]
8686   "TARGET_64BIT"
8687   "or{l}\t{%2, %k0|%k0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "SI")])
8690
8691 (define_insn "*iorsi_2"
8692   [(set (reg 17)
8693         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8694                          (match_operand:SI 2 "general_operand" "rim,ri"))
8695                  (const_int 0)))
8696    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8697         (ior:SI (match_dup 1) (match_dup 2)))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && ix86_binary_operator_ok (IOR, SImode, operands)"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8703
8704 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8705 ;; ??? Special case for immediate operand is missing - it is tricky.
8706 (define_insn "*iorsi_2_zext"
8707   [(set (reg 17)
8708         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8709                          (match_operand:SI 2 "general_operand" "rim"))
8710                  (const_int 0)))
8711    (set (match_operand:DI 0 "register_operand" "=r")
8712         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8713   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8714    && ix86_binary_operator_ok (IOR, SImode, operands)"
8715   "or{l}\t{%2, %k0|%k0, %2}"
8716   [(set_attr "type" "alu")
8717    (set_attr "mode" "SI")])
8718
8719 (define_insn "*iorsi_2_zext_imm"
8720   [(set (reg 17)
8721         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8722                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8723                  (const_int 0)))
8724    (set (match_operand:DI 0 "register_operand" "=r")
8725         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8726   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8727    && ix86_binary_operator_ok (IOR, SImode, operands)"
8728   "or{l}\t{%2, %k0|%k0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "mode" "SI")])
8731
8732 (define_insn "*iorsi_3"
8733   [(set (reg 17)
8734         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8735                          (match_operand:SI 2 "general_operand" "rim"))
8736                  (const_int 0)))
8737    (clobber (match_scratch:SI 0 "=r"))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8740   "or{l}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "SI")])
8743
8744 (define_expand "iorhi3"
8745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8746         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8747                 (match_operand:HI 2 "general_operand" "")))
8748    (clobber (reg:CC FLAGS_REG))]
8749   "TARGET_HIMODE_MATH"
8750   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8751
8752 (define_insn "*iorhi_1"
8753   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8754         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8755                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8756    (clobber (reg:CC FLAGS_REG))]
8757   "ix86_binary_operator_ok (IOR, HImode, operands)"
8758   "or{w}\t{%2, %0|%0, %2}"
8759   [(set_attr "type" "alu")
8760    (set_attr "mode" "HI")])
8761
8762 (define_insn "*iorhi_2"
8763   [(set (reg 17)
8764         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8765                          (match_operand:HI 2 "general_operand" "rim,ri"))
8766                  (const_int 0)))
8767    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8768         (ior:HI (match_dup 1) (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)
8770    && ix86_binary_operator_ok (IOR, HImode, operands)"
8771   "or{w}\t{%2, %0|%0, %2}"
8772   [(set_attr "type" "alu")
8773    (set_attr "mode" "HI")])
8774
8775 (define_insn "*iorhi_3"
8776   [(set (reg 17)
8777         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8778                          (match_operand:HI 2 "general_operand" "rim"))
8779                  (const_int 0)))
8780    (clobber (match_scratch:HI 0 "=r"))]
8781   "ix86_match_ccmode (insn, CCNOmode)
8782    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8783   "or{w}\t{%2, %0|%0, %2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "mode" "HI")])
8786
8787 (define_expand "iorqi3"
8788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8789         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8790                 (match_operand:QI 2 "general_operand" "")))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "TARGET_QIMODE_MATH"
8793   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8794
8795 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8796 (define_insn "*iorqi_1"
8797   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8798         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8799                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8800    (clobber (reg:CC FLAGS_REG))]
8801   "ix86_binary_operator_ok (IOR, QImode, operands)"
8802   "@
8803    or{b}\t{%2, %0|%0, %2}
8804    or{b}\t{%2, %0|%0, %2}
8805    or{l}\t{%k2, %k0|%k0, %k2}"
8806   [(set_attr "type" "alu")
8807    (set_attr "mode" "QI,QI,SI")])
8808
8809 (define_insn "*iorqi_1_slp"
8810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8811         (ior:QI (match_dup 0)
8812                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8815    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8816   "or{b}\t{%1, %0|%0, %1}"
8817   [(set_attr "type" "alu1")
8818    (set_attr "mode" "QI")])
8819
8820 (define_insn "*iorqi_2"
8821   [(set (reg 17)
8822         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8823                          (match_operand:QI 2 "general_operand" "qim,qi"))
8824                  (const_int 0)))
8825    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8826         (ior:QI (match_dup 1) (match_dup 2)))]
8827   "ix86_match_ccmode (insn, CCNOmode)
8828    && ix86_binary_operator_ok (IOR, QImode, operands)"
8829   "or{b}\t{%2, %0|%0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "QI")])
8832
8833 (define_insn "*iorqi_2_slp"
8834   [(set (reg 17)
8835         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8836                          (match_operand:QI 1 "general_operand" "qim,qi"))
8837                  (const_int 0)))
8838    (set (strict_low_part (match_dup 0))
8839         (ior:QI (match_dup 0) (match_dup 1)))]
8840   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8841    && ix86_match_ccmode (insn, CCNOmode)
8842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8843   "or{b}\t{%1, %0|%0, %1}"
8844   [(set_attr "type" "alu1")
8845    (set_attr "mode" "QI")])
8846
8847 (define_insn "*iorqi_3"
8848   [(set (reg 17)
8849         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8850                          (match_operand:QI 2 "general_operand" "qim"))
8851                  (const_int 0)))
8852    (clobber (match_scratch:QI 0 "=q"))]
8853   "ix86_match_ccmode (insn, CCNOmode)
8854    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8855   "or{b}\t{%2, %0|%0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "QI")])
8858
8859 (define_insn "iorqi_ext_0"
8860   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861                          (const_int 8)
8862                          (const_int 8))
8863         (ior:SI 
8864           (zero_extract:SI
8865             (match_operand 1 "ext_register_operand" "0")
8866             (const_int 8)
8867             (const_int 8))
8868           (match_operand 2 "const_int_operand" "n")))
8869    (clobber (reg:CC FLAGS_REG))]
8870   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8871   "or{b}\t{%2, %h0|%h0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "length_immediate" "1")
8874    (set_attr "mode" "QI")])
8875
8876 (define_insn "*iorqi_ext_1"
8877   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878                          (const_int 8)
8879                          (const_int 8))
8880         (ior:SI 
8881           (zero_extract:SI
8882             (match_operand 1 "ext_register_operand" "0")
8883             (const_int 8)
8884             (const_int 8))
8885           (zero_extend:SI
8886             (match_operand:QI 2 "general_operand" "Qm"))))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "!TARGET_64BIT
8889    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8890   "or{b}\t{%2, %h0|%h0, %2}"
8891   [(set_attr "type" "alu")
8892    (set_attr "length_immediate" "0")
8893    (set_attr "mode" "QI")])
8894
8895 (define_insn "*iorqi_ext_1_rex64"
8896   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8897                          (const_int 8)
8898                          (const_int 8))
8899         (ior:SI 
8900           (zero_extract:SI
8901             (match_operand 1 "ext_register_operand" "0")
8902             (const_int 8)
8903             (const_int 8))
8904           (zero_extend:SI
8905             (match_operand 2 "ext_register_operand" "Q"))))
8906    (clobber (reg:CC FLAGS_REG))]
8907   "TARGET_64BIT
8908    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8909   "or{b}\t{%2, %h0|%h0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "length_immediate" "0")
8912    (set_attr "mode" "QI")])
8913
8914 (define_insn "*iorqi_ext_2"
8915   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8916                          (const_int 8)
8917                          (const_int 8))
8918         (ior:SI 
8919           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8920                            (const_int 8)
8921                            (const_int 8))
8922           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8923                            (const_int 8)
8924                            (const_int 8))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8927   "ior{b}\t{%h2, %h0|%h0, %h2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "length_immediate" "0")
8930    (set_attr "mode" "QI")])
8931
8932 (define_split
8933   [(set (match_operand 0 "register_operand" "")
8934         (ior (match_operand 1 "register_operand" "")
8935              (match_operand 2 "const_int_operand" "")))
8936    (clobber (reg:CC FLAGS_REG))]
8937    "reload_completed
8938     && QI_REG_P (operands[0])
8939     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8940     && !(INTVAL (operands[2]) & ~(255 << 8))
8941     && GET_MODE (operands[0]) != QImode"
8942   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8943                    (ior:SI (zero_extract:SI (match_dup 1)
8944                                             (const_int 8) (const_int 8))
8945                            (match_dup 2)))
8946               (clobber (reg:CC FLAGS_REG))])]
8947   "operands[0] = gen_lowpart (SImode, operands[0]);
8948    operands[1] = gen_lowpart (SImode, operands[1]);
8949    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8950
8951 ;; Since OR can be encoded with sign extended immediate, this is only
8952 ;; profitable when 7th bit is set.
8953 (define_split
8954   [(set (match_operand 0 "register_operand" "")
8955         (ior (match_operand 1 "general_operand" "")
8956              (match_operand 2 "const_int_operand" "")))
8957    (clobber (reg:CC FLAGS_REG))]
8958    "reload_completed
8959     && ANY_QI_REG_P (operands[0])
8960     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8961     && !(INTVAL (operands[2]) & ~255)
8962     && (INTVAL (operands[2]) & 128)
8963     && GET_MODE (operands[0]) != QImode"
8964   [(parallel [(set (strict_low_part (match_dup 0))
8965                    (ior:QI (match_dup 1)
8966                            (match_dup 2)))
8967               (clobber (reg:CC FLAGS_REG))])]
8968   "operands[0] = gen_lowpart (QImode, operands[0]);
8969    operands[1] = gen_lowpart (QImode, operands[1]);
8970    operands[2] = gen_lowpart (QImode, operands[2]);")
8971 \f
8972 ;; Logical XOR instructions
8973
8974 ;; %%% This used to optimize known byte-wide and operations to memory.
8975 ;; If this is considered useful, it should be done with splitters.
8976
8977 (define_expand "xordi3"
8978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8979         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8980                 (match_operand:DI 2 "x86_64_general_operand" "")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   "TARGET_64BIT"
8983   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8984
8985 (define_insn "*xordi_1_rex64"
8986   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8987         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8988                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "TARGET_64BIT
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "@
8993    xor{q}\t{%2, %0|%0, %2}
8994    xor{q}\t{%2, %0|%0, %2}"
8995   [(set_attr "type" "alu")
8996    (set_attr "mode" "DI,DI")])
8997
8998 (define_insn "*xordi_2_rex64"
8999   [(set (reg 17)
9000         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9001                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9002                  (const_int 0)))
9003    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9004         (xor:DI (match_dup 1) (match_dup 2)))]
9005   "TARGET_64BIT
9006    && ix86_match_ccmode (insn, CCNOmode)
9007    && ix86_binary_operator_ok (XOR, DImode, operands)"
9008   "@
9009    xor{q}\t{%2, %0|%0, %2}
9010    xor{q}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "DI,DI")])
9013
9014 (define_insn "*xordi_3_rex64"
9015   [(set (reg 17)
9016         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9017                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9018                  (const_int 0)))
9019    (clobber (match_scratch:DI 0 "=r"))]
9020   "TARGET_64BIT
9021    && ix86_match_ccmode (insn, CCNOmode)
9022    && ix86_binary_operator_ok (XOR, DImode, operands)"
9023   "xor{q}\t{%2, %0|%0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "DI")])
9026
9027 (define_expand "xorsi3"
9028   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9029         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9030                 (match_operand:SI 2 "general_operand" "")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   ""
9033   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9034
9035 (define_insn "*xorsi_1"
9036   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9037         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9038                 (match_operand:SI 2 "general_operand" "ri,rm")))
9039    (clobber (reg:CC FLAGS_REG))]
9040   "ix86_binary_operator_ok (XOR, SImode, operands)"
9041   "xor{l}\t{%2, %0|%0, %2}"
9042   [(set_attr "type" "alu")
9043    (set_attr "mode" "SI")])
9044
9045 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9046 ;; Add speccase for immediates
9047 (define_insn "*xorsi_1_zext"
9048   [(set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI
9050           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9051                   (match_operand:SI 2 "general_operand" "rim"))))
9052    (clobber (reg:CC FLAGS_REG))]
9053   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9054   "xor{l}\t{%2, %k0|%k0, %2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "SI")])
9057
9058 (define_insn "*xorsi_1_zext_imm"
9059   [(set (match_operand:DI 0 "register_operand" "=r")
9060         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9061                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9062    (clobber (reg:CC FLAGS_REG))]
9063   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9064   "xor{l}\t{%2, %k0|%k0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "SI")])
9067
9068 (define_insn "*xorsi_2"
9069   [(set (reg 17)
9070         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9071                          (match_operand:SI 2 "general_operand" "rim,ri"))
9072                  (const_int 0)))
9073    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9074         (xor:SI (match_dup 1) (match_dup 2)))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && ix86_binary_operator_ok (XOR, SImode, operands)"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9080
9081 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9082 ;; ??? Special case for immediate operand is missing - it is tricky.
9083 (define_insn "*xorsi_2_zext"
9084   [(set (reg 17)
9085         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9086                          (match_operand:SI 2 "general_operand" "rim"))
9087                  (const_int 0)))
9088    (set (match_operand:DI 0 "register_operand" "=r")
9089         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9090   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091    && ix86_binary_operator_ok (XOR, SImode, operands)"
9092   "xor{l}\t{%2, %k0|%k0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "mode" "SI")])
9095
9096 (define_insn "*xorsi_2_zext_imm"
9097   [(set (reg 17)
9098         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9099                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9100                  (const_int 0)))
9101    (set (match_operand:DI 0 "register_operand" "=r")
9102         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9103   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9104    && ix86_binary_operator_ok (XOR, SImode, operands)"
9105   "xor{l}\t{%2, %k0|%k0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "mode" "SI")])
9108
9109 (define_insn "*xorsi_3"
9110   [(set (reg 17)
9111         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9112                          (match_operand:SI 2 "general_operand" "rim"))
9113                  (const_int 0)))
9114    (clobber (match_scratch:SI 0 "=r"))]
9115   "ix86_match_ccmode (insn, CCNOmode)
9116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9117   "xor{l}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "SI")])
9120
9121 (define_expand "xorhi3"
9122   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9123         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9124                 (match_operand:HI 2 "general_operand" "")))
9125    (clobber (reg:CC FLAGS_REG))]
9126   "TARGET_HIMODE_MATH"
9127   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9128
9129 (define_insn "*xorhi_1"
9130   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9131         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9132                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "ix86_binary_operator_ok (XOR, HImode, operands)"
9135   "xor{w}\t{%2, %0|%0, %2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "mode" "HI")])
9138
9139 (define_insn "*xorhi_2"
9140   [(set (reg 17)
9141         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9142                          (match_operand:HI 2 "general_operand" "rim,ri"))
9143                  (const_int 0)))
9144    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9145         (xor:HI (match_dup 1) (match_dup 2)))]
9146   "ix86_match_ccmode (insn, CCNOmode)
9147    && ix86_binary_operator_ok (XOR, HImode, operands)"
9148   "xor{w}\t{%2, %0|%0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "mode" "HI")])
9151
9152 (define_insn "*xorhi_3"
9153   [(set (reg 17)
9154         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9155                          (match_operand:HI 2 "general_operand" "rim"))
9156                  (const_int 0)))
9157    (clobber (match_scratch:HI 0 "=r"))]
9158   "ix86_match_ccmode (insn, CCNOmode)
9159    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9160   "xor{w}\t{%2, %0|%0, %2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "mode" "HI")])
9163
9164 (define_expand "xorqi3"
9165   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9166         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9167                 (match_operand:QI 2 "general_operand" "")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "TARGET_QIMODE_MATH"
9170   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9171
9172 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9173 (define_insn "*xorqi_1"
9174   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9175         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9176                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9177    (clobber (reg:CC FLAGS_REG))]
9178   "ix86_binary_operator_ok (XOR, QImode, operands)"
9179   "@
9180    xor{b}\t{%2, %0|%0, %2}
9181    xor{b}\t{%2, %0|%0, %2}
9182    xor{l}\t{%k2, %k0|%k0, %k2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "mode" "QI,QI,SI")])
9185
9186 (define_insn "*xorqi_1_slp"
9187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9188         (xor:QI (match_dup 0)
9189                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9192    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9193   "xor{b}\t{%1, %0|%0, %1}"
9194   [(set_attr "type" "alu1")
9195    (set_attr "mode" "QI")])
9196
9197 (define_insn "xorqi_ext_0"
9198   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199                          (const_int 8)
9200                          (const_int 8))
9201         (xor:SI 
9202           (zero_extract:SI
9203             (match_operand 1 "ext_register_operand" "0")
9204             (const_int 8)
9205             (const_int 8))
9206           (match_operand 2 "const_int_operand" "n")))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9209   "xor{b}\t{%2, %h0|%h0, %2}"
9210   [(set_attr "type" "alu")
9211    (set_attr "length_immediate" "1")
9212    (set_attr "mode" "QI")])
9213
9214 (define_insn "*xorqi_ext_1"
9215   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216                          (const_int 8)
9217                          (const_int 8))
9218         (xor:SI 
9219           (zero_extract:SI
9220             (match_operand 1 "ext_register_operand" "0")
9221             (const_int 8)
9222             (const_int 8))
9223           (zero_extend:SI
9224             (match_operand:QI 2 "general_operand" "Qm"))))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "!TARGET_64BIT
9227    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9228   "xor{b}\t{%2, %h0|%h0, %2}"
9229   [(set_attr "type" "alu")
9230    (set_attr "length_immediate" "0")
9231    (set_attr "mode" "QI")])
9232
9233 (define_insn "*xorqi_ext_1_rex64"
9234   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9235                          (const_int 8)
9236                          (const_int 8))
9237         (xor:SI 
9238           (zero_extract:SI
9239             (match_operand 1 "ext_register_operand" "0")
9240             (const_int 8)
9241             (const_int 8))
9242           (zero_extend:SI
9243             (match_operand 2 "ext_register_operand" "Q"))))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "TARGET_64BIT
9246    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9247   "xor{b}\t{%2, %h0|%h0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "length_immediate" "0")
9250    (set_attr "mode" "QI")])
9251
9252 (define_insn "*xorqi_ext_2"
9253   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254                          (const_int 8)
9255                          (const_int 8))
9256         (xor:SI 
9257           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9258                            (const_int 8)
9259                            (const_int 8))
9260           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9261                            (const_int 8)
9262                            (const_int 8))))
9263    (clobber (reg:CC FLAGS_REG))]
9264   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9265   "xor{b}\t{%h2, %h0|%h0, %h2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "length_immediate" "0")
9268    (set_attr "mode" "QI")])
9269
9270 (define_insn "*xorqi_cc_1"
9271   [(set (reg 17)
9272         (compare
9273           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9274                   (match_operand:QI 2 "general_operand" "qim,qi"))
9275           (const_int 0)))
9276    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9277         (xor:QI (match_dup 1) (match_dup 2)))]
9278   "ix86_match_ccmode (insn, CCNOmode)
9279    && ix86_binary_operator_ok (XOR, QImode, operands)"
9280   "xor{b}\t{%2, %0|%0, %2}"
9281   [(set_attr "type" "alu")
9282    (set_attr "mode" "QI")])
9283
9284 (define_insn "*xorqi_2_slp"
9285   [(set (reg 17)
9286         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9287                          (match_operand:QI 1 "general_operand" "qim,qi"))
9288                  (const_int 0)))
9289    (set (strict_low_part (match_dup 0))
9290         (xor:QI (match_dup 0) (match_dup 1)))]
9291   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9292    && ix86_match_ccmode (insn, CCNOmode)
9293    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9294   "xor{b}\t{%1, %0|%0, %1}"
9295   [(set_attr "type" "alu1")
9296    (set_attr "mode" "QI")])
9297
9298 (define_insn "*xorqi_cc_2"
9299   [(set (reg 17)
9300         (compare
9301           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9302                   (match_operand:QI 2 "general_operand" "qim"))
9303           (const_int 0)))
9304    (clobber (match_scratch:QI 0 "=q"))]
9305   "ix86_match_ccmode (insn, CCNOmode)
9306    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9307   "xor{b}\t{%2, %0|%0, %2}"
9308   [(set_attr "type" "alu")
9309    (set_attr "mode" "QI")])
9310
9311 (define_insn "*xorqi_cc_ext_1"
9312   [(set (reg 17)
9313         (compare
9314           (xor:SI
9315             (zero_extract:SI
9316               (match_operand 1 "ext_register_operand" "0")
9317               (const_int 8)
9318               (const_int 8))
9319             (match_operand:QI 2 "general_operand" "qmn"))
9320           (const_int 0)))
9321    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9322                          (const_int 8)
9323                          (const_int 8))
9324         (xor:SI 
9325           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9326           (match_dup 2)))]
9327   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9328   "xor{b}\t{%2, %h0|%h0, %2}"
9329   [(set_attr "type" "alu")
9330    (set_attr "mode" "QI")])
9331
9332 (define_insn "*xorqi_cc_ext_1_rex64"
9333   [(set (reg 17)
9334         (compare
9335           (xor:SI
9336             (zero_extract:SI
9337               (match_operand 1 "ext_register_operand" "0")
9338               (const_int 8)
9339               (const_int 8))
9340             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9341           (const_int 0)))
9342    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9343                          (const_int 8)
9344                          (const_int 8))
9345         (xor:SI 
9346           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9347           (match_dup 2)))]
9348   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9349   "xor{b}\t{%2, %h0|%h0, %2}"
9350   [(set_attr "type" "alu")
9351    (set_attr "mode" "QI")])
9352
9353 (define_expand "xorqi_cc_ext_1"
9354   [(parallel [
9355      (set (reg:CCNO FLAGS_REG)
9356           (compare:CCNO
9357             (xor:SI
9358               (zero_extract:SI
9359                 (match_operand 1 "ext_register_operand" "")
9360                 (const_int 8)
9361                 (const_int 8))
9362               (match_operand:QI 2 "general_operand" ""))
9363             (const_int 0)))
9364      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9365                            (const_int 8)
9366                            (const_int 8))
9367           (xor:SI 
9368             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9369             (match_dup 2)))])]
9370   ""
9371   "")
9372
9373 (define_split
9374   [(set (match_operand 0 "register_operand" "")
9375         (xor (match_operand 1 "register_operand" "")
9376              (match_operand 2 "const_int_operand" "")))
9377    (clobber (reg:CC FLAGS_REG))]
9378    "reload_completed
9379     && QI_REG_P (operands[0])
9380     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9381     && !(INTVAL (operands[2]) & ~(255 << 8))
9382     && GET_MODE (operands[0]) != QImode"
9383   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9384                    (xor:SI (zero_extract:SI (match_dup 1)
9385                                             (const_int 8) (const_int 8))
9386                            (match_dup 2)))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   "operands[0] = gen_lowpart (SImode, operands[0]);
9389    operands[1] = gen_lowpart (SImode, operands[1]);
9390    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9391
9392 ;; Since XOR can be encoded with sign extended immediate, this is only
9393 ;; profitable when 7th bit is set.
9394 (define_split
9395   [(set (match_operand 0 "register_operand" "")
9396         (xor (match_operand 1 "general_operand" "")
9397              (match_operand 2 "const_int_operand" "")))
9398    (clobber (reg:CC FLAGS_REG))]
9399    "reload_completed
9400     && ANY_QI_REG_P (operands[0])
9401     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9402     && !(INTVAL (operands[2]) & ~255)
9403     && (INTVAL (operands[2]) & 128)
9404     && GET_MODE (operands[0]) != QImode"
9405   [(parallel [(set (strict_low_part (match_dup 0))
9406                    (xor:QI (match_dup 1)
9407                            (match_dup 2)))
9408               (clobber (reg:CC FLAGS_REG))])]
9409   "operands[0] = gen_lowpart (QImode, operands[0]);
9410    operands[1] = gen_lowpart (QImode, operands[1]);
9411    operands[2] = gen_lowpart (QImode, operands[2]);")
9412 \f
9413 ;; Negation instructions
9414
9415 (define_expand "negdi2"
9416   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9417                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9418               (clobber (reg:CC FLAGS_REG))])]
9419   ""
9420   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9421
9422 (define_insn "*negdi2_1"
9423   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9424         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "!TARGET_64BIT
9427    && ix86_unary_operator_ok (NEG, DImode, operands)"
9428   "#")
9429
9430 (define_split
9431   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9432         (neg:DI (match_operand:DI 1 "general_operand" "")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "!TARGET_64BIT && reload_completed"
9435   [(parallel
9436     [(set (reg:CCZ FLAGS_REG)
9437           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9438      (set (match_dup 0) (neg:SI (match_dup 2)))])
9439    (parallel
9440     [(set (match_dup 1)
9441           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9442                             (match_dup 3))
9443                    (const_int 0)))
9444      (clobber (reg:CC FLAGS_REG))])
9445    (parallel
9446     [(set (match_dup 1)
9447           (neg:SI (match_dup 1)))
9448      (clobber (reg:CC FLAGS_REG))])]
9449   "split_di (operands+1, 1, operands+2, operands+3);
9450    split_di (operands+0, 1, operands+0, operands+1);")
9451
9452 (define_insn "*negdi2_1_rex64"
9453   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9454         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9457   "neg{q}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "DI")])
9460
9461 ;; The problem with neg is that it does not perform (compare x 0),
9462 ;; it really performs (compare 0 x), which leaves us with the zero
9463 ;; flag being the only useful item.
9464
9465 (define_insn "*negdi2_cmpz_rex64"
9466   [(set (reg:CCZ FLAGS_REG)
9467         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9468                      (const_int 0)))
9469    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9470         (neg:DI (match_dup 1)))]
9471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9472   "neg{q}\t%0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "DI")])
9475
9476
9477 (define_expand "negsi2"
9478   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9479                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9480               (clobber (reg:CC FLAGS_REG))])]
9481   ""
9482   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9483
9484 (define_insn "*negsi2_1"
9485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9486         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "ix86_unary_operator_ok (NEG, SImode, operands)"
9489   "neg{l}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "SI")])
9492
9493 ;; Combine is quite creative about this pattern.
9494 (define_insn "*negsi2_1_zext"
9495   [(set (match_operand:DI 0 "register_operand" "=r")
9496         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9497                                         (const_int 32)))
9498                      (const_int 32)))
9499    (clobber (reg:CC FLAGS_REG))]
9500   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9501   "neg{l}\t%k0"
9502   [(set_attr "type" "negnot")
9503    (set_attr "mode" "SI")])
9504
9505 ;; The problem with neg is that it does not perform (compare x 0),
9506 ;; it really performs (compare 0 x), which leaves us with the zero
9507 ;; flag being the only useful item.
9508
9509 (define_insn "*negsi2_cmpz"
9510   [(set (reg:CCZ FLAGS_REG)
9511         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9512                      (const_int 0)))
9513    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9514         (neg:SI (match_dup 1)))]
9515   "ix86_unary_operator_ok (NEG, SImode, operands)"
9516   "neg{l}\t%0"
9517   [(set_attr "type" "negnot")
9518    (set_attr "mode" "SI")])
9519
9520 (define_insn "*negsi2_cmpz_zext"
9521   [(set (reg:CCZ FLAGS_REG)
9522         (compare:CCZ (lshiftrt:DI
9523                        (neg:DI (ashift:DI
9524                                  (match_operand:DI 1 "register_operand" "0")
9525                                  (const_int 32)))
9526                        (const_int 32))
9527                      (const_int 0)))
9528    (set (match_operand:DI 0 "register_operand" "=r")
9529         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9530                                         (const_int 32)))
9531                      (const_int 32)))]
9532   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9533   "neg{l}\t%k0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "SI")])
9536
9537 (define_expand "neghi2"
9538   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9539                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9540               (clobber (reg:CC FLAGS_REG))])]
9541   "TARGET_HIMODE_MATH"
9542   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9543
9544 (define_insn "*neghi2_1"
9545   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9546         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9547    (clobber (reg:CC FLAGS_REG))]
9548   "ix86_unary_operator_ok (NEG, HImode, operands)"
9549   "neg{w}\t%0"
9550   [(set_attr "type" "negnot")
9551    (set_attr "mode" "HI")])
9552
9553 (define_insn "*neghi2_cmpz"
9554   [(set (reg:CCZ FLAGS_REG)
9555         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9556                      (const_int 0)))
9557    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9558         (neg:HI (match_dup 1)))]
9559   "ix86_unary_operator_ok (NEG, HImode, operands)"
9560   "neg{w}\t%0"
9561   [(set_attr "type" "negnot")
9562    (set_attr "mode" "HI")])
9563
9564 (define_expand "negqi2"
9565   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9566                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9567               (clobber (reg:CC FLAGS_REG))])]
9568   "TARGET_QIMODE_MATH"
9569   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9570
9571 (define_insn "*negqi2_1"
9572   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9573         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "ix86_unary_operator_ok (NEG, QImode, operands)"
9576   "neg{b}\t%0"
9577   [(set_attr "type" "negnot")
9578    (set_attr "mode" "QI")])
9579
9580 (define_insn "*negqi2_cmpz"
9581   [(set (reg:CCZ FLAGS_REG)
9582         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9583                      (const_int 0)))
9584    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9585         (neg:QI (match_dup 1)))]
9586   "ix86_unary_operator_ok (NEG, QImode, operands)"
9587   "neg{b}\t%0"
9588   [(set_attr "type" "negnot")
9589    (set_attr "mode" "QI")])
9590
9591 ;; Changing of sign for FP values is doable using integer unit too.
9592
9593 (define_expand "negsf2"
9594   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9595                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9596               (clobber (reg:CC FLAGS_REG))])]
9597   "TARGET_80387"
9598   "if (TARGET_SSE)
9599      {
9600        /* In case operand is in memory,  we will not use SSE.  */
9601        if (memory_operand (operands[0], VOIDmode)
9602            && rtx_equal_p (operands[0], operands[1]))
9603          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9604        else
9605         {
9606           /* Using SSE is tricky, since we need bitwise negation of -0
9607              in register.  */
9608           rtx reg = gen_reg_rtx (SFmode);
9609           rtx dest = operands[0];
9610           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9611
9612           operands[1] = force_reg (SFmode, operands[1]);
9613           operands[0] = force_reg (SFmode, operands[0]);
9614           reg = force_reg (V4SFmode,
9615                            gen_rtx_CONST_VECTOR (V4SFmode,
9616                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9617                                         CONST0_RTX (SFmode),
9618                                         CONST0_RTX (SFmode))));
9619           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9620           if (dest != operands[0])
9621             emit_move_insn (dest, operands[0]);
9622         }
9623        DONE;
9624      }
9625    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9626
9627 (define_insn "negsf2_memory"
9628   [(set (match_operand:SF 0 "memory_operand" "=m")
9629         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9632   "#")
9633
9634 (define_insn "negsf2_ifs"
9635   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9636         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9637    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "TARGET_SSE
9640    && (reload_in_progress || reload_completed
9641        || (register_operand (operands[0], VOIDmode)
9642            && register_operand (operands[1], VOIDmode)))"
9643   "#")
9644
9645 (define_split
9646   [(set (match_operand:SF 0 "memory_operand" "")
9647         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9648    (use (match_operand:SF 2 "" ""))
9649    (clobber (reg:CC FLAGS_REG))]
9650   ""
9651   [(parallel [(set (match_dup 0)
9652                    (neg:SF (match_dup 1)))
9653               (clobber (reg:CC FLAGS_REG))])])
9654
9655 (define_split
9656   [(set (match_operand:SF 0 "register_operand" "")
9657         (neg:SF (match_operand:SF 1 "register_operand" "")))
9658    (use (match_operand:V4SF 2 "" ""))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "reload_completed && !SSE_REG_P (operands[0])"
9661   [(parallel [(set (match_dup 0)
9662                    (neg:SF (match_dup 1)))
9663               (clobber (reg:CC FLAGS_REG))])])
9664
9665 (define_split
9666   [(set (match_operand:SF 0 "register_operand" "")
9667         (neg:SF (match_operand:SF 1 "register_operand" "")))
9668    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9669    (clobber (reg:CC FLAGS_REG))]
9670   "reload_completed && SSE_REG_P (operands[0])"
9671   [(set (match_dup 0)
9672         (xor:V4SF (match_dup 1)
9673                   (match_dup 2)))]
9674 {
9675   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9676   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9677   if (operands_match_p (operands[0], operands[2]))
9678     {
9679       rtx tmp;
9680       tmp = operands[1];
9681       operands[1] = operands[2];
9682       operands[2] = tmp;
9683     }
9684 })
9685
9686
9687 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9688 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9689 ;; to itself.
9690 (define_insn "*negsf2_if"
9691   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9692         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "TARGET_80387 && !TARGET_SSE
9695    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9696   "#")
9697
9698 (define_split
9699   [(set (match_operand:SF 0 "fp_register_operand" "")
9700         (neg:SF (match_operand:SF 1 "register_operand" "")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "TARGET_80387 && reload_completed"
9703   [(set (match_dup 0)
9704         (neg:SF (match_dup 1)))]
9705   "")
9706
9707 (define_split
9708   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9709         (neg:SF (match_operand:SF 1 "register_operand" "")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_80387 && reload_completed"
9712   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9713               (clobber (reg:CC FLAGS_REG))])]
9714   "operands[1] = gen_int_mode (0x80000000, SImode);
9715    operands[0] = gen_lowpart (SImode, operands[0]);")
9716
9717 (define_split
9718   [(set (match_operand 0 "memory_operand" "")
9719         (neg (match_operand 1 "memory_operand" "")))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9722   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9723               (clobber (reg:CC FLAGS_REG))])]
9724 {
9725   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9726
9727   if (GET_MODE (operands[1]) == XFmode)
9728     size = 10;
9729   operands[0] = adjust_address (operands[0], QImode, size - 1);
9730   operands[1] = gen_int_mode (0x80, QImode);
9731 })
9732
9733 (define_expand "negdf2"
9734   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9735                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9736               (clobber (reg:CC FLAGS_REG))])]
9737   "TARGET_80387"
9738   "if (TARGET_SSE2)
9739      {
9740        /* In case operand is in memory,  we will not use SSE.  */
9741        if (memory_operand (operands[0], VOIDmode)
9742            && rtx_equal_p (operands[0], operands[1]))
9743          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9744        else
9745         {
9746           /* Using SSE is tricky, since we need bitwise negation of -0
9747              in register.  */
9748           rtx reg;
9749 #if HOST_BITS_PER_WIDE_INT >= 64
9750           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9751 #else
9752           rtx imm = immed_double_const (0, 0x80000000, DImode);
9753 #endif
9754           rtx dest = operands[0];
9755
9756           operands[1] = force_reg (DFmode, operands[1]);
9757           operands[0] = force_reg (DFmode, operands[0]);
9758           imm = gen_lowpart (DFmode, imm);
9759           reg = force_reg (V2DFmode,
9760                            gen_rtx_CONST_VECTOR (V2DFmode,
9761                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9762           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9763           if (dest != operands[0])
9764             emit_move_insn (dest, operands[0]);
9765         }
9766        DONE;
9767      }
9768    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9769
9770 (define_insn "negdf2_memory"
9771   [(set (match_operand:DF 0 "memory_operand" "=m")
9772         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9775   "#")
9776
9777 (define_insn "negdf2_ifs"
9778   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9779         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9780    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "!TARGET_64BIT && TARGET_SSE2
9783    && (reload_in_progress || reload_completed
9784        || (register_operand (operands[0], VOIDmode)
9785            && register_operand (operands[1], VOIDmode)))"
9786   "#")
9787
9788 (define_insn "*negdf2_ifs_rex64"
9789   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9790         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9791    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "TARGET_64BIT && TARGET_SSE2
9794    && (reload_in_progress || reload_completed
9795        || (register_operand (operands[0], VOIDmode)
9796            && register_operand (operands[1], VOIDmode)))"
9797   "#")
9798
9799 (define_split
9800   [(set (match_operand:DF 0 "memory_operand" "")
9801         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9802    (use (match_operand:V2DF 2 "" ""))
9803    (clobber (reg:CC FLAGS_REG))]
9804   ""
9805   [(parallel [(set (match_dup 0)
9806                    (neg:DF (match_dup 1)))
9807               (clobber (reg:CC FLAGS_REG))])])
9808
9809 (define_split
9810   [(set (match_operand:DF 0 "register_operand" "")
9811         (neg:DF (match_operand:DF 1 "register_operand" "")))
9812    (use (match_operand:V2DF 2 "" ""))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "reload_completed && !SSE_REG_P (operands[0])
9815    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9816   [(parallel [(set (match_dup 0)
9817                    (neg:DF (match_dup 1)))
9818               (clobber (reg:CC FLAGS_REG))])])
9819
9820 (define_split
9821   [(set (match_operand:DF 0 "register_operand" "")
9822         (neg:DF (match_operand:DF 1 "register_operand" "")))
9823    (use (match_operand:V2DF 2 "" ""))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9826   [(parallel [(set (match_dup 0)
9827                    (xor:DI (match_dup 1) (match_dup 2)))
9828               (clobber (reg:CC FLAGS_REG))])]
9829    "operands[0] = gen_lowpart (DImode, operands[0]);
9830     operands[1] = gen_lowpart (DImode, operands[1]);
9831     operands[2] = gen_lowpart (DImode, operands[2]);")
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 "nonimmediate_operand" ""))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "reload_completed && SSE_REG_P (operands[0])"
9839   [(set (match_dup 0)
9840         (xor:V2DF (match_dup 1)
9841                   (match_dup 2)))]
9842 {
9843   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9844   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9845   /* Avoid possible reformatting on the operands.  */
9846   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9847     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9848   if (operands_match_p (operands[0], operands[2]))
9849     {
9850       rtx tmp;
9851       tmp = operands[1];
9852       operands[1] = operands[2];
9853       operands[2] = tmp;
9854     }
9855 })
9856
9857 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9858 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9859 ;; to itself.
9860 (define_insn "*negdf2_if"
9861   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9862         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "!TARGET_64BIT && TARGET_80387
9865    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9866   "#")
9867
9868 ;; FIXME: We should to allow integer registers here.  Problem is that
9869 ;; we need another scratch register to get constant from.
9870 ;; Forcing constant to mem if no register available in peep2 should be
9871 ;; safe even for PIC mode, because of RIP relative addressing.
9872 (define_insn "*negdf2_if_rex64"
9873   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9874         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9875    (clobber (reg:CC FLAGS_REG))]
9876   "TARGET_64BIT && TARGET_80387
9877    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9878   "#")
9879
9880 (define_split
9881   [(set (match_operand:DF 0 "fp_register_operand" "")
9882         (neg:DF (match_operand:DF 1 "register_operand" "")))
9883    (clobber (reg:CC FLAGS_REG))]
9884   "TARGET_80387 && reload_completed"
9885   [(set (match_dup 0)
9886         (neg:DF (match_dup 1)))]
9887   "")
9888
9889 (define_split
9890   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9891         (neg:DF (match_operand:DF 1 "register_operand" "")))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9894   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9895               (clobber (reg:CC FLAGS_REG))])]
9896   "operands[4] = gen_int_mode (0x80000000, SImode);
9897    split_di (operands+0, 1, operands+2, operands+3);")
9898
9899 (define_expand "negxf2"
9900   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9901                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9902               (clobber (reg:CC FLAGS_REG))])]
9903   "TARGET_80387"
9904   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9905
9906 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9907 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9908 ;; to itself.
9909 (define_insn "*negxf2_if"
9910   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9911         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9912    (clobber (reg:CC FLAGS_REG))]
9913   "TARGET_80387
9914    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9915   "#")
9916
9917 (define_split
9918   [(set (match_operand:XF 0 "fp_register_operand" "")
9919         (neg:XF (match_operand:XF 1 "register_operand" "")))
9920    (clobber (reg:CC FLAGS_REG))]
9921   "TARGET_80387 && reload_completed"
9922   [(set (match_dup 0)
9923         (neg:XF (match_dup 1)))]
9924   "")
9925
9926 (define_split
9927   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9928         (neg:XF (match_operand:XF 1 "register_operand" "")))
9929    (clobber (reg:CC FLAGS_REG))]
9930   "TARGET_80387 && reload_completed"
9931   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9932               (clobber (reg:CC FLAGS_REG))])]
9933   "operands[1] = GEN_INT (0x8000);
9934    operands[0] = gen_rtx_REG (SImode,
9935                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9936
9937 ;; Conditionalize these after reload. If they matches before reload, we 
9938 ;; lose the clobber and ability to use integer instructions.
9939
9940 (define_insn "*negsf2_1"
9941   [(set (match_operand:SF 0 "register_operand" "=f")
9942         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9943   "TARGET_80387 && reload_completed"
9944   "fchs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "SF")])
9947
9948 (define_insn "*negdf2_1"
9949   [(set (match_operand:DF 0 "register_operand" "=f")
9950         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9951   "TARGET_80387 && reload_completed"
9952   "fchs"
9953   [(set_attr "type" "fsgn")
9954    (set_attr "mode" "DF")])
9955
9956 (define_insn "*negextendsfdf2"
9957   [(set (match_operand:DF 0 "register_operand" "=f")
9958         (neg:DF (float_extend:DF
9959                   (match_operand:SF 1 "register_operand" "0"))))]
9960   "TARGET_80387"
9961   "fchs"
9962   [(set_attr "type" "fsgn")
9963    (set_attr "mode" "DF")])
9964
9965 (define_insn "*negxf2_1"
9966   [(set (match_operand:XF 0 "register_operand" "=f")
9967         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9968   "TARGET_80387 && reload_completed"
9969   "fchs"
9970   [(set_attr "type" "fsgn")
9971    (set_attr "mode" "XF")])
9972
9973 (define_insn "*negextenddfxf2"
9974   [(set (match_operand:XF 0 "register_operand" "=f")
9975         (neg:XF (float_extend:XF
9976                   (match_operand:DF 1 "register_operand" "0"))))]
9977   "TARGET_80387"
9978   "fchs"
9979   [(set_attr "type" "fsgn")
9980    (set_attr "mode" "XF")])
9981
9982 (define_insn "*negextendsfxf2"
9983   [(set (match_operand:XF 0 "register_operand" "=f")
9984         (neg:XF (float_extend:XF
9985                   (match_operand:SF 1 "register_operand" "0"))))]
9986   "TARGET_80387"
9987   "fchs"
9988   [(set_attr "type" "fsgn")
9989    (set_attr "mode" "XF")])
9990 \f
9991 ;; Absolute value instructions
9992
9993 (define_expand "abssf2"
9994   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9995                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9996               (clobber (reg:CC FLAGS_REG))])]
9997   "TARGET_80387"
9998   "if (TARGET_SSE)
9999      {
10000        /* In case operand is in memory,  we will not use SSE.  */
10001        if (memory_operand (operands[0], VOIDmode)
10002            && rtx_equal_p (operands[0], operands[1]))
10003          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10004        else
10005         {
10006           /* Using SSE is tricky, since we need bitwise negation of -0
10007              in register.  */
10008           rtx reg = gen_reg_rtx (V4SFmode);
10009           rtx dest = operands[0];
10010           rtx imm;
10011
10012           operands[1] = force_reg (SFmode, operands[1]);
10013           operands[0] = force_reg (SFmode, operands[0]);
10014           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10015           reg = force_reg (V4SFmode,
10016                            gen_rtx_CONST_VECTOR (V4SFmode,
10017                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10018                                       CONST0_RTX (SFmode),
10019                                       CONST0_RTX (SFmode))));
10020           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10021           if (dest != operands[0])
10022             emit_move_insn (dest, operands[0]);
10023         }
10024        DONE;
10025      }
10026    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10027
10028 (define_insn "abssf2_memory"
10029   [(set (match_operand:SF 0 "memory_operand" "=m")
10030         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10033   "#")
10034
10035 (define_insn "abssf2_ifs"
10036   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10037         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10038    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10039    (clobber (reg:CC FLAGS_REG))]
10040   "TARGET_SSE
10041    && (reload_in_progress || reload_completed
10042        || (register_operand (operands[0], VOIDmode)
10043             && register_operand (operands[1], VOIDmode)))"
10044   "#")
10045
10046 (define_split
10047   [(set (match_operand:SF 0 "memory_operand" "")
10048         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10049    (use (match_operand:V4SF 2 "" ""))
10050    (clobber (reg:CC FLAGS_REG))]
10051   ""
10052   [(parallel [(set (match_dup 0)
10053                    (abs:SF (match_dup 1)))
10054               (clobber (reg:CC FLAGS_REG))])])
10055
10056 (define_split
10057   [(set (match_operand:SF 0 "register_operand" "")
10058         (abs:SF (match_operand:SF 1 "register_operand" "")))
10059    (use (match_operand:V4SF 2 "" ""))
10060    (clobber (reg:CC FLAGS_REG))]
10061   "reload_completed && !SSE_REG_P (operands[0])"
10062   [(parallel [(set (match_dup 0)
10063                    (abs:SF (match_dup 1)))
10064               (clobber (reg:CC FLAGS_REG))])])
10065
10066 (define_split
10067   [(set (match_operand:SF 0 "register_operand" "")
10068         (abs:SF (match_operand:SF 1 "register_operand" "")))
10069    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "reload_completed && SSE_REG_P (operands[0])"
10072   [(set (match_dup 0)
10073         (and:V4SF (match_dup 1)
10074                   (match_dup 2)))]
10075 {
10076   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10077   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10078   if (operands_match_p (operands[0], operands[2]))
10079     {
10080       rtx tmp;
10081       tmp = operands[1];
10082       operands[1] = operands[2];
10083       operands[2] = tmp;
10084     }
10085 })
10086
10087 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10088 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10089 ;; to itself.
10090 (define_insn "*abssf2_if"
10091   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10092         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10093    (clobber (reg:CC FLAGS_REG))]
10094   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10095   "#")
10096
10097 (define_split
10098   [(set (match_operand:SF 0 "fp_register_operand" "")
10099         (abs:SF (match_operand:SF 1 "register_operand" "")))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "TARGET_80387 && reload_completed"
10102   [(set (match_dup 0)
10103         (abs:SF (match_dup 1)))]
10104   "")
10105
10106 (define_split
10107   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10108         (abs:SF (match_operand:SF 1 "register_operand" "")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "TARGET_80387 && reload_completed"
10111   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10112               (clobber (reg:CC FLAGS_REG))])]
10113   "operands[1] = gen_int_mode (~0x80000000, SImode);
10114    operands[0] = gen_lowpart (SImode, operands[0]);")
10115
10116 (define_split
10117   [(set (match_operand 0 "memory_operand" "")
10118         (abs (match_operand 1 "memory_operand" "")))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10121   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10122               (clobber (reg:CC FLAGS_REG))])]
10123 {
10124   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10125
10126   if (GET_MODE (operands[1]) == XFmode)
10127     size = 10;
10128   operands[0] = adjust_address (operands[0], QImode, size - 1);
10129   operands[1] = gen_int_mode (~0x80, QImode);
10130 })
10131
10132 (define_expand "absdf2"
10133   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10134                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10135               (clobber (reg:CC FLAGS_REG))])]
10136   "TARGET_80387"
10137   "if (TARGET_SSE2)
10138      {
10139        /* In case operand is in memory,  we will not use SSE.  */
10140        if (memory_operand (operands[0], VOIDmode)
10141            && rtx_equal_p (operands[0], operands[1]))
10142          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10143        else
10144         {
10145           /* Using SSE is tricky, since we need bitwise negation of -0
10146              in register.  */
10147           rtx reg = gen_reg_rtx (V2DFmode);
10148 #if HOST_BITS_PER_WIDE_INT >= 64
10149           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10150 #else
10151           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10152 #endif
10153           rtx dest = operands[0];
10154
10155           operands[1] = force_reg (DFmode, operands[1]);
10156           operands[0] = force_reg (DFmode, operands[0]);
10157
10158           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10159           imm = gen_lowpart (DFmode, imm);
10160           reg = force_reg (V2DFmode,
10161                            gen_rtx_CONST_VECTOR (V2DFmode,
10162                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10163           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10164           if (dest != operands[0])
10165             emit_move_insn (dest, operands[0]);
10166         }
10167        DONE;
10168      }
10169    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10170
10171 (define_insn "absdf2_memory"
10172   [(set (match_operand:DF 0 "memory_operand" "=m")
10173         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10174    (clobber (reg:CC FLAGS_REG))]
10175   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10176   "#")
10177
10178 (define_insn "absdf2_ifs"
10179   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10180         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10181    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "!TARGET_64BIT && TARGET_SSE2
10184    && (reload_in_progress || reload_completed
10185        || (register_operand (operands[0], VOIDmode)
10186            && register_operand (operands[1], VOIDmode)))"
10187   "#")
10188
10189 (define_insn "*absdf2_ifs_rex64"
10190   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10191         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10192    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10193    (clobber (reg:CC FLAGS_REG))]
10194   "TARGET_64BIT && TARGET_SSE2
10195    && (reload_in_progress || reload_completed
10196        || (register_operand (operands[0], VOIDmode)
10197            && register_operand (operands[1], VOIDmode)))"
10198   "#")
10199
10200 (define_split
10201   [(set (match_operand:DF 0 "memory_operand" "")
10202         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10203    (use (match_operand:V2DF 2 "" ""))
10204    (clobber (reg:CC FLAGS_REG))]
10205   ""
10206   [(parallel [(set (match_dup 0)
10207                    (abs:DF (match_dup 1)))
10208               (clobber (reg:CC FLAGS_REG))])])
10209
10210 (define_split
10211   [(set (match_operand:DF 0 "register_operand" "")
10212         (abs:DF (match_operand:DF 1 "register_operand" "")))
10213    (use (match_operand:V2DF 2 "" ""))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "reload_completed && !SSE_REG_P (operands[0])"
10216   [(parallel [(set (match_dup 0)
10217                    (abs:DF (match_dup 1)))
10218               (clobber (reg:CC FLAGS_REG))])])
10219
10220 (define_split
10221   [(set (match_operand:DF 0 "register_operand" "")
10222         (abs:DF (match_operand:DF 1 "register_operand" "")))
10223    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "reload_completed && SSE_REG_P (operands[0])"
10226   [(set (match_dup 0)
10227         (and:V2DF (match_dup 1)
10228                   (match_dup 2)))]
10229 {
10230   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10231   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10232   /* Avoid possible reformatting on the operands.  */
10233   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10234     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10235   if (operands_match_p (operands[0], operands[2]))
10236     {
10237       rtx tmp;
10238       tmp = operands[1];
10239       operands[1] = operands[2];
10240       operands[2] = tmp;
10241     }
10242 })
10243
10244
10245 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10246 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10247 ;; to itself.
10248 (define_insn "*absdf2_if"
10249   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10250         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "!TARGET_64BIT && TARGET_80387
10253    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10254   "#")
10255
10256 ;; FIXME: We should to allow integer registers here.  Problem is that
10257 ;; we need another scratch register to get constant from.
10258 ;; Forcing constant to mem if no register available in peep2 should be
10259 ;; safe even for PIC mode, because of RIP relative addressing.
10260 (define_insn "*absdf2_if_rex64"
10261   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10262         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT && TARGET_80387
10265    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10266   "#")
10267
10268 (define_split
10269   [(set (match_operand:DF 0 "fp_register_operand" "")
10270         (abs:DF (match_operand:DF 1 "register_operand" "")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "TARGET_80387 && reload_completed"
10273   [(set (match_dup 0)
10274         (abs:DF (match_dup 1)))]
10275   "")
10276
10277 (define_split
10278   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10279         (abs:DF (match_operand:DF 1 "register_operand" "")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10282   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10283               (clobber (reg:CC FLAGS_REG))])]
10284   "operands[4] = gen_int_mode (~0x80000000, SImode);
10285    split_di (operands+0, 1, operands+2, operands+3);")
10286
10287 (define_expand "absxf2"
10288   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10289                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10290               (clobber (reg:CC FLAGS_REG))])]
10291   "TARGET_80387"
10292   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10293
10294 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10295 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10296 ;; to itself.
10297 (define_insn "*absxf2_if"
10298   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10299         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "TARGET_80387
10302    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10303   "#")
10304
10305 (define_split
10306   [(set (match_operand:XF 0 "fp_register_operand" "")
10307         (abs:XF (match_operand:XF 1 "register_operand" "")))
10308    (clobber (reg:CC FLAGS_REG))]
10309   "TARGET_80387 && reload_completed"
10310   [(set (match_dup 0)
10311         (abs:XF (match_dup 1)))]
10312   "")
10313
10314 (define_split
10315   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10316         (abs:XF (match_operand:XF 1 "register_operand" "")))
10317    (clobber (reg:CC FLAGS_REG))]
10318   "TARGET_80387 && reload_completed"
10319   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10320               (clobber (reg:CC FLAGS_REG))])]
10321   "operands[1] = GEN_INT (~0x8000);
10322    operands[0] = gen_rtx_REG (SImode,
10323                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10324
10325 (define_insn "*abssf2_1"
10326   [(set (match_operand:SF 0 "register_operand" "=f")
10327         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10328   "TARGET_80387 && reload_completed"
10329   "fabs"
10330   [(set_attr "type" "fsgn")
10331    (set_attr "mode" "SF")])
10332
10333 (define_insn "*absdf2_1"
10334   [(set (match_operand:DF 0 "register_operand" "=f")
10335         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10336   "TARGET_80387 && reload_completed"
10337   "fabs"
10338   [(set_attr "type" "fsgn")
10339    (set_attr "mode" "DF")])
10340
10341 (define_insn "*absextendsfdf2"
10342   [(set (match_operand:DF 0 "register_operand" "=f")
10343         (abs:DF (float_extend:DF
10344                   (match_operand:SF 1 "register_operand" "0"))))]
10345   "TARGET_80387"
10346   "fabs"
10347   [(set_attr "type" "fsgn")
10348    (set_attr "mode" "DF")])
10349
10350 (define_insn "*absxf2_1"
10351   [(set (match_operand:XF 0 "register_operand" "=f")
10352         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10353   "TARGET_80387 && reload_completed"
10354   "fabs"
10355   [(set_attr "type" "fsgn")
10356    (set_attr "mode" "DF")])
10357
10358 (define_insn "*absextenddfxf2"
10359   [(set (match_operand:XF 0 "register_operand" "=f")
10360         (abs:XF (float_extend:XF
10361           (match_operand:DF 1 "register_operand" "0"))))]
10362   "TARGET_80387"
10363   "fabs"
10364   [(set_attr "type" "fsgn")
10365    (set_attr "mode" "XF")])
10366
10367 (define_insn "*absextendsfxf2"
10368   [(set (match_operand:XF 0 "register_operand" "=f")
10369         (abs:XF (float_extend:XF
10370           (match_operand:SF 1 "register_operand" "0"))))]
10371   "TARGET_80387"
10372   "fabs"
10373   [(set_attr "type" "fsgn")
10374    (set_attr "mode" "XF")])
10375 \f
10376 ;; One complement instructions
10377
10378 (define_expand "one_cmpldi2"
10379   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10380         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10381   "TARGET_64BIT"
10382   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10383
10384 (define_insn "*one_cmpldi2_1_rex64"
10385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10386         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10387   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10388   "not{q}\t%0"
10389   [(set_attr "type" "negnot")
10390    (set_attr "mode" "DI")])
10391
10392 (define_insn "*one_cmpldi2_2_rex64"
10393   [(set (reg 17)
10394         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10395                  (const_int 0)))
10396    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397         (not:DI (match_dup 1)))]
10398   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10399    && ix86_unary_operator_ok (NOT, DImode, operands)"
10400   "#"
10401   [(set_attr "type" "alu1")
10402    (set_attr "mode" "DI")])
10403
10404 (define_split
10405   [(set (reg 17)
10406         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10407                  (const_int 0)))
10408    (set (match_operand:DI 0 "nonimmediate_operand" "")
10409         (not:DI (match_dup 1)))]
10410   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10411   [(parallel [(set (reg:CCNO FLAGS_REG)
10412                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10413                                  (const_int 0)))
10414               (set (match_dup 0)
10415                    (xor:DI (match_dup 1) (const_int -1)))])]
10416   "")
10417
10418 (define_expand "one_cmplsi2"
10419   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10420         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10421   ""
10422   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10423
10424 (define_insn "*one_cmplsi2_1"
10425   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10426         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10427   "ix86_unary_operator_ok (NOT, SImode, operands)"
10428   "not{l}\t%0"
10429   [(set_attr "type" "negnot")
10430    (set_attr "mode" "SI")])
10431
10432 ;; ??? Currently never generated - xor is used instead.
10433 (define_insn "*one_cmplsi2_1_zext"
10434   [(set (match_operand:DI 0 "register_operand" "=r")
10435         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10437   "not{l}\t%k0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "SI")])
10440
10441 (define_insn "*one_cmplsi2_2"
10442   [(set (reg 17)
10443         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10444                  (const_int 0)))
10445    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10446         (not:SI (match_dup 1)))]
10447   "ix86_match_ccmode (insn, CCNOmode)
10448    && ix86_unary_operator_ok (NOT, SImode, operands)"
10449   "#"
10450   [(set_attr "type" "alu1")
10451    (set_attr "mode" "SI")])
10452
10453 (define_split
10454   [(set (reg 17)
10455         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10456                  (const_int 0)))
10457    (set (match_operand:SI 0 "nonimmediate_operand" "")
10458         (not:SI (match_dup 1)))]
10459   "ix86_match_ccmode (insn, CCNOmode)"
10460   [(parallel [(set (reg:CCNO FLAGS_REG)
10461                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10462                                  (const_int 0)))
10463               (set (match_dup 0)
10464                    (xor:SI (match_dup 1) (const_int -1)))])]
10465   "")
10466
10467 ;; ??? Currently never generated - xor is used instead.
10468 (define_insn "*one_cmplsi2_2_zext"
10469   [(set (reg 17)
10470         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10471                  (const_int 0)))
10472    (set (match_operand:DI 0 "register_operand" "=r")
10473         (zero_extend:DI (not:SI (match_dup 1))))]
10474   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10475    && ix86_unary_operator_ok (NOT, SImode, operands)"
10476   "#"
10477   [(set_attr "type" "alu1")
10478    (set_attr "mode" "SI")])
10479
10480 (define_split
10481   [(set (reg 17)
10482         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10483                  (const_int 0)))
10484    (set (match_operand:DI 0 "register_operand" "")
10485         (zero_extend:DI (not:SI (match_dup 1))))]
10486   "ix86_match_ccmode (insn, CCNOmode)"
10487   [(parallel [(set (reg:CCNO FLAGS_REG)
10488                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10489                                  (const_int 0)))
10490               (set (match_dup 0)
10491                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10492   "")
10493
10494 (define_expand "one_cmplhi2"
10495   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10496         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10497   "TARGET_HIMODE_MATH"
10498   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10499
10500 (define_insn "*one_cmplhi2_1"
10501   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10502         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10503   "ix86_unary_operator_ok (NOT, HImode, operands)"
10504   "not{w}\t%0"
10505   [(set_attr "type" "negnot")
10506    (set_attr "mode" "HI")])
10507
10508 (define_insn "*one_cmplhi2_2"
10509   [(set (reg 17)
10510         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10511                  (const_int 0)))
10512    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10513         (not:HI (match_dup 1)))]
10514   "ix86_match_ccmode (insn, CCNOmode)
10515    && ix86_unary_operator_ok (NEG, HImode, operands)"
10516   "#"
10517   [(set_attr "type" "alu1")
10518    (set_attr "mode" "HI")])
10519
10520 (define_split
10521   [(set (reg 17)
10522         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10523                  (const_int 0)))
10524    (set (match_operand:HI 0 "nonimmediate_operand" "")
10525         (not:HI (match_dup 1)))]
10526   "ix86_match_ccmode (insn, CCNOmode)"
10527   [(parallel [(set (reg:CCNO FLAGS_REG)
10528                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10529                                  (const_int 0)))
10530               (set (match_dup 0)
10531                    (xor:HI (match_dup 1) (const_int -1)))])]
10532   "")
10533
10534 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10535 (define_expand "one_cmplqi2"
10536   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10537         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10538   "TARGET_QIMODE_MATH"
10539   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10540
10541 (define_insn "*one_cmplqi2_1"
10542   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10543         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10544   "ix86_unary_operator_ok (NOT, QImode, operands)"
10545   "@
10546    not{b}\t%0
10547    not{l}\t%k0"
10548   [(set_attr "type" "negnot")
10549    (set_attr "mode" "QI,SI")])
10550
10551 (define_insn "*one_cmplqi2_2"
10552   [(set (reg 17)
10553         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10554                  (const_int 0)))
10555    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10556         (not:QI (match_dup 1)))]
10557   "ix86_match_ccmode (insn, CCNOmode)
10558    && ix86_unary_operator_ok (NOT, QImode, operands)"
10559   "#"
10560   [(set_attr "type" "alu1")
10561    (set_attr "mode" "QI")])
10562
10563 (define_split
10564   [(set (reg 17)
10565         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10566                  (const_int 0)))
10567    (set (match_operand:QI 0 "nonimmediate_operand" "")
10568         (not:QI (match_dup 1)))]
10569   "ix86_match_ccmode (insn, CCNOmode)"
10570   [(parallel [(set (reg:CCNO FLAGS_REG)
10571                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10572                                  (const_int 0)))
10573               (set (match_dup 0)
10574                    (xor:QI (match_dup 1) (const_int -1)))])]
10575   "")
10576 \f
10577 ;; Arithmetic shift instructions
10578
10579 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10580 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10581 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10582 ;; from the assembler input.
10583 ;;
10584 ;; This instruction shifts the target reg/mem as usual, but instead of
10585 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10586 ;; is a left shift double, bits are taken from the high order bits of
10587 ;; reg, else if the insn is a shift right double, bits are taken from the
10588 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10589 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10590 ;;
10591 ;; Since sh[lr]d does not change the `reg' operand, that is done
10592 ;; separately, making all shifts emit pairs of shift double and normal
10593 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10594 ;; support a 63 bit shift, each shift where the count is in a reg expands
10595 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10596 ;;
10597 ;; If the shift count is a constant, we need never emit more than one
10598 ;; shift pair, instead using moves and sign extension for counts greater
10599 ;; than 31.
10600
10601 (define_expand "ashldi3"
10602   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10603                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10604                               (match_operand:QI 2 "nonmemory_operand" "")))
10605               (clobber (reg:CC FLAGS_REG))])]
10606   ""
10607 {
10608   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10609     {
10610       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10611       DONE;
10612     }
10613   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10614   DONE;
10615 })
10616
10617 (define_insn "*ashldi3_1_rex64"
10618   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10619         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10620                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10621    (clobber (reg:CC FLAGS_REG))]
10622   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10623 {
10624   switch (get_attr_type (insn))
10625     {
10626     case TYPE_ALU:
10627       if (operands[2] != const1_rtx)
10628         abort ();
10629       if (!rtx_equal_p (operands[0], operands[1]))
10630         abort ();
10631       return "add{q}\t{%0, %0|%0, %0}";
10632
10633     case TYPE_LEA:
10634       if (GET_CODE (operands[2]) != CONST_INT
10635           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10636         abort ();
10637       operands[1] = gen_rtx_MULT (DImode, operands[1],
10638                                   GEN_INT (1 << INTVAL (operands[2])));
10639       return "lea{q}\t{%a1, %0|%0, %a1}";
10640
10641     default:
10642       if (REG_P (operands[2]))
10643         return "sal{q}\t{%b2, %0|%0, %b2}";
10644       else if (operands[2] == const1_rtx
10645                && (TARGET_SHIFT1 || optimize_size))
10646         return "sal{q}\t%0";
10647       else
10648         return "sal{q}\t{%2, %0|%0, %2}";
10649     }
10650 }
10651   [(set (attr "type")
10652      (cond [(eq_attr "alternative" "1")
10653               (const_string "lea")
10654             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10655                           (const_int 0))
10656                       (match_operand 0 "register_operand" ""))
10657                  (match_operand 2 "const1_operand" ""))
10658               (const_string "alu")
10659            ]
10660            (const_string "ishift")))
10661    (set_attr "mode" "DI")])
10662
10663 ;; Convert lea to the lea pattern to avoid flags dependency.
10664 (define_split
10665   [(set (match_operand:DI 0 "register_operand" "")
10666         (ashift:DI (match_operand:DI 1 "register_operand" "")
10667                    (match_operand:QI 2 "immediate_operand" "")))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "TARGET_64BIT && reload_completed
10670    && true_regnum (operands[0]) != true_regnum (operands[1])"
10671   [(set (match_dup 0)
10672         (mult:DI (match_dup 1)
10673                  (match_dup 2)))]
10674   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10675
10676 ;; This pattern can't accept a variable shift count, since shifts by
10677 ;; zero don't affect the flags.  We assume that shifts by constant
10678 ;; zero are optimized away.
10679 (define_insn "*ashldi3_cmp_rex64"
10680   [(set (reg 17)
10681         (compare
10682           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10683                      (match_operand:QI 2 "immediate_operand" "e"))
10684           (const_int 0)))
10685    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10686         (ashift:DI (match_dup 1) (match_dup 2)))]
10687   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10689 {
10690   switch (get_attr_type (insn))
10691     {
10692     case TYPE_ALU:
10693       if (operands[2] != const1_rtx)
10694         abort ();
10695       return "add{q}\t{%0, %0|%0, %0}";
10696
10697     default:
10698       if (REG_P (operands[2]))
10699         return "sal{q}\t{%b2, %0|%0, %b2}";
10700       else if (operands[2] == const1_rtx
10701                && (TARGET_SHIFT1 || optimize_size))
10702         return "sal{q}\t%0";
10703       else
10704         return "sal{q}\t{%2, %0|%0, %2}";
10705     }
10706 }
10707   [(set (attr "type")
10708      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709                           (const_int 0))
10710                       (match_operand 0 "register_operand" ""))
10711                  (match_operand 2 "const1_operand" ""))
10712               (const_string "alu")
10713            ]
10714            (const_string "ishift")))
10715    (set_attr "mode" "DI")])
10716
10717 (define_insn "ashldi3_1"
10718   [(set (match_operand:DI 0 "register_operand" "=r")
10719         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10720                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10721    (clobber (match_scratch:SI 3 "=&r"))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "!TARGET_64BIT && TARGET_CMOVE"
10724   "#"
10725   [(set_attr "type" "multi")])
10726
10727 (define_insn "*ashldi3_2"
10728   [(set (match_operand:DI 0 "register_operand" "=r")
10729         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10730                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10731    (clobber (reg:CC FLAGS_REG))]
10732   "!TARGET_64BIT"
10733   "#"
10734   [(set_attr "type" "multi")])
10735
10736 (define_split
10737   [(set (match_operand:DI 0 "register_operand" "")
10738         (ashift:DI (match_operand:DI 1 "register_operand" "")
10739                    (match_operand:QI 2 "nonmemory_operand" "")))
10740    (clobber (match_scratch:SI 3 ""))
10741    (clobber (reg:CC FLAGS_REG))]
10742   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10743   [(const_int 0)]
10744   "ix86_split_ashldi (operands, operands[3]); DONE;")
10745
10746 (define_split
10747   [(set (match_operand:DI 0 "register_operand" "")
10748         (ashift:DI (match_operand:DI 1 "register_operand" "")
10749                    (match_operand:QI 2 "nonmemory_operand" "")))
10750    (clobber (reg:CC FLAGS_REG))]
10751   "!TARGET_64BIT && reload_completed"
10752   [(const_int 0)]
10753   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10754
10755 (define_insn "x86_shld_1"
10756   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10757         (ior:SI (ashift:SI (match_dup 0)
10758                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10759                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10760                   (minus:QI (const_int 32) (match_dup 2)))))
10761    (clobber (reg:CC FLAGS_REG))]
10762   ""
10763   "@
10764    shld{l}\t{%2, %1, %0|%0, %1, %2}
10765    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10766   [(set_attr "type" "ishift")
10767    (set_attr "prefix_0f" "1")
10768    (set_attr "mode" "SI")
10769    (set_attr "pent_pair" "np")
10770    (set_attr "athlon_decode" "vector")])
10771
10772 (define_expand "x86_shift_adj_1"
10773   [(set (reg:CCZ FLAGS_REG)
10774         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10775                              (const_int 32))
10776                      (const_int 0)))
10777    (set (match_operand:SI 0 "register_operand" "")
10778         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10779                          (match_operand:SI 1 "register_operand" "")
10780                          (match_dup 0)))
10781    (set (match_dup 1)
10782         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10783                          (match_operand:SI 3 "register_operand" "r")
10784                          (match_dup 1)))]
10785   "TARGET_CMOVE"
10786   "")
10787
10788 (define_expand "x86_shift_adj_2"
10789   [(use (match_operand:SI 0 "register_operand" ""))
10790    (use (match_operand:SI 1 "register_operand" ""))
10791    (use (match_operand:QI 2 "register_operand" ""))]
10792   ""
10793 {
10794   rtx label = gen_label_rtx ();
10795   rtx tmp;
10796
10797   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10798
10799   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10800   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10801   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10802                               gen_rtx_LABEL_REF (VOIDmode, label),
10803                               pc_rtx);
10804   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10805   JUMP_LABEL (tmp) = label;
10806
10807   emit_move_insn (operands[0], operands[1]);
10808   emit_move_insn (operands[1], const0_rtx);
10809
10810   emit_label (label);
10811   LABEL_NUSES (label) = 1;
10812
10813   DONE;
10814 })
10815
10816 (define_expand "ashlsi3"
10817   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10818         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10819                    (match_operand:QI 2 "nonmemory_operand" "")))
10820    (clobber (reg:CC FLAGS_REG))]
10821   ""
10822   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10823
10824 (define_insn "*ashlsi3_1"
10825   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10826         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10827                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10828    (clobber (reg:CC FLAGS_REG))]
10829   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10830 {
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       if (operands[2] != const1_rtx)
10835         abort ();
10836       if (!rtx_equal_p (operands[0], operands[1]))
10837         abort ();
10838       return "add{l}\t{%0, %0|%0, %0}";
10839
10840     case TYPE_LEA:
10841       return "#";
10842
10843     default:
10844       if (REG_P (operands[2]))
10845         return "sal{l}\t{%b2, %0|%0, %b2}";
10846       else if (operands[2] == const1_rtx
10847                && (TARGET_SHIFT1 || optimize_size))
10848         return "sal{l}\t%0";
10849       else
10850         return "sal{l}\t{%2, %0|%0, %2}";
10851     }
10852 }
10853   [(set (attr "type")
10854      (cond [(eq_attr "alternative" "1")
10855               (const_string "lea")
10856             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10857                           (const_int 0))
10858                       (match_operand 0 "register_operand" ""))
10859                  (match_operand 2 "const1_operand" ""))
10860               (const_string "alu")
10861            ]
10862            (const_string "ishift")))
10863    (set_attr "mode" "SI")])
10864
10865 ;; Convert lea to the lea pattern to avoid flags dependency.
10866 (define_split
10867   [(set (match_operand 0 "register_operand" "")
10868         (ashift (match_operand 1 "index_register_operand" "")
10869                 (match_operand:QI 2 "const_int_operand" "")))
10870    (clobber (reg:CC FLAGS_REG))]
10871   "reload_completed
10872    && true_regnum (operands[0]) != true_regnum (operands[1])"
10873   [(const_int 0)]
10874 {
10875   rtx pat;
10876   operands[0] = gen_lowpart (SImode, operands[0]);
10877   operands[1] = gen_lowpart (Pmode, operands[1]);
10878   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10879   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10880   if (Pmode != SImode)
10881     pat = gen_rtx_SUBREG (SImode, pat, 0);
10882   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10883   DONE;
10884 })
10885
10886 ;; Rare case of shifting RSP is handled by generating move and shift
10887 (define_split
10888   [(set (match_operand 0 "register_operand" "")
10889         (ashift (match_operand 1 "register_operand" "")
10890                 (match_operand:QI 2 "const_int_operand" "")))
10891    (clobber (reg:CC FLAGS_REG))]
10892   "reload_completed
10893    && true_regnum (operands[0]) != true_regnum (operands[1])"
10894   [(const_int 0)]
10895 {
10896   rtx pat, clob;
10897   emit_move_insn (operands[1], operands[0]);
10898   pat = gen_rtx_SET (VOIDmode, operands[0],
10899                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10900                                      operands[0], operands[2]));
10901   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10902   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10903   DONE;
10904 })
10905
10906 (define_insn "*ashlsi3_1_zext"
10907   [(set (match_operand:DI 0 "register_operand" "=r,r")
10908         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10909                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10910    (clobber (reg:CC FLAGS_REG))]
10911   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10912 {
10913   switch (get_attr_type (insn))
10914     {
10915     case TYPE_ALU:
10916       if (operands[2] != const1_rtx)
10917         abort ();
10918       return "add{l}\t{%k0, %k0|%k0, %k0}";
10919
10920     case TYPE_LEA:
10921       return "#";
10922
10923     default:
10924       if (REG_P (operands[2]))
10925         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         return "sal{l}\t%k0";
10929       else
10930         return "sal{l}\t{%2, %k0|%k0, %2}";
10931     }
10932 }
10933   [(set (attr "type")
10934      (cond [(eq_attr "alternative" "1")
10935               (const_string "lea")
10936             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937                      (const_int 0))
10938                  (match_operand 2 "const1_operand" ""))
10939               (const_string "alu")
10940            ]
10941            (const_string "ishift")))
10942    (set_attr "mode" "SI")])
10943
10944 ;; Convert lea to the lea pattern to avoid flags dependency.
10945 (define_split
10946   [(set (match_operand:DI 0 "register_operand" "")
10947         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10948                                 (match_operand:QI 2 "const_int_operand" ""))))
10949    (clobber (reg:CC FLAGS_REG))]
10950   "TARGET_64BIT && reload_completed
10951    && true_regnum (operands[0]) != true_regnum (operands[1])"
10952   [(set (match_dup 0) (zero_extend:DI
10953                         (subreg:SI (mult:SI (match_dup 1)
10954                                             (match_dup 2)) 0)))]
10955 {
10956   operands[1] = gen_lowpart (Pmode, operands[1]);
10957   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10958 })
10959
10960 ;; This pattern can't accept a variable shift count, since shifts by
10961 ;; zero don't affect the flags.  We assume that shifts by constant
10962 ;; zero are optimized away.
10963 (define_insn "*ashlsi3_cmp"
10964   [(set (reg 17)
10965         (compare
10966           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10967                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10968           (const_int 0)))
10969    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10970         (ashift:SI (match_dup 1) (match_dup 2)))]
10971   "ix86_match_ccmode (insn, CCGOCmode)
10972    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10973 {
10974   switch (get_attr_type (insn))
10975     {
10976     case TYPE_ALU:
10977       if (operands[2] != const1_rtx)
10978         abort ();
10979       return "add{l}\t{%0, %0|%0, %0}";
10980
10981     default:
10982       if (REG_P (operands[2]))
10983         return "sal{l}\t{%b2, %0|%0, %b2}";
10984       else if (operands[2] == const1_rtx
10985                && (TARGET_SHIFT1 || optimize_size))
10986         return "sal{l}\t%0";
10987       else
10988         return "sal{l}\t{%2, %0|%0, %2}";
10989     }
10990 }
10991   [(set (attr "type")
10992      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10993                           (const_int 0))
10994                       (match_operand 0 "register_operand" ""))
10995                  (match_operand 2 "const1_operand" ""))
10996               (const_string "alu")
10997            ]
10998            (const_string "ishift")))
10999    (set_attr "mode" "SI")])
11000
11001 (define_insn "*ashlsi3_cmp_zext"
11002   [(set (reg 17)
11003         (compare
11004           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11005                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11006           (const_int 0)))
11007    (set (match_operand:DI 0 "register_operand" "=r")
11008         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11010    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11011 {
11012   switch (get_attr_type (insn))
11013     {
11014     case TYPE_ALU:
11015       if (operands[2] != const1_rtx)
11016         abort ();
11017       return "add{l}\t{%k0, %k0|%k0, %k0}";
11018
11019     default:
11020       if (REG_P (operands[2]))
11021         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11022       else if (operands[2] == const1_rtx
11023                && (TARGET_SHIFT1 || optimize_size))
11024         return "sal{l}\t%k0";
11025       else
11026         return "sal{l}\t{%2, %k0|%k0, %2}";
11027     }
11028 }
11029   [(set (attr "type")
11030      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031                      (const_int 0))
11032                  (match_operand 2 "const1_operand" ""))
11033               (const_string "alu")
11034            ]
11035            (const_string "ishift")))
11036    (set_attr "mode" "SI")])
11037
11038 (define_expand "ashlhi3"
11039   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11040         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11041                    (match_operand:QI 2 "nonmemory_operand" "")))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_HIMODE_MATH"
11044   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11045
11046 (define_insn "*ashlhi3_1_lea"
11047   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11048         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11049                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "!TARGET_PARTIAL_REG_STALL
11052    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11053 {
11054   switch (get_attr_type (insn))
11055     {
11056     case TYPE_LEA:
11057       return "#";
11058     case TYPE_ALU:
11059       if (operands[2] != const1_rtx)
11060         abort ();
11061       return "add{w}\t{%0, %0|%0, %0}";
11062
11063     default:
11064       if (REG_P (operands[2]))
11065         return "sal{w}\t{%b2, %0|%0, %b2}";
11066       else if (operands[2] == const1_rtx
11067                && (TARGET_SHIFT1 || optimize_size))
11068         return "sal{w}\t%0";
11069       else
11070         return "sal{w}\t{%2, %0|%0, %2}";
11071     }
11072 }
11073   [(set (attr "type")
11074      (cond [(eq_attr "alternative" "1")
11075               (const_string "lea")
11076             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11077                           (const_int 0))
11078                       (match_operand 0 "register_operand" ""))
11079                  (match_operand 2 "const1_operand" ""))
11080               (const_string "alu")
11081            ]
11082            (const_string "ishift")))
11083    (set_attr "mode" "HI,SI")])
11084
11085 (define_insn "*ashlhi3_1"
11086   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11087         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11088                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11089    (clobber (reg:CC FLAGS_REG))]
11090   "TARGET_PARTIAL_REG_STALL
11091    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11092 {
11093   switch (get_attr_type (insn))
11094     {
11095     case TYPE_ALU:
11096       if (operands[2] != const1_rtx)
11097         abort ();
11098       return "add{w}\t{%0, %0|%0, %0}";
11099
11100     default:
11101       if (REG_P (operands[2]))
11102         return "sal{w}\t{%b2, %0|%0, %b2}";
11103       else if (operands[2] == const1_rtx
11104                && (TARGET_SHIFT1 || optimize_size))
11105         return "sal{w}\t%0";
11106       else
11107         return "sal{w}\t{%2, %0|%0, %2}";
11108     }
11109 }
11110   [(set (attr "type")
11111      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11112                           (const_int 0))
11113                       (match_operand 0 "register_operand" ""))
11114                  (match_operand 2 "const1_operand" ""))
11115               (const_string "alu")
11116            ]
11117            (const_string "ishift")))
11118    (set_attr "mode" "HI")])
11119
11120 ;; This pattern can't accept a variable shift count, since shifts by
11121 ;; zero don't affect the flags.  We assume that shifts by constant
11122 ;; zero are optimized away.
11123 (define_insn "*ashlhi3_cmp"
11124   [(set (reg 17)
11125         (compare
11126           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11127                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11128           (const_int 0)))
11129    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11130         (ashift:HI (match_dup 1) (match_dup 2)))]
11131   "ix86_match_ccmode (insn, CCGOCmode)
11132    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11133 {
11134   switch (get_attr_type (insn))
11135     {
11136     case TYPE_ALU:
11137       if (operands[2] != const1_rtx)
11138         abort ();
11139       return "add{w}\t{%0, %0|%0, %0}";
11140
11141     default:
11142       if (REG_P (operands[2]))
11143         return "sal{w}\t{%b2, %0|%0, %b2}";
11144       else if (operands[2] == const1_rtx
11145                && (TARGET_SHIFT1 || optimize_size))
11146         return "sal{w}\t%0";
11147       else
11148         return "sal{w}\t{%2, %0|%0, %2}";
11149     }
11150 }
11151   [(set (attr "type")
11152      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11153                           (const_int 0))
11154                       (match_operand 0 "register_operand" ""))
11155                  (match_operand 2 "const1_operand" ""))
11156               (const_string "alu")
11157            ]
11158            (const_string "ishift")))
11159    (set_attr "mode" "HI")])
11160
11161 (define_expand "ashlqi3"
11162   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11163         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11164                    (match_operand:QI 2 "nonmemory_operand" "")))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "TARGET_QIMODE_MATH"
11167   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11168
11169 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11170
11171 (define_insn "*ashlqi3_1_lea"
11172   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11173         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11174                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11175    (clobber (reg:CC FLAGS_REG))]
11176   "!TARGET_PARTIAL_REG_STALL
11177    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11178 {
11179   switch (get_attr_type (insn))
11180     {
11181     case TYPE_LEA:
11182       return "#";
11183     case TYPE_ALU:
11184       if (operands[2] != const1_rtx)
11185         abort ();
11186       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187         return "add{l}\t{%k0, %k0|%k0, %k0}";
11188       else
11189         return "add{b}\t{%0, %0|%0, %0}";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196           else
11197             return "sal{b}\t{%b2, %0|%0, %b2}";
11198         }
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         {
11202           if (get_attr_mode (insn) == MODE_SI)
11203             return "sal{l}\t%0";
11204           else
11205             return "sal{b}\t%0";
11206         }
11207       else
11208         {
11209           if (get_attr_mode (insn) == MODE_SI)
11210             return "sal{l}\t{%2, %k0|%k0, %2}";
11211           else
11212             return "sal{b}\t{%2, %0|%0, %2}";
11213         }
11214     }
11215 }
11216   [(set (attr "type")
11217      (cond [(eq_attr "alternative" "2")
11218               (const_string "lea")
11219             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11220                           (const_int 0))
11221                       (match_operand 0 "register_operand" ""))
11222                  (match_operand 2 "const1_operand" ""))
11223               (const_string "alu")
11224            ]
11225            (const_string "ishift")))
11226    (set_attr "mode" "QI,SI,SI")])
11227
11228 (define_insn "*ashlqi3_1"
11229   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11230         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11231                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11232    (clobber (reg:CC FLAGS_REG))]
11233   "TARGET_PARTIAL_REG_STALL
11234    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11235 {
11236   switch (get_attr_type (insn))
11237     {
11238     case TYPE_ALU:
11239       if (operands[2] != const1_rtx)
11240         abort ();
11241       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11242         return "add{l}\t{%k0, %k0|%k0, %k0}";
11243       else
11244         return "add{b}\t{%0, %0|%0, %0}";
11245
11246     default:
11247       if (REG_P (operands[2]))
11248         {
11249           if (get_attr_mode (insn) == MODE_SI)
11250             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11251           else
11252             return "sal{b}\t{%b2, %0|%0, %b2}";
11253         }
11254       else if (operands[2] == const1_rtx
11255                && (TARGET_SHIFT1 || optimize_size))
11256         {
11257           if (get_attr_mode (insn) == MODE_SI)
11258             return "sal{l}\t%0";
11259           else
11260             return "sal{b}\t%0";
11261         }
11262       else
11263         {
11264           if (get_attr_mode (insn) == MODE_SI)
11265             return "sal{l}\t{%2, %k0|%k0, %2}";
11266           else
11267             return "sal{b}\t{%2, %0|%0, %2}";
11268         }
11269     }
11270 }
11271   [(set (attr "type")
11272      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11273                           (const_int 0))
11274                       (match_operand 0 "register_operand" ""))
11275                  (match_operand 2 "const1_operand" ""))
11276               (const_string "alu")
11277            ]
11278            (const_string "ishift")))
11279    (set_attr "mode" "QI,SI")])
11280
11281 ;; This pattern can't accept a variable shift count, since shifts by
11282 ;; zero don't affect the flags.  We assume that shifts by constant
11283 ;; zero are optimized away.
11284 (define_insn "*ashlqi3_cmp"
11285   [(set (reg 17)
11286         (compare
11287           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11288                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11289           (const_int 0)))
11290    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11291         (ashift:QI (match_dup 1) (match_dup 2)))]
11292   "ix86_match_ccmode (insn, CCGOCmode)
11293    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11294 {
11295   switch (get_attr_type (insn))
11296     {
11297     case TYPE_ALU:
11298       if (operands[2] != const1_rtx)
11299         abort ();
11300       return "add{b}\t{%0, %0|%0, %0}";
11301
11302     default:
11303       if (REG_P (operands[2]))
11304         return "sal{b}\t{%b2, %0|%0, %b2}";
11305       else if (operands[2] == const1_rtx
11306                && (TARGET_SHIFT1 || optimize_size))
11307         return "sal{b}\t%0";
11308       else
11309         return "sal{b}\t{%2, %0|%0, %2}";
11310     }
11311 }
11312   [(set (attr "type")
11313      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11314                           (const_int 0))
11315                       (match_operand 0 "register_operand" ""))
11316                  (match_operand 2 "const1_operand" ""))
11317               (const_string "alu")
11318            ]
11319            (const_string "ishift")))
11320    (set_attr "mode" "QI")])
11321
11322 ;; See comment above `ashldi3' about how this works.
11323
11324 (define_expand "ashrdi3"
11325   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11326                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11327                                 (match_operand:QI 2 "nonmemory_operand" "")))
11328               (clobber (reg:CC FLAGS_REG))])]
11329   ""
11330 {
11331   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11332     {
11333       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11334       DONE;
11335     }
11336   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11337   DONE;
11338 })
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 && (TARGET_USE_CLTD || optimize_size)
11346    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347   "@
11348    {cqto|cqo}
11349    sar{q}\t{%2, %0|%0, %2}"
11350   [(set_attr "type" "imovx,ishift")
11351    (set_attr "prefix_0f" "0,*")
11352    (set_attr "length_immediate" "0,*")
11353    (set_attr "modrm" "0,1")
11354    (set_attr "mode" "DI")])
11355
11356 (define_insn "*ashrdi3_1_one_bit_rex64"
11357   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11359                      (match_operand:QI 2 "const1_operand" "")))
11360    (clobber (reg:CC FLAGS_REG))]
11361   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11362    && (TARGET_SHIFT1 || optimize_size)"
11363   "sar{q}\t%0"
11364   [(set_attr "type" "ishift")
11365    (set (attr "length") 
11366      (if_then_else (match_operand:DI 0 "register_operand" "") 
11367         (const_string "2")
11368         (const_string "*")))])
11369
11370 (define_insn "*ashrdi3_1_rex64"
11371   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11372         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11373                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11374    (clobber (reg:CC FLAGS_REG))]
11375   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11376   "@
11377    sar{q}\t{%2, %0|%0, %2}
11378    sar{q}\t{%b2, %0|%0, %b2}"
11379   [(set_attr "type" "ishift")
11380    (set_attr "mode" "DI")])
11381
11382 ;; This pattern can't accept a variable shift count, since shifts by
11383 ;; zero don't affect the flags.  We assume that shifts by constant
11384 ;; zero are optimized away.
11385 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11386   [(set (reg 17)
11387         (compare
11388           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11389                        (match_operand:QI 2 "const1_operand" ""))
11390           (const_int 0)))
11391    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11392         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11393   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11394    && (TARGET_SHIFT1 || optimize_size)
11395    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11396   "sar{q}\t%0"
11397   [(set_attr "type" "ishift")
11398    (set (attr "length") 
11399      (if_then_else (match_operand:DI 0 "register_operand" "") 
11400         (const_string "2")
11401         (const_string "*")))])
11402
11403 ;; This pattern can't accept a variable shift count, since shifts by
11404 ;; zero don't affect the flags.  We assume that shifts by constant
11405 ;; zero are optimized away.
11406 (define_insn "*ashrdi3_cmp_rex64"
11407   [(set (reg 17)
11408         (compare
11409           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11410                        (match_operand:QI 2 "const_int_operand" "n"))
11411           (const_int 0)))
11412    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11413         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11414   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11415    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11416   "sar{q}\t{%2, %0|%0, %2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "DI")])
11419
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 (match_scratch:SI 3 "=&r"))
11426    (clobber (reg:CC FLAGS_REG))]
11427   "!TARGET_64BIT && TARGET_CMOVE"
11428   "#"
11429   [(set_attr "type" "multi")])
11430
11431 (define_insn "*ashrdi3_2"
11432   [(set (match_operand:DI 0 "register_operand" "=r")
11433         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11434                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11435    (clobber (reg:CC FLAGS_REG))]
11436   "!TARGET_64BIT"
11437   "#"
11438   [(set_attr "type" "multi")])
11439
11440 (define_split
11441   [(set (match_operand:DI 0 "register_operand" "")
11442         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11443                      (match_operand:QI 2 "nonmemory_operand" "")))
11444    (clobber (match_scratch:SI 3 ""))
11445    (clobber (reg:CC FLAGS_REG))]
11446   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11447   [(const_int 0)]
11448   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11449
11450 (define_split
11451   [(set (match_operand:DI 0 "register_operand" "")
11452         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11453                      (match_operand:QI 2 "nonmemory_operand" "")))
11454    (clobber (reg:CC FLAGS_REG))]
11455   "!TARGET_64BIT && reload_completed"
11456   [(const_int 0)]
11457   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11458
11459 (define_insn "x86_shrd_1"
11460   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11461         (ior:SI (ashiftrt:SI (match_dup 0)
11462                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11463                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11464                   (minus:QI (const_int 32) (match_dup 2)))))
11465    (clobber (reg:CC FLAGS_REG))]
11466   ""
11467   "@
11468    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11469    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11470   [(set_attr "type" "ishift")
11471    (set_attr "prefix_0f" "1")
11472    (set_attr "pent_pair" "np")
11473    (set_attr "mode" "SI")])
11474
11475 (define_expand "x86_shift_adj_3"
11476   [(use (match_operand:SI 0 "register_operand" ""))
11477    (use (match_operand:SI 1 "register_operand" ""))
11478    (use (match_operand:QI 2 "register_operand" ""))]
11479   ""
11480 {
11481   rtx label = gen_label_rtx ();
11482   rtx tmp;
11483
11484   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11485
11486   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11487   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11488   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11489                               gen_rtx_LABEL_REF (VOIDmode, label),
11490                               pc_rtx);
11491   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11492   JUMP_LABEL (tmp) = label;
11493
11494   emit_move_insn (operands[0], operands[1]);
11495   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11496
11497   emit_label (label);
11498   LABEL_NUSES (label) = 1;
11499
11500   DONE;
11501 })
11502
11503 (define_insn "ashrsi3_31"
11504   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11505         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11506                      (match_operand:SI 2 "const_int_operand" "i,i")))
11507    (clobber (reg:CC FLAGS_REG))]
11508   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11509    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11510   "@
11511    {cltd|cdq}
11512    sar{l}\t{%2, %0|%0, %2}"
11513   [(set_attr "type" "imovx,ishift")
11514    (set_attr "prefix_0f" "0,*")
11515    (set_attr "length_immediate" "0,*")
11516    (set_attr "modrm" "0,1")
11517    (set_attr "mode" "SI")])
11518
11519 (define_insn "*ashrsi3_31_zext"
11520   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11521         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11522                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11525    && INTVAL (operands[2]) == 31
11526    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11527   "@
11528    {cltd|cdq}
11529    sar{l}\t{%2, %k0|%k0, %2}"
11530   [(set_attr "type" "imovx,ishift")
11531    (set_attr "prefix_0f" "0,*")
11532    (set_attr "length_immediate" "0,*")
11533    (set_attr "modrm" "0,1")
11534    (set_attr "mode" "SI")])
11535
11536 (define_expand "ashrsi3"
11537   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11538         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11539                      (match_operand:QI 2 "nonmemory_operand" "")))
11540    (clobber (reg:CC FLAGS_REG))]
11541   ""
11542   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11543
11544 (define_insn "*ashrsi3_1_one_bit"
11545   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11546         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11547                      (match_operand:QI 2 "const1_operand" "")))
11548    (clobber (reg:CC FLAGS_REG))]
11549   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11550    && (TARGET_SHIFT1 || optimize_size)"
11551   "sar{l}\t%0"
11552   [(set_attr "type" "ishift")
11553    (set (attr "length") 
11554      (if_then_else (match_operand:SI 0 "register_operand" "") 
11555         (const_string "2")
11556         (const_string "*")))])
11557
11558 (define_insn "*ashrsi3_1_one_bit_zext"
11559   [(set (match_operand:DI 0 "register_operand" "=r")
11560         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11561                                      (match_operand:QI 2 "const1_operand" ""))))
11562    (clobber (reg:CC FLAGS_REG))]
11563   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11564    && (TARGET_SHIFT1 || optimize_size)"
11565   "sar{l}\t%k0"
11566   [(set_attr "type" "ishift")
11567    (set_attr "length" "2")])
11568
11569 (define_insn "*ashrsi3_1"
11570   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11571         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11572                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11573    (clobber (reg:CC FLAGS_REG))]
11574   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11575   "@
11576    sar{l}\t{%2, %0|%0, %2}
11577    sar{l}\t{%b2, %0|%0, %b2}"
11578   [(set_attr "type" "ishift")
11579    (set_attr "mode" "SI")])
11580
11581 (define_insn "*ashrsi3_1_zext"
11582   [(set (match_operand:DI 0 "register_operand" "=r,r")
11583         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11584                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11587   "@
11588    sar{l}\t{%2, %k0|%k0, %2}
11589    sar{l}\t{%b2, %k0|%k0, %b2}"
11590   [(set_attr "type" "ishift")
11591    (set_attr "mode" "SI")])
11592
11593 ;; This pattern can't accept a variable shift count, since shifts by
11594 ;; zero don't affect the flags.  We assume that shifts by constant
11595 ;; zero are optimized away.
11596 (define_insn "*ashrsi3_one_bit_cmp"
11597   [(set (reg 17)
11598         (compare
11599           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11600                        (match_operand:QI 2 "const1_operand" ""))
11601           (const_int 0)))
11602    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11603         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11604   "ix86_match_ccmode (insn, CCGOCmode)
11605    && (TARGET_SHIFT1 || optimize_size)
11606    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607   "sar{l}\t%0"
11608   [(set_attr "type" "ishift")
11609    (set (attr "length") 
11610      (if_then_else (match_operand:SI 0 "register_operand" "") 
11611         (const_string "2")
11612         (const_string "*")))])
11613
11614 (define_insn "*ashrsi3_one_bit_cmp_zext"
11615   [(set (reg 17)
11616         (compare
11617           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11618                        (match_operand:QI 2 "const1_operand" ""))
11619           (const_int 0)))
11620    (set (match_operand:DI 0 "register_operand" "=r")
11621         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11622   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11623    && (TARGET_SHIFT1 || optimize_size)
11624    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11625   "sar{l}\t%k0"
11626   [(set_attr "type" "ishift")
11627    (set_attr "length" "2")])
11628
11629 ;; This pattern can't accept a variable shift count, since shifts by
11630 ;; zero don't affect the flags.  We assume that shifts by constant
11631 ;; zero are optimized away.
11632 (define_insn "*ashrsi3_cmp"
11633   [(set (reg 17)
11634         (compare
11635           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11636                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11637           (const_int 0)))
11638    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11639         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11640   "ix86_match_ccmode (insn, CCGOCmode)
11641    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11642   "sar{l}\t{%2, %0|%0, %2}"
11643   [(set_attr "type" "ishift")
11644    (set_attr "mode" "SI")])
11645
11646 (define_insn "*ashrsi3_cmp_zext"
11647   [(set (reg 17)
11648         (compare
11649           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11650                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11651           (const_int 0)))
11652    (set (match_operand:DI 0 "register_operand" "=r")
11653         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11654   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11655    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11656   "sar{l}\t{%2, %k0|%k0, %2}"
11657   [(set_attr "type" "ishift")
11658    (set_attr "mode" "SI")])
11659
11660 (define_expand "ashrhi3"
11661   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11662         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11663                      (match_operand:QI 2 "nonmemory_operand" "")))
11664    (clobber (reg:CC FLAGS_REG))]
11665   "TARGET_HIMODE_MATH"
11666   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11667
11668 (define_insn "*ashrhi3_1_one_bit"
11669   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11670         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11671                      (match_operand:QI 2 "const1_operand" "")))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11674    && (TARGET_SHIFT1 || optimize_size)"
11675   "sar{w}\t%0"
11676   [(set_attr "type" "ishift")
11677    (set (attr "length") 
11678      (if_then_else (match_operand 0 "register_operand" "") 
11679         (const_string "2")
11680         (const_string "*")))])
11681
11682 (define_insn "*ashrhi3_1"
11683   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11684         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11685                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11688   "@
11689    sar{w}\t{%2, %0|%0, %2}
11690    sar{w}\t{%b2, %0|%0, %b2}"
11691   [(set_attr "type" "ishift")
11692    (set_attr "mode" "HI")])
11693
11694 ;; This pattern can't accept a variable shift count, since shifts by
11695 ;; zero don't affect the flags.  We assume that shifts by constant
11696 ;; zero are optimized away.
11697 (define_insn "*ashrhi3_one_bit_cmp"
11698   [(set (reg 17)
11699         (compare
11700           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11701                        (match_operand:QI 2 "const1_operand" ""))
11702           (const_int 0)))
11703    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11704         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11705   "ix86_match_ccmode (insn, CCGOCmode)
11706    && (TARGET_SHIFT1 || optimize_size)
11707    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11708   "sar{w}\t%0"
11709   [(set_attr "type" "ishift")
11710    (set (attr "length") 
11711      (if_then_else (match_operand 0 "register_operand" "") 
11712         (const_string "2")
11713         (const_string "*")))])
11714
11715 ;; This pattern can't accept a variable shift count, since shifts by
11716 ;; zero don't affect the flags.  We assume that shifts by constant
11717 ;; zero are optimized away.
11718 (define_insn "*ashrhi3_cmp"
11719   [(set (reg 17)
11720         (compare
11721           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11722                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11723           (const_int 0)))
11724    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11725         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11726   "ix86_match_ccmode (insn, CCGOCmode)
11727    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11728   "sar{w}\t{%2, %0|%0, %2}"
11729   [(set_attr "type" "ishift")
11730    (set_attr "mode" "HI")])
11731
11732 (define_expand "ashrqi3"
11733   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11734         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11735                      (match_operand:QI 2 "nonmemory_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "TARGET_QIMODE_MATH"
11738   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11739
11740 (define_insn "*ashrqi3_1_one_bit"
11741   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11742         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11743                      (match_operand:QI 2 "const1_operand" "")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11746    && (TARGET_SHIFT1 || optimize_size)"
11747   "sar{b}\t%0"
11748   [(set_attr "type" "ishift")
11749    (set (attr "length") 
11750      (if_then_else (match_operand 0 "register_operand" "") 
11751         (const_string "2")
11752         (const_string "*")))])
11753
11754 (define_insn "*ashrqi3_1_one_bit_slp"
11755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11756         (ashiftrt:QI (match_dup 0)
11757                      (match_operand:QI 1 "const1_operand" "")))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11760    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11761    && (TARGET_SHIFT1 || optimize_size)"
11762   "sar{b}\t%0"
11763   [(set_attr "type" "ishift1")
11764    (set (attr "length") 
11765      (if_then_else (match_operand 0 "register_operand" "") 
11766         (const_string "2")
11767         (const_string "*")))])
11768
11769 (define_insn "*ashrqi3_1"
11770   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11771         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11772                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11773    (clobber (reg:CC FLAGS_REG))]
11774   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11775   "@
11776    sar{b}\t{%2, %0|%0, %2}
11777    sar{b}\t{%b2, %0|%0, %b2}"
11778   [(set_attr "type" "ishift")
11779    (set_attr "mode" "QI")])
11780
11781 (define_insn "*ashrqi3_1_slp"
11782   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11783         (ashiftrt:QI (match_dup 0)
11784                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11787    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11788   "@
11789    sar{b}\t{%1, %0|%0, %1}
11790    sar{b}\t{%b1, %0|%0, %b1}"
11791   [(set_attr "type" "ishift1")
11792    (set_attr "mode" "QI")])
11793
11794 ;; This pattern can't accept a variable shift count, since shifts by
11795 ;; zero don't affect the flags.  We assume that shifts by constant
11796 ;; zero are optimized away.
11797 (define_insn "*ashrqi3_one_bit_cmp"
11798   [(set (reg 17)
11799         (compare
11800           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11801                        (match_operand:QI 2 "const1_operand" "I"))
11802           (const_int 0)))
11803    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11804         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11805   "ix86_match_ccmode (insn, CCGOCmode)
11806    && (TARGET_SHIFT1 || optimize_size)
11807    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11808   "sar{b}\t%0"
11809   [(set_attr "type" "ishift")
11810    (set (attr "length") 
11811      (if_then_else (match_operand 0 "register_operand" "") 
11812         (const_string "2")
11813         (const_string "*")))])
11814
11815 ;; This pattern can't accept a variable shift count, since shifts by
11816 ;; zero don't affect the flags.  We assume that shifts by constant
11817 ;; zero are optimized away.
11818 (define_insn "*ashrqi3_cmp"
11819   [(set (reg 17)
11820         (compare
11821           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11822                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11823           (const_int 0)))
11824    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11825         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11826   "ix86_match_ccmode (insn, CCGOCmode)
11827    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11828   "sar{b}\t{%2, %0|%0, %2}"
11829   [(set_attr "type" "ishift")
11830    (set_attr "mode" "QI")])
11831 \f
11832 ;; Logical shift instructions
11833
11834 ;; See comment above `ashldi3' about how this works.
11835
11836 (define_expand "lshrdi3"
11837   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11838                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11839                                 (match_operand:QI 2 "nonmemory_operand" "")))
11840               (clobber (reg:CC FLAGS_REG))])]
11841   ""
11842 {
11843   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11844     {
11845       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11846       DONE;
11847     }
11848   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11849   DONE;
11850 })
11851
11852 (define_insn "*lshrdi3_1_one_bit_rex64"
11853   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11854         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" "")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11858    && (TARGET_SHIFT1 || optimize_size)"
11859   "shr{q}\t%0"
11860   [(set_attr "type" "ishift")
11861    (set (attr "length") 
11862      (if_then_else (match_operand:DI 0 "register_operand" "") 
11863         (const_string "2")
11864         (const_string "*")))])
11865
11866 (define_insn "*lshrdi3_1_rex64"
11867   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11868         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11869                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11872   "@
11873    shr{q}\t{%2, %0|%0, %2}
11874    shr{q}\t{%b2, %0|%0, %b2}"
11875   [(set_attr "type" "ishift")
11876    (set_attr "mode" "DI")])
11877
11878 ;; This pattern can't accept a variable shift count, since shifts by
11879 ;; zero don't affect the flags.  We assume that shifts by constant
11880 ;; zero are optimized away.
11881 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11882   [(set (reg 17)
11883         (compare
11884           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885                        (match_operand:QI 2 "const1_operand" ""))
11886           (const_int 0)))
11887    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11888         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11889   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11890    && (TARGET_SHIFT1 || optimize_size)
11891    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11892   "shr{q}\t%0"
11893   [(set_attr "type" "ishift")
11894    (set (attr "length") 
11895      (if_then_else (match_operand:DI 0 "register_operand" "") 
11896         (const_string "2")
11897         (const_string "*")))])
11898
11899 ;; This pattern can't accept a variable shift count, since shifts by
11900 ;; zero don't affect the flags.  We assume that shifts by constant
11901 ;; zero are optimized away.
11902 (define_insn "*lshrdi3_cmp_rex64"
11903   [(set (reg 17)
11904         (compare
11905           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11906                        (match_operand:QI 2 "const_int_operand" "e"))
11907           (const_int 0)))
11908    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11909         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11910   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11911    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11912   "shr{q}\t{%2, %0|%0, %2}"
11913   [(set_attr "type" "ishift")
11914    (set_attr "mode" "DI")])
11915
11916 (define_insn "lshrdi3_1"
11917   [(set (match_operand:DI 0 "register_operand" "=r")
11918         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11919                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11920    (clobber (match_scratch:SI 3 "=&r"))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "!TARGET_64BIT && TARGET_CMOVE"
11923   "#"
11924   [(set_attr "type" "multi")])
11925
11926 (define_insn "*lshrdi3_2"
11927   [(set (match_operand:DI 0 "register_operand" "=r")
11928         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11929                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11930    (clobber (reg:CC FLAGS_REG))]
11931   "!TARGET_64BIT"
11932   "#"
11933   [(set_attr "type" "multi")])
11934
11935 (define_split 
11936   [(set (match_operand:DI 0 "register_operand" "")
11937         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11938                      (match_operand:QI 2 "nonmemory_operand" "")))
11939    (clobber (match_scratch:SI 3 ""))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11942   [(const_int 0)]
11943   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11944
11945 (define_split 
11946   [(set (match_operand:DI 0 "register_operand" "")
11947         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11948                      (match_operand:QI 2 "nonmemory_operand" "")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "!TARGET_64BIT && reload_completed"
11951   [(const_int 0)]
11952   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11953
11954 (define_expand "lshrsi3"
11955   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11956         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11957                      (match_operand:QI 2 "nonmemory_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   ""
11960   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11961
11962 (define_insn "*lshrsi3_1_one_bit"
11963   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11964         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11965                      (match_operand:QI 2 "const1_operand" "")))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11968    && (TARGET_SHIFT1 || optimize_size)"
11969   "shr{l}\t%0"
11970   [(set_attr "type" "ishift")
11971    (set (attr "length") 
11972      (if_then_else (match_operand:SI 0 "register_operand" "") 
11973         (const_string "2")
11974         (const_string "*")))])
11975
11976 (define_insn "*lshrsi3_1_one_bit_zext"
11977   [(set (match_operand:DI 0 "register_operand" "=r")
11978         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11979                      (match_operand:QI 2 "const1_operand" "")))
11980    (clobber (reg:CC FLAGS_REG))]
11981   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11982    && (TARGET_SHIFT1 || optimize_size)"
11983   "shr{l}\t%k0"
11984   [(set_attr "type" "ishift")
11985    (set_attr "length" "2")])
11986
11987 (define_insn "*lshrsi3_1"
11988   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11989         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11990                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11991    (clobber (reg:CC FLAGS_REG))]
11992   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11993   "@
11994    shr{l}\t{%2, %0|%0, %2}
11995    shr{l}\t{%b2, %0|%0, %b2}"
11996   [(set_attr "type" "ishift")
11997    (set_attr "mode" "SI")])
11998
11999 (define_insn "*lshrsi3_1_zext"
12000   [(set (match_operand:DI 0 "register_operand" "=r,r")
12001         (zero_extend:DI
12002           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12003                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12006   "@
12007    shr{l}\t{%2, %k0|%k0, %2}
12008    shr{l}\t{%b2, %k0|%k0, %b2}"
12009   [(set_attr "type" "ishift")
12010    (set_attr "mode" "SI")])
12011
12012 ;; This pattern can't accept a variable shift count, since shifts by
12013 ;; zero don't affect the flags.  We assume that shifts by constant
12014 ;; zero are optimized away.
12015 (define_insn "*lshrsi3_one_bit_cmp"
12016   [(set (reg 17)
12017         (compare
12018           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12019                        (match_operand:QI 2 "const1_operand" ""))
12020           (const_int 0)))
12021    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12022         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12023   "ix86_match_ccmode (insn, CCGOCmode)
12024    && (TARGET_SHIFT1 || optimize_size)
12025    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026   "shr{l}\t%0"
12027   [(set_attr "type" "ishift")
12028    (set (attr "length") 
12029      (if_then_else (match_operand:SI 0 "register_operand" "") 
12030         (const_string "2")
12031         (const_string "*")))])
12032
12033 (define_insn "*lshrsi3_cmp_one_bit_zext"
12034   [(set (reg 17)
12035         (compare
12036           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12037                        (match_operand:QI 2 "const1_operand" ""))
12038           (const_int 0)))
12039    (set (match_operand:DI 0 "register_operand" "=r")
12040         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12041   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12042    && (TARGET_SHIFT1 || optimize_size)
12043    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044   "shr{l}\t%k0"
12045   [(set_attr "type" "ishift")
12046    (set_attr "length" "2")])
12047
12048 ;; This pattern can't accept a variable shift count, since shifts by
12049 ;; zero don't affect the flags.  We assume that shifts by constant
12050 ;; zero are optimized away.
12051 (define_insn "*lshrsi3_cmp"
12052   [(set (reg 17)
12053         (compare
12054           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12055                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12056           (const_int 0)))
12057    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12058         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12059   "ix86_match_ccmode (insn, CCGOCmode)
12060    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12061   "shr{l}\t{%2, %0|%0, %2}"
12062   [(set_attr "type" "ishift")
12063    (set_attr "mode" "SI")])
12064
12065 (define_insn "*lshrsi3_cmp_zext"
12066   [(set (reg 17)
12067         (compare
12068           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12069                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12070           (const_int 0)))
12071    (set (match_operand:DI 0 "register_operand" "=r")
12072         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12073   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12074    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12075   "shr{l}\t{%2, %k0|%k0, %2}"
12076   [(set_attr "type" "ishift")
12077    (set_attr "mode" "SI")])
12078
12079 (define_expand "lshrhi3"
12080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12081         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12082                      (match_operand:QI 2 "nonmemory_operand" "")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_HIMODE_MATH"
12085   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12086
12087 (define_insn "*lshrhi3_1_one_bit"
12088   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12089         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090                      (match_operand:QI 2 "const1_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12093    && (TARGET_SHIFT1 || optimize_size)"
12094   "shr{w}\t%0"
12095   [(set_attr "type" "ishift")
12096    (set (attr "length") 
12097      (if_then_else (match_operand 0 "register_operand" "") 
12098         (const_string "2")
12099         (const_string "*")))])
12100
12101 (define_insn "*lshrhi3_1"
12102   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12103         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12104                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107   "@
12108    shr{w}\t{%2, %0|%0, %2}
12109    shr{w}\t{%b2, %0|%0, %b2}"
12110   [(set_attr "type" "ishift")
12111    (set_attr "mode" "HI")])
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_one_bit_cmp"
12117   [(set (reg 17)
12118         (compare
12119           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120                        (match_operand:QI 2 "const1_operand" ""))
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    && (TARGET_SHIFT1 || optimize_size)
12126    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12127   "shr{w}\t%0"
12128   [(set_attr "type" "ishift")
12129    (set (attr "length") 
12130      (if_then_else (match_operand:SI 0 "register_operand" "") 
12131         (const_string "2")
12132         (const_string "*")))])
12133
12134 ;; This pattern can't accept a variable shift count, since shifts by
12135 ;; zero don't affect the flags.  We assume that shifts by constant
12136 ;; zero are optimized away.
12137 (define_insn "*lshrhi3_cmp"
12138   [(set (reg 17)
12139         (compare
12140           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12141                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12142           (const_int 0)))
12143    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12144         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12145   "ix86_match_ccmode (insn, CCGOCmode)
12146    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12147   "shr{w}\t{%2, %0|%0, %2}"
12148   [(set_attr "type" "ishift")
12149    (set_attr "mode" "HI")])
12150
12151 (define_expand "lshrqi3"
12152   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12153         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12154                      (match_operand:QI 2 "nonmemory_operand" "")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "TARGET_QIMODE_MATH"
12157   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12158
12159 (define_insn "*lshrqi3_1_one_bit"
12160   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12161         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12162                      (match_operand:QI 2 "const1_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12165    && (TARGET_SHIFT1 || optimize_size)"
12166   "shr{b}\t%0"
12167   [(set_attr "type" "ishift")
12168    (set (attr "length") 
12169      (if_then_else (match_operand 0 "register_operand" "") 
12170         (const_string "2")
12171         (const_string "*")))])
12172
12173 (define_insn "*lshrqi3_1_one_bit_slp"
12174   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12175         (lshiftrt:QI (match_dup 0)
12176                      (match_operand:QI 1 "const1_operand" "")))
12177    (clobber (reg:CC FLAGS_REG))]
12178   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12179    && (TARGET_SHIFT1 || optimize_size)"
12180   "shr{b}\t%0"
12181   [(set_attr "type" "ishift1")
12182    (set (attr "length") 
12183      (if_then_else (match_operand 0 "register_operand" "") 
12184         (const_string "2")
12185         (const_string "*")))])
12186
12187 (define_insn "*lshrqi3_1"
12188   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12189         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12190                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12191    (clobber (reg:CC FLAGS_REG))]
12192   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12193   "@
12194    shr{b}\t{%2, %0|%0, %2}
12195    shr{b}\t{%b2, %0|%0, %b2}"
12196   [(set_attr "type" "ishift")
12197    (set_attr "mode" "QI")])
12198
12199 (define_insn "*lshrqi3_1_slp"
12200   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12201         (lshiftrt:QI (match_dup 0)
12202                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12205    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12206   "@
12207    shr{b}\t{%1, %0|%0, %1}
12208    shr{b}\t{%b1, %0|%0, %b1}"
12209   [(set_attr "type" "ishift1")
12210    (set_attr "mode" "QI")])
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_one_bit_cmp"
12216   [(set (reg 17)
12217         (compare
12218           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219                        (match_operand:QI 2 "const1_operand" ""))
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    && (TARGET_SHIFT1 || optimize_size)
12225    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12226   "shr{b}\t%0"
12227   [(set_attr "type" "ishift")
12228    (set (attr "length") 
12229      (if_then_else (match_operand:SI 0 "register_operand" "") 
12230         (const_string "2")
12231         (const_string "*")))])
12232
12233 ;; This pattern can't accept a variable shift count, since shifts by
12234 ;; zero don't affect the flags.  We assume that shifts by constant
12235 ;; zero are optimized away.
12236 (define_insn "*lshrqi2_cmp"
12237   [(set (reg 17)
12238         (compare
12239           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12241           (const_int 0)))
12242    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12243         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12244   "ix86_match_ccmode (insn, CCGOCmode)
12245    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12246   "shr{b}\t{%2, %0|%0, %2}"
12247   [(set_attr "type" "ishift")
12248    (set_attr "mode" "QI")])
12249 \f
12250 ;; Rotate instructions
12251
12252 (define_expand "rotldi3"
12253   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12254         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12255                    (match_operand:QI 2 "nonmemory_operand" "")))
12256    (clobber (reg:CC FLAGS_REG))]
12257   "TARGET_64BIT"
12258   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12259
12260 (define_insn "*rotlsi3_1_one_bit_rex64"
12261   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12262         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12263                    (match_operand:QI 2 "const1_operand" "")))
12264    (clobber (reg:CC FLAGS_REG))]
12265   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12266    && (TARGET_SHIFT1 || optimize_size)"
12267   "rol{q}\t%0"
12268   [(set_attr "type" "rotate")
12269    (set (attr "length") 
12270      (if_then_else (match_operand:DI 0 "register_operand" "") 
12271         (const_string "2")
12272         (const_string "*")))])
12273
12274 (define_insn "*rotldi3_1_rex64"
12275   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12276         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12277                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12278    (clobber (reg:CC FLAGS_REG))]
12279   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12280   "@
12281    rol{q}\t{%2, %0|%0, %2}
12282    rol{q}\t{%b2, %0|%0, %b2}"
12283   [(set_attr "type" "rotate")
12284    (set_attr "mode" "DI")])
12285
12286 (define_expand "rotlsi3"
12287   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12288         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12289                    (match_operand:QI 2 "nonmemory_operand" "")))
12290    (clobber (reg:CC FLAGS_REG))]
12291   ""
12292   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12293
12294 (define_insn "*rotlsi3_1_one_bit"
12295   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12296         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12297                    (match_operand:QI 2 "const1_operand" "")))
12298    (clobber (reg:CC FLAGS_REG))]
12299   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12300    && (TARGET_SHIFT1 || optimize_size)"
12301   "rol{l}\t%0"
12302   [(set_attr "type" "rotate")
12303    (set (attr "length") 
12304      (if_then_else (match_operand:SI 0 "register_operand" "") 
12305         (const_string "2")
12306         (const_string "*")))])
12307
12308 (define_insn "*rotlsi3_1_one_bit_zext"
12309   [(set (match_operand:DI 0 "register_operand" "=r")
12310         (zero_extend:DI
12311           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12312                      (match_operand:QI 2 "const1_operand" ""))))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12315    && (TARGET_SHIFT1 || optimize_size)"
12316   "rol{l}\t%k0"
12317   [(set_attr "type" "rotate")
12318    (set_attr "length" "2")])
12319
12320 (define_insn "*rotlsi3_1"
12321   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12322         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12323                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12324    (clobber (reg:CC FLAGS_REG))]
12325   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12326   "@
12327    rol{l}\t{%2, %0|%0, %2}
12328    rol{l}\t{%b2, %0|%0, %b2}"
12329   [(set_attr "type" "rotate")
12330    (set_attr "mode" "SI")])
12331
12332 (define_insn "*rotlsi3_1_zext"
12333   [(set (match_operand:DI 0 "register_operand" "=r,r")
12334         (zero_extend:DI
12335           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12336                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12339   "@
12340    rol{l}\t{%2, %k0|%k0, %2}
12341    rol{l}\t{%b2, %k0|%k0, %b2}"
12342   [(set_attr "type" "rotate")
12343    (set_attr "mode" "SI")])
12344
12345 (define_expand "rotlhi3"
12346   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12347         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12348                    (match_operand:QI 2 "nonmemory_operand" "")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "TARGET_HIMODE_MATH"
12351   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12352
12353 (define_insn "*rotlhi3_1_one_bit"
12354   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12355         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12356                    (match_operand:QI 2 "const1_operand" "")))
12357    (clobber (reg:CC FLAGS_REG))]
12358   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12359    && (TARGET_SHIFT1 || optimize_size)"
12360   "rol{w}\t%0"
12361   [(set_attr "type" "rotate")
12362    (set (attr "length") 
12363      (if_then_else (match_operand 0 "register_operand" "") 
12364         (const_string "2")
12365         (const_string "*")))])
12366
12367 (define_insn "*rotlhi3_1"
12368   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12369         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12370                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12371    (clobber (reg:CC FLAGS_REG))]
12372   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12373   "@
12374    rol{w}\t{%2, %0|%0, %2}
12375    rol{w}\t{%b2, %0|%0, %b2}"
12376   [(set_attr "type" "rotate")
12377    (set_attr "mode" "HI")])
12378
12379 (define_expand "rotlqi3"
12380   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12381         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12382                    (match_operand:QI 2 "nonmemory_operand" "")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "TARGET_QIMODE_MATH"
12385   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12386
12387 (define_insn "*rotlqi3_1_one_bit_slp"
12388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389         (rotate:QI (match_dup 0)
12390                    (match_operand:QI 1 "const1_operand" "")))
12391    (clobber (reg:CC FLAGS_REG))]
12392   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12393    && (TARGET_SHIFT1 || optimize_size)"
12394   "rol{b}\t%0"
12395   [(set_attr "type" "rotate1")
12396    (set (attr "length") 
12397      (if_then_else (match_operand 0 "register_operand" "") 
12398         (const_string "2")
12399         (const_string "*")))])
12400
12401 (define_insn "*rotlqi3_1_one_bit"
12402   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12403         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12404                    (match_operand:QI 2 "const1_operand" "")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12407    && (TARGET_SHIFT1 || optimize_size)"
12408   "rol{b}\t%0"
12409   [(set_attr "type" "rotate")
12410    (set (attr "length") 
12411      (if_then_else (match_operand 0 "register_operand" "") 
12412         (const_string "2")
12413         (const_string "*")))])
12414
12415 (define_insn "*rotlqi3_1_slp"
12416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12417         (rotate:QI (match_dup 0)
12418                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12421    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12422   "@
12423    rol{b}\t{%1, %0|%0, %1}
12424    rol{b}\t{%b1, %0|%0, %b1}"
12425   [(set_attr "type" "rotate1")
12426    (set_attr "mode" "QI")])
12427
12428 (define_insn "*rotlqi3_1"
12429   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12430         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12431                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12434   "@
12435    rol{b}\t{%2, %0|%0, %2}
12436    rol{b}\t{%b2, %0|%0, %b2}"
12437   [(set_attr "type" "rotate")
12438    (set_attr "mode" "QI")])
12439
12440 (define_expand "rotrdi3"
12441   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12442         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12443                      (match_operand:QI 2 "nonmemory_operand" "")))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "TARGET_64BIT"
12446   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12447
12448 (define_insn "*rotrdi3_1_one_bit_rex64"
12449   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12450         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12451                      (match_operand:QI 2 "const1_operand" "")))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12454    && (TARGET_SHIFT1 || optimize_size)"
12455   "ror{q}\t%0"
12456   [(set_attr "type" "rotate")
12457    (set (attr "length") 
12458      (if_then_else (match_operand:DI 0 "register_operand" "") 
12459         (const_string "2")
12460         (const_string "*")))])
12461
12462 (define_insn "*rotrdi3_1_rex64"
12463   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12464         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12465                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12468   "@
12469    ror{q}\t{%2, %0|%0, %2}
12470    ror{q}\t{%b2, %0|%0, %b2}"
12471   [(set_attr "type" "rotate")
12472    (set_attr "mode" "DI")])
12473
12474 (define_expand "rotrsi3"
12475   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12476         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12477                      (match_operand:QI 2 "nonmemory_operand" "")))
12478    (clobber (reg:CC FLAGS_REG))]
12479   ""
12480   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12481
12482 (define_insn "*rotrsi3_1_one_bit"
12483   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12484         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12485                      (match_operand:QI 2 "const1_operand" "")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12488    && (TARGET_SHIFT1 || optimize_size)"
12489   "ror{l}\t%0"
12490   [(set_attr "type" "rotate")
12491    (set (attr "length") 
12492      (if_then_else (match_operand:SI 0 "register_operand" "") 
12493         (const_string "2")
12494         (const_string "*")))])
12495
12496 (define_insn "*rotrsi3_1_one_bit_zext"
12497   [(set (match_operand:DI 0 "register_operand" "=r")
12498         (zero_extend:DI
12499           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12500                        (match_operand:QI 2 "const1_operand" ""))))
12501    (clobber (reg:CC FLAGS_REG))]
12502   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12503    && (TARGET_SHIFT1 || optimize_size)"
12504   "ror{l}\t%k0"
12505   [(set_attr "type" "rotate")
12506    (set (attr "length") 
12507      (if_then_else (match_operand:SI 0 "register_operand" "") 
12508         (const_string "2")
12509         (const_string "*")))])
12510
12511 (define_insn "*rotrsi3_1"
12512   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12513         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12514                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12515    (clobber (reg:CC FLAGS_REG))]
12516   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12517   "@
12518    ror{l}\t{%2, %0|%0, %2}
12519    ror{l}\t{%b2, %0|%0, %b2}"
12520   [(set_attr "type" "rotate")
12521    (set_attr "mode" "SI")])
12522
12523 (define_insn "*rotrsi3_1_zext"
12524   [(set (match_operand:DI 0 "register_operand" "=r,r")
12525         (zero_extend:DI
12526           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12527                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12528    (clobber (reg:CC FLAGS_REG))]
12529   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12530   "@
12531    ror{l}\t{%2, %k0|%k0, %2}
12532    ror{l}\t{%b2, %k0|%k0, %b2}"
12533   [(set_attr "type" "rotate")
12534    (set_attr "mode" "SI")])
12535
12536 (define_expand "rotrhi3"
12537   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12538         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12539                      (match_operand:QI 2 "nonmemory_operand" "")))
12540    (clobber (reg:CC FLAGS_REG))]
12541   "TARGET_HIMODE_MATH"
12542   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12543
12544 (define_insn "*rotrhi3_one_bit"
12545   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12546         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12547                      (match_operand:QI 2 "const1_operand" "")))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12550    && (TARGET_SHIFT1 || optimize_size)"
12551   "ror{w}\t%0"
12552   [(set_attr "type" "rotate")
12553    (set (attr "length") 
12554      (if_then_else (match_operand 0 "register_operand" "") 
12555         (const_string "2")
12556         (const_string "*")))])
12557
12558 (define_insn "*rotrhi3"
12559   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12560         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12561                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12564   "@
12565    ror{w}\t{%2, %0|%0, %2}
12566    ror{w}\t{%b2, %0|%0, %b2}"
12567   [(set_attr "type" "rotate")
12568    (set_attr "mode" "HI")])
12569
12570 (define_expand "rotrqi3"
12571   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12572         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12573                      (match_operand:QI 2 "nonmemory_operand" "")))
12574    (clobber (reg:CC FLAGS_REG))]
12575   "TARGET_QIMODE_MATH"
12576   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12577
12578 (define_insn "*rotrqi3_1_one_bit"
12579   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12580         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12581                      (match_operand:QI 2 "const1_operand" "")))
12582    (clobber (reg:CC FLAGS_REG))]
12583   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12584    && (TARGET_SHIFT1 || optimize_size)"
12585   "ror{b}\t%0"
12586   [(set_attr "type" "rotate")
12587    (set (attr "length") 
12588      (if_then_else (match_operand 0 "register_operand" "") 
12589         (const_string "2")
12590         (const_string "*")))])
12591
12592 (define_insn "*rotrqi3_1_one_bit_slp"
12593   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12594         (rotatert:QI (match_dup 0)
12595                      (match_operand:QI 1 "const1_operand" "")))
12596    (clobber (reg:CC FLAGS_REG))]
12597   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12598    && (TARGET_SHIFT1 || optimize_size)"
12599   "ror{b}\t%0"
12600   [(set_attr "type" "rotate1")
12601    (set (attr "length") 
12602      (if_then_else (match_operand 0 "register_operand" "") 
12603         (const_string "2")
12604         (const_string "*")))])
12605
12606 (define_insn "*rotrqi3_1"
12607   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12608         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12609                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12610    (clobber (reg:CC FLAGS_REG))]
12611   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12612   "@
12613    ror{b}\t{%2, %0|%0, %2}
12614    ror{b}\t{%b2, %0|%0, %b2}"
12615   [(set_attr "type" "rotate")
12616    (set_attr "mode" "QI")])
12617
12618 (define_insn "*rotrqi3_1_slp"
12619   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12620         (rotatert:QI (match_dup 0)
12621                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12624    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12625   "@
12626    ror{b}\t{%1, %0|%0, %1}
12627    ror{b}\t{%b1, %0|%0, %b1}"
12628   [(set_attr "type" "rotate1")
12629    (set_attr "mode" "QI")])
12630 \f
12631 ;; Bit set / bit test instructions
12632
12633 (define_expand "extv"
12634   [(set (match_operand:SI 0 "register_operand" "")
12635         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12636                          (match_operand:SI 2 "immediate_operand" "")
12637                          (match_operand:SI 3 "immediate_operand" "")))]
12638   ""
12639 {
12640   /* Handle extractions from %ah et al.  */
12641   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12642     FAIL;
12643
12644   /* From mips.md: extract_bit_field doesn't verify that our source
12645      matches the predicate, so check it again here.  */
12646   if (! register_operand (operands[1], VOIDmode))
12647     FAIL;
12648 })
12649
12650 (define_expand "extzv"
12651   [(set (match_operand:SI 0 "register_operand" "")
12652         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12653                          (match_operand:SI 2 "immediate_operand" "")
12654                          (match_operand:SI 3 "immediate_operand" "")))]
12655   ""
12656 {
12657   /* Handle extractions from %ah et al.  */
12658   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12659     FAIL;
12660
12661   /* From mips.md: extract_bit_field doesn't verify that our source
12662      matches the predicate, so check it again here.  */
12663   if (! register_operand (operands[1], VOIDmode))
12664     FAIL;
12665 })
12666
12667 (define_expand "insv"
12668   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12669                       (match_operand 1 "immediate_operand" "")
12670                       (match_operand 2 "immediate_operand" ""))
12671         (match_operand 3 "register_operand" ""))]
12672   ""
12673 {
12674   /* Handle extractions from %ah et al.  */
12675   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12676     FAIL;
12677
12678   /* From mips.md: insert_bit_field doesn't verify that our source
12679      matches the predicate, so check it again here.  */
12680   if (! register_operand (operands[0], VOIDmode))
12681     FAIL;
12682
12683   if (TARGET_64BIT)
12684     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12685   else
12686     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12687
12688   DONE;
12689 })
12690
12691 ;; %%% bts, btr, btc, bt.
12692 \f
12693 ;; Store-flag instructions.
12694
12695 ;; For all sCOND expanders, also expand the compare or test insn that
12696 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12697
12698 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12699 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12700 ;; way, which can later delete the movzx if only QImode is needed.
12701
12702 (define_expand "seq"
12703   [(set (match_operand:QI 0 "register_operand" "")
12704         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12705   ""
12706   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12707
12708 (define_expand "sne"
12709   [(set (match_operand:QI 0 "register_operand" "")
12710         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12711   ""
12712   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12713
12714 (define_expand "sgt"
12715   [(set (match_operand:QI 0 "register_operand" "")
12716         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12717   ""
12718   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12719
12720 (define_expand "sgtu"
12721   [(set (match_operand:QI 0 "register_operand" "")
12722         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12723   ""
12724   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12725
12726 (define_expand "slt"
12727   [(set (match_operand:QI 0 "register_operand" "")
12728         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729   ""
12730   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12731
12732 (define_expand "sltu"
12733   [(set (match_operand:QI 0 "register_operand" "")
12734         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735   ""
12736   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12737
12738 (define_expand "sge"
12739   [(set (match_operand:QI 0 "register_operand" "")
12740         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12741   ""
12742   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12743
12744 (define_expand "sgeu"
12745   [(set (match_operand:QI 0 "register_operand" "")
12746         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747   ""
12748   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12749
12750 (define_expand "sle"
12751   [(set (match_operand:QI 0 "register_operand" "")
12752         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12753   ""
12754   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12755
12756 (define_expand "sleu"
12757   [(set (match_operand:QI 0 "register_operand" "")
12758         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12759   ""
12760   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12761
12762 (define_expand "sunordered"
12763   [(set (match_operand:QI 0 "register_operand" "")
12764         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12765   "TARGET_80387 || TARGET_SSE"
12766   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12767
12768 (define_expand "sordered"
12769   [(set (match_operand:QI 0 "register_operand" "")
12770         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12771   "TARGET_80387"
12772   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12773
12774 (define_expand "suneq"
12775   [(set (match_operand:QI 0 "register_operand" "")
12776         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12777   "TARGET_80387 || TARGET_SSE"
12778   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12779
12780 (define_expand "sunge"
12781   [(set (match_operand:QI 0 "register_operand" "")
12782         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12783   "TARGET_80387 || TARGET_SSE"
12784   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12785
12786 (define_expand "sungt"
12787   [(set (match_operand:QI 0 "register_operand" "")
12788         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12789   "TARGET_80387 || TARGET_SSE"
12790   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12791
12792 (define_expand "sunle"
12793   [(set (match_operand:QI 0 "register_operand" "")
12794         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12795   "TARGET_80387 || TARGET_SSE"
12796   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12797
12798 (define_expand "sunlt"
12799   [(set (match_operand:QI 0 "register_operand" "")
12800         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12801   "TARGET_80387 || TARGET_SSE"
12802   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12803
12804 (define_expand "sltgt"
12805   [(set (match_operand:QI 0 "register_operand" "")
12806         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12807   "TARGET_80387 || TARGET_SSE"
12808   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12809
12810 (define_insn "*setcc_1"
12811   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812         (match_operator:QI 1 "ix86_comparison_operator"
12813           [(reg 17) (const_int 0)]))]
12814   ""
12815   "set%C1\t%0"
12816   [(set_attr "type" "setcc")
12817    (set_attr "mode" "QI")])
12818
12819 (define_insn "setcc_2"
12820   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12821         (match_operator:QI 1 "ix86_comparison_operator"
12822           [(reg 17) (const_int 0)]))]
12823   ""
12824   "set%C1\t%0"
12825   [(set_attr "type" "setcc")
12826    (set_attr "mode" "QI")])
12827
12828 ;; In general it is not safe to assume too much about CCmode registers,
12829 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12830 ;; conditions this is safe on x86, so help combine not create
12831 ;;
12832 ;;      seta    %al
12833 ;;      testb   %al, %al
12834 ;;      sete    %al
12835
12836 (define_split 
12837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12838         (ne:QI (match_operator 1 "ix86_comparison_operator"
12839                  [(reg 17) (const_int 0)])
12840             (const_int 0)))]
12841   ""
12842   [(set (match_dup 0) (match_dup 1))]
12843 {
12844   PUT_MODE (operands[1], QImode);
12845 })
12846
12847 (define_split 
12848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12849         (ne:QI (match_operator 1 "ix86_comparison_operator"
12850                  [(reg 17) (const_int 0)])
12851             (const_int 0)))]
12852   ""
12853   [(set (match_dup 0) (match_dup 1))]
12854 {
12855   PUT_MODE (operands[1], QImode);
12856 })
12857
12858 (define_split 
12859   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12860         (eq:QI (match_operator 1 "ix86_comparison_operator"
12861                  [(reg 17) (const_int 0)])
12862             (const_int 0)))]
12863   ""
12864   [(set (match_dup 0) (match_dup 1))]
12865 {
12866   rtx new_op1 = copy_rtx (operands[1]);
12867   operands[1] = new_op1;
12868   PUT_MODE (new_op1, QImode);
12869   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12870                                              GET_MODE (XEXP (new_op1, 0))));
12871
12872   /* Make sure that (a) the CCmode we have for the flags is strong
12873      enough for the reversed compare or (b) we have a valid FP compare.  */
12874   if (! ix86_comparison_operator (new_op1, VOIDmode))
12875     FAIL;
12876 })
12877
12878 (define_split 
12879   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12880         (eq:QI (match_operator 1 "ix86_comparison_operator"
12881                  [(reg 17) (const_int 0)])
12882             (const_int 0)))]
12883   ""
12884   [(set (match_dup 0) (match_dup 1))]
12885 {
12886   rtx new_op1 = copy_rtx (operands[1]);
12887   operands[1] = new_op1;
12888   PUT_MODE (new_op1, QImode);
12889   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12890                                              GET_MODE (XEXP (new_op1, 0))));
12891
12892   /* Make sure that (a) the CCmode we have for the flags is strong
12893      enough for the reversed compare or (b) we have a valid FP compare.  */
12894   if (! ix86_comparison_operator (new_op1, VOIDmode))
12895     FAIL;
12896 })
12897
12898 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12899 ;; subsequent logical operations are used to imitate conditional moves.
12900 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12901 ;; it directly.  Further holding this value in pseudo register might bring
12902 ;; problem in implicit normalization in spill code.
12903 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12904 ;; instructions after reload by splitting the conditional move patterns.
12905
12906 (define_insn "*sse_setccsf"
12907   [(set (match_operand:SF 0 "register_operand" "=x")
12908         (match_operator:SF 1 "sse_comparison_operator"
12909           [(match_operand:SF 2 "register_operand" "0")
12910            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12911   "TARGET_SSE && reload_completed"
12912   "cmp%D1ss\t{%3, %0|%0, %3}"
12913   [(set_attr "type" "ssecmp")
12914    (set_attr "mode" "SF")])
12915
12916 (define_insn "*sse_setccdf"
12917   [(set (match_operand:DF 0 "register_operand" "=Y")
12918         (match_operator:DF 1 "sse_comparison_operator"
12919           [(match_operand:DF 2 "register_operand" "0")
12920            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12921   "TARGET_SSE2 && reload_completed"
12922   "cmp%D1sd\t{%3, %0|%0, %3}"
12923   [(set_attr "type" "ssecmp")
12924    (set_attr "mode" "DF")])
12925 \f
12926 ;; Basic conditional jump instructions.
12927 ;; We ignore the overflow flag for signed branch instructions.
12928
12929 ;; For all bCOND expanders, also expand the compare or test insn that
12930 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12931
12932 (define_expand "beq"
12933   [(set (pc)
12934         (if_then_else (match_dup 1)
12935                       (label_ref (match_operand 0 "" ""))
12936                       (pc)))]
12937   ""
12938   "ix86_expand_branch (EQ, operands[0]); DONE;")
12939
12940 (define_expand "bne"
12941   [(set (pc)
12942         (if_then_else (match_dup 1)
12943                       (label_ref (match_operand 0 "" ""))
12944                       (pc)))]
12945   ""
12946   "ix86_expand_branch (NE, operands[0]); DONE;")
12947
12948 (define_expand "bgt"
12949   [(set (pc)
12950         (if_then_else (match_dup 1)
12951                       (label_ref (match_operand 0 "" ""))
12952                       (pc)))]
12953   ""
12954   "ix86_expand_branch (GT, operands[0]); DONE;")
12955
12956 (define_expand "bgtu"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (GTU, operands[0]); DONE;")
12963
12964 (define_expand "blt"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (LT, operands[0]); DONE;")
12971
12972 (define_expand "bltu"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "ix86_expand_branch (LTU, operands[0]); DONE;")
12979
12980 (define_expand "bge"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   ""
12986   "ix86_expand_branch (GE, operands[0]); DONE;")
12987
12988 (define_expand "bgeu"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   ""
12994   "ix86_expand_branch (GEU, operands[0]); DONE;")
12995
12996 (define_expand "ble"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   ""
13002   "ix86_expand_branch (LE, operands[0]); DONE;")
13003
13004 (define_expand "bleu"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   ""
13010   "ix86_expand_branch (LEU, operands[0]); DONE;")
13011
13012 (define_expand "bunordered"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   "TARGET_80387 || TARGET_SSE"
13018   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13019
13020 (define_expand "bordered"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   "TARGET_80387 || TARGET_SSE"
13026   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13027
13028 (define_expand "buneq"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   "TARGET_80387 || TARGET_SSE"
13034   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13035
13036 (define_expand "bunge"
13037   [(set (pc)
13038         (if_then_else (match_dup 1)
13039                       (label_ref (match_operand 0 "" ""))
13040                       (pc)))]
13041   "TARGET_80387 || TARGET_SSE"
13042   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13043
13044 (define_expand "bungt"
13045   [(set (pc)
13046         (if_then_else (match_dup 1)
13047                       (label_ref (match_operand 0 "" ""))
13048                       (pc)))]
13049   "TARGET_80387 || TARGET_SSE"
13050   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13051
13052 (define_expand "bunle"
13053   [(set (pc)
13054         (if_then_else (match_dup 1)
13055                       (label_ref (match_operand 0 "" ""))
13056                       (pc)))]
13057   "TARGET_80387 || TARGET_SSE"
13058   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13059
13060 (define_expand "bunlt"
13061   [(set (pc)
13062         (if_then_else (match_dup 1)
13063                       (label_ref (match_operand 0 "" ""))
13064                       (pc)))]
13065   "TARGET_80387 || TARGET_SSE"
13066   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13067
13068 (define_expand "bltgt"
13069   [(set (pc)
13070         (if_then_else (match_dup 1)
13071                       (label_ref (match_operand 0 "" ""))
13072                       (pc)))]
13073   "TARGET_80387 || TARGET_SSE"
13074   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13075
13076 (define_insn "*jcc_1"
13077   [(set (pc)
13078         (if_then_else (match_operator 1 "ix86_comparison_operator"
13079                                       [(reg 17) (const_int 0)])
13080                       (label_ref (match_operand 0 "" ""))
13081                       (pc)))]
13082   ""
13083   "%+j%C1\t%l0"
13084   [(set_attr "type" "ibr")
13085    (set_attr "modrm" "0")
13086    (set (attr "length")
13087            (if_then_else (and (ge (minus (match_dup 0) (pc))
13088                                   (const_int -126))
13089                               (lt (minus (match_dup 0) (pc))
13090                                   (const_int 128)))
13091              (const_int 2)
13092              (const_int 6)))])
13093
13094 (define_insn "*jcc_2"
13095   [(set (pc)
13096         (if_then_else (match_operator 1 "ix86_comparison_operator"
13097                                       [(reg 17) (const_int 0)])
13098                       (pc)
13099                       (label_ref (match_operand 0 "" ""))))]
13100   ""
13101   "%+j%c1\t%l0"
13102   [(set_attr "type" "ibr")
13103    (set_attr "modrm" "0")
13104    (set (attr "length")
13105            (if_then_else (and (ge (minus (match_dup 0) (pc))
13106                                   (const_int -126))
13107                               (lt (minus (match_dup 0) (pc))
13108                                   (const_int 128)))
13109              (const_int 2)
13110              (const_int 6)))])
13111
13112 ;; In general it is not safe to assume too much about CCmode registers,
13113 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13114 ;; conditions this is safe on x86, so help combine not create
13115 ;;
13116 ;;      seta    %al
13117 ;;      testb   %al, %al
13118 ;;      je      Lfoo
13119
13120 (define_split 
13121   [(set (pc)
13122         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13123                                       [(reg 17) (const_int 0)])
13124                           (const_int 0))
13125                       (label_ref (match_operand 1 "" ""))
13126                       (pc)))]
13127   ""
13128   [(set (pc)
13129         (if_then_else (match_dup 0)
13130                       (label_ref (match_dup 1))
13131                       (pc)))]
13132 {
13133   PUT_MODE (operands[0], VOIDmode);
13134 })
13135   
13136 (define_split 
13137   [(set (pc)
13138         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13139                                       [(reg 17) (const_int 0)])
13140                           (const_int 0))
13141                       (label_ref (match_operand 1 "" ""))
13142                       (pc)))]
13143   ""
13144   [(set (pc)
13145         (if_then_else (match_dup 0)
13146                       (label_ref (match_dup 1))
13147                       (pc)))]
13148 {
13149   rtx new_op0 = copy_rtx (operands[0]);
13150   operands[0] = new_op0;
13151   PUT_MODE (new_op0, VOIDmode);
13152   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13153                                              GET_MODE (XEXP (new_op0, 0))));
13154
13155   /* Make sure that (a) the CCmode we have for the flags is strong
13156      enough for the reversed compare or (b) we have a valid FP compare.  */
13157   if (! ix86_comparison_operator (new_op0, VOIDmode))
13158     FAIL;
13159 })
13160
13161 ;; Define combination compare-and-branch fp compare instructions to use
13162 ;; during early optimization.  Splitting the operation apart early makes
13163 ;; for bad code when we want to reverse the operation.
13164
13165 (define_insn "*fp_jcc_1"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "register_operand" "f")])
13170           (label_ref (match_operand 3 "" ""))
13171           (pc)))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))]
13174   "TARGET_CMOVE && TARGET_80387
13175    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13176    && FLOAT_MODE_P (GET_MODE (operands[1]))
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13179   "#")
13180
13181 (define_insn "*fp_jcc_1_sse"
13182   [(set (pc)
13183         (if_then_else (match_operator 0 "comparison_operator"
13184                         [(match_operand 1 "register_operand" "f#x,x#f")
13185                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13186           (label_ref (match_operand 3 "" ""))
13187           (pc)))
13188    (clobber (reg:CCFP FPSR_REG))
13189    (clobber (reg:CCFP FLAGS_REG))]
13190   "TARGET_80387
13191    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13192    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13193    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13194   "#")
13195
13196 (define_insn "*fp_jcc_1_sse_only"
13197   [(set (pc)
13198         (if_then_else (match_operator 0 "comparison_operator"
13199                         [(match_operand 1 "register_operand" "x")
13200                          (match_operand 2 "nonimmediate_operand" "xm")])
13201           (label_ref (match_operand 3 "" ""))
13202           (pc)))
13203    (clobber (reg:CCFP FPSR_REG))
13204    (clobber (reg:CCFP FLAGS_REG))]
13205   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208   "#")
13209
13210 (define_insn "*fp_jcc_2"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "register_operand" "f")])
13215           (pc)
13216           (label_ref (match_operand 3 "" ""))))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))]
13219   "TARGET_CMOVE && TARGET_80387
13220    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13221    && FLOAT_MODE_P (GET_MODE (operands[1]))
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13224   "#")
13225
13226 (define_insn "*fp_jcc_2_sse"
13227   [(set (pc)
13228         (if_then_else (match_operator 0 "comparison_operator"
13229                         [(match_operand 1 "register_operand" "f#x,x#f")
13230                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13231           (pc)
13232           (label_ref (match_operand 3 "" ""))))
13233    (clobber (reg:CCFP FPSR_REG))
13234    (clobber (reg:CCFP FLAGS_REG))]
13235   "TARGET_80387
13236    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13238    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13239   "#")
13240
13241 (define_insn "*fp_jcc_2_sse_only"
13242   [(set (pc)
13243         (if_then_else (match_operator 0 "comparison_operator"
13244                         [(match_operand 1 "register_operand" "x")
13245                          (match_operand 2 "nonimmediate_operand" "xm")])
13246           (pc)
13247           (label_ref (match_operand 3 "" ""))))
13248    (clobber (reg:CCFP FPSR_REG))
13249    (clobber (reg:CCFP FLAGS_REG))]
13250   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13251    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13252    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13253   "#")
13254
13255 (define_insn "*fp_jcc_3"
13256   [(set (pc)
13257         (if_then_else (match_operator 0 "comparison_operator"
13258                         [(match_operand 1 "register_operand" "f")
13259                          (match_operand 2 "nonimmediate_operand" "fm")])
13260           (label_ref (match_operand 3 "" ""))
13261           (pc)))
13262    (clobber (reg:CCFP FPSR_REG))
13263    (clobber (reg:CCFP FLAGS_REG))
13264    (clobber (match_scratch:HI 4 "=a"))]
13265   "TARGET_80387
13266    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13267    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13268    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13269    && SELECT_CC_MODE (GET_CODE (operands[0]),
13270                       operands[1], operands[2]) == CCFPmode
13271    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13272   "#")
13273
13274 (define_insn "*fp_jcc_4"
13275   [(set (pc)
13276         (if_then_else (match_operator 0 "comparison_operator"
13277                         [(match_operand 1 "register_operand" "f")
13278                          (match_operand 2 "nonimmediate_operand" "fm")])
13279           (pc)
13280           (label_ref (match_operand 3 "" ""))))
13281    (clobber (reg:CCFP FPSR_REG))
13282    (clobber (reg:CCFP FLAGS_REG))
13283    (clobber (match_scratch:HI 4 "=a"))]
13284   "TARGET_80387
13285    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13286    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13287    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13288    && SELECT_CC_MODE (GET_CODE (operands[0]),
13289                       operands[1], operands[2]) == CCFPmode
13290    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13291   "#")
13292
13293 (define_insn "*fp_jcc_5"
13294   [(set (pc)
13295         (if_then_else (match_operator 0 "comparison_operator"
13296                         [(match_operand 1 "register_operand" "f")
13297                          (match_operand 2 "register_operand" "f")])
13298           (label_ref (match_operand 3 "" ""))
13299           (pc)))
13300    (clobber (reg:CCFP FPSR_REG))
13301    (clobber (reg:CCFP FLAGS_REG))
13302    (clobber (match_scratch:HI 4 "=a"))]
13303   "TARGET_80387
13304    && FLOAT_MODE_P (GET_MODE (operands[1]))
13305    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13306    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13307   "#")
13308
13309 (define_insn "*fp_jcc_6"
13310   [(set (pc)
13311         (if_then_else (match_operator 0 "comparison_operator"
13312                         [(match_operand 1 "register_operand" "f")
13313                          (match_operand 2 "register_operand" "f")])
13314           (pc)
13315           (label_ref (match_operand 3 "" ""))))
13316    (clobber (reg:CCFP FPSR_REG))
13317    (clobber (reg:CCFP FLAGS_REG))
13318    (clobber (match_scratch:HI 4 "=a"))]
13319   "TARGET_80387
13320    && FLOAT_MODE_P (GET_MODE (operands[1]))
13321    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13322    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13323   "#")
13324
13325 (define_split
13326   [(set (pc)
13327         (if_then_else (match_operator 0 "comparison_operator"
13328                         [(match_operand 1 "register_operand" "")
13329                          (match_operand 2 "nonimmediate_operand" "")])
13330           (match_operand 3 "" "")
13331           (match_operand 4 "" "")))
13332    (clobber (reg:CCFP FPSR_REG))
13333    (clobber (reg:CCFP FLAGS_REG))]
13334   "reload_completed"
13335   [(const_int 0)]
13336 {
13337   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13338                         operands[3], operands[4], NULL_RTX);
13339   DONE;
13340 })
13341
13342 (define_split
13343   [(set (pc)
13344         (if_then_else (match_operator 0 "comparison_operator"
13345                         [(match_operand 1 "register_operand" "")
13346                          (match_operand 2 "nonimmediate_operand" "")])
13347           (match_operand 3 "" "")
13348           (match_operand 4 "" "")))
13349    (clobber (reg:CCFP FPSR_REG))
13350    (clobber (reg:CCFP FLAGS_REG))
13351    (clobber (match_scratch:HI 5 "=a"))]
13352   "reload_completed"
13353   [(set (pc)
13354         (if_then_else (match_dup 6)
13355           (match_dup 3)
13356           (match_dup 4)))]
13357 {
13358   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13359                         operands[3], operands[4], operands[5]);
13360   DONE;
13361 })
13362 \f
13363 ;; Unconditional and other jump instructions
13364
13365 (define_insn "jump"
13366   [(set (pc)
13367         (label_ref (match_operand 0 "" "")))]
13368   ""
13369   "jmp\t%l0"
13370   [(set_attr "type" "ibr")
13371    (set (attr "length")
13372            (if_then_else (and (ge (minus (match_dup 0) (pc))
13373                                   (const_int -126))
13374                               (lt (minus (match_dup 0) (pc))
13375                                   (const_int 128)))
13376              (const_int 2)
13377              (const_int 5)))
13378    (set_attr "modrm" "0")])
13379
13380 (define_expand "indirect_jump"
13381   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13382   ""
13383   "")
13384
13385 (define_insn "*indirect_jump"
13386   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13387   "!TARGET_64BIT"
13388   "jmp\t%A0"
13389   [(set_attr "type" "ibr")
13390    (set_attr "length_immediate" "0")])
13391
13392 (define_insn "*indirect_jump_rtx64"
13393   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13394   "TARGET_64BIT"
13395   "jmp\t%A0"
13396   [(set_attr "type" "ibr")
13397    (set_attr "length_immediate" "0")])
13398
13399 (define_expand "tablejump"
13400   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13401               (use (label_ref (match_operand 1 "" "")))])]
13402   ""
13403 {
13404   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13405      relative.  Convert the relative address to an absolute address.  */
13406   if (flag_pic)
13407     {
13408       rtx op0, op1;
13409       enum rtx_code code;
13410
13411       if (TARGET_64BIT)
13412         {
13413           code = PLUS;
13414           op0 = operands[0];
13415           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13416         }
13417       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13418         {
13419           code = PLUS;
13420           op0 = operands[0];
13421           op1 = pic_offset_table_rtx;
13422         }
13423       else
13424         {
13425           code = MINUS;
13426           op0 = pic_offset_table_rtx;
13427           op1 = operands[0];
13428         }
13429
13430       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13431                                          OPTAB_DIRECT);
13432     }
13433 })
13434
13435 (define_insn "*tablejump_1"
13436   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13437    (use (label_ref (match_operand 1 "" "")))]
13438   "!TARGET_64BIT"
13439   "jmp\t%A0"
13440   [(set_attr "type" "ibr")
13441    (set_attr "length_immediate" "0")])
13442
13443 (define_insn "*tablejump_1_rtx64"
13444   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13445    (use (label_ref (match_operand 1 "" "")))]
13446   "TARGET_64BIT"
13447   "jmp\t%A0"
13448   [(set_attr "type" "ibr")
13449    (set_attr "length_immediate" "0")])
13450 \f
13451 ;; Loop instruction
13452 ;;
13453 ;; This is all complicated by the fact that since this is a jump insn
13454 ;; we must handle our own reloads.
13455
13456 (define_expand "doloop_end"
13457   [(use (match_operand 0 "" ""))        ; loop pseudo
13458    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13459    (use (match_operand 2 "" ""))        ; max iterations
13460    (use (match_operand 3 "" ""))        ; loop level 
13461    (use (match_operand 4 "" ""))]       ; label
13462   "!TARGET_64BIT && TARGET_USE_LOOP"
13463   "                                 
13464 {
13465   /* Only use cloop on innermost loops.  */
13466   if (INTVAL (operands[3]) > 1)
13467     FAIL;
13468   if (GET_MODE (operands[0]) != SImode)
13469     FAIL;
13470   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13471                                            operands[0]));
13472   DONE;
13473 }")
13474
13475 (define_insn "doloop_end_internal"
13476   [(set (pc)
13477         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13478                           (const_int 1))
13479                       (label_ref (match_operand 0 "" ""))
13480                       (pc)))
13481    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13482         (plus:SI (match_dup 1)
13483                  (const_int -1)))
13484    (clobber (match_scratch:SI 3 "=X,X,r"))
13485    (clobber (reg:CC FLAGS_REG))]
13486   "!TARGET_64BIT && TARGET_USE_LOOP
13487    && (reload_in_progress || reload_completed
13488        || register_operand (operands[2], VOIDmode))"
13489 {
13490   if (which_alternative != 0)
13491     return "#";
13492   if (get_attr_length (insn) == 2)
13493     return "%+loop\t%l0";
13494   else
13495     return "dec{l}\t%1\;%+jne\t%l0";
13496 }
13497   [(set (attr "length")
13498         (if_then_else (and (eq_attr "alternative" "0")
13499                            (and (ge (minus (match_dup 0) (pc))
13500                                     (const_int -126))
13501                                 (lt (minus (match_dup 0) (pc))
13502                                     (const_int 128))))
13503                       (const_int 2)
13504                       (const_int 16)))
13505    ;; We don't know the type before shorten branches.  Optimistically expect
13506    ;; the loop instruction to match.
13507    (set (attr "type") (const_string "ibr"))])
13508
13509 (define_split
13510   [(set (pc)
13511         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13512                           (const_int 1))
13513                       (match_operand 0 "" "")
13514                       (pc)))
13515    (set (match_dup 1)
13516         (plus:SI (match_dup 1)
13517                  (const_int -1)))
13518    (clobber (match_scratch:SI 2 ""))
13519    (clobber (reg:CC FLAGS_REG))]
13520   "!TARGET_64BIT && TARGET_USE_LOOP
13521    && reload_completed
13522    && REGNO (operands[1]) != 2"
13523   [(parallel [(set (reg:CCZ FLAGS_REG)
13524                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13525                                  (const_int 0)))
13526               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13527    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13528                            (match_dup 0)
13529                            (pc)))]
13530   "")
13531   
13532 (define_split
13533   [(set (pc)
13534         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13535                           (const_int 1))
13536                       (match_operand 0 "" "")
13537                       (pc)))
13538    (set (match_operand:SI 2 "nonimmediate_operand" "")
13539         (plus:SI (match_dup 1)
13540                  (const_int -1)))
13541    (clobber (match_scratch:SI 3 ""))
13542    (clobber (reg:CC FLAGS_REG))]
13543   "!TARGET_64BIT && TARGET_USE_LOOP
13544    && reload_completed
13545    && (! REG_P (operands[2])
13546        || ! rtx_equal_p (operands[1], operands[2]))"
13547   [(set (match_dup 3) (match_dup 1))
13548    (parallel [(set (reg:CCZ FLAGS_REG)
13549                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13550                                 (const_int 0)))
13551               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13552    (set (match_dup 2) (match_dup 3))
13553    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13554                            (match_dup 0)
13555                            (pc)))]
13556   "")
13557
13558 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13559
13560 (define_peephole2
13561   [(set (reg 17) (match_operand 0 "" ""))
13562    (set (match_operand:QI 1 "register_operand" "")
13563         (match_operator:QI 2 "ix86_comparison_operator"
13564           [(reg 17) (const_int 0)]))
13565    (set (match_operand 3 "q_regs_operand" "")
13566         (zero_extend (match_dup 1)))]
13567   "(peep2_reg_dead_p (3, operands[1])
13568     || operands_match_p (operands[1], operands[3]))
13569    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13570   [(set (match_dup 4) (match_dup 0))
13571    (set (strict_low_part (match_dup 5))
13572         (match_dup 2))]
13573 {
13574   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13575   operands[5] = gen_lowpart (QImode, operands[3]);
13576   ix86_expand_clear (operands[3]);
13577 })
13578
13579 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13580
13581 (define_peephole2
13582   [(set (reg 17) (match_operand 0 "" ""))
13583    (set (match_operand:QI 1 "register_operand" "")
13584         (match_operator:QI 2 "ix86_comparison_operator"
13585           [(reg 17) (const_int 0)]))
13586    (parallel [(set (match_operand 3 "q_regs_operand" "")
13587                    (zero_extend (match_dup 1)))
13588               (clobber (reg:CC FLAGS_REG))])]
13589   "(peep2_reg_dead_p (3, operands[1])
13590     || operands_match_p (operands[1], operands[3]))
13591    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13592   [(set (match_dup 4) (match_dup 0))
13593    (set (strict_low_part (match_dup 5))
13594         (match_dup 2))]
13595 {
13596   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13597   operands[5] = gen_lowpart (QImode, operands[3]);
13598   ix86_expand_clear (operands[3]);
13599 })
13600 \f
13601 ;; Call instructions.
13602
13603 ;; The predicates normally associated with named expanders are not properly
13604 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13605 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13606
13607 ;; Call subroutine returning no value.
13608
13609 (define_expand "call_pop"
13610   [(parallel [(call (match_operand:QI 0 "" "")
13611                     (match_operand:SI 1 "" ""))
13612               (set (reg:SI SP_REG)
13613                    (plus:SI (reg:SI SP_REG)
13614                             (match_operand:SI 3 "" "")))])]
13615   "!TARGET_64BIT"
13616 {
13617   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13618   DONE;
13619 })
13620
13621 (define_insn "*call_pop_0"
13622   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13623          (match_operand:SI 1 "" ""))
13624    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13625                             (match_operand:SI 2 "immediate_operand" "")))]
13626   "!TARGET_64BIT"
13627 {
13628   if (SIBLING_CALL_P (insn))
13629     return "jmp\t%P0";
13630   else
13631     return "call\t%P0";
13632 }
13633   [(set_attr "type" "call")])
13634   
13635 (define_insn "*call_pop_1"
13636   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637          (match_operand:SI 1 "" ""))
13638    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13639                             (match_operand:SI 2 "immediate_operand" "i")))]
13640   "!TARGET_64BIT"
13641 {
13642   if (constant_call_address_operand (operands[0], Pmode))
13643     {
13644       if (SIBLING_CALL_P (insn))
13645         return "jmp\t%P0";
13646       else
13647         return "call\t%P0";
13648     }
13649   if (SIBLING_CALL_P (insn))
13650     return "jmp\t%A0";
13651   else
13652     return "call\t%A0";
13653 }
13654   [(set_attr "type" "call")])
13655
13656 (define_expand "call"
13657   [(call (match_operand:QI 0 "" "")
13658          (match_operand 1 "" ""))
13659    (use (match_operand 2 "" ""))]
13660   ""
13661 {
13662   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13663   DONE;
13664 })
13665
13666 (define_expand "sibcall"
13667   [(call (match_operand:QI 0 "" "")
13668          (match_operand 1 "" ""))
13669    (use (match_operand 2 "" ""))]
13670   ""
13671 {
13672   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13673   DONE;
13674 })
13675
13676 (define_insn "*call_0"
13677   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13678          (match_operand 1 "" ""))]
13679   ""
13680 {
13681   if (SIBLING_CALL_P (insn))
13682     return "jmp\t%P0";
13683   else
13684     return "call\t%P0";
13685 }
13686   [(set_attr "type" "call")])
13687
13688 (define_insn "*call_1"
13689   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13690          (match_operand 1 "" ""))]
13691   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13692 {
13693   if (constant_call_address_operand (operands[0], Pmode))
13694     return "call\t%P0";
13695   return "call\t%A0";
13696 }
13697   [(set_attr "type" "call")])
13698
13699 (define_insn "*sibcall_1"
13700   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13701          (match_operand 1 "" ""))]
13702   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13703 {
13704   if (constant_call_address_operand (operands[0], Pmode))
13705     return "jmp\t%P0";
13706   return "jmp\t%A0";
13707 }
13708   [(set_attr "type" "call")])
13709
13710 (define_insn "*call_1_rex64"
13711   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13712          (match_operand 1 "" ""))]
13713   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13714 {
13715   if (constant_call_address_operand (operands[0], Pmode))
13716     return "call\t%P0";
13717   return "call\t%A0";
13718 }
13719   [(set_attr "type" "call")])
13720
13721 (define_insn "*sibcall_1_rex64"
13722   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13723          (match_operand 1 "" ""))]
13724   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13725   "jmp\t%P0"
13726   [(set_attr "type" "call")])
13727
13728 (define_insn "*sibcall_1_rex64_v"
13729   [(call (mem:QI (reg:DI 40))
13730          (match_operand 0 "" ""))]
13731   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13732   "jmp\t*%%r11"
13733   [(set_attr "type" "call")])
13734
13735
13736 ;; Call subroutine, returning value in operand 0
13737
13738 (define_expand "call_value_pop"
13739   [(parallel [(set (match_operand 0 "" "")
13740                    (call (match_operand:QI 1 "" "")
13741                          (match_operand:SI 2 "" "")))
13742               (set (reg:SI SP_REG)
13743                    (plus:SI (reg:SI SP_REG)
13744                             (match_operand:SI 4 "" "")))])]
13745   "!TARGET_64BIT"
13746 {
13747   ix86_expand_call (operands[0], operands[1], operands[2],
13748                     operands[3], operands[4], 0);
13749   DONE;
13750 })
13751
13752 (define_expand "call_value"
13753   [(set (match_operand 0 "" "")
13754         (call (match_operand:QI 1 "" "")
13755               (match_operand:SI 2 "" "")))
13756    (use (match_operand:SI 3 "" ""))]
13757   ;; Operand 2 not used on the i386.
13758   ""
13759 {
13760   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13761   DONE;
13762 })
13763
13764 (define_expand "sibcall_value"
13765   [(set (match_operand 0 "" "")
13766         (call (match_operand:QI 1 "" "")
13767               (match_operand:SI 2 "" "")))
13768    (use (match_operand:SI 3 "" ""))]
13769   ;; Operand 2 not used on the i386.
13770   ""
13771 {
13772   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13773   DONE;
13774 })
13775
13776 ;; Call subroutine returning any type.
13777
13778 (define_expand "untyped_call"
13779   [(parallel [(call (match_operand 0 "" "")
13780                     (const_int 0))
13781               (match_operand 1 "" "")
13782               (match_operand 2 "" "")])]
13783   ""
13784 {
13785   int i;
13786
13787   /* In order to give reg-stack an easier job in validating two
13788      coprocessor registers as containing a possible return value,
13789      simply pretend the untyped call returns a complex long double
13790      value.  */
13791
13792   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13793                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13794                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13795                     NULL, 0);
13796
13797   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13798     {
13799       rtx set = XVECEXP (operands[2], 0, i);
13800       emit_move_insn (SET_DEST (set), SET_SRC (set));
13801     }
13802
13803   /* The optimizer does not know that the call sets the function value
13804      registers we stored in the result block.  We avoid problems by
13805      claiming that all hard registers are used and clobbered at this
13806      point.  */
13807   emit_insn (gen_blockage (const0_rtx));
13808
13809   DONE;
13810 })
13811 \f
13812 ;; Prologue and epilogue instructions
13813
13814 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13815 ;; all of memory.  This blocks insns from being moved across this point.
13816
13817 (define_insn "blockage"
13818   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13819   ""
13820   ""
13821   [(set_attr "length" "0")])
13822
13823 ;; Insn emitted into the body of a function to return from a function.
13824 ;; This is only done if the function's epilogue is known to be simple.
13825 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13826
13827 (define_expand "return"
13828   [(return)]
13829   "ix86_can_use_return_insn_p ()"
13830 {
13831   if (current_function_pops_args)
13832     {
13833       rtx popc = GEN_INT (current_function_pops_args);
13834       emit_jump_insn (gen_return_pop_internal (popc));
13835       DONE;
13836     }
13837 })
13838
13839 (define_insn "return_internal"
13840   [(return)]
13841   "reload_completed"
13842   "ret"
13843   [(set_attr "length" "1")
13844    (set_attr "length_immediate" "0")
13845    (set_attr "modrm" "0")])
13846
13847 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13848 ;; instruction Athlon and K8 have.
13849
13850 (define_insn "return_internal_long"
13851   [(return)
13852    (unspec [(const_int 0)] UNSPEC_REP)]
13853   "reload_completed"
13854   "rep {;} ret"
13855   [(set_attr "length" "1")
13856    (set_attr "length_immediate" "0")
13857    (set_attr "prefix_rep" "1")
13858    (set_attr "modrm" "0")])
13859
13860 (define_insn "return_pop_internal"
13861   [(return)
13862    (use (match_operand:SI 0 "const_int_operand" ""))]
13863   "reload_completed"
13864   "ret\t%0"
13865   [(set_attr "length" "3")
13866    (set_attr "length_immediate" "2")
13867    (set_attr "modrm" "0")])
13868
13869 (define_insn "return_indirect_internal"
13870   [(return)
13871    (use (match_operand:SI 0 "register_operand" "r"))]
13872   "reload_completed"
13873   "jmp\t%A0"
13874   [(set_attr "type" "ibr")
13875    (set_attr "length_immediate" "0")])
13876
13877 (define_insn "nop"
13878   [(const_int 0)]
13879   ""
13880   "nop"
13881   [(set_attr "length" "1")
13882    (set_attr "length_immediate" "0")
13883    (set_attr "modrm" "0")])
13884
13885 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13886 ;; branch prediction penalty for the third jump in a 16-byte
13887 ;; block on K8.
13888
13889 (define_insn "align"
13890   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13891   ""
13892 {
13893 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13894   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13895 #else
13896   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13897      The align insn is used to avoid 3 jump instructions in the row to improve
13898      branch prediction and the benefits hardly outweight the cost of extra 8
13899      nops on the average inserted by full alignment pseudo operation.  */
13900 #endif
13901   return "";
13902 }
13903   [(set_attr "length" "16")])
13904
13905 (define_expand "prologue"
13906   [(const_int 1)]
13907   ""
13908   "ix86_expand_prologue (); DONE;")
13909
13910 (define_insn "set_got"
13911   [(set (match_operand:SI 0 "register_operand" "=r")
13912         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13913    (clobber (reg:CC FLAGS_REG))]
13914   "!TARGET_64BIT"
13915   { return output_set_got (operands[0]); }
13916   [(set_attr "type" "multi")
13917    (set_attr "length" "12")])
13918
13919 (define_expand "epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (1); DONE;")
13923
13924 (define_expand "sibcall_epilogue"
13925   [(const_int 1)]
13926   ""
13927   "ix86_expand_epilogue (0); DONE;")
13928
13929 (define_expand "eh_return"
13930   [(use (match_operand 0 "register_operand" ""))]
13931   ""
13932 {
13933   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13934
13935   /* Tricky bit: we write the address of the handler to which we will
13936      be returning into someone else's stack frame, one word below the
13937      stack address we wish to restore.  */
13938   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940   tmp = gen_rtx_MEM (Pmode, tmp);
13941   emit_move_insn (tmp, ra);
13942
13943   if (Pmode == SImode)
13944     emit_jump_insn (gen_eh_return_si (sa));
13945   else
13946     emit_jump_insn (gen_eh_return_di (sa));
13947   emit_barrier ();
13948   DONE;
13949 })
13950
13951 (define_insn_and_split "eh_return_si"
13952   [(set (pc) 
13953         (unspec [(match_operand:SI 0 "register_operand" "c")]
13954                  UNSPEC_EH_RETURN))]
13955   "!TARGET_64BIT"
13956   "#"
13957   "reload_completed"
13958   [(const_int 1)]
13959   "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn_and_split "eh_return_di"
13962   [(set (pc) 
13963         (unspec [(match_operand:DI 0 "register_operand" "c")]
13964                  UNSPEC_EH_RETURN))]
13965   "TARGET_64BIT"
13966   "#"
13967   "reload_completed"
13968   [(const_int 1)]
13969   "ix86_expand_epilogue (2); DONE;")
13970
13971 (define_insn "leave"
13972   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974    (clobber (mem:BLK (scratch)))]
13975   "!TARGET_64BIT"
13976   "leave"
13977   [(set_attr "type" "leave")])
13978
13979 (define_insn "leave_rex64"
13980   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982    (clobber (mem:BLK (scratch)))]
13983   "TARGET_64BIT"
13984   "leave"
13985   [(set_attr "type" "leave")])
13986 \f
13987 (define_expand "ffssi2"
13988   [(parallel
13989      [(set (match_operand:SI 0 "register_operand" "") 
13990            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991       (clobber (match_scratch:SI 2 ""))
13992       (clobber (reg:CC FLAGS_REG))])]
13993   ""
13994   "")
13995
13996 (define_insn_and_split "*ffs_cmove"
13997   [(set (match_operand:SI 0 "register_operand" "=r") 
13998         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999    (clobber (match_scratch:SI 2 "=&r"))
14000    (clobber (reg:CC FLAGS_REG))]
14001   "TARGET_CMOVE"
14002   "#"
14003   "&& reload_completed"
14004   [(set (match_dup 2) (const_int -1))
14005    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007    (set (match_dup 0) (if_then_else:SI
14008                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009                         (match_dup 2)
14010                         (match_dup 0)))
14011    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012               (clobber (reg:CC FLAGS_REG))])]
14013   "")
14014
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   ""
14021   "#"
14022   "reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025    (set (strict_low_part (match_dup 3))
14026         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030               (clobber (reg:CC FLAGS_REG))])
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033 {
14034   operands[3] = gen_lowpart (QImode, operands[2]);
14035   ix86_expand_clear (operands[2]);
14036 })
14037
14038 (define_insn "*ffssi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:SI 0 "register_operand" "=r")
14043         (ctz:SI (match_dup 1)))]
14044   ""
14045   "bsf{l}\t{%1, %0|%0, %1}"
14046   [(set_attr "prefix_0f" "1")])
14047
14048 (define_expand "ffsdi2"
14049   [(parallel
14050      [(set (match_operand:DI 0 "register_operand" "") 
14051            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052       (clobber (match_scratch:DI 2 ""))
14053       (clobber (reg:CC 17))])]
14054   "TARGET_64BIT && TARGET_CMOVE"
14055   "")
14056
14057 (define_insn_and_split "*ffs_rex64"
14058   [(set (match_operand:DI 0 "register_operand" "=r") 
14059         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060    (clobber (match_scratch:DI 2 "=&r"))
14061    (clobber (reg:CC 17))]
14062   "TARGET_64BIT && TARGET_CMOVE"
14063   "#"
14064   "&& reload_completed"
14065   [(set (match_dup 2) (const_int -1))
14066    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14067               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14068    (set (match_dup 0) (if_then_else:DI
14069                         (eq (reg:CCZ 17) (const_int 0))
14070                         (match_dup 2)
14071                         (match_dup 0)))
14072    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14073               (clobber (reg:CC 17))])]
14074   "")
14075
14076 (define_insn "*ffsdi_1"
14077   [(set (reg:CCZ 17)
14078         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14079                      (const_int 0)))
14080    (set (match_operand:DI 0 "register_operand" "=r")
14081         (ctz:DI (match_dup 1)))]
14082   "TARGET_64BIT"
14083   "bsf{q}\t{%1, %0|%0, %1}"
14084   [(set_attr "prefix_0f" "1")])
14085
14086 (define_insn "ctzsi2"
14087   [(set (match_operand:SI 0 "register_operand" "=r")
14088         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsf{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14093
14094 (define_insn "ctzdi2"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14097    (clobber (reg:CC 17))]
14098   "TARGET_64BIT"
14099   "bsf{q}\t{%1, %0|%0, %1}"
14100   [(set_attr "prefix_0f" "1")])
14101
14102 (define_expand "clzsi2"
14103   [(parallel
14104      [(set (match_operand:SI 0 "register_operand" "")
14105            (minus:SI (const_int 31)
14106                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107       (clobber (reg:CC FLAGS_REG))])
14108    (parallel
14109      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110       (clobber (reg:CC FLAGS_REG))])]
14111   ""
14112   "")
14113
14114 (define_insn "*bsr"
14115   [(set (match_operand:SI 0 "register_operand" "=r")
14116         (minus:SI (const_int 31)
14117                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118    (clobber (reg:CC FLAGS_REG))]
14119   ""
14120   "bsr{l}\t{%1, %0|%0, %1}"
14121   [(set_attr "prefix_0f" "1")])
14122
14123 (define_expand "clzdi2"
14124   [(parallel
14125      [(set (match_operand:DI 0 "register_operand" "")
14126            (minus:DI (const_int 63)
14127                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14128       (clobber (reg:CC 17))])
14129    (parallel
14130      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14131       (clobber (reg:CC 17))])]
14132   "TARGET_64BIT"
14133   "")
14134
14135 (define_insn "*bsr_rex64"
14136   [(set (match_operand:DI 0 "register_operand" "=r")
14137         (minus:DI (const_int 63)
14138                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14139    (clobber (reg:CC 17))]
14140   "TARGET_64BIT"
14141   "bsr{q}\t{%1, %0|%0, %1}"
14142   [(set_attr "prefix_0f" "1")])
14143 \f
14144 ;; Thread-local storage patterns for ELF.
14145 ;;
14146 ;; Note that these code sequences must appear exactly as shown
14147 ;; in order to allow linker relaxation.
14148
14149 (define_insn "*tls_global_dynamic_32_gnu"
14150   [(set (match_operand:SI 0 "register_operand" "=a")
14151         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14152                     (match_operand:SI 2 "tls_symbolic_operand" "")
14153                     (match_operand:SI 3 "call_insn_operand" "")]
14154                     UNSPEC_TLS_GD))
14155    (clobber (match_scratch:SI 4 "=d"))
14156    (clobber (match_scratch:SI 5 "=c"))
14157    (clobber (reg:CC FLAGS_REG))]
14158   "!TARGET_64BIT && TARGET_GNU_TLS"
14159   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14160   [(set_attr "type" "multi")
14161    (set_attr "length" "12")])
14162
14163 (define_insn "*tls_global_dynamic_32_sun"
14164   [(set (match_operand:SI 0 "register_operand" "=a")
14165         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14166                     (match_operand:SI 2 "tls_symbolic_operand" "")
14167                     (match_operand:SI 3 "call_insn_operand" "")]
14168                     UNSPEC_TLS_GD))
14169    (clobber (match_scratch:SI 4 "=d"))
14170    (clobber (match_scratch:SI 5 "=c"))
14171    (clobber (reg:CC FLAGS_REG))]
14172   "!TARGET_64BIT && TARGET_SUN_TLS"
14173   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14174         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14175   [(set_attr "type" "multi")
14176    (set_attr "length" "14")])
14177
14178 (define_expand "tls_global_dynamic_32"
14179   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14180                    (unspec:SI
14181                     [(match_dup 2)
14182                      (match_operand:SI 1 "tls_symbolic_operand" "")
14183                      (match_dup 3)]
14184                     UNSPEC_TLS_GD))
14185               (clobber (match_scratch:SI 4 ""))
14186               (clobber (match_scratch:SI 5 ""))
14187               (clobber (reg:CC FLAGS_REG))])]
14188   ""
14189 {
14190   if (flag_pic)
14191     operands[2] = pic_offset_table_rtx;
14192   else
14193     {
14194       operands[2] = gen_reg_rtx (Pmode);
14195       emit_insn (gen_set_got (operands[2]));
14196     }
14197   operands[3] = ix86_tls_get_addr ();
14198 })
14199
14200 (define_insn "*tls_global_dynamic_64"
14201   [(set (match_operand:DI 0 "register_operand" "=a")
14202         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14203                       (match_operand:DI 3 "" "")))
14204    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14205               UNSPEC_TLS_GD)]
14206   "TARGET_64BIT"
14207   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14208   [(set_attr "type" "multi")
14209    (set_attr "length" "16")])
14210
14211 (define_expand "tls_global_dynamic_64"
14212   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14213                    (call (mem:QI (match_dup 2)) (const_int 0)))
14214               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14215                          UNSPEC_TLS_GD)])]
14216   ""
14217 {
14218   operands[2] = ix86_tls_get_addr ();
14219 })
14220
14221 (define_insn "*tls_local_dynamic_base_32_gnu"
14222   [(set (match_operand:SI 0 "register_operand" "=a")
14223         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14224                     (match_operand:SI 2 "call_insn_operand" "")]
14225                    UNSPEC_TLS_LD_BASE))
14226    (clobber (match_scratch:SI 3 "=d"))
14227    (clobber (match_scratch:SI 4 "=c"))
14228    (clobber (reg:CC FLAGS_REG))]
14229   "!TARGET_64BIT && TARGET_GNU_TLS"
14230   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14231   [(set_attr "type" "multi")
14232    (set_attr "length" "11")])
14233
14234 (define_insn "*tls_local_dynamic_base_32_sun"
14235   [(set (match_operand:SI 0 "register_operand" "=a")
14236         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237                     (match_operand:SI 2 "call_insn_operand" "")]
14238                    UNSPEC_TLS_LD_BASE))
14239    (clobber (match_scratch:SI 3 "=d"))
14240    (clobber (match_scratch:SI 4 "=c"))
14241    (clobber (reg:CC FLAGS_REG))]
14242   "!TARGET_64BIT && TARGET_SUN_TLS"
14243   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14244         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "13")])
14247
14248 (define_expand "tls_local_dynamic_base_32"
14249   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14250                    (unspec:SI [(match_dup 1) (match_dup 2)]
14251                               UNSPEC_TLS_LD_BASE))
14252               (clobber (match_scratch:SI 3 ""))
14253               (clobber (match_scratch:SI 4 ""))
14254               (clobber (reg:CC FLAGS_REG))])]
14255   ""
14256 {
14257   if (flag_pic)
14258     operands[1] = pic_offset_table_rtx;
14259   else
14260     {
14261       operands[1] = gen_reg_rtx (Pmode);
14262       emit_insn (gen_set_got (operands[1]));
14263     }
14264   operands[2] = ix86_tls_get_addr ();
14265 })
14266
14267 (define_insn "*tls_local_dynamic_base_64"
14268   [(set (match_operand:DI 0 "register_operand" "=a")
14269         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14270                       (match_operand:DI 2 "" "")))
14271    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14272   "TARGET_64BIT"
14273   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14274   [(set_attr "type" "multi")
14275    (set_attr "length" "12")])
14276
14277 (define_expand "tls_local_dynamic_base_64"
14278   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14279                    (call (mem:QI (match_dup 1)) (const_int 0)))
14280               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14281   ""
14282 {
14283   operands[1] = ix86_tls_get_addr ();
14284 })
14285
14286 ;; Local dynamic of a single variable is a lose.  Show combine how
14287 ;; to convert that back to global dynamic.
14288
14289 (define_insn_and_split "*tls_local_dynamic_32_once"
14290   [(set (match_operand:SI 0 "register_operand" "=a")
14291         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14292                              (match_operand:SI 2 "call_insn_operand" "")]
14293                             UNSPEC_TLS_LD_BASE)
14294                  (const:SI (unspec:SI
14295                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14296                             UNSPEC_DTPOFF))))
14297    (clobber (match_scratch:SI 4 "=d"))
14298    (clobber (match_scratch:SI 5 "=c"))
14299    (clobber (reg:CC FLAGS_REG))]
14300   ""
14301   "#"
14302   ""
14303   [(parallel [(set (match_dup 0)
14304                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14305                               UNSPEC_TLS_GD))
14306               (clobber (match_dup 4))
14307               (clobber (match_dup 5))
14308               (clobber (reg:CC FLAGS_REG))])]
14309   "")
14310
14311 ;; Load and add the thread base pointer from %gs:0.
14312
14313 (define_insn "*load_tp_si"
14314   [(set (match_operand:SI 0 "register_operand" "=r")
14315         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14316   "!TARGET_64BIT"
14317   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14318   [(set_attr "type" "imov")
14319    (set_attr "modrm" "0")
14320    (set_attr "length" "7")
14321    (set_attr "memory" "load")
14322    (set_attr "imm_disp" "false")])
14323
14324 (define_insn "*add_tp_si"
14325   [(set (match_operand:SI 0 "register_operand" "=r")
14326         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14327                  (match_operand:SI 1 "register_operand" "0")))
14328    (clobber (reg:CC FLAGS_REG))]
14329   "!TARGET_64BIT"
14330   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14331   [(set_attr "type" "alu")
14332    (set_attr "modrm" "0")
14333    (set_attr "length" "7")
14334    (set_attr "memory" "load")
14335    (set_attr "imm_disp" "false")])
14336
14337 (define_insn "*load_tp_di"
14338   [(set (match_operand:DI 0 "register_operand" "=r")
14339         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14340   "TARGET_64BIT"
14341   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14342   [(set_attr "type" "imov")
14343    (set_attr "modrm" "0")
14344    (set_attr "length" "7")
14345    (set_attr "memory" "load")
14346    (set_attr "imm_disp" "false")])
14347
14348 (define_insn "*add_tp_di"
14349   [(set (match_operand:DI 0 "register_operand" "=r")
14350         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14351                  (match_operand:DI 1 "register_operand" "0")))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "TARGET_64BIT"
14354   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14355   [(set_attr "type" "alu")
14356    (set_attr "modrm" "0")
14357    (set_attr "length" "7")
14358    (set_attr "memory" "load")
14359    (set_attr "imm_disp" "false")])
14360 \f
14361 ;; These patterns match the binary 387 instructions for addM3, subM3,
14362 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14363 ;; SFmode.  The first is the normal insn, the second the same insn but
14364 ;; with one operand a conversion, and the third the same insn but with
14365 ;; the other operand a conversion.  The conversion may be SFmode or
14366 ;; SImode if the target mode DFmode, but only SImode if the target mode
14367 ;; is SFmode.
14368
14369 ;; Gcc is slightly more smart about handling normal two address instructions
14370 ;; so use special patterns for add and mull.
14371 (define_insn "*fop_sf_comm_nosse"
14372   [(set (match_operand:SF 0 "register_operand" "=f")
14373         (match_operator:SF 3 "binary_fp_operator"
14374                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14375                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14376   "TARGET_80387 && !TARGET_SSE_MATH
14377    && COMMUTATIVE_ARITH_P (operands[3])
14378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14379   "* return output_387_binary_op (insn, operands);"
14380   [(set (attr "type") 
14381         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14382            (const_string "fmul")
14383            (const_string "fop")))
14384    (set_attr "mode" "SF")])
14385
14386 (define_insn "*fop_sf_comm"
14387   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14388         (match_operator:SF 3 "binary_fp_operator"
14389                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14390                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14391   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14392    && COMMUTATIVE_ARITH_P (operands[3])
14393    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14394   "* return output_387_binary_op (insn, operands);"
14395   [(set (attr "type") 
14396         (if_then_else (eq_attr "alternative" "1")
14397            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14398               (const_string "ssemul")
14399               (const_string "sseadd"))
14400            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14401               (const_string "fmul")
14402               (const_string "fop"))))
14403    (set_attr "mode" "SF")])
14404
14405 (define_insn "*fop_sf_comm_sse"
14406   [(set (match_operand:SF 0 "register_operand" "=x")
14407         (match_operator:SF 3 "binary_fp_operator"
14408                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14409                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14410   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14411    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14412   "* return output_387_binary_op (insn, operands);"
14413   [(set (attr "type") 
14414         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14415            (const_string "ssemul")
14416            (const_string "sseadd")))
14417    (set_attr "mode" "SF")])
14418
14419 (define_insn "*fop_df_comm_nosse"
14420   [(set (match_operand:DF 0 "register_operand" "=f")
14421         (match_operator:DF 3 "binary_fp_operator"
14422                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14423                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14424   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14425    && COMMUTATIVE_ARITH_P (operands[3])
14426    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14427   "* return output_387_binary_op (insn, operands);"
14428   [(set (attr "type") 
14429         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14430            (const_string "fmul")
14431            (const_string "fop")))
14432    (set_attr "mode" "DF")])
14433
14434 (define_insn "*fop_df_comm"
14435   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14436         (match_operator:DF 3 "binary_fp_operator"
14437                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14438                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14439   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14440    && COMMUTATIVE_ARITH_P (operands[3])
14441    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14442   "* return output_387_binary_op (insn, operands);"
14443   [(set (attr "type") 
14444         (if_then_else (eq_attr "alternative" "1")
14445            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14446               (const_string "ssemul")
14447               (const_string "sseadd"))
14448            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14449               (const_string "fmul")
14450               (const_string "fop"))))
14451    (set_attr "mode" "DF")])
14452
14453 (define_insn "*fop_df_comm_sse"
14454   [(set (match_operand:DF 0 "register_operand" "=Y")
14455         (match_operator:DF 3 "binary_fp_operator"
14456                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14457                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14458   "TARGET_SSE2 && TARGET_SSE_MATH
14459    && COMMUTATIVE_ARITH_P (operands[3])
14460    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14461   "* return output_387_binary_op (insn, operands);"
14462   [(set (attr "type") 
14463         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14464            (const_string "ssemul")
14465            (const_string "sseadd")))
14466    (set_attr "mode" "DF")])
14467
14468 (define_insn "*fop_xf_comm"
14469   [(set (match_operand:XF 0 "register_operand" "=f")
14470         (match_operator:XF 3 "binary_fp_operator"
14471                         [(match_operand:XF 1 "register_operand" "%0")
14472                          (match_operand:XF 2 "register_operand" "f")]))]
14473   "TARGET_80387
14474    && COMMUTATIVE_ARITH_P (operands[3])"
14475   "* return output_387_binary_op (insn, operands);"
14476   [(set (attr "type") 
14477         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14478            (const_string "fmul")
14479            (const_string "fop")))
14480    (set_attr "mode" "XF")])
14481
14482 (define_insn "*fop_sf_1_nosse"
14483   [(set (match_operand:SF 0 "register_operand" "=f,f")
14484         (match_operator:SF 3 "binary_fp_operator"
14485                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14486                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14487   "TARGET_80387 && !TARGET_SSE_MATH
14488    && !COMMUTATIVE_ARITH_P (operands[3])
14489    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14490   "* return output_387_binary_op (insn, operands);"
14491   [(set (attr "type") 
14492         (cond [(match_operand:SF 3 "mult_operator" "") 
14493                  (const_string "fmul")
14494                (match_operand:SF 3 "div_operator" "") 
14495                  (const_string "fdiv")
14496               ]
14497               (const_string "fop")))
14498    (set_attr "mode" "SF")])
14499
14500 (define_insn "*fop_sf_1"
14501   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14502         (match_operator:SF 3 "binary_fp_operator"
14503                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14504                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14505   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14506    && !COMMUTATIVE_ARITH_P (operands[3])
14507    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14508   "* return output_387_binary_op (insn, operands);"
14509   [(set (attr "type") 
14510         (cond [(and (eq_attr "alternative" "2")
14511                     (match_operand:SF 3 "mult_operator" ""))
14512                  (const_string "ssemul")
14513                (and (eq_attr "alternative" "2")
14514                     (match_operand:SF 3 "div_operator" ""))
14515                  (const_string "ssediv")
14516                (eq_attr "alternative" "2")
14517                  (const_string "sseadd")
14518                (match_operand:SF 3 "mult_operator" "") 
14519                  (const_string "fmul")
14520                (match_operand:SF 3 "div_operator" "") 
14521                  (const_string "fdiv")
14522               ]
14523               (const_string "fop")))
14524    (set_attr "mode" "SF")])
14525
14526 (define_insn "*fop_sf_1_sse"
14527   [(set (match_operand:SF 0 "register_operand" "=x")
14528         (match_operator:SF 3 "binary_fp_operator"
14529                         [(match_operand:SF 1 "register_operand" "0")
14530                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14531   "TARGET_SSE_MATH
14532    && !COMMUTATIVE_ARITH_P (operands[3])"
14533   "* return output_387_binary_op (insn, operands);"
14534   [(set (attr "type") 
14535         (cond [(match_operand:SF 3 "mult_operator" "")
14536                  (const_string "ssemul")
14537                (match_operand:SF 3 "div_operator" "")
14538                  (const_string "ssediv")
14539               ]
14540               (const_string "sseadd")))
14541    (set_attr "mode" "SF")])
14542
14543 ;; ??? Add SSE splitters for these!
14544 (define_insn "*fop_sf_2"
14545   [(set (match_operand:SF 0 "register_operand" "=f,f")
14546         (match_operator:SF 3 "binary_fp_operator"
14547           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14548            (match_operand:SF 2 "register_operand" "0,0")]))]
14549   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14550   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14551   [(set (attr "type") 
14552         (cond [(match_operand:SF 3 "mult_operator" "") 
14553                  (const_string "fmul")
14554                (match_operand:SF 3 "div_operator" "") 
14555                  (const_string "fdiv")
14556               ]
14557               (const_string "fop")))
14558    (set_attr "fp_int_src" "true")
14559    (set_attr "mode" "SI")])
14560
14561 (define_insn "*fop_sf_3"
14562   [(set (match_operand:SF 0 "register_operand" "=f,f")
14563         (match_operator:SF 3 "binary_fp_operator"
14564           [(match_operand:SF 1 "register_operand" "0,0")
14565            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14566   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14567   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14568   [(set (attr "type") 
14569         (cond [(match_operand:SF 3 "mult_operator" "") 
14570                  (const_string "fmul")
14571                (match_operand:SF 3 "div_operator" "") 
14572                  (const_string "fdiv")
14573               ]
14574               (const_string "fop")))
14575    (set_attr "fp_int_src" "true")
14576    (set_attr "mode" "SI")])
14577
14578 (define_insn "*fop_df_1_nosse"
14579   [(set (match_operand:DF 0 "register_operand" "=f,f")
14580         (match_operator:DF 3 "binary_fp_operator"
14581                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14582                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14583   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14584    && !COMMUTATIVE_ARITH_P (operands[3])
14585    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14586   "* return output_387_binary_op (insn, operands);"
14587   [(set (attr "type") 
14588         (cond [(match_operand:DF 3 "mult_operator" "") 
14589                  (const_string "fmul")
14590                (match_operand:DF 3 "div_operator" "")
14591                  (const_string "fdiv")
14592               ]
14593               (const_string "fop")))
14594    (set_attr "mode" "DF")])
14595
14596
14597 (define_insn "*fop_df_1"
14598   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14599         (match_operator:DF 3 "binary_fp_operator"
14600                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14601                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14602   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14603    && !COMMUTATIVE_ARITH_P (operands[3])
14604    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14605   "* return output_387_binary_op (insn, operands);"
14606   [(set (attr "type") 
14607         (cond [(and (eq_attr "alternative" "2")
14608                     (match_operand:SF 3 "mult_operator" ""))
14609                  (const_string "ssemul")
14610                (and (eq_attr "alternative" "2")
14611                     (match_operand:SF 3 "div_operator" ""))
14612                  (const_string "ssediv")
14613                (eq_attr "alternative" "2")
14614                  (const_string "sseadd")
14615                (match_operand:DF 3 "mult_operator" "") 
14616                  (const_string "fmul")
14617                (match_operand:DF 3 "div_operator" "") 
14618                  (const_string "fdiv")
14619               ]
14620               (const_string "fop")))
14621    (set_attr "mode" "DF")])
14622
14623 (define_insn "*fop_df_1_sse"
14624   [(set (match_operand:DF 0 "register_operand" "=Y")
14625         (match_operator:DF 3 "binary_fp_operator"
14626                         [(match_operand:DF 1 "register_operand" "0")
14627                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14628   "TARGET_SSE2 && TARGET_SSE_MATH
14629    && !COMMUTATIVE_ARITH_P (operands[3])"
14630   "* return output_387_binary_op (insn, operands);"
14631   [(set_attr "mode" "DF")
14632    (set (attr "type") 
14633         (cond [(match_operand:SF 3 "mult_operator" "")
14634                  (const_string "ssemul")
14635                (match_operand:SF 3 "div_operator" "")
14636                  (const_string "ssediv")
14637               ]
14638               (const_string "sseadd")))])
14639
14640 ;; ??? Add SSE splitters for these!
14641 (define_insn "*fop_df_2"
14642   [(set (match_operand:DF 0 "register_operand" "=f,f")
14643         (match_operator:DF 3 "binary_fp_operator"
14644            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14645             (match_operand:DF 2 "register_operand" "0,0")]))]
14646   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14648   [(set (attr "type") 
14649         (cond [(match_operand:DF 3 "mult_operator" "") 
14650                  (const_string "fmul")
14651                (match_operand:DF 3 "div_operator" "") 
14652                  (const_string "fdiv")
14653               ]
14654               (const_string "fop")))
14655    (set_attr "fp_int_src" "true")
14656    (set_attr "mode" "SI")])
14657
14658 (define_insn "*fop_df_3"
14659   [(set (match_operand:DF 0 "register_operand" "=f,f")
14660         (match_operator:DF 3 "binary_fp_operator"
14661            [(match_operand:DF 1 "register_operand" "0,0")
14662             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14663   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14664   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14665   [(set (attr "type") 
14666         (cond [(match_operand:DF 3 "mult_operator" "") 
14667                  (const_string "fmul")
14668                (match_operand:DF 3 "div_operator" "") 
14669                  (const_string "fdiv")
14670               ]
14671               (const_string "fop")))
14672    (set_attr "fp_int_src" "true")
14673    (set_attr "mode" "SI")])
14674
14675 (define_insn "*fop_df_4"
14676   [(set (match_operand:DF 0 "register_operand" "=f,f")
14677         (match_operator:DF 3 "binary_fp_operator"
14678            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14679             (match_operand:DF 2 "register_operand" "0,f")]))]
14680   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14681    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14682   "* return output_387_binary_op (insn, operands);"
14683   [(set (attr "type") 
14684         (cond [(match_operand:DF 3 "mult_operator" "") 
14685                  (const_string "fmul")
14686                (match_operand:DF 3 "div_operator" "") 
14687                  (const_string "fdiv")
14688               ]
14689               (const_string "fop")))
14690    (set_attr "mode" "SF")])
14691
14692 (define_insn "*fop_df_5"
14693   [(set (match_operand:DF 0 "register_operand" "=f,f")
14694         (match_operator:DF 3 "binary_fp_operator"
14695           [(match_operand:DF 1 "register_operand" "0,f")
14696            (float_extend:DF
14697             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14698   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14699   "* return output_387_binary_op (insn, operands);"
14700   [(set (attr "type") 
14701         (cond [(match_operand:DF 3 "mult_operator" "") 
14702                  (const_string "fmul")
14703                (match_operand:DF 3 "div_operator" "") 
14704                  (const_string "fdiv")
14705               ]
14706               (const_string "fop")))
14707    (set_attr "mode" "SF")])
14708
14709 (define_insn "*fop_df_6"
14710   [(set (match_operand:DF 0 "register_operand" "=f,f")
14711         (match_operator:DF 3 "binary_fp_operator"
14712           [(float_extend:DF
14713             (match_operand:SF 1 "register_operand" "0,f"))
14714            (float_extend:DF
14715             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14716   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14717   "* return output_387_binary_op (insn, operands);"
14718   [(set (attr "type") 
14719         (cond [(match_operand:DF 3 "mult_operator" "") 
14720                  (const_string "fmul")
14721                (match_operand:DF 3 "div_operator" "") 
14722                  (const_string "fdiv")
14723               ]
14724               (const_string "fop")))
14725    (set_attr "mode" "SF")])
14726
14727 (define_insn "*fop_xf_1"
14728   [(set (match_operand:XF 0 "register_operand" "=f,f")
14729         (match_operator:XF 3 "binary_fp_operator"
14730                         [(match_operand:XF 1 "register_operand" "0,f")
14731                          (match_operand:XF 2 "register_operand" "f,0")]))]
14732   "TARGET_80387
14733    && !COMMUTATIVE_ARITH_P (operands[3])"
14734   "* return output_387_binary_op (insn, operands);"
14735   [(set (attr "type") 
14736         (cond [(match_operand:XF 3 "mult_operator" "") 
14737                  (const_string "fmul")
14738                (match_operand:XF 3 "div_operator" "") 
14739                  (const_string "fdiv")
14740               ]
14741               (const_string "fop")))
14742    (set_attr "mode" "XF")])
14743
14744 (define_insn "*fop_xf_2"
14745   [(set (match_operand:XF 0 "register_operand" "=f,f")
14746         (match_operator:XF 3 "binary_fp_operator"
14747            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14748             (match_operand:XF 2 "register_operand" "0,0")]))]
14749   "TARGET_80387 && TARGET_USE_FIOP"
14750   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14751   [(set (attr "type") 
14752         (cond [(match_operand:XF 3 "mult_operator" "") 
14753                  (const_string "fmul")
14754                (match_operand:XF 3 "div_operator" "") 
14755                  (const_string "fdiv")
14756               ]
14757               (const_string "fop")))
14758    (set_attr "fp_int_src" "true")
14759    (set_attr "mode" "SI")])
14760
14761 (define_insn "*fop_xf_3"
14762   [(set (match_operand:XF 0 "register_operand" "=f,f")
14763         (match_operator:XF 3 "binary_fp_operator"
14764           [(match_operand:XF 1 "register_operand" "0,0")
14765            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14766   "TARGET_80387 && TARGET_USE_FIOP"
14767   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14768   [(set (attr "type") 
14769         (cond [(match_operand:XF 3 "mult_operator" "") 
14770                  (const_string "fmul")
14771                (match_operand:XF 3 "div_operator" "") 
14772                  (const_string "fdiv")
14773               ]
14774               (const_string "fop")))
14775    (set_attr "fp_int_src" "true")
14776    (set_attr "mode" "SI")])
14777
14778 (define_insn "*fop_xf_4"
14779   [(set (match_operand:XF 0 "register_operand" "=f,f")
14780         (match_operator:XF 3 "binary_fp_operator"
14781            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14782             (match_operand:XF 2 "register_operand" "0,f")]))]
14783   "TARGET_80387"
14784   "* return output_387_binary_op (insn, operands);"
14785   [(set (attr "type") 
14786         (cond [(match_operand:XF 3 "mult_operator" "") 
14787                  (const_string "fmul")
14788                (match_operand:XF 3 "div_operator" "") 
14789                  (const_string "fdiv")
14790               ]
14791               (const_string "fop")))
14792    (set_attr "mode" "SF")])
14793
14794 (define_insn "*fop_xf_5"
14795   [(set (match_operand:XF 0 "register_operand" "=f,f")
14796         (match_operator:XF 3 "binary_fp_operator"
14797           [(match_operand:XF 1 "register_operand" "0,f")
14798            (float_extend:XF
14799             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14800   "TARGET_80387"
14801   "* return output_387_binary_op (insn, operands);"
14802   [(set (attr "type") 
14803         (cond [(match_operand:XF 3 "mult_operator" "") 
14804                  (const_string "fmul")
14805                (match_operand:XF 3 "div_operator" "") 
14806                  (const_string "fdiv")
14807               ]
14808               (const_string "fop")))
14809    (set_attr "mode" "SF")])
14810
14811 (define_insn "*fop_xf_6"
14812   [(set (match_operand:XF 0 "register_operand" "=f,f")
14813         (match_operator:XF 3 "binary_fp_operator"
14814           [(float_extend:XF
14815             (match_operand 1 "register_operand" "0,f"))
14816            (float_extend:XF
14817             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14818   "TARGET_80387"
14819   "* return output_387_binary_op (insn, operands);"
14820   [(set (attr "type") 
14821         (cond [(match_operand:XF 3 "mult_operator" "") 
14822                  (const_string "fmul")
14823                (match_operand:XF 3 "div_operator" "") 
14824                  (const_string "fdiv")
14825               ]
14826               (const_string "fop")))
14827    (set_attr "mode" "SF")])
14828
14829 (define_split
14830   [(set (match_operand 0 "register_operand" "")
14831         (match_operator 3 "binary_fp_operator"
14832            [(float (match_operand:SI 1 "register_operand" ""))
14833             (match_operand 2 "register_operand" "")]))]
14834   "TARGET_80387 && reload_completed
14835    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14836   [(const_int 0)]
14837
14838   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14839   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14840   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14841                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14842                                           GET_MODE (operands[3]),
14843                                           operands[4],
14844                                           operands[2])));
14845   ix86_free_from_memory (GET_MODE (operands[1]));
14846   DONE;
14847 })
14848
14849 (define_split
14850   [(set (match_operand 0 "register_operand" "")
14851         (match_operator 3 "binary_fp_operator"
14852            [(match_operand 1 "register_operand" "")
14853             (float (match_operand:SI 2 "register_operand" ""))]))]
14854   "TARGET_80387 && reload_completed
14855    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14856   [(const_int 0)]
14857 {
14858   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14859   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14860   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14861                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14862                                           GET_MODE (operands[3]),
14863                                           operands[1],
14864                                           operands[4])));
14865   ix86_free_from_memory (GET_MODE (operands[2]));
14866   DONE;
14867 })
14868 \f
14869 ;; FPU special functions.
14870
14871 (define_expand "sqrtsf2"
14872   [(set (match_operand:SF 0 "register_operand" "")
14873         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14874   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14875 {
14876   if (!TARGET_SSE_MATH)
14877     operands[1] = force_reg (SFmode, operands[1]);
14878 })
14879
14880 (define_insn "sqrtsf2_1"
14881   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14882         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14883   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14884    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14885   "@
14886    fsqrt
14887    sqrtss\t{%1, %0|%0, %1}"
14888   [(set_attr "type" "fpspc,sse")
14889    (set_attr "mode" "SF,SF")
14890    (set_attr "athlon_decode" "direct,*")])
14891
14892 (define_insn "sqrtsf2_1_sse_only"
14893   [(set (match_operand:SF 0 "register_operand" "=x")
14894         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14895   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14896   "sqrtss\t{%1, %0|%0, %1}"
14897   [(set_attr "type" "sse")
14898    (set_attr "mode" "SF")
14899    (set_attr "athlon_decode" "*")])
14900
14901 (define_insn "sqrtsf2_i387"
14902   [(set (match_operand:SF 0 "register_operand" "=f")
14903         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14904   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14905    && !TARGET_SSE_MATH"
14906   "fsqrt"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "mode" "SF")
14909    (set_attr "athlon_decode" "direct")])
14910
14911 (define_expand "sqrtdf2"
14912   [(set (match_operand:DF 0 "register_operand" "")
14913         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14914   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14915    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14916 {
14917   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14918     operands[1] = force_reg (DFmode, operands[1]);
14919 })
14920
14921 (define_insn "sqrtdf2_1"
14922   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14923         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14924   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14925    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14926   "@
14927    fsqrt
14928    sqrtsd\t{%1, %0|%0, %1}"
14929   [(set_attr "type" "fpspc,sse")
14930    (set_attr "mode" "DF,DF")
14931    (set_attr "athlon_decode" "direct,*")])
14932
14933 (define_insn "sqrtdf2_1_sse_only"
14934   [(set (match_operand:DF 0 "register_operand" "=Y")
14935         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14936   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14937   "sqrtsd\t{%1, %0|%0, %1}"
14938   [(set_attr "type" "sse")
14939    (set_attr "mode" "DF")
14940    (set_attr "athlon_decode" "*")])
14941
14942 (define_insn "sqrtdf2_i387"
14943   [(set (match_operand:DF 0 "register_operand" "=f")
14944         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14945   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14946    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14947   "fsqrt"
14948   [(set_attr "type" "fpspc")
14949    (set_attr "mode" "DF")
14950    (set_attr "athlon_decode" "direct")])
14951
14952 (define_insn "*sqrtextendsfdf2"
14953   [(set (match_operand:DF 0 "register_operand" "=f")
14954         (sqrt:DF (float_extend:DF
14955                   (match_operand:SF 1 "register_operand" "0"))))]
14956   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14957    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14958   "fsqrt"
14959   [(set_attr "type" "fpspc")
14960    (set_attr "mode" "DF")
14961    (set_attr "athlon_decode" "direct")])
14962
14963 (define_insn "sqrtxf2"
14964   [(set (match_operand:XF 0 "register_operand" "=f")
14965         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14966   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14967    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14968   "fsqrt"
14969   [(set_attr "type" "fpspc")
14970    (set_attr "mode" "XF")
14971    (set_attr "athlon_decode" "direct")])
14972
14973 (define_insn "*sqrtextenddfxf2"
14974   [(set (match_operand:XF 0 "register_operand" "=f")
14975         (sqrt:XF (float_extend:XF
14976                   (match_operand:DF 1 "register_operand" "0"))))]
14977   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14978   "fsqrt"
14979   [(set_attr "type" "fpspc")
14980    (set_attr "mode" "XF")
14981    (set_attr "athlon_decode" "direct")])
14982
14983 (define_insn "*sqrtextendsfxf2"
14984   [(set (match_operand:XF 0 "register_operand" "=f")
14985         (sqrt:XF (float_extend:XF
14986                   (match_operand:SF 1 "register_operand" "0"))))]
14987   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14988   "fsqrt"
14989   [(set_attr "type" "fpspc")
14990    (set_attr "mode" "XF")
14991    (set_attr "athlon_decode" "direct")])
14992
14993 (define_insn "fpremxf4"
14994   [(set (match_operand:XF 0 "register_operand" "=f")
14995         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14996                     (match_operand:XF 3 "register_operand" "1")]
14997                    UNSPEC_FPREM_F))
14998    (set (match_operand:XF 1 "register_operand" "=u")
14999         (unspec:XF [(match_dup 2) (match_dup 3)]
15000                    UNSPEC_FPREM_U))
15001    (set (reg:CCFP FPSR_REG)
15002         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15003   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15004    && flag_unsafe_math_optimizations"
15005   "fprem"
15006   [(set_attr "type" "fpspc")
15007    (set_attr "mode" "XF")])
15008
15009 (define_expand "fmodsf3"
15010   [(use (match_operand:SF 0 "register_operand" ""))
15011    (use (match_operand:SF 1 "register_operand" ""))
15012    (use (match_operand:SF 2 "register_operand" ""))]
15013   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15014    && flag_unsafe_math_optimizations"
15015 {
15016   rtx label = gen_label_rtx ();
15017
15018   rtx op1 = gen_reg_rtx (XFmode);
15019   rtx op2 = gen_reg_rtx (XFmode);
15020
15021   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15022   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15023
15024   emit_label (label);
15025
15026   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15027   ix86_emit_fp_unordered_jump (label);
15028
15029   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15030   DONE;
15031 })
15032
15033 (define_expand "fmoddf3"
15034   [(use (match_operand:DF 0 "register_operand" ""))
15035    (use (match_operand:DF 1 "register_operand" ""))
15036    (use (match_operand:DF 2 "register_operand" ""))]
15037   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15038    && flag_unsafe_math_optimizations"
15039 {
15040   rtx label = gen_label_rtx ();
15041
15042   rtx op1 = gen_reg_rtx (XFmode);
15043   rtx op2 = gen_reg_rtx (XFmode);
15044
15045   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15046   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15047
15048   emit_label (label);
15049
15050   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15051   ix86_emit_fp_unordered_jump (label);
15052
15053   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15054   DONE;
15055 })
15056
15057 (define_expand "fmodxf3"
15058   [(use (match_operand:XF 0 "register_operand" ""))
15059    (use (match_operand:XF 1 "register_operand" ""))
15060    (use (match_operand:XF 2 "register_operand" ""))]
15061   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15062    && flag_unsafe_math_optimizations"
15063 {
15064   rtx label = gen_label_rtx ();
15065
15066   emit_label (label);
15067
15068   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15069                            operands[1], operands[2]));
15070   ix86_emit_fp_unordered_jump (label);
15071
15072   emit_move_insn (operands[0], operands[1]);
15073   DONE;
15074 })
15075
15076 (define_insn "fprem1xf4"
15077   [(set (match_operand:XF 0 "register_operand" "=f")
15078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15079                     (match_operand:XF 3 "register_operand" "1")]
15080                    UNSPEC_FPREM1_F))
15081    (set (match_operand:XF 1 "register_operand" "=u")
15082         (unspec:XF [(match_dup 2) (match_dup 3)]
15083                    UNSPEC_FPREM1_U))
15084    (set (reg:CCFP FPSR_REG)
15085         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15086   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15087    && flag_unsafe_math_optimizations"
15088   "fprem1"
15089   [(set_attr "type" "fpspc")
15090    (set_attr "mode" "XF")])
15091
15092 (define_expand "dremsf3"
15093   [(use (match_operand:SF 0 "register_operand" ""))
15094    (use (match_operand:SF 1 "register_operand" ""))
15095    (use (match_operand:SF 2 "register_operand" ""))]
15096   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15097    && flag_unsafe_math_optimizations"
15098 {
15099   rtx label = gen_label_rtx ();
15100
15101   rtx op1 = gen_reg_rtx (XFmode);
15102   rtx op2 = gen_reg_rtx (XFmode);
15103
15104   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15105   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15106
15107   emit_label (label);
15108
15109   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15110   ix86_emit_fp_unordered_jump (label);
15111
15112   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15113   DONE;
15114 })
15115
15116 (define_expand "dremdf3"
15117   [(use (match_operand:DF 0 "register_operand" ""))
15118    (use (match_operand:DF 1 "register_operand" ""))
15119    (use (match_operand:DF 2 "register_operand" ""))]
15120   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15121    && flag_unsafe_math_optimizations"
15122 {
15123   rtx label = gen_label_rtx ();
15124
15125   rtx op1 = gen_reg_rtx (XFmode);
15126   rtx op2 = gen_reg_rtx (XFmode);
15127
15128   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15129   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15130
15131   emit_label (label);
15132
15133   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15134   ix86_emit_fp_unordered_jump (label);
15135
15136   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15137   DONE;
15138 })
15139
15140 (define_expand "dremxf3"
15141   [(use (match_operand:XF 0 "register_operand" ""))
15142    (use (match_operand:XF 1 "register_operand" ""))
15143    (use (match_operand:XF 2 "register_operand" ""))]
15144   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15145    && flag_unsafe_math_optimizations"
15146 {
15147   rtx label = gen_label_rtx ();
15148
15149   emit_label (label);
15150
15151   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15152                             operands[1], operands[2]));
15153   ix86_emit_fp_unordered_jump (label);
15154
15155   emit_move_insn (operands[0], operands[1]);
15156   DONE;
15157 })
15158
15159 (define_insn "*sindf2"
15160   [(set (match_operand:DF 0 "register_operand" "=f")
15161         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15162   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15163    && flag_unsafe_math_optimizations"
15164   "fsin"
15165   [(set_attr "type" "fpspc")
15166    (set_attr "mode" "DF")])
15167
15168 (define_insn "*sinsf2"
15169   [(set (match_operand:SF 0 "register_operand" "=f")
15170         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15171   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15172    && flag_unsafe_math_optimizations"
15173   "fsin"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "SF")])
15176
15177 (define_insn "*sinextendsfdf2"
15178   [(set (match_operand:DF 0 "register_operand" "=f")
15179         (unspec:DF [(float_extend:DF
15180                      (match_operand:SF 1 "register_operand" "0"))]
15181                    UNSPEC_SIN))]
15182   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15183    && flag_unsafe_math_optimizations"
15184   "fsin"
15185   [(set_attr "type" "fpspc")
15186    (set_attr "mode" "DF")])
15187
15188 (define_insn "*sinxf2"
15189   [(set (match_operand:XF 0 "register_operand" "=f")
15190         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15191   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15192    && flag_unsafe_math_optimizations"
15193   "fsin"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "XF")])
15196
15197 (define_insn "*cosdf2"
15198   [(set (match_operand:DF 0 "register_operand" "=f")
15199         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15201    && flag_unsafe_math_optimizations"
15202   "fcos"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "DF")])
15205
15206 (define_insn "*cossf2"
15207   [(set (match_operand:SF 0 "register_operand" "=f")
15208         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15209   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15210    && flag_unsafe_math_optimizations"
15211   "fcos"
15212   [(set_attr "type" "fpspc")
15213    (set_attr "mode" "SF")])
15214
15215 (define_insn "*cosextendsfdf2"
15216   [(set (match_operand:DF 0 "register_operand" "=f")
15217         (unspec:DF [(float_extend:DF
15218                      (match_operand:SF 1 "register_operand" "0"))]
15219                    UNSPEC_COS))]
15220   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15221    && flag_unsafe_math_optimizations"
15222   "fcos"
15223   [(set_attr "type" "fpspc")
15224    (set_attr "mode" "DF")])
15225
15226 (define_insn "*cosxf2"
15227   [(set (match_operand:XF 0 "register_operand" "=f")
15228         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15229   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230    && flag_unsafe_math_optimizations"
15231   "fcos"
15232   [(set_attr "type" "fpspc")
15233    (set_attr "mode" "XF")])
15234
15235 ;; With sincos pattern defined, sin and cos builtin function will be
15236 ;; expanded to sincos pattern with one of its outputs left unused. 
15237 ;; Cse pass  will detected, if two sincos patterns can be combined,
15238 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15239 ;; depending on the unused output.
15240
15241 (define_insn "sincosdf3"
15242   [(set (match_operand:DF 0 "register_operand" "=f")
15243         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15244                    UNSPEC_SINCOS_COS))
15245    (set (match_operand:DF 1 "register_operand" "=u")
15246         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15247   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15248    && flag_unsafe_math_optimizations"
15249   "fsincos"
15250   [(set_attr "type" "fpspc")
15251    (set_attr "mode" "DF")])
15252
15253 (define_split
15254   [(set (match_operand:DF 0 "register_operand" "")
15255         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15256                    UNSPEC_SINCOS_COS))
15257    (set (match_operand:DF 1 "register_operand" "")
15258         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15259   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15260    && !reload_completed && !reload_in_progress"
15261   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15262   "")
15263
15264 (define_split
15265   [(set (match_operand:DF 0 "register_operand" "")
15266         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15267                    UNSPEC_SINCOS_COS))
15268    (set (match_operand:DF 1 "register_operand" "")
15269         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15270   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15271    && !reload_completed && !reload_in_progress"
15272   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15273   "")
15274
15275 (define_insn "sincossf3"
15276   [(set (match_operand:SF 0 "register_operand" "=f")
15277         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15278                    UNSPEC_SINCOS_COS))
15279    (set (match_operand:SF 1 "register_operand" "=u")
15280         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15281   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15282    && flag_unsafe_math_optimizations"
15283   "fsincos"
15284   [(set_attr "type" "fpspc")
15285    (set_attr "mode" "SF")])
15286
15287 (define_split
15288   [(set (match_operand:SF 0 "register_operand" "")
15289         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15290                    UNSPEC_SINCOS_COS))
15291    (set (match_operand:SF 1 "register_operand" "")
15292         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15293   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15294    && !reload_completed && !reload_in_progress"
15295   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15296   "")
15297
15298 (define_split
15299   [(set (match_operand:SF 0 "register_operand" "")
15300         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15301                    UNSPEC_SINCOS_COS))
15302    (set (match_operand:SF 1 "register_operand" "")
15303         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15304   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15305    && !reload_completed && !reload_in_progress"
15306   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15307   "")
15308
15309 (define_insn "*sincosextendsfdf3"
15310   [(set (match_operand:DF 0 "register_operand" "=f")
15311         (unspec:DF [(float_extend:DF
15312                      (match_operand:SF 2 "register_operand" "0"))]
15313                    UNSPEC_SINCOS_COS))
15314    (set (match_operand:DF 1 "register_operand" "=u")
15315         (unspec:DF [(float_extend:DF
15316                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15317   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15318    && flag_unsafe_math_optimizations"
15319   "fsincos"
15320   [(set_attr "type" "fpspc")
15321    (set_attr "mode" "DF")])
15322
15323 (define_split
15324   [(set (match_operand:DF 0 "register_operand" "")
15325         (unspec:DF [(float_extend:DF
15326                      (match_operand:SF 2 "register_operand" ""))]
15327                    UNSPEC_SINCOS_COS))
15328    (set (match_operand:DF 1 "register_operand" "")
15329         (unspec:DF [(float_extend:DF
15330                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15331   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15332    && !reload_completed && !reload_in_progress"
15333   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15334                                    (match_dup 2))] UNSPEC_SIN))]
15335   "")
15336
15337 (define_split
15338   [(set (match_operand:DF 0 "register_operand" "")
15339         (unspec:DF [(float_extend:DF
15340                      (match_operand:SF 2 "register_operand" ""))]
15341                    UNSPEC_SINCOS_COS))
15342    (set (match_operand:DF 1 "register_operand" "")
15343         (unspec:DF [(float_extend:DF
15344                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15345   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15346    && !reload_completed && !reload_in_progress"
15347   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15348                                    (match_dup 2))] UNSPEC_COS))]
15349   "")
15350
15351 (define_insn "sincosxf3"
15352   [(set (match_operand:XF 0 "register_operand" "=f")
15353         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15354                    UNSPEC_SINCOS_COS))
15355    (set (match_operand:XF 1 "register_operand" "=u")
15356         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15357   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15358    && flag_unsafe_math_optimizations"
15359   "fsincos"
15360   [(set_attr "type" "fpspc")
15361    (set_attr "mode" "XF")])
15362
15363 (define_split
15364   [(set (match_operand:XF 0 "register_operand" "")
15365         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15366                    UNSPEC_SINCOS_COS))
15367    (set (match_operand:XF 1 "register_operand" "")
15368         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15369   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15370    && !reload_completed && !reload_in_progress"
15371   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15372   "")
15373
15374 (define_split
15375   [(set (match_operand:XF 0 "register_operand" "")
15376         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15377                    UNSPEC_SINCOS_COS))
15378    (set (match_operand:XF 1 "register_operand" "")
15379         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15380   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15381    && !reload_completed && !reload_in_progress"
15382   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15383   "")
15384
15385 (define_insn "*tandf3_1"
15386   [(set (match_operand:DF 0 "register_operand" "=f")
15387         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15388                    UNSPEC_TAN_ONE))
15389    (set (match_operand:DF 1 "register_operand" "=u")
15390         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15391   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15392    && flag_unsafe_math_optimizations"
15393   "fptan"
15394   [(set_attr "type" "fpspc")
15395    (set_attr "mode" "DF")])
15396
15397 ;; optimize sequence: fptan
15398 ;;                    fstp    %st(0)
15399 ;;                    fld1
15400 ;; into fptan insn.
15401
15402 (define_peephole2
15403   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15404                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15405                              UNSPEC_TAN_ONE))
15406              (set (match_operand:DF 1 "register_operand" "")
15407                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15408    (set (match_dup 0)
15409         (match_operand:DF 3 "immediate_operand" ""))]
15410   "standard_80387_constant_p (operands[3]) == 2"
15411   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15412              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15413   "")
15414
15415 (define_expand "tandf2"
15416   [(parallel [(set (match_dup 2)
15417                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15418                               UNSPEC_TAN_ONE))
15419               (set (match_operand:DF 0 "register_operand" "")
15420                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15421   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15422    && flag_unsafe_math_optimizations"
15423 {
15424   operands[2] = gen_reg_rtx (DFmode);
15425 })
15426
15427 (define_insn "*tansf3_1"
15428   [(set (match_operand:SF 0 "register_operand" "=f")
15429         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15430                    UNSPEC_TAN_ONE))
15431    (set (match_operand:SF 1 "register_operand" "=u")
15432         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15433   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15434    && flag_unsafe_math_optimizations"
15435   "fptan"
15436   [(set_attr "type" "fpspc")
15437    (set_attr "mode" "SF")])
15438
15439 ;; optimize sequence: fptan
15440 ;;                    fstp    %st(0)
15441 ;;                    fld1
15442 ;; into fptan insn.
15443
15444 (define_peephole2
15445   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15446                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15447                              UNSPEC_TAN_ONE))
15448              (set (match_operand:SF 1 "register_operand" "")
15449                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15450    (set (match_dup 0)
15451         (match_operand:SF 3 "immediate_operand" ""))]
15452   "standard_80387_constant_p (operands[3]) == 2"
15453   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15454              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15455   "")
15456
15457 (define_expand "tansf2"
15458   [(parallel [(set (match_dup 2)
15459                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15460                               UNSPEC_TAN_ONE))
15461               (set (match_operand:SF 0 "register_operand" "")
15462                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15463   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15464    && flag_unsafe_math_optimizations"
15465 {
15466   operands[2] = gen_reg_rtx (SFmode);
15467 })
15468
15469 (define_insn "*tanxf3_1"
15470   [(set (match_operand:XF 0 "register_operand" "=f")
15471         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15472                    UNSPEC_TAN_ONE))
15473    (set (match_operand:XF 1 "register_operand" "=u")
15474         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15475   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15476    && flag_unsafe_math_optimizations"
15477   "fptan"
15478   [(set_attr "type" "fpspc")
15479    (set_attr "mode" "XF")])
15480
15481 ;; optimize sequence: fptan
15482 ;;                    fstp    %st(0)
15483 ;;                    fld1
15484 ;; into fptan insn.
15485
15486 (define_peephole2
15487   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15488                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15489                              UNSPEC_TAN_ONE))
15490              (set (match_operand:XF 1 "register_operand" "")
15491                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15492    (set (match_dup 0)
15493         (match_operand:XF 3 "immediate_operand" ""))]
15494   "standard_80387_constant_p (operands[3]) == 2"
15495   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15496              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15497   "")
15498
15499 (define_expand "tanxf2"
15500   [(parallel [(set (match_dup 2)
15501                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15502                               UNSPEC_TAN_ONE))
15503               (set (match_operand:XF 0 "register_operand" "")
15504                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15505   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15506    && flag_unsafe_math_optimizations"
15507 {
15508   operands[2] = gen_reg_rtx (XFmode);
15509 })
15510
15511 (define_insn "atan2df3_1"
15512   [(set (match_operand:DF 0 "register_operand" "=f")
15513         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15514                     (match_operand:DF 1 "register_operand" "u")]
15515                    UNSPEC_FPATAN))
15516    (clobber (match_scratch:DF 3 "=1"))]
15517   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15518    && flag_unsafe_math_optimizations"
15519   "fpatan"
15520   [(set_attr "type" "fpspc")
15521    (set_attr "mode" "DF")])
15522
15523 (define_expand "atan2df3"
15524   [(use (match_operand:DF 0 "register_operand" "=f"))
15525    (use (match_operand:DF 2 "register_operand" "0"))
15526    (use (match_operand:DF 1 "register_operand" "u"))]
15527   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15528    && flag_unsafe_math_optimizations"
15529 {
15530   rtx copy = gen_reg_rtx (DFmode);
15531   emit_move_insn (copy, operands[1]);
15532   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15533   DONE;
15534 })
15535
15536 (define_expand "atandf2"
15537   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15538                    (unspec:DF [(match_dup 2)
15539                                (match_operand:DF 1 "register_operand" "")]
15540                     UNSPEC_FPATAN))
15541               (clobber (match_scratch:DF 3 ""))])]
15542   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15543    && flag_unsafe_math_optimizations"
15544 {
15545   operands[2] = gen_reg_rtx (DFmode);
15546   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15547 })
15548
15549 (define_insn "atan2sf3_1"
15550   [(set (match_operand:SF 0 "register_operand" "=f")
15551         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15552                     (match_operand:SF 1 "register_operand" "u")]
15553                    UNSPEC_FPATAN))
15554    (clobber (match_scratch:SF 3 "=1"))]
15555   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15556    && flag_unsafe_math_optimizations"
15557   "fpatan"
15558   [(set_attr "type" "fpspc")
15559    (set_attr "mode" "SF")])
15560
15561 (define_expand "atan2sf3"
15562   [(use (match_operand:SF 0 "register_operand" "=f"))
15563    (use (match_operand:SF 2 "register_operand" "0"))
15564    (use (match_operand:SF 1 "register_operand" "u"))]
15565   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15566    && flag_unsafe_math_optimizations"
15567 {
15568   rtx copy = gen_reg_rtx (SFmode);
15569   emit_move_insn (copy, operands[1]);
15570   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15571   DONE;
15572 })
15573
15574 (define_expand "atansf2"
15575   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15576                    (unspec:SF [(match_dup 2)
15577                                (match_operand:SF 1 "register_operand" "")]
15578                     UNSPEC_FPATAN))
15579               (clobber (match_scratch:SF 3 ""))])]
15580   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15581    && flag_unsafe_math_optimizations"
15582 {
15583   operands[2] = gen_reg_rtx (SFmode);
15584   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15585 })
15586
15587 (define_insn "atan2xf3_1"
15588   [(set (match_operand:XF 0 "register_operand" "=f")
15589         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15590                     (match_operand:XF 1 "register_operand" "u")]
15591                    UNSPEC_FPATAN))
15592    (clobber (match_scratch:XF 3 "=1"))]
15593   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15594    && flag_unsafe_math_optimizations"
15595   "fpatan"
15596   [(set_attr "type" "fpspc")
15597    (set_attr "mode" "XF")])
15598
15599 (define_expand "atan2xf3"
15600   [(use (match_operand:XF 0 "register_operand" "=f"))
15601    (use (match_operand:XF 2 "register_operand" "0"))
15602    (use (match_operand:XF 1 "register_operand" "u"))]
15603   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15604    && flag_unsafe_math_optimizations"
15605 {
15606   rtx copy = gen_reg_rtx (XFmode);
15607   emit_move_insn (copy, operands[1]);
15608   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15609   DONE;
15610 })
15611
15612 (define_expand "atanxf2"
15613   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15614                    (unspec:XF [(match_dup 2)
15615                                (match_operand:XF 1 "register_operand" "")]
15616                     UNSPEC_FPATAN))
15617               (clobber (match_scratch:XF 3 ""))])]
15618   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15619    && flag_unsafe_math_optimizations"
15620 {
15621   operands[2] = gen_reg_rtx (XFmode);
15622   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15623 })
15624
15625 (define_expand "asindf2"
15626   [(set (match_dup 2)
15627         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15628    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15629    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15630    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15631    (parallel [(set (match_dup 7)
15632                    (unspec:XF [(match_dup 6) (match_dup 2)]
15633                               UNSPEC_FPATAN))
15634               (clobber (match_scratch:XF 8 ""))])
15635    (set (match_operand:DF 0 "register_operand" "")
15636         (float_truncate:DF (match_dup 7)))]
15637   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15638    && flag_unsafe_math_optimizations"
15639 {
15640   int i;
15641
15642   for (i=2; i<8; i++)
15643     operands[i] = gen_reg_rtx (XFmode);
15644
15645   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15646 })
15647
15648 (define_expand "asinsf2"
15649   [(set (match_dup 2)
15650         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15651    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15652    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15653    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15654    (parallel [(set (match_dup 7)
15655                    (unspec:XF [(match_dup 6) (match_dup 2)]
15656                               UNSPEC_FPATAN))
15657               (clobber (match_scratch:XF 8 ""))])
15658    (set (match_operand:SF 0 "register_operand" "")
15659         (float_truncate:SF (match_dup 7)))]
15660   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15661    && flag_unsafe_math_optimizations"
15662 {
15663   int i;
15664
15665   for (i=2; i<8; i++)
15666     operands[i] = gen_reg_rtx (XFmode);
15667
15668   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15669 })
15670
15671 (define_expand "asinxf2"
15672   [(set (match_dup 2)
15673         (mult:XF (match_operand:XF 1 "register_operand" "")
15674                  (match_dup 1)))
15675    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15676    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15677    (parallel [(set (match_operand:XF 0 "register_operand" "")
15678                    (unspec:XF [(match_dup 5) (match_dup 1)]
15679                               UNSPEC_FPATAN))
15680               (clobber (match_scratch:XF 6 ""))])]
15681   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15682    && flag_unsafe_math_optimizations"
15683 {
15684   int i;
15685
15686   for (i=2; i<6; i++)
15687     operands[i] = gen_reg_rtx (XFmode);
15688
15689   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15690 })
15691
15692 (define_expand "acosdf2"
15693   [(set (match_dup 2)
15694         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15695    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15696    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15697    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15698    (parallel [(set (match_dup 7)
15699                    (unspec:XF [(match_dup 2) (match_dup 6)]
15700                               UNSPEC_FPATAN))
15701               (clobber (match_scratch:XF 8 ""))])
15702    (set (match_operand:DF 0 "register_operand" "")
15703         (float_truncate:DF (match_dup 7)))]
15704   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15705    && flag_unsafe_math_optimizations"
15706 {
15707   int i;
15708
15709   for (i=2; i<8; i++)
15710     operands[i] = gen_reg_rtx (XFmode);
15711
15712   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15713 })
15714
15715 (define_expand "acossf2"
15716   [(set (match_dup 2)
15717         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15718    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15719    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15720    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15721    (parallel [(set (match_dup 7)
15722                    (unspec:XF [(match_dup 2) (match_dup 6)]
15723                               UNSPEC_FPATAN))
15724               (clobber (match_scratch:XF 8 ""))])
15725    (set (match_operand:SF 0 "register_operand" "")
15726         (float_truncate:SF (match_dup 7)))]
15727   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15728    && flag_unsafe_math_optimizations"
15729 {
15730   int i;
15731
15732   for (i=2; i<8; i++)
15733     operands[i] = gen_reg_rtx (XFmode);
15734
15735   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15736 })
15737
15738 (define_expand "acosxf2"
15739   [(set (match_dup 2)
15740         (mult:XF (match_operand:XF 1 "register_operand" "")
15741                  (match_dup 1)))
15742    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15743    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15744    (parallel [(set (match_operand:XF 0 "register_operand" "")
15745                    (unspec:XF [(match_dup 1) (match_dup 5)]
15746                               UNSPEC_FPATAN))
15747               (clobber (match_scratch:XF 6 ""))])]
15748   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15749    && flag_unsafe_math_optimizations"
15750 {
15751   int i;
15752
15753   for (i=2; i<6; i++)
15754     operands[i] = gen_reg_rtx (XFmode);
15755
15756   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15757 })
15758
15759 (define_insn "fyl2x_xf3"
15760   [(set (match_operand:XF 0 "register_operand" "=f")
15761         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15762                     (match_operand:XF 1 "register_operand" "u")]
15763                    UNSPEC_FYL2X))
15764    (clobber (match_scratch:XF 3 "=1"))]
15765   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15766    && flag_unsafe_math_optimizations"
15767   "fyl2x"
15768   [(set_attr "type" "fpspc")
15769    (set_attr "mode" "XF")])
15770
15771 (define_expand "logsf2"
15772   [(set (match_dup 2)
15773         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15774    (parallel [(set (match_dup 4)
15775                    (unspec:XF [(match_dup 2)
15776                                (match_dup 3)] UNSPEC_FYL2X))
15777               (clobber (match_scratch:XF 5 ""))])
15778    (set (match_operand:SF 0 "register_operand" "")
15779         (float_truncate:SF (match_dup 4)))]
15780   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15781    && flag_unsafe_math_optimizations"
15782 {
15783   rtx temp;
15784
15785   operands[2] = gen_reg_rtx (XFmode);
15786   operands[3] = gen_reg_rtx (XFmode);
15787   operands[4] = gen_reg_rtx (XFmode);
15788
15789   temp = standard_80387_constant_rtx (4); /* fldln2 */
15790   emit_move_insn (operands[3], temp);
15791 })
15792
15793 (define_expand "logdf2"
15794   [(set (match_dup 2)
15795         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15796    (parallel [(set (match_dup 4)
15797                    (unspec:XF [(match_dup 2)
15798                                (match_dup 3)] UNSPEC_FYL2X))
15799               (clobber (match_scratch:XF 5 ""))])
15800    (set (match_operand:DF 0 "register_operand" "")
15801         (float_truncate:DF (match_dup 4)))]
15802   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15803    && flag_unsafe_math_optimizations"
15804 {
15805   rtx temp;
15806
15807   operands[2] = gen_reg_rtx (XFmode);
15808   operands[3] = gen_reg_rtx (XFmode);
15809   operands[4] = gen_reg_rtx (XFmode);
15810
15811   temp = standard_80387_constant_rtx (4); /* fldln2 */
15812   emit_move_insn (operands[3], temp);
15813 })
15814
15815 (define_expand "logxf2"
15816   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15817                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15818                                (match_dup 2)] UNSPEC_FYL2X))
15819               (clobber (match_scratch:XF 3 ""))])]
15820   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15821    && flag_unsafe_math_optimizations"
15822 {
15823   rtx temp;
15824
15825   operands[2] = gen_reg_rtx (XFmode);
15826   temp = standard_80387_constant_rtx (4); /* fldln2 */
15827   emit_move_insn (operands[2], temp);
15828 })
15829
15830 (define_expand "log10sf2"
15831   [(set (match_dup 2)
15832         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15833    (parallel [(set (match_dup 4)
15834                    (unspec:XF [(match_dup 2)
15835                                (match_dup 3)] UNSPEC_FYL2X))
15836               (clobber (match_scratch:XF 5 ""))])
15837    (set (match_operand:SF 0 "register_operand" "")
15838         (float_truncate:SF (match_dup 4)))]
15839   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15840    && flag_unsafe_math_optimizations"
15841 {
15842   rtx temp;
15843
15844   operands[2] = gen_reg_rtx (XFmode);
15845   operands[3] = gen_reg_rtx (XFmode);
15846   operands[4] = gen_reg_rtx (XFmode);
15847
15848   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15849   emit_move_insn (operands[3], temp);
15850 })
15851
15852 (define_expand "log10df2"
15853   [(set (match_dup 2)
15854         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15855    (parallel [(set (match_dup 4)
15856                    (unspec:XF [(match_dup 2)
15857                                (match_dup 3)] UNSPEC_FYL2X))
15858               (clobber (match_scratch:XF 5 ""))])
15859    (set (match_operand:DF 0 "register_operand" "")
15860         (float_truncate:DF (match_dup 4)))]
15861   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15862    && flag_unsafe_math_optimizations"
15863 {
15864   rtx temp;
15865
15866   operands[2] = gen_reg_rtx (XFmode);
15867   operands[3] = gen_reg_rtx (XFmode);
15868   operands[4] = gen_reg_rtx (XFmode);
15869
15870   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15871   emit_move_insn (operands[3], temp);
15872 })
15873
15874 (define_expand "log10xf2"
15875   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15876                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15877                                (match_dup 2)] UNSPEC_FYL2X))
15878               (clobber (match_scratch:XF 3 ""))])]
15879   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15880    && flag_unsafe_math_optimizations"
15881 {
15882   rtx temp;
15883
15884   operands[2] = gen_reg_rtx (XFmode);
15885   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15886   emit_move_insn (operands[2], temp);
15887 })
15888
15889 (define_expand "log2sf2"
15890   [(set (match_dup 2)
15891         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15892    (parallel [(set (match_dup 4)
15893                    (unspec:XF [(match_dup 2)
15894                                (match_dup 3)] UNSPEC_FYL2X))
15895               (clobber (match_scratch:XF 5 ""))])
15896    (set (match_operand:SF 0 "register_operand" "")
15897         (float_truncate:SF (match_dup 4)))]
15898   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15899    && flag_unsafe_math_optimizations"
15900 {
15901   operands[2] = gen_reg_rtx (XFmode);
15902   operands[3] = gen_reg_rtx (XFmode);
15903   operands[4] = gen_reg_rtx (XFmode);
15904
15905   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15906 })
15907
15908 (define_expand "log2df2"
15909   [(set (match_dup 2)
15910         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15911    (parallel [(set (match_dup 4)
15912                    (unspec:XF [(match_dup 2)
15913                                (match_dup 3)] UNSPEC_FYL2X))
15914               (clobber (match_scratch:XF 5 ""))])
15915    (set (match_operand:DF 0 "register_operand" "")
15916         (float_truncate:DF (match_dup 4)))]
15917   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15918    && flag_unsafe_math_optimizations"
15919 {
15920   operands[2] = gen_reg_rtx (XFmode);
15921   operands[3] = gen_reg_rtx (XFmode);
15922   operands[4] = gen_reg_rtx (XFmode);
15923
15924   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15925 })
15926
15927 (define_expand "log2xf2"
15928   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15929                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15930                                (match_dup 2)] UNSPEC_FYL2X))
15931               (clobber (match_scratch:XF 3 ""))])]
15932   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15933    && flag_unsafe_math_optimizations"
15934 {
15935   operands[2] = gen_reg_rtx (XFmode);
15936   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15937 })
15938
15939 (define_insn "fyl2xp1_xf3"
15940   [(set (match_operand:XF 0 "register_operand" "=f")
15941         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15942                     (match_operand:XF 1 "register_operand" "u")]
15943                    UNSPEC_FYL2XP1))
15944    (clobber (match_scratch:XF 3 "=1"))]
15945   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15946    && flag_unsafe_math_optimizations"
15947   "fyl2xp1"
15948   [(set_attr "type" "fpspc")
15949    (set_attr "mode" "XF")])
15950
15951 (define_expand "log1psf2"
15952   [(use (match_operand:XF 0 "register_operand" ""))
15953    (use (match_operand:XF 1 "register_operand" ""))]
15954   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15955    && flag_unsafe_math_optimizations"
15956 {
15957   rtx op0 = gen_reg_rtx (XFmode);
15958   rtx op1 = gen_reg_rtx (XFmode);
15959
15960   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15961   ix86_emit_i387_log1p (op0, op1);
15962   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15963   DONE;
15964 })
15965
15966 (define_expand "log1pdf2"
15967   [(use (match_operand:XF 0 "register_operand" ""))
15968    (use (match_operand:XF 1 "register_operand" ""))]
15969   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15970    && flag_unsafe_math_optimizations"
15971 {
15972   rtx op0 = gen_reg_rtx (XFmode);
15973   rtx op1 = gen_reg_rtx (XFmode);
15974
15975   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15976   ix86_emit_i387_log1p (op0, op1);
15977   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15978   DONE;
15979 })
15980
15981 (define_expand "log1pxf2"
15982   [(use (match_operand:XF 0 "register_operand" ""))
15983    (use (match_operand:XF 1 "register_operand" ""))]
15984   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15985    && flag_unsafe_math_optimizations"
15986 {
15987   ix86_emit_i387_log1p (operands[0], operands[1]);
15988   DONE;
15989 })
15990
15991 (define_insn "*fxtractxf3"
15992   [(set (match_operand:XF 0 "register_operand" "=f")
15993         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15994                    UNSPEC_XTRACT_FRACT))
15995    (set (match_operand:XF 1 "register_operand" "=u")
15996         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15997   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15998    && flag_unsafe_math_optimizations"
15999   "fxtract"
16000   [(set_attr "type" "fpspc")
16001    (set_attr "mode" "XF")])
16002
16003 (define_expand "logbsf2"
16004   [(set (match_dup 2)
16005         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16006    (parallel [(set (match_dup 3)
16007                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16008               (set (match_dup 4)
16009                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16010    (set (match_operand:SF 0 "register_operand" "")
16011         (float_truncate:SF (match_dup 4)))]
16012   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16013    && flag_unsafe_math_optimizations"
16014 {
16015   operands[2] = gen_reg_rtx (XFmode);
16016   operands[3] = gen_reg_rtx (XFmode);
16017   operands[4] = gen_reg_rtx (XFmode);
16018 })
16019
16020 (define_expand "logbdf2"
16021   [(set (match_dup 2)
16022         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16023    (parallel [(set (match_dup 3)
16024                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16025               (set (match_dup 4)
16026                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16027    (set (match_operand:DF 0 "register_operand" "")
16028         (float_truncate:DF (match_dup 4)))]
16029   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16030    && flag_unsafe_math_optimizations"
16031 {
16032   operands[2] = gen_reg_rtx (XFmode);
16033   operands[3] = gen_reg_rtx (XFmode);
16034   operands[4] = gen_reg_rtx (XFmode);
16035 })
16036
16037 (define_expand "logbxf2"
16038   [(parallel [(set (match_dup 2)
16039                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16040                               UNSPEC_XTRACT_FRACT))
16041               (set (match_operand:XF 0 "register_operand" "")
16042                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16043   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16044    && flag_unsafe_math_optimizations"
16045 {
16046   operands[2] = gen_reg_rtx (XFmode);
16047 })
16048
16049 (define_expand "ilogbsi2"
16050   [(parallel [(set (match_dup 2)
16051                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16052                               UNSPEC_XTRACT_FRACT))
16053               (set (match_operand:XF 3 "register_operand" "")
16054                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16055    (parallel [(set (match_operand:SI 0 "register_operand" "")
16056                    (fix:SI (match_dup 3)))
16057               (clobber (reg:CC FLAGS_REG))])]
16058   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16059    && flag_unsafe_math_optimizations"
16060 {
16061   operands[2] = gen_reg_rtx (XFmode);
16062   operands[3] = gen_reg_rtx (XFmode);
16063 })
16064
16065 (define_insn "*f2xm1xf2"
16066   [(set (match_operand:XF 0 "register_operand" "=f")
16067         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16068          UNSPEC_F2XM1))]
16069   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16070    && flag_unsafe_math_optimizations"
16071   "f2xm1"
16072   [(set_attr "type" "fpspc")
16073    (set_attr "mode" "XF")])
16074
16075 (define_insn "*fscalexf4"
16076   [(set (match_operand:XF 0 "register_operand" "=f")
16077         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16078                     (match_operand:XF 3 "register_operand" "1")]
16079                    UNSPEC_FSCALE_FRACT))
16080    (set (match_operand:XF 1 "register_operand" "=u")
16081         (unspec:XF [(match_dup 2) (match_dup 3)]
16082                    UNSPEC_FSCALE_EXP))]
16083   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16084    && flag_unsafe_math_optimizations"
16085   "fscale"
16086   [(set_attr "type" "fpspc")
16087    (set_attr "mode" "XF")])
16088
16089 (define_expand "expsf2"
16090   [(set (match_dup 2)
16091         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16092    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16093    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16094    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16095    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16096    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16097    (parallel [(set (match_dup 10)
16098                    (unspec:XF [(match_dup 9) (match_dup 5)]
16099                               UNSPEC_FSCALE_FRACT))
16100               (set (match_dup 11)
16101                    (unspec:XF [(match_dup 9) (match_dup 5)]
16102                               UNSPEC_FSCALE_EXP))])
16103    (set (match_operand:SF 0 "register_operand" "")
16104         (float_truncate:SF (match_dup 10)))]
16105   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16106    && flag_unsafe_math_optimizations"
16107 {
16108   rtx temp;
16109   int i;
16110
16111   for (i=2; i<12; i++)
16112     operands[i] = gen_reg_rtx (XFmode);
16113   temp = standard_80387_constant_rtx (5); /* fldl2e */
16114   emit_move_insn (operands[3], temp);
16115   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16116 })
16117
16118 (define_expand "expdf2"
16119   [(set (match_dup 2)
16120         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16121    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16122    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16123    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16124    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16125    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16126    (parallel [(set (match_dup 10)
16127                    (unspec:XF [(match_dup 9) (match_dup 5)]
16128                               UNSPEC_FSCALE_FRACT))
16129               (set (match_dup 11)
16130                    (unspec:XF [(match_dup 9) (match_dup 5)]
16131                               UNSPEC_FSCALE_EXP))])
16132    (set (match_operand:DF 0 "register_operand" "")
16133         (float_truncate:DF (match_dup 10)))]
16134   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16135    && flag_unsafe_math_optimizations"
16136 {
16137   rtx temp;
16138   int i;
16139
16140   for (i=2; i<12; i++)
16141     operands[i] = gen_reg_rtx (XFmode);
16142   temp = standard_80387_constant_rtx (5); /* fldl2e */
16143   emit_move_insn (operands[3], temp);
16144   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16145 })
16146
16147 (define_expand "expxf2"
16148   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16149                                (match_dup 2)))
16150    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16151    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16152    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16153    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16154    (parallel [(set (match_operand:XF 0 "register_operand" "")
16155                    (unspec:XF [(match_dup 8) (match_dup 4)]
16156                               UNSPEC_FSCALE_FRACT))
16157               (set (match_dup 9)
16158                    (unspec:XF [(match_dup 8) (match_dup 4)]
16159                               UNSPEC_FSCALE_EXP))])]
16160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16161    && flag_unsafe_math_optimizations"
16162 {
16163   rtx temp;
16164   int i;
16165
16166   for (i=2; i<10; i++)
16167     operands[i] = gen_reg_rtx (XFmode);
16168   temp = standard_80387_constant_rtx (5); /* fldl2e */
16169   emit_move_insn (operands[2], temp);
16170   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16171 })
16172
16173 (define_expand "exp10sf2"
16174   [(set (match_dup 2)
16175         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16176    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16177    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16178    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16179    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16180    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16181    (parallel [(set (match_dup 10)
16182                    (unspec:XF [(match_dup 9) (match_dup 5)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 11)
16185                    (unspec:XF [(match_dup 9) (match_dup 5)]
16186                               UNSPEC_FSCALE_EXP))])
16187    (set (match_operand:SF 0 "register_operand" "")
16188         (float_truncate:SF (match_dup 10)))]
16189   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16190    && flag_unsafe_math_optimizations"
16191 {
16192   rtx temp;
16193   int i;
16194
16195   for (i=2; i<12; i++)
16196     operands[i] = gen_reg_rtx (XFmode);
16197   temp = standard_80387_constant_rtx (6); /* fldl2t */
16198   emit_move_insn (operands[3], temp);
16199   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16200 })
16201
16202 (define_expand "exp10df2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16206    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16207    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16208    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16209    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16210    (parallel [(set (match_dup 10)
16211                    (unspec:XF [(match_dup 9) (match_dup 5)]
16212                               UNSPEC_FSCALE_FRACT))
16213               (set (match_dup 11)
16214                    (unspec:XF [(match_dup 9) (match_dup 5)]
16215                               UNSPEC_FSCALE_EXP))])
16216    (set (match_operand:DF 0 "register_operand" "")
16217         (float_truncate:DF (match_dup 10)))]
16218   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16219    && flag_unsafe_math_optimizations"
16220 {
16221   rtx temp;
16222   int i;
16223
16224   for (i=2; i<12; i++)
16225     operands[i] = gen_reg_rtx (XFmode);
16226   temp = standard_80387_constant_rtx (6); /* fldl2t */
16227   emit_move_insn (operands[3], temp);
16228   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16229 })
16230
16231 (define_expand "exp10xf2"
16232   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16233                                (match_dup 2)))
16234    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16235    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16236    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16237    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16238    (parallel [(set (match_operand:XF 0 "register_operand" "")
16239                    (unspec:XF [(match_dup 8) (match_dup 4)]
16240                               UNSPEC_FSCALE_FRACT))
16241               (set (match_dup 9)
16242                    (unspec:XF [(match_dup 8) (match_dup 4)]
16243                               UNSPEC_FSCALE_EXP))])]
16244   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   rtx temp;
16248   int i;
16249
16250   for (i=2; i<10; i++)
16251     operands[i] = gen_reg_rtx (XFmode);
16252   temp = standard_80387_constant_rtx (6); /* fldl2t */
16253   emit_move_insn (operands[2], temp);
16254   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16255 })
16256
16257 (define_expand "exp2sf2"
16258   [(set (match_dup 2)
16259         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16260    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16261    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16262    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16263    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16264    (parallel [(set (match_dup 8)
16265                    (unspec:XF [(match_dup 7) (match_dup 3)]
16266                               UNSPEC_FSCALE_FRACT))
16267               (set (match_dup 9)
16268                    (unspec:XF [(match_dup 7) (match_dup 3)]
16269                               UNSPEC_FSCALE_EXP))])
16270    (set (match_operand:SF 0 "register_operand" "")
16271         (float_truncate:SF (match_dup 8)))]
16272   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16273    && flag_unsafe_math_optimizations"
16274 {
16275   int i;
16276
16277   for (i=2; i<10; i++)
16278     operands[i] = gen_reg_rtx (XFmode);
16279   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16280 })
16281
16282 (define_expand "exp2df2"
16283   [(set (match_dup 2)
16284         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16285    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16286    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16287    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16288    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16289    (parallel [(set (match_dup 8)
16290                    (unspec:XF [(match_dup 7) (match_dup 3)]
16291                               UNSPEC_FSCALE_FRACT))
16292               (set (match_dup 9)
16293                    (unspec:XF [(match_dup 7) (match_dup 3)]
16294                               UNSPEC_FSCALE_EXP))])
16295    (set (match_operand:DF 0 "register_operand" "")
16296         (float_truncate:DF (match_dup 8)))]
16297   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16298    && flag_unsafe_math_optimizations"
16299 {
16300   int i;
16301
16302   for (i=2; i<10; i++)
16303     operands[i] = gen_reg_rtx (XFmode);
16304   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16305 })
16306
16307 (define_expand "exp2xf2"
16308   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16309    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16310    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16311    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16312    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16313    (parallel [(set (match_operand:XF 0 "register_operand" "")
16314                    (unspec:XF [(match_dup 7) (match_dup 3)]
16315                               UNSPEC_FSCALE_FRACT))
16316               (set (match_dup 8)
16317                    (unspec:XF [(match_dup 7) (match_dup 3)]
16318                               UNSPEC_FSCALE_EXP))])]
16319   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16320    && flag_unsafe_math_optimizations"
16321 {
16322   int i;
16323
16324   for (i=2; i<9; i++)
16325     operands[i] = gen_reg_rtx (XFmode);
16326   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16327 })
16328
16329 (define_expand "expm1df2"
16330   [(set (match_dup 2)
16331         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16332    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16333    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16334    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16335    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16336    (parallel [(set (match_dup 8)
16337                    (unspec:XF [(match_dup 7) (match_dup 5)]
16338                               UNSPEC_FSCALE_FRACT))
16339                    (set (match_dup 9)
16340                    (unspec:XF [(match_dup 7) (match_dup 5)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (parallel [(set (match_dup 11)
16343                    (unspec:XF [(match_dup 10) (match_dup 9)]
16344                               UNSPEC_FSCALE_FRACT))
16345               (set (match_dup 12)
16346                    (unspec:XF [(match_dup 10) (match_dup 9)]
16347                               UNSPEC_FSCALE_EXP))])
16348    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16349    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16350    (set (match_operand:DF 0 "register_operand" "")
16351         (float_truncate:DF (match_dup 14)))]
16352   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16353    && flag_unsafe_math_optimizations"
16354 {
16355   rtx temp;
16356   int i;
16357
16358   for (i=2; i<15; i++)
16359     operands[i] = gen_reg_rtx (XFmode);
16360   temp = standard_80387_constant_rtx (5); /* fldl2e */
16361   emit_move_insn (operands[3], temp);
16362   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16363 })
16364
16365 (define_expand "expm1sf2"
16366   [(set (match_dup 2)
16367         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16368    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16369    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16370    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16371    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16372    (parallel [(set (match_dup 8)
16373                    (unspec:XF [(match_dup 7) (match_dup 5)]
16374                               UNSPEC_FSCALE_FRACT))
16375                    (set (match_dup 9)
16376                    (unspec:XF [(match_dup 7) (match_dup 5)]
16377                               UNSPEC_FSCALE_EXP))])
16378    (parallel [(set (match_dup 11)
16379                    (unspec:XF [(match_dup 10) (match_dup 9)]
16380                               UNSPEC_FSCALE_FRACT))
16381               (set (match_dup 12)
16382                    (unspec:XF [(match_dup 10) (match_dup 9)]
16383                               UNSPEC_FSCALE_EXP))])
16384    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16385    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16386    (set (match_operand:SF 0 "register_operand" "")
16387         (float_truncate:SF (match_dup 14)))]
16388   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16389    && flag_unsafe_math_optimizations"
16390 {
16391   rtx temp;
16392   int i;
16393
16394   for (i=2; i<15; i++)
16395     operands[i] = gen_reg_rtx (XFmode);
16396   temp = standard_80387_constant_rtx (5); /* fldl2e */
16397   emit_move_insn (operands[3], temp);
16398   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16399 })
16400
16401 (define_expand "expm1xf2"
16402   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16403                                (match_dup 2)))
16404    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16405    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16406    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16407    (parallel [(set (match_dup 7)
16408                    (unspec:XF [(match_dup 6) (match_dup 4)]
16409                               UNSPEC_FSCALE_FRACT))
16410                    (set (match_dup 8)
16411                    (unspec:XF [(match_dup 6) (match_dup 4)]
16412                               UNSPEC_FSCALE_EXP))])
16413    (parallel [(set (match_dup 10)
16414                    (unspec:XF [(match_dup 9) (match_dup 8)]
16415                               UNSPEC_FSCALE_FRACT))
16416               (set (match_dup 11)
16417                    (unspec:XF [(match_dup 9) (match_dup 8)]
16418                               UNSPEC_FSCALE_EXP))])
16419    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16420    (set (match_operand:XF 0 "register_operand" "")
16421         (plus:XF (match_dup 12) (match_dup 7)))]
16422   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16423    && flag_unsafe_math_optimizations"
16424 {
16425   rtx temp;
16426   int i;
16427
16428   for (i=2; i<13; i++)
16429     operands[i] = gen_reg_rtx (XFmode);
16430   temp = standard_80387_constant_rtx (5); /* fldl2e */
16431   emit_move_insn (operands[2], temp);
16432   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16433 })
16434 \f
16435
16436 (define_insn "frndintxf2"
16437   [(set (match_operand:XF 0 "register_operand" "=f")
16438         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16439          UNSPEC_FRNDINT))]
16440   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16441    && flag_unsafe_math_optimizations"
16442   "frndint"
16443   [(set_attr "type" "fpspc")
16444    (set_attr "mode" "XF")])
16445
16446 (define_expand "rintdf2"
16447   [(use (match_operand:DF 0 "register_operand" ""))
16448    (use (match_operand:DF 1 "register_operand" ""))]
16449   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16450    && flag_unsafe_math_optimizations"
16451 {
16452   rtx op0 = gen_reg_rtx (XFmode);
16453   rtx op1 = gen_reg_rtx (XFmode);
16454
16455   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16456   emit_insn (gen_frndintxf2 (op0, op1));
16457
16458   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16459   DONE;
16460 })
16461
16462 (define_expand "rintsf2"
16463   [(use (match_operand:SF 0 "register_operand" ""))
16464    (use (match_operand:SF 1 "register_operand" ""))]
16465   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16466    && flag_unsafe_math_optimizations"
16467 {
16468   rtx op0 = gen_reg_rtx (XFmode);
16469   rtx op1 = gen_reg_rtx (XFmode);
16470
16471   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16472   emit_insn (gen_frndintxf2 (op0, op1));
16473
16474   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16475   DONE;
16476 })
16477
16478 (define_expand "rintxf2"
16479   [(use (match_operand:XF 0 "register_operand" ""))
16480    (use (match_operand:XF 1 "register_operand" ""))]
16481   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16482    && flag_unsafe_math_optimizations"
16483 {
16484   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16485   DONE;
16486 })
16487
16488 (define_insn "frndintxf2_floor"
16489   [(set (match_operand:XF 0 "register_operand" "=f")
16490         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16491          UNSPEC_FRNDINT_FLOOR))
16492    (use (match_operand:HI 2 "memory_operand" "m"))
16493    (use (match_operand:HI 3 "memory_operand" "m"))]
16494   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16495    && flag_unsafe_math_optimizations"
16496   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16497   [(set_attr "type" "frndint")
16498    (set_attr "i387_cw" "floor")
16499    (set_attr "mode" "XF")])
16500
16501 (define_expand "floordf2"
16502   [(use (match_operand:DF 0 "register_operand" ""))
16503    (use (match_operand:DF 1 "register_operand" ""))]
16504   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16505    && flag_unsafe_math_optimizations"
16506 {
16507   rtx op0 = gen_reg_rtx (XFmode);
16508   rtx op1 = gen_reg_rtx (XFmode);
16509   rtx op2 = assign_386_stack_local (HImode, 1);
16510   rtx op3 = assign_386_stack_local (HImode, 2);
16511         
16512   ix86_optimize_mode_switching = 1;
16513
16514   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16515   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16516
16517   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16518   DONE;
16519 })
16520
16521 (define_expand "floorsf2"
16522   [(use (match_operand:SF 0 "register_operand" ""))
16523    (use (match_operand:SF 1 "register_operand" ""))]
16524   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16525    && flag_unsafe_math_optimizations"
16526 {
16527   rtx op0 = gen_reg_rtx (XFmode);
16528   rtx op1 = gen_reg_rtx (XFmode);
16529   rtx op2 = assign_386_stack_local (HImode, 1);
16530   rtx op3 = assign_386_stack_local (HImode, 2);
16531         
16532   ix86_optimize_mode_switching = 1;
16533
16534   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16535   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16536
16537   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16538   DONE;
16539 })
16540
16541 (define_expand "floorxf2"
16542   [(use (match_operand:XF 0 "register_operand" ""))
16543    (use (match_operand:XF 1 "register_operand" ""))]
16544   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16545    && flag_unsafe_math_optimizations"
16546 {
16547   rtx op2 = assign_386_stack_local (HImode, 1);
16548   rtx op3 = assign_386_stack_local (HImode, 2);
16549         
16550   ix86_optimize_mode_switching = 1;
16551
16552   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16553   DONE;
16554 })
16555
16556 (define_insn "frndintxf2_ceil"
16557   [(set (match_operand:XF 0 "register_operand" "=f")
16558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16559          UNSPEC_FRNDINT_CEIL))
16560    (use (match_operand:HI 2 "memory_operand" "m"))
16561    (use (match_operand:HI 3 "memory_operand" "m"))]
16562   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16563    && flag_unsafe_math_optimizations"
16564   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16565   [(set_attr "type" "frndint")
16566    (set_attr "i387_cw" "ceil")
16567    (set_attr "mode" "XF")])
16568
16569 (define_expand "ceildf2"
16570   [(use (match_operand:DF 0 "register_operand" ""))
16571    (use (match_operand:DF 1 "register_operand" ""))]
16572   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16573    && flag_unsafe_math_optimizations"
16574 {
16575   rtx op0 = gen_reg_rtx (XFmode);
16576   rtx op1 = gen_reg_rtx (XFmode);
16577   rtx op2 = assign_386_stack_local (HImode, 1);
16578   rtx op3 = assign_386_stack_local (HImode, 2);
16579         
16580   ix86_optimize_mode_switching = 1;
16581
16582   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16583   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16584
16585   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16586   DONE;
16587 })
16588
16589 (define_expand "ceilsf2"
16590   [(use (match_operand:SF 0 "register_operand" ""))
16591    (use (match_operand:SF 1 "register_operand" ""))]
16592   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16593    && flag_unsafe_math_optimizations"
16594 {
16595   rtx op0 = gen_reg_rtx (XFmode);
16596   rtx op1 = gen_reg_rtx (XFmode);
16597   rtx op2 = assign_386_stack_local (HImode, 1);
16598   rtx op3 = assign_386_stack_local (HImode, 2);
16599         
16600   ix86_optimize_mode_switching = 1;
16601
16602   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16603   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16604
16605   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16606   DONE;
16607 })
16608
16609 (define_expand "ceilxf2"
16610   [(use (match_operand:XF 0 "register_operand" ""))
16611    (use (match_operand:XF 1 "register_operand" ""))]
16612   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16613    && flag_unsafe_math_optimizations"
16614 {
16615   rtx op2 = assign_386_stack_local (HImode, 1);
16616   rtx op3 = assign_386_stack_local (HImode, 2);
16617         
16618   ix86_optimize_mode_switching = 1;
16619
16620   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16621   DONE;
16622 })
16623
16624 (define_insn "frndintxf2_trunc"
16625   [(set (match_operand:XF 0 "register_operand" "=f")
16626         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16627          UNSPEC_FRNDINT_TRUNC))
16628    (use (match_operand:HI 2 "memory_operand" "m"))
16629    (use (match_operand:HI 3 "memory_operand" "m"))]
16630   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16631    && flag_unsafe_math_optimizations"
16632   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16633   [(set_attr "type" "frndint")
16634    (set_attr "i387_cw" "trunc")
16635    (set_attr "mode" "XF")])
16636
16637 (define_expand "btruncdf2"
16638   [(use (match_operand:DF 0 "register_operand" ""))
16639    (use (match_operand:DF 1 "register_operand" ""))]
16640   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16641    && flag_unsafe_math_optimizations"
16642 {
16643   rtx op0 = gen_reg_rtx (XFmode);
16644   rtx op1 = gen_reg_rtx (XFmode);
16645   rtx op2 = assign_386_stack_local (HImode, 1);
16646   rtx op3 = assign_386_stack_local (HImode, 2);
16647         
16648   ix86_optimize_mode_switching = 1;
16649
16650   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16651   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16652
16653   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16654   DONE;
16655 })
16656
16657 (define_expand "btruncsf2"
16658   [(use (match_operand:SF 0 "register_operand" ""))
16659    (use (match_operand:SF 1 "register_operand" ""))]
16660   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16661    && flag_unsafe_math_optimizations"
16662 {
16663   rtx op0 = gen_reg_rtx (XFmode);
16664   rtx op1 = gen_reg_rtx (XFmode);
16665   rtx op2 = assign_386_stack_local (HImode, 1);
16666   rtx op3 = assign_386_stack_local (HImode, 2);
16667         
16668   ix86_optimize_mode_switching = 1;
16669
16670   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16671   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16672
16673   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16674   DONE;
16675 })
16676
16677 (define_expand "btruncxf2"
16678   [(use (match_operand:XF 0 "register_operand" ""))
16679    (use (match_operand:XF 1 "register_operand" ""))]
16680   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16681    && flag_unsafe_math_optimizations"
16682 {
16683   rtx op2 = assign_386_stack_local (HImode, 1);
16684   rtx op3 = assign_386_stack_local (HImode, 2);
16685         
16686   ix86_optimize_mode_switching = 1;
16687
16688   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16689   DONE;
16690 })
16691
16692 (define_insn "frndintxf2_mask_pm"
16693   [(set (match_operand:XF 0 "register_operand" "=f")
16694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16695          UNSPEC_FRNDINT_MASK_PM))
16696    (use (match_operand:HI 2 "memory_operand" "m"))
16697    (use (match_operand:HI 3 "memory_operand" "m"))]
16698   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16699    && flag_unsafe_math_optimizations"
16700   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16701   [(set_attr "type" "frndint")
16702    (set_attr "i387_cw" "mask_pm")
16703    (set_attr "mode" "XF")])
16704
16705 (define_expand "nearbyintdf2"
16706   [(use (match_operand:DF 0 "register_operand" ""))
16707    (use (match_operand:DF 1 "register_operand" ""))]
16708   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16709    && flag_unsafe_math_optimizations"
16710 {
16711   rtx op0 = gen_reg_rtx (XFmode);
16712   rtx op1 = gen_reg_rtx (XFmode);
16713   rtx op2 = assign_386_stack_local (HImode, 1);
16714   rtx op3 = assign_386_stack_local (HImode, 2);
16715         
16716   ix86_optimize_mode_switching = 1;
16717
16718   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16719   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16720
16721   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16722   DONE;
16723 })
16724
16725 (define_expand "nearbyintsf2"
16726   [(use (match_operand:SF 0 "register_operand" ""))
16727    (use (match_operand:SF 1 "register_operand" ""))]
16728   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16729    && flag_unsafe_math_optimizations"
16730 {
16731   rtx op0 = gen_reg_rtx (XFmode);
16732   rtx op1 = gen_reg_rtx (XFmode);
16733   rtx op2 = assign_386_stack_local (HImode, 1);
16734   rtx op3 = assign_386_stack_local (HImode, 2);
16735         
16736   ix86_optimize_mode_switching = 1;
16737
16738   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16739   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16740
16741   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16742   DONE;
16743 })
16744
16745 (define_expand "nearbyintxf2"
16746   [(use (match_operand:XF 0 "register_operand" ""))
16747    (use (match_operand:XF 1 "register_operand" ""))]
16748   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16749    && flag_unsafe_math_optimizations"
16750 {
16751   rtx op2 = assign_386_stack_local (HImode, 1);
16752   rtx op3 = assign_386_stack_local (HImode, 2);
16753         
16754   ix86_optimize_mode_switching = 1;
16755
16756   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16757                                      op2, op3));
16758   DONE;
16759 })
16760
16761 \f
16762 ;; Block operation instructions
16763
16764 (define_insn "cld"
16765  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16766  ""
16767  "cld"
16768   [(set_attr "type" "cld")])
16769
16770 (define_expand "movmemsi"
16771   [(use (match_operand:BLK 0 "memory_operand" ""))
16772    (use (match_operand:BLK 1 "memory_operand" ""))
16773    (use (match_operand:SI 2 "nonmemory_operand" ""))
16774    (use (match_operand:SI 3 "const_int_operand" ""))]
16775   "! optimize_size"
16776 {
16777  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16778    DONE;
16779  else
16780    FAIL;
16781 })
16782
16783 (define_expand "movmemdi"
16784   [(use (match_operand:BLK 0 "memory_operand" ""))
16785    (use (match_operand:BLK 1 "memory_operand" ""))
16786    (use (match_operand:DI 2 "nonmemory_operand" ""))
16787    (use (match_operand:DI 3 "const_int_operand" ""))]
16788   "TARGET_64BIT"
16789 {
16790  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16791    DONE;
16792  else
16793    FAIL;
16794 })
16795
16796 ;; Most CPUs don't like single string operations
16797 ;; Handle this case here to simplify previous expander.
16798
16799 (define_expand "strmov"
16800   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16801    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16802    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16803               (clobber (reg:CC FLAGS_REG))])
16804    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16805               (clobber (reg:CC FLAGS_REG))])]
16806   ""
16807 {
16808   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16809
16810   /* If .md ever supports :P for Pmode, these can be directly
16811      in the pattern above.  */
16812   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16813   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16814
16815   if (TARGET_SINGLE_STRINGOP || optimize_size)
16816     {
16817       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16818                                       operands[2], operands[3],
16819                                       operands[5], operands[6]));
16820       DONE;
16821     }
16822
16823   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16824 })
16825
16826 (define_expand "strmov_singleop"
16827   [(parallel [(set (match_operand 1 "memory_operand" "")
16828                    (match_operand 3 "memory_operand" ""))
16829               (set (match_operand 0 "register_operand" "")
16830                    (match_operand 4 "" ""))
16831               (set (match_operand 2 "register_operand" "")
16832                    (match_operand 5 "" ""))
16833               (use (reg:SI DIRFLAG_REG))])]
16834   "TARGET_SINGLE_STRINGOP || optimize_size"
16835   "")
16836
16837 (define_insn "*strmovdi_rex_1"
16838   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16839         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16840    (set (match_operand:DI 0 "register_operand" "=D")
16841         (plus:DI (match_dup 2)
16842                  (const_int 8)))
16843    (set (match_operand:DI 1 "register_operand" "=S")
16844         (plus:DI (match_dup 3)
16845                  (const_int 8)))
16846    (use (reg:SI DIRFLAG_REG))]
16847   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16848   "movsq"
16849   [(set_attr "type" "str")
16850    (set_attr "mode" "DI")
16851    (set_attr "memory" "both")])
16852
16853 (define_insn "*strmovsi_1"
16854   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16855         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16856    (set (match_operand:SI 0 "register_operand" "=D")
16857         (plus:SI (match_dup 2)
16858                  (const_int 4)))
16859    (set (match_operand:SI 1 "register_operand" "=S")
16860         (plus:SI (match_dup 3)
16861                  (const_int 4)))
16862    (use (reg:SI DIRFLAG_REG))]
16863   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16864   "{movsl|movsd}"
16865   [(set_attr "type" "str")
16866    (set_attr "mode" "SI")
16867    (set_attr "memory" "both")])
16868
16869 (define_insn "*strmovsi_rex_1"
16870   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16871         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16872    (set (match_operand:DI 0 "register_operand" "=D")
16873         (plus:DI (match_dup 2)
16874                  (const_int 4)))
16875    (set (match_operand:DI 1 "register_operand" "=S")
16876         (plus:DI (match_dup 3)
16877                  (const_int 4)))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880   "{movsl|movsd}"
16881   [(set_attr "type" "str")
16882    (set_attr "mode" "SI")
16883    (set_attr "memory" "both")])
16884
16885 (define_insn "*strmovhi_1"
16886   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16887         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16888    (set (match_operand:SI 0 "register_operand" "=D")
16889         (plus:SI (match_dup 2)
16890                  (const_int 2)))
16891    (set (match_operand:SI 1 "register_operand" "=S")
16892         (plus:SI (match_dup 3)
16893                  (const_int 2)))
16894    (use (reg:SI DIRFLAG_REG))]
16895   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16896   "movsw"
16897   [(set_attr "type" "str")
16898    (set_attr "memory" "both")
16899    (set_attr "mode" "HI")])
16900
16901 (define_insn "*strmovhi_rex_1"
16902   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16903         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16904    (set (match_operand:DI 0 "register_operand" "=D")
16905         (plus:DI (match_dup 2)
16906                  (const_int 2)))
16907    (set (match_operand:DI 1 "register_operand" "=S")
16908         (plus:DI (match_dup 3)
16909                  (const_int 2)))
16910    (use (reg:SI DIRFLAG_REG))]
16911   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16912   "movsw"
16913   [(set_attr "type" "str")
16914    (set_attr "memory" "both")
16915    (set_attr "mode" "HI")])
16916
16917 (define_insn "*strmovqi_1"
16918   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16919         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16920    (set (match_operand:SI 0 "register_operand" "=D")
16921         (plus:SI (match_dup 2)
16922                  (const_int 1)))
16923    (set (match_operand:SI 1 "register_operand" "=S")
16924         (plus:SI (match_dup 3)
16925                  (const_int 1)))
16926    (use (reg:SI DIRFLAG_REG))]
16927   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16928   "movsb"
16929   [(set_attr "type" "str")
16930    (set_attr "memory" "both")
16931    (set_attr "mode" "QI")])
16932
16933 (define_insn "*strmovqi_rex_1"
16934   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16935         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16936    (set (match_operand:DI 0 "register_operand" "=D")
16937         (plus:DI (match_dup 2)
16938                  (const_int 1)))
16939    (set (match_operand:DI 1 "register_operand" "=S")
16940         (plus:DI (match_dup 3)
16941                  (const_int 1)))
16942    (use (reg:SI DIRFLAG_REG))]
16943   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16944   "movsb"
16945   [(set_attr "type" "str")
16946    (set_attr "memory" "both")
16947    (set_attr "mode" "QI")])
16948
16949 (define_expand "rep_mov"
16950   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16951               (set (match_operand 0 "register_operand" "")
16952                    (match_operand 5 "" ""))
16953               (set (match_operand 2 "register_operand" "")
16954                    (match_operand 6 "" ""))
16955               (set (match_operand 1 "memory_operand" "")
16956                    (match_operand 3 "memory_operand" ""))
16957               (use (match_dup 4))
16958               (use (reg:SI DIRFLAG_REG))])]
16959   ""
16960   "")
16961
16962 (define_insn "*rep_movdi_rex64"
16963   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16964    (set (match_operand:DI 0 "register_operand" "=D") 
16965         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16966                             (const_int 3))
16967                  (match_operand:DI 3 "register_operand" "0")))
16968    (set (match_operand:DI 1 "register_operand" "=S") 
16969         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16970                  (match_operand:DI 4 "register_operand" "1")))
16971    (set (mem:BLK (match_dup 3))
16972         (mem:BLK (match_dup 4)))
16973    (use (match_dup 5))
16974    (use (reg:SI DIRFLAG_REG))]
16975   "TARGET_64BIT"
16976   "{rep\;movsq|rep movsq}"
16977   [(set_attr "type" "str")
16978    (set_attr "prefix_rep" "1")
16979    (set_attr "memory" "both")
16980    (set_attr "mode" "DI")])
16981
16982 (define_insn "*rep_movsi"
16983   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16984    (set (match_operand:SI 0 "register_operand" "=D") 
16985         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16986                             (const_int 2))
16987                  (match_operand:SI 3 "register_operand" "0")))
16988    (set (match_operand:SI 1 "register_operand" "=S") 
16989         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16990                  (match_operand:SI 4 "register_operand" "1")))
16991    (set (mem:BLK (match_dup 3))
16992         (mem:BLK (match_dup 4)))
16993    (use (match_dup 5))
16994    (use (reg:SI DIRFLAG_REG))]
16995   "!TARGET_64BIT"
16996   "{rep\;movsl|rep movsd}"
16997   [(set_attr "type" "str")
16998    (set_attr "prefix_rep" "1")
16999    (set_attr "memory" "both")
17000    (set_attr "mode" "SI")])
17001
17002 (define_insn "*rep_movsi_rex64"
17003   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17004    (set (match_operand:DI 0 "register_operand" "=D") 
17005         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17006                             (const_int 2))
17007                  (match_operand:DI 3 "register_operand" "0")))
17008    (set (match_operand:DI 1 "register_operand" "=S") 
17009         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17010                  (match_operand:DI 4 "register_operand" "1")))
17011    (set (mem:BLK (match_dup 3))
17012         (mem:BLK (match_dup 4)))
17013    (use (match_dup 5))
17014    (use (reg:SI DIRFLAG_REG))]
17015   "TARGET_64BIT"
17016   "{rep\;movsl|rep movsd}"
17017   [(set_attr "type" "str")
17018    (set_attr "prefix_rep" "1")
17019    (set_attr "memory" "both")
17020    (set_attr "mode" "SI")])
17021
17022 (define_insn "*rep_movqi"
17023   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17024    (set (match_operand:SI 0 "register_operand" "=D") 
17025         (plus:SI (match_operand:SI 3 "register_operand" "0")
17026                  (match_operand:SI 5 "register_operand" "2")))
17027    (set (match_operand:SI 1 "register_operand" "=S") 
17028         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17029    (set (mem:BLK (match_dup 3))
17030         (mem:BLK (match_dup 4)))
17031    (use (match_dup 5))
17032    (use (reg:SI DIRFLAG_REG))]
17033   "!TARGET_64BIT"
17034   "{rep\;movsb|rep movsb}"
17035   [(set_attr "type" "str")
17036    (set_attr "prefix_rep" "1")
17037    (set_attr "memory" "both")
17038    (set_attr "mode" "SI")])
17039
17040 (define_insn "*rep_movqi_rex64"
17041   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17042    (set (match_operand:DI 0 "register_operand" "=D") 
17043         (plus:DI (match_operand:DI 3 "register_operand" "0")
17044                  (match_operand:DI 5 "register_operand" "2")))
17045    (set (match_operand:DI 1 "register_operand" "=S") 
17046         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17047    (set (mem:BLK (match_dup 3))
17048         (mem:BLK (match_dup 4)))
17049    (use (match_dup 5))
17050    (use (reg:SI DIRFLAG_REG))]
17051   "TARGET_64BIT"
17052   "{rep\;movsb|rep movsb}"
17053   [(set_attr "type" "str")
17054    (set_attr "prefix_rep" "1")
17055    (set_attr "memory" "both")
17056    (set_attr "mode" "SI")])
17057
17058 (define_expand "clrmemsi"
17059    [(use (match_operand:BLK 0 "memory_operand" ""))
17060     (use (match_operand:SI 1 "nonmemory_operand" ""))
17061     (use (match_operand 2 "const_int_operand" ""))]
17062   ""
17063 {
17064  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17065    DONE;
17066  else
17067    FAIL;
17068 })
17069
17070 (define_expand "clrmemdi"
17071    [(use (match_operand:BLK 0 "memory_operand" ""))
17072     (use (match_operand:DI 1 "nonmemory_operand" ""))
17073     (use (match_operand 2 "const_int_operand" ""))]
17074   "TARGET_64BIT"
17075 {
17076  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17077    DONE;
17078  else
17079    FAIL;
17080 })
17081
17082 ;; Most CPUs don't like single string operations
17083 ;; Handle this case here to simplify previous expander.
17084
17085 (define_expand "strset"
17086   [(set (match_operand 1 "memory_operand" "")
17087         (match_operand 2 "register_operand" ""))
17088    (parallel [(set (match_operand 0 "register_operand" "")
17089                    (match_dup 3))
17090               (clobber (reg:CC FLAGS_REG))])]
17091   ""
17092 {
17093   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17094     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17095
17096   /* If .md ever supports :P for Pmode, this can be directly
17097      in the pattern above.  */
17098   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17099                               GEN_INT (GET_MODE_SIZE (GET_MODE
17100                                                       (operands[2]))));
17101   if (TARGET_SINGLE_STRINGOP || optimize_size)
17102     {
17103       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17104                                       operands[3]));
17105       DONE;
17106     }
17107 })
17108
17109 (define_expand "strset_singleop"
17110   [(parallel [(set (match_operand 1 "memory_operand" "")
17111                    (match_operand 2 "register_operand" ""))
17112               (set (match_operand 0 "register_operand" "")
17113                    (match_operand 3 "" ""))
17114               (use (reg:SI DIRFLAG_REG))])]
17115   "TARGET_SINGLE_STRINGOP || optimize_size"
17116   "")
17117
17118 (define_insn "*strsetdi_rex_1"
17119   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17120         (match_operand:DI 2 "register_operand" "a"))
17121    (set (match_operand:DI 0 "register_operand" "=D")
17122         (plus:DI (match_dup 1)
17123                  (const_int 8)))
17124    (use (reg:SI DIRFLAG_REG))]
17125   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17126   "stosq"
17127   [(set_attr "type" "str")
17128    (set_attr "memory" "store")
17129    (set_attr "mode" "DI")])
17130
17131 (define_insn "*strsetsi_1"
17132   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17133         (match_operand:SI 2 "register_operand" "a"))
17134    (set (match_operand:SI 0 "register_operand" "=D")
17135         (plus:SI (match_dup 1)
17136                  (const_int 4)))
17137    (use (reg:SI DIRFLAG_REG))]
17138   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17139   "{stosl|stosd}"
17140   [(set_attr "type" "str")
17141    (set_attr "memory" "store")
17142    (set_attr "mode" "SI")])
17143
17144 (define_insn "*strsetsi_rex_1"
17145   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17146         (match_operand:SI 2 "register_operand" "a"))
17147    (set (match_operand:DI 0 "register_operand" "=D")
17148         (plus:DI (match_dup 1)
17149                  (const_int 4)))
17150    (use (reg:SI DIRFLAG_REG))]
17151   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17152   "{stosl|stosd}"
17153   [(set_attr "type" "str")
17154    (set_attr "memory" "store")
17155    (set_attr "mode" "SI")])
17156
17157 (define_insn "*strsethi_1"
17158   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17159         (match_operand:HI 2 "register_operand" "a"))
17160    (set (match_operand:SI 0 "register_operand" "=D")
17161         (plus:SI (match_dup 1)
17162                  (const_int 2)))
17163    (use (reg:SI DIRFLAG_REG))]
17164   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17165   "stosw"
17166   [(set_attr "type" "str")
17167    (set_attr "memory" "store")
17168    (set_attr "mode" "HI")])
17169
17170 (define_insn "*strsethi_rex_1"
17171   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17172         (match_operand:HI 2 "register_operand" "a"))
17173    (set (match_operand:DI 0 "register_operand" "=D")
17174         (plus:DI (match_dup 1)
17175                  (const_int 2)))
17176    (use (reg:SI DIRFLAG_REG))]
17177   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17178   "stosw"
17179   [(set_attr "type" "str")
17180    (set_attr "memory" "store")
17181    (set_attr "mode" "HI")])
17182
17183 (define_insn "*strsetqi_1"
17184   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17185         (match_operand:QI 2 "register_operand" "a"))
17186    (set (match_operand:SI 0 "register_operand" "=D")
17187         (plus:SI (match_dup 1)
17188                  (const_int 1)))
17189    (use (reg:SI DIRFLAG_REG))]
17190   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17191   "stosb"
17192   [(set_attr "type" "str")
17193    (set_attr "memory" "store")
17194    (set_attr "mode" "QI")])
17195
17196 (define_insn "*strsetqi_rex_1"
17197   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17198         (match_operand:QI 2 "register_operand" "a"))
17199    (set (match_operand:DI 0 "register_operand" "=D")
17200         (plus:DI (match_dup 1)
17201                  (const_int 1)))
17202    (use (reg:SI DIRFLAG_REG))]
17203   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17204   "stosb"
17205   [(set_attr "type" "str")
17206    (set_attr "memory" "store")
17207    (set_attr "mode" "QI")])
17208
17209 (define_expand "rep_stos"
17210   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17211               (set (match_operand 0 "register_operand" "")
17212                    (match_operand 4 "" ""))
17213               (set (match_operand 2 "memory_operand" "") (const_int 0))
17214               (use (match_operand 3 "register_operand" ""))
17215               (use (match_dup 1))
17216               (use (reg:SI DIRFLAG_REG))])]
17217   ""
17218   "")
17219
17220 (define_insn "*rep_stosdi_rex64"
17221   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17222    (set (match_operand:DI 0 "register_operand" "=D") 
17223         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17224                             (const_int 3))
17225                  (match_operand:DI 3 "register_operand" "0")))
17226    (set (mem:BLK (match_dup 3))
17227         (const_int 0))
17228    (use (match_operand:DI 2 "register_operand" "a"))
17229    (use (match_dup 4))
17230    (use (reg:SI DIRFLAG_REG))]
17231   "TARGET_64BIT"
17232   "{rep\;stosq|rep stosq}"
17233   [(set_attr "type" "str")
17234    (set_attr "prefix_rep" "1")
17235    (set_attr "memory" "store")
17236    (set_attr "mode" "DI")])
17237
17238 (define_insn "*rep_stossi"
17239   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17240    (set (match_operand:SI 0 "register_operand" "=D") 
17241         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17242                             (const_int 2))
17243                  (match_operand:SI 3 "register_operand" "0")))
17244    (set (mem:BLK (match_dup 3))
17245         (const_int 0))
17246    (use (match_operand:SI 2 "register_operand" "a"))
17247    (use (match_dup 4))
17248    (use (reg:SI DIRFLAG_REG))]
17249   "!TARGET_64BIT"
17250   "{rep\;stosl|rep stosd}"
17251   [(set_attr "type" "str")
17252    (set_attr "prefix_rep" "1")
17253    (set_attr "memory" "store")
17254    (set_attr "mode" "SI")])
17255
17256 (define_insn "*rep_stossi_rex64"
17257   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17258    (set (match_operand:DI 0 "register_operand" "=D") 
17259         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17260                             (const_int 2))
17261                  (match_operand:DI 3 "register_operand" "0")))
17262    (set (mem:BLK (match_dup 3))
17263         (const_int 0))
17264    (use (match_operand:SI 2 "register_operand" "a"))
17265    (use (match_dup 4))
17266    (use (reg:SI DIRFLAG_REG))]
17267   "TARGET_64BIT"
17268   "{rep\;stosl|rep stosd}"
17269   [(set_attr "type" "str")
17270    (set_attr "prefix_rep" "1")
17271    (set_attr "memory" "store")
17272    (set_attr "mode" "SI")])
17273
17274 (define_insn "*rep_stosqi"
17275   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17276    (set (match_operand:SI 0 "register_operand" "=D") 
17277         (plus:SI (match_operand:SI 3 "register_operand" "0")
17278                  (match_operand:SI 4 "register_operand" "1")))
17279    (set (mem:BLK (match_dup 3))
17280         (const_int 0))
17281    (use (match_operand:QI 2 "register_operand" "a"))
17282    (use (match_dup 4))
17283    (use (reg:SI DIRFLAG_REG))]
17284   "!TARGET_64BIT"
17285   "{rep\;stosb|rep stosb}"
17286   [(set_attr "type" "str")
17287    (set_attr "prefix_rep" "1")
17288    (set_attr "memory" "store")
17289    (set_attr "mode" "QI")])
17290
17291 (define_insn "*rep_stosqi_rex64"
17292   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17293    (set (match_operand:DI 0 "register_operand" "=D") 
17294         (plus:DI (match_operand:DI 3 "register_operand" "0")
17295                  (match_operand:DI 4 "register_operand" "1")))
17296    (set (mem:BLK (match_dup 3))
17297         (const_int 0))
17298    (use (match_operand:QI 2 "register_operand" "a"))
17299    (use (match_dup 4))
17300    (use (reg:SI DIRFLAG_REG))]
17301   "TARGET_64BIT"
17302   "{rep\;stosb|rep stosb}"
17303   [(set_attr "type" "str")
17304    (set_attr "prefix_rep" "1")
17305    (set_attr "memory" "store")
17306    (set_attr "mode" "QI")])
17307
17308 (define_expand "cmpstrsi"
17309   [(set (match_operand:SI 0 "register_operand" "")
17310         (compare:SI (match_operand:BLK 1 "general_operand" "")
17311                     (match_operand:BLK 2 "general_operand" "")))
17312    (use (match_operand 3 "general_operand" ""))
17313    (use (match_operand 4 "immediate_operand" ""))]
17314   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17315 {
17316   rtx addr1, addr2, out, outlow, count, countreg, align;
17317
17318   /* Can't use this if the user has appropriated esi or edi.  */
17319   if (global_regs[4] || global_regs[5])
17320     FAIL;
17321
17322   out = operands[0];
17323   if (GET_CODE (out) != REG)
17324     out = gen_reg_rtx (SImode);
17325
17326   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17327   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17328   if (addr1 != XEXP (operands[1], 0))
17329     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17330   if (addr2 != XEXP (operands[2], 0))
17331     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17332
17333   count = operands[3];
17334   countreg = ix86_zero_extend_to_Pmode (count);
17335
17336   /* %%% Iff we are testing strict equality, we can use known alignment
17337      to good advantage.  This may be possible with combine, particularly
17338      once cc0 is dead.  */
17339   align = operands[4];
17340
17341   emit_insn (gen_cld ());
17342   if (GET_CODE (count) == CONST_INT)
17343     {
17344       if (INTVAL (count) == 0)
17345         {
17346           emit_move_insn (operands[0], const0_rtx);
17347           DONE;
17348         }
17349       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17350                                     operands[1], operands[2]));
17351     }
17352   else
17353     {
17354       if (TARGET_64BIT)
17355         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17356       else
17357         emit_insn (gen_cmpsi_1 (countreg, countreg));
17358       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17359                                  operands[1], operands[2]));
17360     }
17361
17362   outlow = gen_lowpart (QImode, out);
17363   emit_insn (gen_cmpintqi (outlow));
17364   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17365
17366   if (operands[0] != out)
17367     emit_move_insn (operands[0], out);
17368
17369   DONE;
17370 })
17371
17372 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17373
17374 (define_expand "cmpintqi"
17375   [(set (match_dup 1)
17376         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17377    (set (match_dup 2)
17378         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17379    (parallel [(set (match_operand:QI 0 "register_operand" "")
17380                    (minus:QI (match_dup 1)
17381                              (match_dup 2)))
17382               (clobber (reg:CC FLAGS_REG))])]
17383   ""
17384   "operands[1] = gen_reg_rtx (QImode);
17385    operands[2] = gen_reg_rtx (QImode);")
17386
17387 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17388 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17389
17390 (define_expand "cmpstrqi_nz_1"
17391   [(parallel [(set (reg:CC FLAGS_REG)
17392                    (compare:CC (match_operand 4 "memory_operand" "")
17393                                (match_operand 5 "memory_operand" "")))
17394               (use (match_operand 2 "register_operand" ""))
17395               (use (match_operand:SI 3 "immediate_operand" ""))
17396               (use (reg:SI DIRFLAG_REG))
17397               (clobber (match_operand 0 "register_operand" ""))
17398               (clobber (match_operand 1 "register_operand" ""))
17399               (clobber (match_dup 2))])]
17400   ""
17401   "")
17402
17403 (define_insn "*cmpstrqi_nz_1"
17404   [(set (reg:CC FLAGS_REG)
17405         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17406                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17407    (use (match_operand:SI 6 "register_operand" "2"))
17408    (use (match_operand:SI 3 "immediate_operand" "i"))
17409    (use (reg:SI DIRFLAG_REG))
17410    (clobber (match_operand:SI 0 "register_operand" "=S"))
17411    (clobber (match_operand:SI 1 "register_operand" "=D"))
17412    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17413   "!TARGET_64BIT"
17414   "repz{\;| }cmpsb"
17415   [(set_attr "type" "str")
17416    (set_attr "mode" "QI")
17417    (set_attr "prefix_rep" "1")])
17418
17419 (define_insn "*cmpstrqi_nz_rex_1"
17420   [(set (reg:CC FLAGS_REG)
17421         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17422                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17423    (use (match_operand:DI 6 "register_operand" "2"))
17424    (use (match_operand:SI 3 "immediate_operand" "i"))
17425    (use (reg:SI DIRFLAG_REG))
17426    (clobber (match_operand:DI 0 "register_operand" "=S"))
17427    (clobber (match_operand:DI 1 "register_operand" "=D"))
17428    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17429   "TARGET_64BIT"
17430   "repz{\;| }cmpsb"
17431   [(set_attr "type" "str")
17432    (set_attr "mode" "QI")
17433    (set_attr "prefix_rep" "1")])
17434
17435 ;; The same, but the count is not known to not be zero.
17436
17437 (define_expand "cmpstrqi_1"
17438   [(parallel [(set (reg:CC FLAGS_REG)
17439                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17440                                      (const_int 0))
17441                   (compare:CC (match_operand 4 "memory_operand" "")
17442                               (match_operand 5 "memory_operand" ""))
17443                   (const_int 0)))
17444               (use (match_operand:SI 3 "immediate_operand" ""))
17445               (use (reg:CC FLAGS_REG))
17446               (use (reg:SI DIRFLAG_REG))
17447               (clobber (match_operand 0 "register_operand" ""))
17448               (clobber (match_operand 1 "register_operand" ""))
17449               (clobber (match_dup 2))])]
17450   ""
17451   "")
17452
17453 (define_insn "*cmpstrqi_1"
17454   [(set (reg:CC FLAGS_REG)
17455         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17456                              (const_int 0))
17457           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17458                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17459           (const_int 0)))
17460    (use (match_operand:SI 3 "immediate_operand" "i"))
17461    (use (reg:CC FLAGS_REG))
17462    (use (reg:SI DIRFLAG_REG))
17463    (clobber (match_operand:SI 0 "register_operand" "=S"))
17464    (clobber (match_operand:SI 1 "register_operand" "=D"))
17465    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17466   "!TARGET_64BIT"
17467   "repz{\;| }cmpsb"
17468   [(set_attr "type" "str")
17469    (set_attr "mode" "QI")
17470    (set_attr "prefix_rep" "1")])
17471
17472 (define_insn "*cmpstrqi_rex_1"
17473   [(set (reg:CC FLAGS_REG)
17474         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17475                              (const_int 0))
17476           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17477                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17478           (const_int 0)))
17479    (use (match_operand:SI 3 "immediate_operand" "i"))
17480    (use (reg:CC FLAGS_REG))
17481    (use (reg:SI DIRFLAG_REG))
17482    (clobber (match_operand:DI 0 "register_operand" "=S"))
17483    (clobber (match_operand:DI 1 "register_operand" "=D"))
17484    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17485   "TARGET_64BIT"
17486   "repz{\;| }cmpsb"
17487   [(set_attr "type" "str")
17488    (set_attr "mode" "QI")
17489    (set_attr "prefix_rep" "1")])
17490
17491 (define_expand "strlensi"
17492   [(set (match_operand:SI 0 "register_operand" "")
17493         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17494                     (match_operand:QI 2 "immediate_operand" "")
17495                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17496   ""
17497 {
17498  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17499    DONE;
17500  else
17501    FAIL;
17502 })
17503
17504 (define_expand "strlendi"
17505   [(set (match_operand:DI 0 "register_operand" "")
17506         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17507                     (match_operand:QI 2 "immediate_operand" "")
17508                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17509   ""
17510 {
17511  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17512    DONE;
17513  else
17514    FAIL;
17515 })
17516
17517 (define_expand "strlenqi_1"
17518   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17519               (use (reg:SI DIRFLAG_REG))
17520               (clobber (match_operand 1 "register_operand" ""))
17521               (clobber (reg:CC FLAGS_REG))])]
17522   ""
17523   "")
17524
17525 (define_insn "*strlenqi_1"
17526   [(set (match_operand:SI 0 "register_operand" "=&c")
17527         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17528                     (match_operand:QI 2 "register_operand" "a")
17529                     (match_operand:SI 3 "immediate_operand" "i")
17530                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17531    (use (reg:SI DIRFLAG_REG))
17532    (clobber (match_operand:SI 1 "register_operand" "=D"))
17533    (clobber (reg:CC FLAGS_REG))]
17534   "!TARGET_64BIT"
17535   "repnz{\;| }scasb"
17536   [(set_attr "type" "str")
17537    (set_attr "mode" "QI")
17538    (set_attr "prefix_rep" "1")])
17539
17540 (define_insn "*strlenqi_rex_1"
17541   [(set (match_operand:DI 0 "register_operand" "=&c")
17542         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17543                     (match_operand:QI 2 "register_operand" "a")
17544                     (match_operand:DI 3 "immediate_operand" "i")
17545                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17546    (use (reg:SI DIRFLAG_REG))
17547    (clobber (match_operand:DI 1 "register_operand" "=D"))
17548    (clobber (reg:CC FLAGS_REG))]
17549   "TARGET_64BIT"
17550   "repnz{\;| }scasb"
17551   [(set_attr "type" "str")
17552    (set_attr "mode" "QI")
17553    (set_attr "prefix_rep" "1")])
17554
17555 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17556 ;; handled in combine, but it is not currently up to the task.
17557 ;; When used for their truth value, the cmpstr* expanders generate
17558 ;; code like this:
17559 ;;
17560 ;;   repz cmpsb
17561 ;;   seta       %al
17562 ;;   setb       %dl
17563 ;;   cmpb       %al, %dl
17564 ;;   jcc        label
17565 ;;
17566 ;; The intermediate three instructions are unnecessary.
17567
17568 ;; This one handles cmpstr*_nz_1...
17569 (define_peephole2
17570   [(parallel[
17571      (set (reg:CC FLAGS_REG)
17572           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17573                       (mem:BLK (match_operand 5 "register_operand" ""))))
17574      (use (match_operand 6 "register_operand" ""))
17575      (use (match_operand:SI 3 "immediate_operand" ""))
17576      (use (reg:SI DIRFLAG_REG))
17577      (clobber (match_operand 0 "register_operand" ""))
17578      (clobber (match_operand 1 "register_operand" ""))
17579      (clobber (match_operand 2 "register_operand" ""))])
17580    (set (match_operand:QI 7 "register_operand" "")
17581         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17582    (set (match_operand:QI 8 "register_operand" "")
17583         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17584    (set (reg 17)
17585         (compare (match_dup 7) (match_dup 8)))
17586   ]
17587   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17588   [(parallel[
17589      (set (reg:CC FLAGS_REG)
17590           (compare:CC (mem:BLK (match_dup 4))
17591                       (mem:BLK (match_dup 5))))
17592      (use (match_dup 6))
17593      (use (match_dup 3))
17594      (use (reg:SI DIRFLAG_REG))
17595      (clobber (match_dup 0))
17596      (clobber (match_dup 1))
17597      (clobber (match_dup 2))])]
17598   "")
17599
17600 ;; ...and this one handles cmpstr*_1.
17601 (define_peephole2
17602   [(parallel[
17603      (set (reg:CC FLAGS_REG)
17604           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17605                                (const_int 0))
17606             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17607                         (mem:BLK (match_operand 5 "register_operand" "")))
17608             (const_int 0)))
17609      (use (match_operand:SI 3 "immediate_operand" ""))
17610      (use (reg:CC FLAGS_REG))
17611      (use (reg:SI DIRFLAG_REG))
17612      (clobber (match_operand 0 "register_operand" ""))
17613      (clobber (match_operand 1 "register_operand" ""))
17614      (clobber (match_operand 2 "register_operand" ""))])
17615    (set (match_operand:QI 7 "register_operand" "")
17616         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17617    (set (match_operand:QI 8 "register_operand" "")
17618         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17619    (set (reg 17)
17620         (compare (match_dup 7) (match_dup 8)))
17621   ]
17622   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17623   [(parallel[
17624      (set (reg:CC FLAGS_REG)
17625           (if_then_else:CC (ne (match_dup 6)
17626                                (const_int 0))
17627             (compare:CC (mem:BLK (match_dup 4))
17628                         (mem:BLK (match_dup 5)))
17629             (const_int 0)))
17630      (use (match_dup 3))
17631      (use (reg:CC FLAGS_REG))
17632      (use (reg:SI DIRFLAG_REG))
17633      (clobber (match_dup 0))
17634      (clobber (match_dup 1))
17635      (clobber (match_dup 2))])]
17636   "")
17637
17638
17639 \f
17640 ;; Conditional move instructions.
17641
17642 (define_expand "movdicc"
17643   [(set (match_operand:DI 0 "register_operand" "")
17644         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17645                          (match_operand:DI 2 "general_operand" "")
17646                          (match_operand:DI 3 "general_operand" "")))]
17647   "TARGET_64BIT"
17648   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17649
17650 (define_insn "x86_movdicc_0_m1_rex64"
17651   [(set (match_operand:DI 0 "register_operand" "=r")
17652         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17653           (const_int -1)
17654           (const_int 0)))
17655    (clobber (reg:CC FLAGS_REG))]
17656   "TARGET_64BIT"
17657   "sbb{q}\t%0, %0"
17658   ; Since we don't have the proper number of operands for an alu insn,
17659   ; fill in all the blanks.
17660   [(set_attr "type" "alu")
17661    (set_attr "pent_pair" "pu")
17662    (set_attr "memory" "none")
17663    (set_attr "imm_disp" "false")
17664    (set_attr "mode" "DI")
17665    (set_attr "length_immediate" "0")])
17666
17667 (define_insn "movdicc_c_rex64"
17668   [(set (match_operand:DI 0 "register_operand" "=r,r")
17669         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17670                                 [(reg 17) (const_int 0)])
17671                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17672                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17673   "TARGET_64BIT && TARGET_CMOVE
17674    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17675   "@
17676    cmov%O2%C1\t{%2, %0|%0, %2}
17677    cmov%O2%c1\t{%3, %0|%0, %3}"
17678   [(set_attr "type" "icmov")
17679    (set_attr "mode" "DI")])
17680
17681 (define_expand "movsicc"
17682   [(set (match_operand:SI 0 "register_operand" "")
17683         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17684                          (match_operand:SI 2 "general_operand" "")
17685                          (match_operand:SI 3 "general_operand" "")))]
17686   ""
17687   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17688
17689 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17690 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17691 ;; So just document what we're doing explicitly.
17692
17693 (define_insn "x86_movsicc_0_m1"
17694   [(set (match_operand:SI 0 "register_operand" "=r")
17695         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17696           (const_int -1)
17697           (const_int 0)))
17698    (clobber (reg:CC FLAGS_REG))]
17699   ""
17700   "sbb{l}\t%0, %0"
17701   ; Since we don't have the proper number of operands for an alu insn,
17702   ; fill in all the blanks.
17703   [(set_attr "type" "alu")
17704    (set_attr "pent_pair" "pu")
17705    (set_attr "memory" "none")
17706    (set_attr "imm_disp" "false")
17707    (set_attr "mode" "SI")
17708    (set_attr "length_immediate" "0")])
17709
17710 (define_insn "*movsicc_noc"
17711   [(set (match_operand:SI 0 "register_operand" "=r,r")
17712         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17713                                 [(reg 17) (const_int 0)])
17714                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17715                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17716   "TARGET_CMOVE
17717    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17718   "@
17719    cmov%O2%C1\t{%2, %0|%0, %2}
17720    cmov%O2%c1\t{%3, %0|%0, %3}"
17721   [(set_attr "type" "icmov")
17722    (set_attr "mode" "SI")])
17723
17724 (define_expand "movhicc"
17725   [(set (match_operand:HI 0 "register_operand" "")
17726         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17727                          (match_operand:HI 2 "general_operand" "")
17728                          (match_operand:HI 3 "general_operand" "")))]
17729   "TARGET_HIMODE_MATH"
17730   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17731
17732 (define_insn "*movhicc_noc"
17733   [(set (match_operand:HI 0 "register_operand" "=r,r")
17734         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17735                                 [(reg 17) (const_int 0)])
17736                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17737                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17738   "TARGET_CMOVE
17739    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17740   "@
17741    cmov%O2%C1\t{%2, %0|%0, %2}
17742    cmov%O2%c1\t{%3, %0|%0, %3}"
17743   [(set_attr "type" "icmov")
17744    (set_attr "mode" "HI")])
17745
17746 (define_expand "movqicc"
17747   [(set (match_operand:QI 0 "register_operand" "")
17748         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17749                          (match_operand:QI 2 "general_operand" "")
17750                          (match_operand:QI 3 "general_operand" "")))]
17751   "TARGET_QIMODE_MATH"
17752   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17753
17754 (define_insn_and_split "*movqicc_noc"
17755   [(set (match_operand:QI 0 "register_operand" "=r,r")
17756         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17757                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17758                       (match_operand:QI 2 "register_operand" "r,0")
17759                       (match_operand:QI 3 "register_operand" "0,r")))]
17760   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17761   "#"
17762   "&& reload_completed"
17763   [(set (match_dup 0)
17764         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17765                       (match_dup 2)
17766                       (match_dup 3)))]
17767   "operands[0] = gen_lowpart (SImode, operands[0]);
17768    operands[2] = gen_lowpart (SImode, operands[2]);
17769    operands[3] = gen_lowpart (SImode, operands[3]);"
17770   [(set_attr "type" "icmov")
17771    (set_attr "mode" "SI")])
17772
17773 (define_expand "movsfcc"
17774   [(set (match_operand:SF 0 "register_operand" "")
17775         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17776                          (match_operand:SF 2 "register_operand" "")
17777                          (match_operand:SF 3 "register_operand" "")))]
17778   "TARGET_CMOVE"
17779   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17780
17781 (define_insn "*movsfcc_1"
17782   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17783         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17784                                 [(reg 17) (const_int 0)])
17785                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17786                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17787   "TARGET_CMOVE
17788    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17789   "@
17790    fcmov%F1\t{%2, %0|%0, %2}
17791    fcmov%f1\t{%3, %0|%0, %3}
17792    cmov%O2%C1\t{%2, %0|%0, %2}
17793    cmov%O2%c1\t{%3, %0|%0, %3}"
17794   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17795    (set_attr "mode" "SF,SF,SI,SI")])
17796
17797 (define_expand "movdfcc"
17798   [(set (match_operand:DF 0 "register_operand" "")
17799         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17800                          (match_operand:DF 2 "register_operand" "")
17801                          (match_operand:DF 3 "register_operand" "")))]
17802   "TARGET_CMOVE"
17803   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17804
17805 (define_insn "*movdfcc_1"
17806   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17807         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17808                                 [(reg 17) (const_int 0)])
17809                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17810                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17811   "!TARGET_64BIT && TARGET_CMOVE
17812    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17813   "@
17814    fcmov%F1\t{%2, %0|%0, %2}
17815    fcmov%f1\t{%3, %0|%0, %3}
17816    #
17817    #"
17818   [(set_attr "type" "fcmov,fcmov,multi,multi")
17819    (set_attr "mode" "DF")])
17820
17821 (define_insn "*movdfcc_1_rex64"
17822   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17823         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17824                                 [(reg 17) (const_int 0)])
17825                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17826                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17827   "TARGET_64BIT && TARGET_CMOVE
17828    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17829   "@
17830    fcmov%F1\t{%2, %0|%0, %2}
17831    fcmov%f1\t{%3, %0|%0, %3}
17832    cmov%O2%C1\t{%2, %0|%0, %2}
17833    cmov%O2%c1\t{%3, %0|%0, %3}"
17834   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17835    (set_attr "mode" "DF")])
17836
17837 (define_split
17838   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17839         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17840                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17841                       (match_operand:DF 2 "nonimmediate_operand" "")
17842                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17843   "!TARGET_64BIT && reload_completed"
17844   [(set (match_dup 2)
17845         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17846                       (match_dup 5)
17847                       (match_dup 7)))
17848    (set (match_dup 3)
17849         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17850                       (match_dup 6)
17851                       (match_dup 8)))]
17852   "split_di (operands+2, 1, operands+5, operands+6);
17853    split_di (operands+3, 1, operands+7, operands+8);
17854    split_di (operands, 1, operands+2, operands+3);")
17855
17856 (define_expand "movxfcc"
17857   [(set (match_operand:XF 0 "register_operand" "")
17858         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17859                          (match_operand:XF 2 "register_operand" "")
17860                          (match_operand:XF 3 "register_operand" "")))]
17861   "TARGET_CMOVE"
17862   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17863
17864 (define_insn "*movxfcc_1"
17865   [(set (match_operand:XF 0 "register_operand" "=f,f")
17866         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17867                                 [(reg 17) (const_int 0)])
17868                       (match_operand:XF 2 "register_operand" "f,0")
17869                       (match_operand:XF 3 "register_operand" "0,f")))]
17870   "TARGET_CMOVE"
17871   "@
17872    fcmov%F1\t{%2, %0|%0, %2}
17873    fcmov%f1\t{%3, %0|%0, %3}"
17874   [(set_attr "type" "fcmov")
17875    (set_attr "mode" "XF")])
17876
17877 (define_expand "minsf3"
17878   [(parallel [
17879      (set (match_operand:SF 0 "register_operand" "")
17880           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17881                                (match_operand:SF 2 "nonimmediate_operand" ""))
17882                            (match_dup 1)
17883                            (match_dup 2)))
17884      (clobber (reg:CC FLAGS_REG))])]
17885   "TARGET_SSE"
17886   "")
17887
17888 (define_insn "*minsf"
17889   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17890         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17891                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17892                          (match_dup 1)
17893                          (match_dup 2)))
17894    (clobber (reg:CC FLAGS_REG))]
17895   "TARGET_SSE && TARGET_IEEE_FP"
17896   "#")
17897
17898 (define_insn "*minsf_nonieee"
17899   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17900         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17901                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17902                          (match_dup 1)
17903                          (match_dup 2)))
17904    (clobber (reg:CC FLAGS_REG))]
17905   "TARGET_SSE && !TARGET_IEEE_FP
17906    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17907   "#")
17908
17909 (define_split
17910   [(set (match_operand:SF 0 "register_operand" "")
17911         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17912                              (match_operand:SF 2 "nonimmediate_operand" ""))
17913                          (match_operand:SF 3 "register_operand" "")
17914                          (match_operand:SF 4 "nonimmediate_operand" "")))
17915    (clobber (reg:CC FLAGS_REG))]
17916   "SSE_REG_P (operands[0]) && reload_completed
17917    && ((operands_match_p (operands[1], operands[3])
17918         && operands_match_p (operands[2], operands[4]))
17919        || (operands_match_p (operands[1], operands[4])
17920            && operands_match_p (operands[2], operands[3])))"
17921   [(set (match_dup 0)
17922         (if_then_else:SF (lt (match_dup 1)
17923                              (match_dup 2))
17924                          (match_dup 1)
17925                          (match_dup 2)))])
17926
17927 ;; Conditional addition patterns
17928 (define_expand "addqicc"
17929   [(match_operand:QI 0 "register_operand" "")
17930    (match_operand 1 "comparison_operator" "")
17931    (match_operand:QI 2 "register_operand" "")
17932    (match_operand:QI 3 "const_int_operand" "")]
17933   ""
17934   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17935
17936 (define_expand "addhicc"
17937   [(match_operand:HI 0 "register_operand" "")
17938    (match_operand 1 "comparison_operator" "")
17939    (match_operand:HI 2 "register_operand" "")
17940    (match_operand:HI 3 "const_int_operand" "")]
17941   ""
17942   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17943
17944 (define_expand "addsicc"
17945   [(match_operand:SI 0 "register_operand" "")
17946    (match_operand 1 "comparison_operator" "")
17947    (match_operand:SI 2 "register_operand" "")
17948    (match_operand:SI 3 "const_int_operand" "")]
17949   ""
17950   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17951
17952 (define_expand "adddicc"
17953   [(match_operand:DI 0 "register_operand" "")
17954    (match_operand 1 "comparison_operator" "")
17955    (match_operand:DI 2 "register_operand" "")
17956    (match_operand:DI 3 "const_int_operand" "")]
17957   "TARGET_64BIT"
17958   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17959
17960 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17961
17962 (define_split
17963   [(set (match_operand:SF 0 "fp_register_operand" "")
17964         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17965                              (match_operand:SF 2 "register_operand" ""))
17966                          (match_operand:SF 3 "register_operand" "")
17967                          (match_operand:SF 4 "register_operand" "")))
17968    (clobber (reg:CC FLAGS_REG))]
17969   "reload_completed
17970    && ((operands_match_p (operands[1], operands[3])
17971         && operands_match_p (operands[2], operands[4]))
17972        || (operands_match_p (operands[1], operands[4])
17973            && operands_match_p (operands[2], operands[3])))"
17974   [(set (reg:CCFP FLAGS_REG)
17975         (compare:CCFP (match_dup 2)
17976                       (match_dup 1)))
17977    (set (match_dup 0)
17978         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17979                          (match_dup 1)
17980                          (match_dup 2)))])
17981
17982 (define_insn "*minsf_sse"
17983   [(set (match_operand:SF 0 "register_operand" "=x")
17984         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17985                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17986                          (match_dup 1)
17987                          (match_dup 2)))]
17988   "TARGET_SSE && reload_completed"
17989   "minss\t{%2, %0|%0, %2}"
17990   [(set_attr "type" "sse")
17991    (set_attr "mode" "SF")])
17992
17993 (define_expand "mindf3"
17994   [(parallel [
17995      (set (match_operand:DF 0 "register_operand" "")
17996           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17997                                (match_operand:DF 2 "nonimmediate_operand" ""))
17998                            (match_dup 1)
17999                            (match_dup 2)))
18000      (clobber (reg:CC FLAGS_REG))])]
18001   "TARGET_SSE2 && TARGET_SSE_MATH"
18002   "#")
18003
18004 (define_insn "*mindf"
18005   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18006         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18007                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18008                          (match_dup 1)
18009                          (match_dup 2)))
18010    (clobber (reg:CC FLAGS_REG))]
18011   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18012   "#")
18013
18014 (define_insn "*mindf_nonieee"
18015   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18016         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18017                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18018                          (match_dup 1)
18019                          (match_dup 2)))
18020    (clobber (reg:CC FLAGS_REG))]
18021   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18023   "#")
18024
18025 (define_split
18026   [(set (match_operand:DF 0 "register_operand" "")
18027         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18028                              (match_operand:DF 2 "nonimmediate_operand" ""))
18029                          (match_operand:DF 3 "register_operand" "")
18030                          (match_operand:DF 4 "nonimmediate_operand" "")))
18031    (clobber (reg:CC FLAGS_REG))]
18032   "SSE_REG_P (operands[0]) && reload_completed
18033    && ((operands_match_p (operands[1], operands[3])
18034         && operands_match_p (operands[2], operands[4]))
18035        || (operands_match_p (operands[1], operands[4])
18036            && operands_match_p (operands[2], operands[3])))"
18037   [(set (match_dup 0)
18038         (if_then_else:DF (lt (match_dup 1)
18039                              (match_dup 2))
18040                          (match_dup 1)
18041                          (match_dup 2)))])
18042
18043 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18044 (define_split
18045   [(set (match_operand:DF 0 "fp_register_operand" "")
18046         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18047                              (match_operand:DF 2 "register_operand" ""))
18048                          (match_operand:DF 3 "register_operand" "")
18049                          (match_operand:DF 4 "register_operand" "")))
18050    (clobber (reg:CC FLAGS_REG))]
18051   "reload_completed
18052    && ((operands_match_p (operands[1], operands[3])
18053         && operands_match_p (operands[2], operands[4]))
18054        || (operands_match_p (operands[1], operands[4])
18055            && operands_match_p (operands[2], operands[3])))"
18056   [(set (reg:CCFP FLAGS_REG)
18057         (compare:CCFP (match_dup 2)
18058                       (match_dup 1)))
18059    (set (match_dup 0)
18060         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18061                          (match_dup 1)
18062                          (match_dup 2)))])
18063
18064 (define_insn "*mindf_sse"
18065   [(set (match_operand:DF 0 "register_operand" "=Y")
18066         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18067                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18068                          (match_dup 1)
18069                          (match_dup 2)))]
18070   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18071   "minsd\t{%2, %0|%0, %2}"
18072   [(set_attr "type" "sse")
18073    (set_attr "mode" "DF")])
18074
18075 (define_expand "maxsf3"
18076   [(parallel [
18077      (set (match_operand:SF 0 "register_operand" "")
18078           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18079                                (match_operand:SF 2 "nonimmediate_operand" ""))
18080                            (match_dup 1)
18081                            (match_dup 2)))
18082      (clobber (reg:CC FLAGS_REG))])]
18083   "TARGET_SSE"
18084   "#")
18085
18086 (define_insn "*maxsf"
18087   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18088         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18089                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18090                          (match_dup 1)
18091                          (match_dup 2)))
18092    (clobber (reg:CC FLAGS_REG))]
18093   "TARGET_SSE && TARGET_IEEE_FP"
18094   "#")
18095
18096 (define_insn "*maxsf_nonieee"
18097   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18098         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18099                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18100                          (match_dup 1)
18101                          (match_dup 2)))
18102    (clobber (reg:CC FLAGS_REG))]
18103   "TARGET_SSE && !TARGET_IEEE_FP
18104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18105   "#")
18106
18107 (define_split
18108   [(set (match_operand:SF 0 "register_operand" "")
18109         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18110                              (match_operand:SF 2 "nonimmediate_operand" ""))
18111                          (match_operand:SF 3 "register_operand" "")
18112                          (match_operand:SF 4 "nonimmediate_operand" "")))
18113    (clobber (reg:CC FLAGS_REG))]
18114   "SSE_REG_P (operands[0]) && reload_completed
18115    && ((operands_match_p (operands[1], operands[3])
18116         && operands_match_p (operands[2], operands[4]))
18117        || (operands_match_p (operands[1], operands[4])
18118            && operands_match_p (operands[2], operands[3])))"
18119   [(set (match_dup 0)
18120         (if_then_else:SF (gt (match_dup 1)
18121                              (match_dup 2))
18122                          (match_dup 1)
18123                          (match_dup 2)))])
18124
18125 (define_split
18126   [(set (match_operand:SF 0 "fp_register_operand" "")
18127         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18128                              (match_operand:SF 2 "register_operand" ""))
18129                          (match_operand:SF 3 "register_operand" "")
18130                          (match_operand:SF 4 "register_operand" "")))
18131    (clobber (reg:CC FLAGS_REG))]
18132   "reload_completed
18133    && ((operands_match_p (operands[1], operands[3])
18134         && operands_match_p (operands[2], operands[4]))
18135        || (operands_match_p (operands[1], operands[4])
18136            && operands_match_p (operands[2], operands[3])))"
18137   [(set (reg:CCFP FLAGS_REG)
18138         (compare:CCFP (match_dup 1)
18139                       (match_dup 2)))
18140    (set (match_dup 0)
18141         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18142                          (match_dup 1)
18143                          (match_dup 2)))])
18144
18145 (define_insn "*maxsf_sse"
18146   [(set (match_operand:SF 0 "register_operand" "=x")
18147         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18148                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18149                          (match_dup 1)
18150                          (match_dup 2)))]
18151   "TARGET_SSE && reload_completed"
18152   "maxss\t{%2, %0|%0, %2}"
18153   [(set_attr "type" "sse")
18154    (set_attr "mode" "SF")])
18155
18156 (define_expand "maxdf3"
18157   [(parallel [
18158      (set (match_operand:DF 0 "register_operand" "")
18159           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18160                                (match_operand:DF 2 "nonimmediate_operand" ""))
18161                            (match_dup 1)
18162                            (match_dup 2)))
18163      (clobber (reg:CC FLAGS_REG))])]
18164   "TARGET_SSE2 && TARGET_SSE_MATH"
18165   "#")
18166
18167 (define_insn "*maxdf"
18168   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18169         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18170                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18171                          (match_dup 1)
18172                          (match_dup 2)))
18173    (clobber (reg:CC FLAGS_REG))]
18174   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18175   "#")
18176
18177 (define_insn "*maxdf_nonieee"
18178   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18179         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18180                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18181                          (match_dup 1)
18182                          (match_dup 2)))
18183    (clobber (reg:CC FLAGS_REG))]
18184   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18185    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18186   "#")
18187
18188 (define_split
18189   [(set (match_operand:DF 0 "register_operand" "")
18190         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18191                              (match_operand:DF 2 "nonimmediate_operand" ""))
18192                          (match_operand:DF 3 "register_operand" "")
18193                          (match_operand:DF 4 "nonimmediate_operand" "")))
18194    (clobber (reg:CC FLAGS_REG))]
18195   "SSE_REG_P (operands[0]) && reload_completed
18196    && ((operands_match_p (operands[1], operands[3])
18197         && operands_match_p (operands[2], operands[4]))
18198        || (operands_match_p (operands[1], operands[4])
18199            && operands_match_p (operands[2], operands[3])))"
18200   [(set (match_dup 0)
18201         (if_then_else:DF (gt (match_dup 1)
18202                              (match_dup 2))
18203                          (match_dup 1)
18204                          (match_dup 2)))])
18205
18206 (define_split
18207   [(set (match_operand:DF 0 "fp_register_operand" "")
18208         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18209                              (match_operand:DF 2 "register_operand" ""))
18210                          (match_operand:DF 3 "register_operand" "")
18211                          (match_operand:DF 4 "register_operand" "")))
18212    (clobber (reg:CC FLAGS_REG))]
18213   "reload_completed
18214    && ((operands_match_p (operands[1], operands[3])
18215         && operands_match_p (operands[2], operands[4]))
18216        || (operands_match_p (operands[1], operands[4])
18217            && operands_match_p (operands[2], operands[3])))"
18218   [(set (reg:CCFP FLAGS_REG)
18219         (compare:CCFP (match_dup 1)
18220                       (match_dup 2)))
18221    (set (match_dup 0)
18222         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18223                          (match_dup 1)
18224                          (match_dup 2)))])
18225
18226 (define_insn "*maxdf_sse"
18227   [(set (match_operand:DF 0 "register_operand" "=Y")
18228         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18229                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18230                          (match_dup 1)
18231                          (match_dup 2)))]
18232   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18233   "maxsd\t{%2, %0|%0, %2}"
18234   [(set_attr "type" "sse")
18235    (set_attr "mode" "DF")])
18236 \f
18237 ;; Misc patterns (?)
18238
18239 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18240 ;; Otherwise there will be nothing to keep
18241 ;; 
18242 ;; [(set (reg ebp) (reg esp))]
18243 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18244 ;;  (clobber (eflags)]
18245 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18246 ;;
18247 ;; in proper program order.
18248 (define_insn "pro_epilogue_adjust_stack_1"
18249   [(set (match_operand:SI 0 "register_operand" "=r,r")
18250         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18251                  (match_operand:SI 2 "immediate_operand" "i,i")))
18252    (clobber (reg:CC FLAGS_REG))
18253    (clobber (mem:BLK (scratch)))]
18254   "!TARGET_64BIT"
18255 {
18256   switch (get_attr_type (insn))
18257     {
18258     case TYPE_IMOV:
18259       return "mov{l}\t{%1, %0|%0, %1}";
18260
18261     case TYPE_ALU:
18262       if (GET_CODE (operands[2]) == CONST_INT
18263           && (INTVAL (operands[2]) == 128
18264               || (INTVAL (operands[2]) < 0
18265                   && INTVAL (operands[2]) != -128)))
18266         {
18267           operands[2] = GEN_INT (-INTVAL (operands[2]));
18268           return "sub{l}\t{%2, %0|%0, %2}";
18269         }
18270       return "add{l}\t{%2, %0|%0, %2}";
18271
18272     case TYPE_LEA:
18273       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18274       return "lea{l}\t{%a2, %0|%0, %a2}";
18275
18276     default:
18277       abort ();
18278     }
18279 }
18280   [(set (attr "type")
18281         (cond [(eq_attr "alternative" "0")
18282                  (const_string "alu")
18283                (match_operand:SI 2 "const0_operand" "")
18284                  (const_string "imov")
18285               ]
18286               (const_string "lea")))
18287    (set_attr "mode" "SI")])
18288
18289 (define_insn "pro_epilogue_adjust_stack_rex64"
18290   [(set (match_operand:DI 0 "register_operand" "=r,r")
18291         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18292                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18293    (clobber (reg:CC FLAGS_REG))
18294    (clobber (mem:BLK (scratch)))]
18295   "TARGET_64BIT"
18296 {
18297   switch (get_attr_type (insn))
18298     {
18299     case TYPE_IMOV:
18300       return "mov{q}\t{%1, %0|%0, %1}";
18301
18302     case TYPE_ALU:
18303       if (GET_CODE (operands[2]) == CONST_INT
18304           /* Avoid overflows.  */
18305           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18306           && (INTVAL (operands[2]) == 128
18307               || (INTVAL (operands[2]) < 0
18308                   && INTVAL (operands[2]) != -128)))
18309         {
18310           operands[2] = GEN_INT (-INTVAL (operands[2]));
18311           return "sub{q}\t{%2, %0|%0, %2}";
18312         }
18313       return "add{q}\t{%2, %0|%0, %2}";
18314
18315     case TYPE_LEA:
18316       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18317       return "lea{q}\t{%a2, %0|%0, %a2}";
18318
18319     default:
18320       abort ();
18321     }
18322 }
18323   [(set (attr "type")
18324         (cond [(eq_attr "alternative" "0")
18325                  (const_string "alu")
18326                (match_operand:DI 2 "const0_operand" "")
18327                  (const_string "imov")
18328               ]
18329               (const_string "lea")))
18330    (set_attr "mode" "DI")])
18331
18332 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18333   [(set (match_operand:DI 0 "register_operand" "=r,r")
18334         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18335                  (match_operand:DI 3 "immediate_operand" "i,i")))
18336    (use (match_operand:DI 2 "register_operand" "r,r"))
18337    (clobber (reg:CC FLAGS_REG))
18338    (clobber (mem:BLK (scratch)))]
18339   "TARGET_64BIT"
18340 {
18341   switch (get_attr_type (insn))
18342     {
18343     case TYPE_ALU:
18344       return "add{q}\t{%2, %0|%0, %2}";
18345
18346     case TYPE_LEA:
18347       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18348       return "lea{q}\t{%a2, %0|%0, %a2}";
18349
18350     default:
18351       abort ();
18352     }
18353 }
18354   [(set_attr "type" "alu,lea")
18355    (set_attr "mode" "DI")])
18356
18357 ;; Placeholder for the conditional moves.  This one is split either to SSE
18358 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18359 ;; fact is that compares supported by the cmp??ss instructions are exactly
18360 ;; swapped of those supported by cmove sequence.
18361 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18362 ;; supported by i387 comparisons and we do need to emit two conditional moves
18363 ;; in tandem.
18364
18365 (define_insn "sse_movsfcc"
18366   [(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")
18367         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18368                         [(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")
18369                          (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")])
18370                       (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")
18371                       (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")))
18372    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18373    (clobber (reg:CC FLAGS_REG))]
18374   "TARGET_SSE
18375    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18376    /* Avoid combine from being smart and converting min/max
18377       instruction patterns into conditional moves.  */
18378    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18379         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18380        || !rtx_equal_p (operands[4], operands[2])
18381        || !rtx_equal_p (operands[5], operands[3]))
18382    && (!TARGET_IEEE_FP
18383        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18384   "#")
18385
18386 (define_insn "sse_movsfcc_eq"
18387   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18388         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18389                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18390                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18391                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18392    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18393    (clobber (reg:CC FLAGS_REG))]
18394   "TARGET_SSE
18395    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18396   "#")
18397
18398 (define_insn "sse_movdfcc"
18399   [(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")
18400         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18401                         [(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")
18402                          (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")])
18403                       (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")
18404                       (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")))
18405    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18406    (clobber (reg:CC FLAGS_REG))]
18407   "TARGET_SSE2
18408    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18409    /* Avoid combine from being smart and converting min/max
18410       instruction patterns into conditional moves.  */
18411    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18412         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18413        || !rtx_equal_p (operands[4], operands[2])
18414        || !rtx_equal_p (operands[5], operands[3]))
18415    && (!TARGET_IEEE_FP
18416        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18417   "#")
18418
18419 (define_insn "sse_movdfcc_eq"
18420   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18421         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18422                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18423                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18424                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18425    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18426    (clobber (reg:CC FLAGS_REG))]
18427   "TARGET_SSE
18428    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18429   "#")
18430
18431 ;; For non-sse moves just expand the usual cmove sequence.
18432 (define_split
18433   [(set (match_operand 0 "register_operand" "")
18434         (if_then_else (match_operator 1 "comparison_operator"
18435                         [(match_operand 4 "nonimmediate_operand" "")
18436                          (match_operand 5 "register_operand" "")])
18437                       (match_operand 2 "nonimmediate_operand" "")
18438                       (match_operand 3 "nonimmediate_operand" "")))
18439    (clobber (match_operand 6 "" ""))
18440    (clobber (reg:CC FLAGS_REG))]
18441   "!SSE_REG_P (operands[0]) && reload_completed
18442    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18443   [(const_int 0)]
18444 {
18445    ix86_compare_op0 = operands[5];
18446    ix86_compare_op1 = operands[4];
18447    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18448                                  VOIDmode, operands[5], operands[4]);
18449    ix86_expand_fp_movcc (operands);
18450    DONE;
18451 })
18452
18453 ;; Split SSE based conditional move into sequence:
18454 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18455 ;; and   op2, op0   -  zero op2 if comparison was false
18456 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18457 ;; or    op2, op0   -  get the nonzero one into the result.
18458 (define_split
18459   [(set (match_operand:SF 0 "register_operand" "")
18460         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18461                         [(match_operand:SF 4 "register_operand" "")
18462                          (match_operand:SF 5 "nonimmediate_operand" "")])
18463                       (match_operand:SF 2 "register_operand" "")
18464                       (match_operand:SF 3 "register_operand" "")))
18465    (clobber (match_operand 6 "" ""))
18466    (clobber (reg:CC FLAGS_REG))]
18467   "SSE_REG_P (operands[0]) && reload_completed"
18468   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18469    (set (match_dup 2) (and:V4SF (match_dup 2)
18470                                 (match_dup 8)))
18471    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18472                                           (match_dup 3)))
18473    (set (match_dup 0) (ior:V4SF (match_dup 6)
18474                                 (match_dup 7)))]
18475 {
18476   /* If op2 == op3, op3 would be clobbered before it is used.  */
18477   if (operands_match_p (operands[2], operands[3]))
18478     {
18479       emit_move_insn (operands[0], operands[2]);
18480       DONE;
18481     }
18482
18483   PUT_MODE (operands[1], GET_MODE (operands[0]));
18484   if (operands_match_p (operands[0], operands[4]))
18485     operands[6] = operands[4], operands[7] = operands[2];
18486   else
18487     operands[6] = operands[2], operands[7] = operands[4];
18488   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18489   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18490   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18491   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18492   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18493   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18494 })
18495
18496 (define_split
18497   [(set (match_operand:DF 0 "register_operand" "")
18498         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18499                         [(match_operand:DF 4 "register_operand" "")
18500                          (match_operand:DF 5 "nonimmediate_operand" "")])
18501                       (match_operand:DF 2 "register_operand" "")
18502                       (match_operand:DF 3 "register_operand" "")))
18503    (clobber (match_operand 6 "" ""))
18504    (clobber (reg:CC FLAGS_REG))]
18505   "SSE_REG_P (operands[0]) && reload_completed"
18506   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18507    (set (match_dup 2) (and:V2DF (match_dup 2)
18508                                 (match_dup 8)))
18509    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18510                                           (match_dup 3)))
18511    (set (match_dup 0) (ior:V2DF (match_dup 6)
18512                                 (match_dup 7)))]
18513 {
18514   if (GET_MODE (operands[2]) == DFmode
18515       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18516     {
18517       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18518       emit_insn (gen_sse2_unpcklpd (op, op, op));
18519       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18520       emit_insn (gen_sse2_unpcklpd (op, op, op));
18521     }
18522
18523   /* If op2 == op3, op3 would be clobbered before it is used.  */
18524   if (operands_match_p (operands[2], operands[3]))
18525     {
18526       emit_move_insn (operands[0], operands[2]);
18527       DONE;
18528     }
18529
18530   PUT_MODE (operands[1], GET_MODE (operands[0]));
18531   if (operands_match_p (operands[0], operands[4]))
18532     operands[6] = operands[4], operands[7] = operands[2];
18533   else
18534     operands[6] = operands[2], operands[7] = operands[4];
18535   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18536   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18537   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18538   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18539   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18540   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18541 })
18542
18543 ;; Special case of conditional move we can handle effectively.
18544 ;; Do not brother with the integer/floating point case, since these are
18545 ;; bot considerably slower, unlike in the generic case.
18546 (define_insn "*sse_movsfcc_const0_1"
18547   [(set (match_operand:SF 0 "register_operand" "=&x")
18548         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18549                         [(match_operand:SF 4 "register_operand" "0")
18550                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18551                       (match_operand:SF 2 "register_operand" "x")
18552                       (match_operand:SF 3 "const0_operand" "X")))]
18553   "TARGET_SSE"
18554   "#")
18555
18556 (define_insn "*sse_movsfcc_const0_2"
18557   [(set (match_operand:SF 0 "register_operand" "=&x")
18558         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18559                         [(match_operand:SF 4 "register_operand" "0")
18560                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18561                       (match_operand:SF 2 "const0_operand" "X")
18562                       (match_operand:SF 3 "register_operand" "x")))]
18563   "TARGET_SSE"
18564   "#")
18565
18566 (define_insn "*sse_movsfcc_const0_3"
18567   [(set (match_operand:SF 0 "register_operand" "=&x")
18568         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18569                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18570                          (match_operand:SF 5 "register_operand" "0")])
18571                       (match_operand:SF 2 "register_operand" "x")
18572                       (match_operand:SF 3 "const0_operand" "X")))]
18573   "TARGET_SSE"
18574   "#")
18575
18576 (define_insn "*sse_movsfcc_const0_4"
18577   [(set (match_operand:SF 0 "register_operand" "=&x")
18578         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18579                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18580                          (match_operand:SF 5 "register_operand" "0")])
18581                       (match_operand:SF 2 "const0_operand" "X")
18582                       (match_operand:SF 3 "register_operand" "x")))]
18583   "TARGET_SSE"
18584   "#")
18585
18586 (define_insn "*sse_movdfcc_const0_1"
18587   [(set (match_operand:DF 0 "register_operand" "=&Y")
18588         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18589                         [(match_operand:DF 4 "register_operand" "0")
18590                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18591                       (match_operand:DF 2 "register_operand" "Y")
18592                       (match_operand:DF 3 "const0_operand" "X")))]
18593   "TARGET_SSE2"
18594   "#")
18595
18596 (define_insn "*sse_movdfcc_const0_2"
18597   [(set (match_operand:DF 0 "register_operand" "=&Y")
18598         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18599                         [(match_operand:DF 4 "register_operand" "0")
18600                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18601                       (match_operand:DF 2 "const0_operand" "X")
18602                       (match_operand:DF 3 "register_operand" "Y")))]
18603   "TARGET_SSE2"
18604   "#")
18605
18606 (define_insn "*sse_movdfcc_const0_3"
18607   [(set (match_operand:DF 0 "register_operand" "=&Y")
18608         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18609                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18610                          (match_operand:DF 5 "register_operand" "0")])
18611                       (match_operand:DF 2 "register_operand" "Y")
18612                       (match_operand:DF 3 "const0_operand" "X")))]
18613   "TARGET_SSE2"
18614   "#")
18615
18616 (define_insn "*sse_movdfcc_const0_4"
18617   [(set (match_operand:DF 0 "register_operand" "=&Y")
18618         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18619                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18620                          (match_operand:DF 5 "register_operand" "0")])
18621                       (match_operand:DF 2 "const0_operand" "X")
18622                       (match_operand:DF 3 "register_operand" "Y")))]
18623   "TARGET_SSE2"
18624   "#")
18625
18626 (define_split
18627   [(set (match_operand:SF 0 "register_operand" "")
18628         (if_then_else (match_operator 1 "comparison_operator"
18629                         [(match_operand:SF 4 "nonimmediate_operand" "")
18630                          (match_operand:SF 5 "nonimmediate_operand" "")])
18631                       (match_operand:SF 2 "nonmemory_operand" "")
18632                       (match_operand:SF 3 "nonmemory_operand" "")))]
18633   "SSE_REG_P (operands[0]) && reload_completed
18634    && (const0_operand (operands[2], GET_MODE (operands[0]))
18635        || const0_operand (operands[3], GET_MODE (operands[0])))"
18636   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18637    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18638 {
18639   PUT_MODE (operands[1], GET_MODE (operands[0]));
18640   if (!sse_comparison_operator (operands[1], VOIDmode)
18641       || !rtx_equal_p (operands[0], operands[4]))
18642     {
18643       rtx tmp = operands[5];
18644       operands[5] = operands[4];
18645       operands[4] = tmp;
18646       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18647     }
18648   if (!rtx_equal_p (operands[0], operands[4]))
18649     abort ();
18650   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18651   if (const0_operand (operands[2], GET_MODE (operands[2])))
18652     {
18653       operands[7] = operands[3];
18654       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18655     }
18656   else
18657     {
18658       operands[7] = operands[2];
18659       operands[6] = operands[8];
18660     }
18661   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18662 })
18663
18664 (define_split
18665   [(set (match_operand:DF 0 "register_operand" "")
18666         (if_then_else (match_operator 1 "comparison_operator"
18667                         [(match_operand:DF 4 "nonimmediate_operand" "")
18668                          (match_operand:DF 5 "nonimmediate_operand" "")])
18669                       (match_operand:DF 2 "nonmemory_operand" "")
18670                       (match_operand:DF 3 "nonmemory_operand" "")))]
18671   "SSE_REG_P (operands[0]) && reload_completed
18672    && (const0_operand (operands[2], GET_MODE (operands[0]))
18673        || const0_operand (operands[3], GET_MODE (operands[0])))"
18674   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18675    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18676 {
18677   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18678       && GET_MODE (operands[2]) == DFmode)
18679     {
18680       if (REG_P (operands[2]))
18681         {
18682           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18683           emit_insn (gen_sse2_unpcklpd (op, op, op));
18684         }
18685       if (REG_P (operands[3]))
18686         {
18687           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18688           emit_insn (gen_sse2_unpcklpd (op, op, op));
18689         }
18690     }
18691   PUT_MODE (operands[1], GET_MODE (operands[0]));
18692   if (!sse_comparison_operator (operands[1], VOIDmode)
18693       || !rtx_equal_p (operands[0], operands[4]))
18694     {
18695       rtx tmp = operands[5];
18696       operands[5] = operands[4];
18697       operands[4] = tmp;
18698       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18699     }
18700   if (!rtx_equal_p (operands[0], operands[4]))
18701     abort ();
18702   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18703   if (const0_operand (operands[2], GET_MODE (operands[2])))
18704     {
18705       operands[7] = operands[3];
18706       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18707     }
18708   else
18709     {
18710       operands[7] = operands[2];
18711       operands[6] = operands[8];
18712     }
18713   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18714 })
18715
18716 (define_expand "allocate_stack_worker"
18717   [(match_operand:SI 0 "register_operand" "")]
18718   "TARGET_STACK_PROBE"
18719 {
18720   if (reload_completed)
18721     {
18722       if (TARGET_64BIT)
18723         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18724       else
18725         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18726     }
18727   else
18728     {
18729       if (TARGET_64BIT)
18730         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18731       else
18732         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18733     }
18734   DONE;
18735 })
18736
18737 (define_insn "allocate_stack_worker_1"
18738   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18739     UNSPECV_STACK_PROBE)
18740    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18741    (clobber (match_scratch:SI 1 "=0"))
18742    (clobber (reg:CC FLAGS_REG))]
18743   "!TARGET_64BIT && TARGET_STACK_PROBE"
18744   "call\t__alloca"
18745   [(set_attr "type" "multi")
18746    (set_attr "length" "5")])
18747
18748 (define_expand "allocate_stack_worker_postreload"
18749   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18750                                     UNSPECV_STACK_PROBE)
18751               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18752               (clobber (match_dup 0))
18753               (clobber (reg:CC FLAGS_REG))])]
18754   ""
18755   "")
18756
18757 (define_insn "allocate_stack_worker_rex64"
18758   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18759     UNSPECV_STACK_PROBE)
18760    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18761    (clobber (match_scratch:DI 1 "=0"))
18762    (clobber (reg:CC FLAGS_REG))]
18763   "TARGET_64BIT && TARGET_STACK_PROBE"
18764   "call\t__alloca"
18765   [(set_attr "type" "multi")
18766    (set_attr "length" "5")])
18767
18768 (define_expand "allocate_stack_worker_rex64_postreload"
18769   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18770                                     UNSPECV_STACK_PROBE)
18771               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18772               (clobber (match_dup 0))
18773               (clobber (reg:CC FLAGS_REG))])]
18774   ""
18775   "")
18776
18777 (define_expand "allocate_stack"
18778   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18779                    (minus:SI (reg:SI SP_REG)
18780                              (match_operand:SI 1 "general_operand" "")))
18781               (clobber (reg:CC FLAGS_REG))])
18782    (parallel [(set (reg:SI SP_REG)
18783                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18784               (clobber (reg:CC FLAGS_REG))])]
18785   "TARGET_STACK_PROBE"
18786 {
18787 #ifdef CHECK_STACK_LIMIT
18788   if (GET_CODE (operands[1]) == CONST_INT
18789       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18790     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18791                            operands[1]));
18792   else 
18793 #endif
18794     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18795                                                             operands[1])));
18796
18797   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18798   DONE;
18799 })
18800
18801 (define_expand "builtin_setjmp_receiver"
18802   [(label_ref (match_operand 0 "" ""))]
18803   "!TARGET_64BIT && flag_pic"
18804 {
18805   emit_insn (gen_set_got (pic_offset_table_rtx));
18806   DONE;
18807 })
18808 \f
18809 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18810
18811 (define_split
18812   [(set (match_operand 0 "register_operand" "")
18813         (match_operator 3 "promotable_binary_operator"
18814            [(match_operand 1 "register_operand" "")
18815             (match_operand 2 "aligned_operand" "")]))
18816    (clobber (reg:CC FLAGS_REG))]
18817   "! TARGET_PARTIAL_REG_STALL && reload_completed
18818    && ((GET_MODE (operands[0]) == HImode 
18819         && ((!optimize_size && !TARGET_FAST_PREFIX)
18820             || GET_CODE (operands[2]) != CONST_INT
18821             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18822        || (GET_MODE (operands[0]) == QImode 
18823            && (TARGET_PROMOTE_QImode || optimize_size)))"
18824   [(parallel [(set (match_dup 0)
18825                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18826               (clobber (reg:CC FLAGS_REG))])]
18827   "operands[0] = gen_lowpart (SImode, operands[0]);
18828    operands[1] = gen_lowpart (SImode, operands[1]);
18829    if (GET_CODE (operands[3]) != ASHIFT)
18830      operands[2] = gen_lowpart (SImode, operands[2]);
18831    PUT_MODE (operands[3], SImode);")
18832
18833 ; Promote the QImode tests, as i386 has encoding of the AND
18834 ; instruction with 32-bit sign-extended immediate and thus the
18835 ; instruction size is unchanged, except in the %eax case for
18836 ; which it is increased by one byte, hence the ! optimize_size.
18837 (define_split
18838   [(set (reg 17)
18839         (compare (and (match_operand 1 "aligned_operand" "")
18840                       (match_operand 2 "const_int_operand" ""))
18841                  (const_int 0)))
18842    (set (match_operand 0 "register_operand" "")
18843         (and (match_dup 1) (match_dup 2)))]
18844   "! TARGET_PARTIAL_REG_STALL && reload_completed
18845    /* Ensure that the operand will remain sign-extended immediate.  */
18846    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18847    && ! optimize_size
18848    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18849        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18850   [(parallel [(set (reg:CCNO FLAGS_REG)
18851                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18852                                  (const_int 0)))
18853               (set (match_dup 0)
18854                    (and:SI (match_dup 1) (match_dup 2)))])]
18855   "operands[2]
18856      = gen_int_mode (INTVAL (operands[2])
18857                      & GET_MODE_MASK (GET_MODE (operands[0])),
18858                      SImode);
18859    operands[0] = gen_lowpart (SImode, operands[0]);
18860    operands[1] = gen_lowpart (SImode, operands[1]);")
18861
18862 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18863 ; the TEST instruction with 32-bit sign-extended immediate and thus
18864 ; the instruction size would at least double, which is not what we
18865 ; want even with ! optimize_size.
18866 (define_split
18867   [(set (reg 17)
18868         (compare (and (match_operand:HI 0 "aligned_operand" "")
18869                       (match_operand:HI 1 "const_int_operand" ""))
18870                  (const_int 0)))]
18871   "! TARGET_PARTIAL_REG_STALL && reload_completed
18872    /* Ensure that the operand will remain sign-extended immediate.  */
18873    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18874    && ! TARGET_FAST_PREFIX
18875    && ! optimize_size"
18876   [(set (reg:CCNO FLAGS_REG)
18877         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18878                       (const_int 0)))]
18879   "operands[1]
18880      = gen_int_mode (INTVAL (operands[1])
18881                      & GET_MODE_MASK (GET_MODE (operands[0])),
18882                      SImode);
18883    operands[0] = gen_lowpart (SImode, operands[0]);")
18884
18885 (define_split
18886   [(set (match_operand 0 "register_operand" "")
18887         (neg (match_operand 1 "register_operand" "")))
18888    (clobber (reg:CC FLAGS_REG))]
18889   "! TARGET_PARTIAL_REG_STALL && reload_completed
18890    && (GET_MODE (operands[0]) == HImode
18891        || (GET_MODE (operands[0]) == QImode 
18892            && (TARGET_PROMOTE_QImode || optimize_size)))"
18893   [(parallel [(set (match_dup 0)
18894                    (neg:SI (match_dup 1)))
18895               (clobber (reg:CC FLAGS_REG))])]
18896   "operands[0] = gen_lowpart (SImode, operands[0]);
18897    operands[1] = gen_lowpart (SImode, operands[1]);")
18898
18899 (define_split
18900   [(set (match_operand 0 "register_operand" "")
18901         (not (match_operand 1 "register_operand" "")))]
18902   "! TARGET_PARTIAL_REG_STALL && reload_completed
18903    && (GET_MODE (operands[0]) == HImode
18904        || (GET_MODE (operands[0]) == QImode 
18905            && (TARGET_PROMOTE_QImode || optimize_size)))"
18906   [(set (match_dup 0)
18907         (not:SI (match_dup 1)))]
18908   "operands[0] = gen_lowpart (SImode, operands[0]);
18909    operands[1] = gen_lowpart (SImode, operands[1]);")
18910
18911 (define_split 
18912   [(set (match_operand 0 "register_operand" "")
18913         (if_then_else (match_operator 1 "comparison_operator" 
18914                                 [(reg 17) (const_int 0)])
18915                       (match_operand 2 "register_operand" "")
18916                       (match_operand 3 "register_operand" "")))]
18917   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18918    && (GET_MODE (operands[0]) == HImode
18919        || (GET_MODE (operands[0]) == QImode 
18920            && (TARGET_PROMOTE_QImode || optimize_size)))"
18921   [(set (match_dup 0)
18922         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18923   "operands[0] = gen_lowpart (SImode, operands[0]);
18924    operands[2] = gen_lowpart (SImode, operands[2]);
18925    operands[3] = gen_lowpart (SImode, operands[3]);")
18926                         
18927 \f
18928 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18929 ;; transform a complex memory operation into two memory to register operations.
18930
18931 ;; Don't push memory operands
18932 (define_peephole2
18933   [(set (match_operand:SI 0 "push_operand" "")
18934         (match_operand:SI 1 "memory_operand" ""))
18935    (match_scratch:SI 2 "r")]
18936   "! optimize_size && ! TARGET_PUSH_MEMORY"
18937   [(set (match_dup 2) (match_dup 1))
18938    (set (match_dup 0) (match_dup 2))]
18939   "")
18940
18941 (define_peephole2
18942   [(set (match_operand:DI 0 "push_operand" "")
18943         (match_operand:DI 1 "memory_operand" ""))
18944    (match_scratch:DI 2 "r")]
18945   "! optimize_size && ! TARGET_PUSH_MEMORY"
18946   [(set (match_dup 2) (match_dup 1))
18947    (set (match_dup 0) (match_dup 2))]
18948   "")
18949
18950 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18951 ;; SImode pushes.
18952 (define_peephole2
18953   [(set (match_operand:SF 0 "push_operand" "")
18954         (match_operand:SF 1 "memory_operand" ""))
18955    (match_scratch:SF 2 "r")]
18956   "! optimize_size && ! TARGET_PUSH_MEMORY"
18957   [(set (match_dup 2) (match_dup 1))
18958    (set (match_dup 0) (match_dup 2))]
18959   "")
18960
18961 (define_peephole2
18962   [(set (match_operand:HI 0 "push_operand" "")
18963         (match_operand:HI 1 "memory_operand" ""))
18964    (match_scratch:HI 2 "r")]
18965   "! optimize_size && ! TARGET_PUSH_MEMORY"
18966   [(set (match_dup 2) (match_dup 1))
18967    (set (match_dup 0) (match_dup 2))]
18968   "")
18969
18970 (define_peephole2
18971   [(set (match_operand:QI 0 "push_operand" "")
18972         (match_operand:QI 1 "memory_operand" ""))
18973    (match_scratch:QI 2 "q")]
18974   "! optimize_size && ! TARGET_PUSH_MEMORY"
18975   [(set (match_dup 2) (match_dup 1))
18976    (set (match_dup 0) (match_dup 2))]
18977   "")
18978
18979 ;; Don't move an immediate directly to memory when the instruction
18980 ;; gets too big.
18981 (define_peephole2
18982   [(match_scratch:SI 1 "r")
18983    (set (match_operand:SI 0 "memory_operand" "")
18984         (const_int 0))]
18985   "! optimize_size
18986    && ! TARGET_USE_MOV0
18987    && TARGET_SPLIT_LONG_MOVES
18988    && get_attr_length (insn) >= ix86_cost->large_insn
18989    && peep2_regno_dead_p (0, FLAGS_REG)"
18990   [(parallel [(set (match_dup 1) (const_int 0))
18991               (clobber (reg:CC FLAGS_REG))])
18992    (set (match_dup 0) (match_dup 1))]
18993   "")
18994
18995 (define_peephole2
18996   [(match_scratch:HI 1 "r")
18997    (set (match_operand:HI 0 "memory_operand" "")
18998         (const_int 0))]
18999   "! optimize_size
19000    && ! TARGET_USE_MOV0
19001    && TARGET_SPLIT_LONG_MOVES
19002    && get_attr_length (insn) >= ix86_cost->large_insn
19003    && peep2_regno_dead_p (0, FLAGS_REG)"
19004   [(parallel [(set (match_dup 2) (const_int 0))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (set (match_dup 0) (match_dup 1))]
19007   "operands[2] = gen_lowpart (SImode, operands[1]);")
19008
19009 (define_peephole2
19010   [(match_scratch:QI 1 "q")
19011    (set (match_operand:QI 0 "memory_operand" "")
19012         (const_int 0))]
19013   "! optimize_size
19014    && ! TARGET_USE_MOV0
19015    && TARGET_SPLIT_LONG_MOVES
19016    && get_attr_length (insn) >= ix86_cost->large_insn
19017    && peep2_regno_dead_p (0, FLAGS_REG)"
19018   [(parallel [(set (match_dup 2) (const_int 0))
19019               (clobber (reg:CC FLAGS_REG))])
19020    (set (match_dup 0) (match_dup 1))]
19021   "operands[2] = gen_lowpart (SImode, operands[1]);")
19022
19023 (define_peephole2
19024   [(match_scratch:SI 2 "r")
19025    (set (match_operand:SI 0 "memory_operand" "")
19026         (match_operand:SI 1 "immediate_operand" ""))]
19027   "! optimize_size
19028    && get_attr_length (insn) >= ix86_cost->large_insn
19029    && TARGET_SPLIT_LONG_MOVES"
19030   [(set (match_dup 2) (match_dup 1))
19031    (set (match_dup 0) (match_dup 2))]
19032   "")
19033
19034 (define_peephole2
19035   [(match_scratch:HI 2 "r")
19036    (set (match_operand:HI 0 "memory_operand" "")
19037         (match_operand:HI 1 "immediate_operand" ""))]
19038   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19039   && TARGET_SPLIT_LONG_MOVES"
19040   [(set (match_dup 2) (match_dup 1))
19041    (set (match_dup 0) (match_dup 2))]
19042   "")
19043
19044 (define_peephole2
19045   [(match_scratch:QI 2 "q")
19046    (set (match_operand:QI 0 "memory_operand" "")
19047         (match_operand:QI 1 "immediate_operand" ""))]
19048   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19049   && TARGET_SPLIT_LONG_MOVES"
19050   [(set (match_dup 2) (match_dup 1))
19051    (set (match_dup 0) (match_dup 2))]
19052   "")
19053
19054 ;; Don't compare memory with zero, load and use a test instead.
19055 (define_peephole2
19056   [(set (reg 17)
19057         (compare (match_operand:SI 0 "memory_operand" "")
19058                  (const_int 0)))
19059    (match_scratch:SI 3 "r")]
19060   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19061   [(set (match_dup 3) (match_dup 0))
19062    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19063   "")
19064
19065 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19066 ;; Don't split NOTs with a displacement operand, because resulting XOR
19067 ;; will not be pairable anyway.
19068 ;;
19069 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19070 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19071 ;; so this split helps here as well.
19072 ;;
19073 ;; Note: Can't do this as a regular split because we can't get proper
19074 ;; lifetime information then.
19075
19076 (define_peephole2
19077   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19078         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19079   "!optimize_size
19080    && peep2_regno_dead_p (0, FLAGS_REG)
19081    && ((TARGET_PENTIUM 
19082         && (GET_CODE (operands[0]) != MEM
19083             || !memory_displacement_operand (operands[0], SImode)))
19084        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19085   [(parallel [(set (match_dup 0)
19086                    (xor:SI (match_dup 1) (const_int -1)))
19087               (clobber (reg:CC FLAGS_REG))])]
19088   "")
19089
19090 (define_peephole2
19091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19092         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19093   "!optimize_size
19094    && peep2_regno_dead_p (0, FLAGS_REG)
19095    && ((TARGET_PENTIUM 
19096         && (GET_CODE (operands[0]) != MEM
19097             || !memory_displacement_operand (operands[0], HImode)))
19098        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19099   [(parallel [(set (match_dup 0)
19100                    (xor:HI (match_dup 1) (const_int -1)))
19101               (clobber (reg:CC FLAGS_REG))])]
19102   "")
19103
19104 (define_peephole2
19105   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19106         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19107   "!optimize_size
19108    && peep2_regno_dead_p (0, FLAGS_REG)
19109    && ((TARGET_PENTIUM 
19110         && (GET_CODE (operands[0]) != MEM
19111             || !memory_displacement_operand (operands[0], QImode)))
19112        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19113   [(parallel [(set (match_dup 0)
19114                    (xor:QI (match_dup 1) (const_int -1)))
19115               (clobber (reg:CC FLAGS_REG))])]
19116   "")
19117
19118 ;; Non pairable "test imm, reg" instructions can be translated to
19119 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19120 ;; byte opcode instead of two, have a short form for byte operands),
19121 ;; so do it for other CPUs as well.  Given that the value was dead,
19122 ;; this should not create any new dependencies.  Pass on the sub-word
19123 ;; versions if we're concerned about partial register stalls.
19124
19125 (define_peephole2
19126   [(set (reg 17)
19127         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19128                          (match_operand:SI 1 "immediate_operand" ""))
19129                  (const_int 0)))]
19130   "ix86_match_ccmode (insn, CCNOmode)
19131    && (true_regnum (operands[0]) != 0
19132        || (GET_CODE (operands[1]) == CONST_INT
19133            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19134    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19135   [(parallel
19136      [(set (reg:CCNO FLAGS_REG)
19137            (compare:CCNO (and:SI (match_dup 0)
19138                                  (match_dup 1))
19139                          (const_int 0)))
19140       (set (match_dup 0)
19141            (and:SI (match_dup 0) (match_dup 1)))])]
19142   "")
19143
19144 ;; We don't need to handle HImode case, because it will be promoted to SImode
19145 ;; on ! TARGET_PARTIAL_REG_STALL
19146
19147 (define_peephole2
19148   [(set (reg 17)
19149         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19150                          (match_operand:QI 1 "immediate_operand" ""))
19151                  (const_int 0)))]
19152   "! TARGET_PARTIAL_REG_STALL
19153    && ix86_match_ccmode (insn, CCNOmode)
19154    && true_regnum (operands[0]) != 0
19155    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19156   [(parallel
19157      [(set (reg:CCNO FLAGS_REG)
19158            (compare:CCNO (and:QI (match_dup 0)
19159                                  (match_dup 1))
19160                          (const_int 0)))
19161       (set (match_dup 0)
19162            (and:QI (match_dup 0) (match_dup 1)))])]
19163   "")
19164
19165 (define_peephole2
19166   [(set (reg 17)
19167         (compare
19168           (and:SI
19169             (zero_extract:SI
19170               (match_operand 0 "ext_register_operand" "")
19171               (const_int 8)
19172               (const_int 8))
19173             (match_operand 1 "const_int_operand" ""))
19174           (const_int 0)))]
19175   "! TARGET_PARTIAL_REG_STALL
19176    && ix86_match_ccmode (insn, CCNOmode)
19177    && true_regnum (operands[0]) != 0
19178    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19179   [(parallel [(set (reg:CCNO FLAGS_REG)
19180                    (compare:CCNO
19181                        (and:SI
19182                          (zero_extract:SI
19183                          (match_dup 0)
19184                          (const_int 8)
19185                          (const_int 8))
19186                         (match_dup 1))
19187                    (const_int 0)))
19188               (set (zero_extract:SI (match_dup 0)
19189                                     (const_int 8)
19190                                     (const_int 8))
19191                    (and:SI 
19192                      (zero_extract:SI
19193                        (match_dup 0)
19194                        (const_int 8)
19195                        (const_int 8))
19196                      (match_dup 1)))])]
19197   "")
19198
19199 ;; Don't do logical operations with memory inputs.
19200 (define_peephole2
19201   [(match_scratch:SI 2 "r")
19202    (parallel [(set (match_operand:SI 0 "register_operand" "")
19203                    (match_operator:SI 3 "arith_or_logical_operator"
19204                      [(match_dup 0)
19205                       (match_operand:SI 1 "memory_operand" "")]))
19206               (clobber (reg:CC FLAGS_REG))])]
19207   "! optimize_size && ! TARGET_READ_MODIFY"
19208   [(set (match_dup 2) (match_dup 1))
19209    (parallel [(set (match_dup 0)
19210                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19211               (clobber (reg:CC FLAGS_REG))])]
19212   "")
19213
19214 (define_peephole2
19215   [(match_scratch:SI 2 "r")
19216    (parallel [(set (match_operand:SI 0 "register_operand" "")
19217                    (match_operator:SI 3 "arith_or_logical_operator"
19218                      [(match_operand:SI 1 "memory_operand" "")
19219                       (match_dup 0)]))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   "! optimize_size && ! TARGET_READ_MODIFY"
19222   [(set (match_dup 2) (match_dup 1))
19223    (parallel [(set (match_dup 0)
19224                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19225               (clobber (reg:CC FLAGS_REG))])]
19226   "")
19227
19228 ; Don't do logical operations with memory outputs
19229 ;
19230 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19231 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19232 ; the same decoder scheduling characteristics as the original.
19233
19234 (define_peephole2
19235   [(match_scratch:SI 2 "r")
19236    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19237                    (match_operator:SI 3 "arith_or_logical_operator"
19238                      [(match_dup 0)
19239                       (match_operand:SI 1 "nonmemory_operand" "")]))
19240               (clobber (reg:CC FLAGS_REG))])]
19241   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19242   [(set (match_dup 2) (match_dup 0))
19243    (parallel [(set (match_dup 2)
19244                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19245               (clobber (reg:CC FLAGS_REG))])
19246    (set (match_dup 0) (match_dup 2))]
19247   "")
19248
19249 (define_peephole2
19250   [(match_scratch:SI 2 "r")
19251    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19252                    (match_operator:SI 3 "arith_or_logical_operator"
19253                      [(match_operand:SI 1 "nonmemory_operand" "")
19254                       (match_dup 0)]))
19255               (clobber (reg:CC FLAGS_REG))])]
19256   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19257   [(set (match_dup 2) (match_dup 0))
19258    (parallel [(set (match_dup 2)
19259                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19260               (clobber (reg:CC FLAGS_REG))])
19261    (set (match_dup 0) (match_dup 2))]
19262   "")
19263
19264 ;; Attempt to always use XOR for zeroing registers.
19265 (define_peephole2
19266   [(set (match_operand 0 "register_operand" "")
19267         (const_int 0))]
19268   "(GET_MODE (operands[0]) == QImode
19269     || GET_MODE (operands[0]) == HImode
19270     || GET_MODE (operands[0]) == SImode
19271     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19272    && (! TARGET_USE_MOV0 || optimize_size)
19273    && peep2_regno_dead_p (0, FLAGS_REG)"
19274   [(parallel [(set (match_dup 0) (const_int 0))
19275               (clobber (reg:CC FLAGS_REG))])]
19276   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19277                               operands[0]);")
19278
19279 (define_peephole2
19280   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19281         (const_int 0))]
19282   "(GET_MODE (operands[0]) == QImode
19283     || GET_MODE (operands[0]) == HImode)
19284    && (! TARGET_USE_MOV0 || optimize_size)
19285    && peep2_regno_dead_p (0, FLAGS_REG)"
19286   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19287               (clobber (reg:CC FLAGS_REG))])])
19288
19289 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19290 (define_peephole2
19291   [(set (match_operand 0 "register_operand" "")
19292         (const_int -1))]
19293   "(GET_MODE (operands[0]) == HImode
19294     || GET_MODE (operands[0]) == SImode 
19295     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19296    && (optimize_size || TARGET_PENTIUM)
19297    && peep2_regno_dead_p (0, FLAGS_REG)"
19298   [(parallel [(set (match_dup 0) (const_int -1))
19299               (clobber (reg:CC FLAGS_REG))])]
19300   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19301                               operands[0]);")
19302
19303 ;; Attempt to convert simple leas to adds. These can be created by
19304 ;; move expanders.
19305 (define_peephole2
19306   [(set (match_operand:SI 0 "register_operand" "")
19307         (plus:SI (match_dup 0)
19308                  (match_operand:SI 1 "nonmemory_operand" "")))]
19309   "peep2_regno_dead_p (0, FLAGS_REG)"
19310   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19311               (clobber (reg:CC FLAGS_REG))])]
19312   "")
19313
19314 (define_peephole2
19315   [(set (match_operand:SI 0 "register_operand" "")
19316         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19317                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19318   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19319   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "operands[2] = gen_lowpart (SImode, operands[2]);")
19322
19323 (define_peephole2
19324   [(set (match_operand:DI 0 "register_operand" "")
19325         (plus:DI (match_dup 0)
19326                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19327   "peep2_regno_dead_p (0, FLAGS_REG)"
19328   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19329               (clobber (reg:CC FLAGS_REG))])]
19330   "")
19331
19332 (define_peephole2
19333   [(set (match_operand:SI 0 "register_operand" "")
19334         (mult:SI (match_dup 0)
19335                  (match_operand:SI 1 "const_int_operand" "")))]
19336   "exact_log2 (INTVAL (operands[1])) >= 0
19337    && peep2_regno_dead_p (0, FLAGS_REG)"
19338   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19341
19342 (define_peephole2
19343   [(set (match_operand:DI 0 "register_operand" "")
19344         (mult:DI (match_dup 0)
19345                  (match_operand:DI 1 "const_int_operand" "")))]
19346   "exact_log2 (INTVAL (operands[1])) >= 0
19347    && peep2_regno_dead_p (0, FLAGS_REG)"
19348   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19349               (clobber (reg:CC FLAGS_REG))])]
19350   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19351
19352 (define_peephole2
19353   [(set (match_operand:SI 0 "register_operand" "")
19354         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19355                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19356   "exact_log2 (INTVAL (operands[2])) >= 0
19357    && REGNO (operands[0]) == REGNO (operands[1])
19358    && peep2_regno_dead_p (0, FLAGS_REG)"
19359   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19360               (clobber (reg:CC FLAGS_REG))])]
19361   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19362
19363 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19364 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19365 ;; many CPUs it is also faster, since special hardware to avoid esp
19366 ;; dependencies is present.
19367
19368 ;; While some of these conversions may be done using splitters, we use peepholes
19369 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19370
19371 ;; Convert prologue esp subtractions to push.
19372 ;; We need register to push.  In order to keep verify_flow_info happy we have
19373 ;; two choices
19374 ;; - use scratch and clobber it in order to avoid dependencies
19375 ;; - use already live register
19376 ;; We can't use the second way right now, since there is no reliable way how to
19377 ;; verify that given register is live.  First choice will also most likely in
19378 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19379 ;; call clobbered registers are dead.  We may want to use base pointer as an
19380 ;; alternative when no register is available later.
19381
19382 (define_peephole2
19383   [(match_scratch:SI 0 "r")
19384    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19385               (clobber (reg:CC FLAGS_REG))
19386               (clobber (mem:BLK (scratch)))])]
19387   "optimize_size || !TARGET_SUB_ESP_4"
19388   [(clobber (match_dup 0))
19389    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19390               (clobber (mem:BLK (scratch)))])])
19391
19392 (define_peephole2
19393   [(match_scratch:SI 0 "r")
19394    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19395               (clobber (reg:CC FLAGS_REG))
19396               (clobber (mem:BLK (scratch)))])]
19397   "optimize_size || !TARGET_SUB_ESP_8"
19398   [(clobber (match_dup 0))
19399    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19400    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19401               (clobber (mem:BLK (scratch)))])])
19402
19403 ;; Convert esp subtractions to push.
19404 (define_peephole2
19405   [(match_scratch:SI 0 "r")
19406    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19407               (clobber (reg:CC FLAGS_REG))])]
19408   "optimize_size || !TARGET_SUB_ESP_4"
19409   [(clobber (match_dup 0))
19410    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19411
19412 (define_peephole2
19413   [(match_scratch:SI 0 "r")
19414    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19415               (clobber (reg:CC FLAGS_REG))])]
19416   "optimize_size || !TARGET_SUB_ESP_8"
19417   [(clobber (match_dup 0))
19418    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19419    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19420
19421 ;; Convert epilogue deallocator to pop.
19422 (define_peephole2
19423   [(match_scratch:SI 0 "r")
19424    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19425               (clobber (reg:CC FLAGS_REG))
19426               (clobber (mem:BLK (scratch)))])]
19427   "optimize_size || !TARGET_ADD_ESP_4"
19428   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19429               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19430               (clobber (mem:BLK (scratch)))])]
19431   "")
19432
19433 ;; Two pops case is tricky, since pop causes dependency on destination register.
19434 ;; We use two registers if available.
19435 (define_peephole2
19436   [(match_scratch:SI 0 "r")
19437    (match_scratch:SI 1 "r")
19438    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19439               (clobber (reg:CC FLAGS_REG))
19440               (clobber (mem:BLK (scratch)))])]
19441   "optimize_size || !TARGET_ADD_ESP_8"
19442   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19443               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19444               (clobber (mem:BLK (scratch)))])
19445    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19446               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19447   "")
19448
19449 (define_peephole2
19450   [(match_scratch:SI 0 "r")
19451    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19452               (clobber (reg:CC FLAGS_REG))
19453               (clobber (mem:BLK (scratch)))])]
19454   "optimize_size"
19455   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19456               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19457               (clobber (mem:BLK (scratch)))])
19458    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19459               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19460   "")
19461
19462 ;; Convert esp additions to pop.
19463 (define_peephole2
19464   [(match_scratch:SI 0 "r")
19465    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19466               (clobber (reg:CC FLAGS_REG))])]
19467   ""
19468   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19469               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19470   "")
19471
19472 ;; Two pops case is tricky, since pop causes dependency on destination register.
19473 ;; We use two registers if available.
19474 (define_peephole2
19475   [(match_scratch:SI 0 "r")
19476    (match_scratch:SI 1 "r")
19477    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19478               (clobber (reg:CC FLAGS_REG))])]
19479   ""
19480   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19481               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19482    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19483               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19484   "")
19485
19486 (define_peephole2
19487   [(match_scratch:SI 0 "r")
19488    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19489               (clobber (reg:CC FLAGS_REG))])]
19490   "optimize_size"
19491   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19492               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19493    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19494               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19495   "")
19496 \f
19497 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19498 ;; required and register dies.
19499 (define_peephole2
19500   [(set (reg 17)
19501         (compare (match_operand:SI 0 "register_operand" "")
19502                  (match_operand:SI 1 "incdec_operand" "")))]
19503   "ix86_match_ccmode (insn, CCGCmode)
19504    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19505   [(parallel [(set (reg:CCGC FLAGS_REG)
19506                    (compare:CCGC (match_dup 0)
19507                                  (match_dup 1)))
19508               (clobber (match_dup 0))])]
19509   "")
19510
19511 (define_peephole2
19512   [(set (reg 17)
19513         (compare (match_operand:HI 0 "register_operand" "")
19514                  (match_operand:HI 1 "incdec_operand" "")))]
19515   "ix86_match_ccmode (insn, CCGCmode)
19516    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19517   [(parallel [(set (reg:CCGC FLAGS_REG)
19518                    (compare:CCGC (match_dup 0)
19519                                  (match_dup 1)))
19520               (clobber (match_dup 0))])]
19521   "")
19522
19523 (define_peephole2
19524   [(set (reg 17)
19525         (compare (match_operand:QI 0 "register_operand" "")
19526                  (match_operand:QI 1 "incdec_operand" "")))]
19527   "ix86_match_ccmode (insn, CCGCmode)
19528    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19529   [(parallel [(set (reg:CCGC FLAGS_REG)
19530                    (compare:CCGC (match_dup 0)
19531                                  (match_dup 1)))
19532               (clobber (match_dup 0))])]
19533   "")
19534
19535 ;; Convert compares with 128 to shorter add -128
19536 (define_peephole2
19537   [(set (reg 17)
19538         (compare (match_operand:SI 0 "register_operand" "")
19539                  (const_int 128)))]
19540   "ix86_match_ccmode (insn, CCGCmode)
19541    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19542   [(parallel [(set (reg:CCGC FLAGS_REG)
19543                    (compare:CCGC (match_dup 0)
19544                                  (const_int 128)))
19545               (clobber (match_dup 0))])]
19546   "")
19547
19548 (define_peephole2
19549   [(set (reg 17)
19550         (compare (match_operand:HI 0 "register_operand" "")
19551                  (const_int 128)))]
19552   "ix86_match_ccmode (insn, CCGCmode)
19553    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19554   [(parallel [(set (reg:CCGC FLAGS_REG)
19555                    (compare:CCGC (match_dup 0)
19556                                  (const_int 128)))
19557               (clobber (match_dup 0))])]
19558   "")
19559 \f
19560 (define_peephole2
19561   [(match_scratch:DI 0 "r")
19562    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19563               (clobber (reg:CC FLAGS_REG))
19564               (clobber (mem:BLK (scratch)))])]
19565   "optimize_size || !TARGET_SUB_ESP_4"
19566   [(clobber (match_dup 0))
19567    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19568               (clobber (mem:BLK (scratch)))])])
19569
19570 (define_peephole2
19571   [(match_scratch:DI 0 "r")
19572    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19573               (clobber (reg:CC FLAGS_REG))
19574               (clobber (mem:BLK (scratch)))])]
19575   "optimize_size || !TARGET_SUB_ESP_8"
19576   [(clobber (match_dup 0))
19577    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19578    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19579               (clobber (mem:BLK (scratch)))])])
19580
19581 ;; Convert esp subtractions to push.
19582 (define_peephole2
19583   [(match_scratch:DI 0 "r")
19584    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19585               (clobber (reg:CC FLAGS_REG))])]
19586   "optimize_size || !TARGET_SUB_ESP_4"
19587   [(clobber (match_dup 0))
19588    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19589
19590 (define_peephole2
19591   [(match_scratch:DI 0 "r")
19592    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19593               (clobber (reg:CC FLAGS_REG))])]
19594   "optimize_size || !TARGET_SUB_ESP_8"
19595   [(clobber (match_dup 0))
19596    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19597    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19598
19599 ;; Convert epilogue deallocator to pop.
19600 (define_peephole2
19601   [(match_scratch:DI 0 "r")
19602    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19603               (clobber (reg:CC FLAGS_REG))
19604               (clobber (mem:BLK (scratch)))])]
19605   "optimize_size || !TARGET_ADD_ESP_4"
19606   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19607               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19608               (clobber (mem:BLK (scratch)))])]
19609   "")
19610
19611 ;; Two pops case is tricky, since pop causes dependency on destination register.
19612 ;; We use two registers if available.
19613 (define_peephole2
19614   [(match_scratch:DI 0 "r")
19615    (match_scratch:DI 1 "r")
19616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19617               (clobber (reg:CC FLAGS_REG))
19618               (clobber (mem:BLK (scratch)))])]
19619   "optimize_size || !TARGET_ADD_ESP_8"
19620   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19621               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19622               (clobber (mem:BLK (scratch)))])
19623    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19624               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19625   "")
19626
19627 (define_peephole2
19628   [(match_scratch:DI 0 "r")
19629    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19630               (clobber (reg:CC FLAGS_REG))
19631               (clobber (mem:BLK (scratch)))])]
19632   "optimize_size"
19633   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19634               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19635               (clobber (mem:BLK (scratch)))])
19636    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19637               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19638   "")
19639
19640 ;; Convert esp additions to pop.
19641 (define_peephole2
19642   [(match_scratch:DI 0 "r")
19643    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19644               (clobber (reg:CC FLAGS_REG))])]
19645   ""
19646   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19647               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19648   "")
19649
19650 ;; Two pops case is tricky, since pop causes dependency on destination register.
19651 ;; We use two registers if available.
19652 (define_peephole2
19653   [(match_scratch:DI 0 "r")
19654    (match_scratch:DI 1 "r")
19655    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19656               (clobber (reg:CC FLAGS_REG))])]
19657   ""
19658   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19659               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19660    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19661               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19662   "")
19663
19664 (define_peephole2
19665   [(match_scratch:DI 0 "r")
19666    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19667               (clobber (reg:CC FLAGS_REG))])]
19668   "optimize_size"
19669   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19670               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19671    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19672               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19673   "")
19674 \f
19675 ;; Convert imul by three, five and nine into lea
19676 (define_peephole2
19677   [(parallel
19678     [(set (match_operand:SI 0 "register_operand" "")
19679           (mult:SI (match_operand:SI 1 "register_operand" "")
19680                    (match_operand:SI 2 "const_int_operand" "")))
19681      (clobber (reg:CC FLAGS_REG))])]
19682   "INTVAL (operands[2]) == 3
19683    || INTVAL (operands[2]) == 5
19684    || INTVAL (operands[2]) == 9"
19685   [(set (match_dup 0)
19686         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19687                  (match_dup 1)))]
19688   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19689
19690 (define_peephole2
19691   [(parallel
19692     [(set (match_operand:SI 0 "register_operand" "")
19693           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19694                    (match_operand:SI 2 "const_int_operand" "")))
19695      (clobber (reg:CC FLAGS_REG))])]
19696   "!optimize_size 
19697    && (INTVAL (operands[2]) == 3
19698        || INTVAL (operands[2]) == 5
19699        || INTVAL (operands[2]) == 9)"
19700   [(set (match_dup 0) (match_dup 1))
19701    (set (match_dup 0)
19702         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19703                  (match_dup 0)))]
19704   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19705
19706 (define_peephole2
19707   [(parallel
19708     [(set (match_operand:DI 0 "register_operand" "")
19709           (mult:DI (match_operand:DI 1 "register_operand" "")
19710                    (match_operand:DI 2 "const_int_operand" "")))
19711      (clobber (reg:CC FLAGS_REG))])]
19712   "TARGET_64BIT
19713    && (INTVAL (operands[2]) == 3
19714        || INTVAL (operands[2]) == 5
19715        || INTVAL (operands[2]) == 9)"
19716   [(set (match_dup 0)
19717         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19718                  (match_dup 1)))]
19719   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19720
19721 (define_peephole2
19722   [(parallel
19723     [(set (match_operand:DI 0 "register_operand" "")
19724           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19725                    (match_operand:DI 2 "const_int_operand" "")))
19726      (clobber (reg:CC FLAGS_REG))])]
19727   "TARGET_64BIT
19728    && !optimize_size 
19729    && (INTVAL (operands[2]) == 3
19730        || INTVAL (operands[2]) == 5
19731        || INTVAL (operands[2]) == 9)"
19732   [(set (match_dup 0) (match_dup 1))
19733    (set (match_dup 0)
19734         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19735                  (match_dup 0)))]
19736   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19737
19738 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19739 ;; imul $32bit_imm, reg, reg is direct decoded.
19740 (define_peephole2
19741   [(match_scratch:DI 3 "r")
19742    (parallel [(set (match_operand:DI 0 "register_operand" "")
19743                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19744                             (match_operand:DI 2 "immediate_operand" "")))
19745               (clobber (reg:CC FLAGS_REG))])]
19746   "TARGET_K8 && !optimize_size
19747    && (GET_CODE (operands[2]) != CONST_INT
19748        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19749   [(set (match_dup 3) (match_dup 1))
19750    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19751               (clobber (reg:CC FLAGS_REG))])]
19752 "")
19753
19754 (define_peephole2
19755   [(match_scratch:SI 3 "r")
19756    (parallel [(set (match_operand:SI 0 "register_operand" "")
19757                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19758                             (match_operand:SI 2 "immediate_operand" "")))
19759               (clobber (reg:CC FLAGS_REG))])]
19760   "TARGET_K8 && !optimize_size
19761    && (GET_CODE (operands[2]) != CONST_INT
19762        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19763   [(set (match_dup 3) (match_dup 1))
19764    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19765               (clobber (reg:CC FLAGS_REG))])]
19766 "")
19767
19768 (define_peephole2
19769   [(match_scratch:SI 3 "r")
19770    (parallel [(set (match_operand:DI 0 "register_operand" "")
19771                    (zero_extend:DI
19772                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19773                               (match_operand:SI 2 "immediate_operand" ""))))
19774               (clobber (reg:CC FLAGS_REG))])]
19775   "TARGET_K8 && !optimize_size
19776    && (GET_CODE (operands[2]) != CONST_INT
19777        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19778   [(set (match_dup 3) (match_dup 1))
19779    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19780               (clobber (reg:CC FLAGS_REG))])]
19781 "")
19782
19783 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19784 ;; Convert it into imul reg, reg
19785 ;; It would be better to force assembler to encode instruction using long
19786 ;; immediate, but there is apparently no way to do so.
19787 (define_peephole2
19788   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19789                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19790                             (match_operand:DI 2 "const_int_operand" "")))
19791               (clobber (reg:CC FLAGS_REG))])
19792    (match_scratch:DI 3 "r")]
19793   "TARGET_K8 && !optimize_size
19794    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19795   [(set (match_dup 3) (match_dup 2))
19796    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19797               (clobber (reg:CC FLAGS_REG))])]
19798 {
19799   if (!rtx_equal_p (operands[0], operands[1]))
19800     emit_move_insn (operands[0], operands[1]);
19801 })
19802
19803 (define_peephole2
19804   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19805                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19806                             (match_operand:SI 2 "const_int_operand" "")))
19807               (clobber (reg:CC FLAGS_REG))])
19808    (match_scratch:SI 3 "r")]
19809   "TARGET_K8 && !optimize_size
19810    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19811   [(set (match_dup 3) (match_dup 2))
19812    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19813               (clobber (reg:CC FLAGS_REG))])]
19814 {
19815   if (!rtx_equal_p (operands[0], operands[1]))
19816     emit_move_insn (operands[0], operands[1]);
19817 })
19818
19819 (define_peephole2
19820   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19821                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19822                             (match_operand:HI 2 "immediate_operand" "")))
19823               (clobber (reg:CC FLAGS_REG))])
19824    (match_scratch:HI 3 "r")]
19825   "TARGET_K8 && !optimize_size"
19826   [(set (match_dup 3) (match_dup 2))
19827    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19828               (clobber (reg:CC FLAGS_REG))])]
19829 {
19830   if (!rtx_equal_p (operands[0], operands[1]))
19831     emit_move_insn (operands[0], operands[1]);
19832 })
19833 \f
19834 ;; Call-value patterns last so that the wildcard operand does not
19835 ;; disrupt insn-recog's switch tables.
19836
19837 (define_insn "*call_value_pop_0"
19838   [(set (match_operand 0 "" "")
19839         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19840               (match_operand:SI 2 "" "")))
19841    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19842                             (match_operand:SI 3 "immediate_operand" "")))]
19843   "!TARGET_64BIT"
19844 {
19845   if (SIBLING_CALL_P (insn))
19846     return "jmp\t%P1";
19847   else
19848     return "call\t%P1";
19849 }
19850   [(set_attr "type" "callv")])
19851
19852 (define_insn "*call_value_pop_1"
19853   [(set (match_operand 0 "" "")
19854         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19855               (match_operand:SI 2 "" "")))
19856    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19857                             (match_operand:SI 3 "immediate_operand" "i")))]
19858   "!TARGET_64BIT"
19859 {
19860   if (constant_call_address_operand (operands[1], Pmode))
19861     {
19862       if (SIBLING_CALL_P (insn))
19863         return "jmp\t%P1";
19864       else
19865         return "call\t%P1";
19866     }
19867   if (SIBLING_CALL_P (insn))
19868     return "jmp\t%A1";
19869   else
19870     return "call\t%A1";
19871 }
19872   [(set_attr "type" "callv")])
19873
19874 (define_insn "*call_value_0"
19875   [(set (match_operand 0 "" "")
19876         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19877               (match_operand:SI 2 "" "")))]
19878   "!TARGET_64BIT"
19879 {
19880   if (SIBLING_CALL_P (insn))
19881     return "jmp\t%P1";
19882   else
19883     return "call\t%P1";
19884 }
19885   [(set_attr "type" "callv")])
19886
19887 (define_insn "*call_value_0_rex64"
19888   [(set (match_operand 0 "" "")
19889         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19890               (match_operand:DI 2 "const_int_operand" "")))]
19891   "TARGET_64BIT"
19892 {
19893   if (SIBLING_CALL_P (insn))
19894     return "jmp\t%P1";
19895   else
19896     return "call\t%P1";
19897 }
19898   [(set_attr "type" "callv")])
19899
19900 (define_insn "*call_value_1"
19901   [(set (match_operand 0 "" "")
19902         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19903               (match_operand:SI 2 "" "")))]
19904   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19905 {
19906   if (constant_call_address_operand (operands[1], Pmode))
19907     return "call\t%P1";
19908   return "call\t%*%1";
19909 }
19910   [(set_attr "type" "callv")])
19911
19912 (define_insn "*sibcall_value_1"
19913   [(set (match_operand 0 "" "")
19914         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19915               (match_operand:SI 2 "" "")))]
19916   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19917 {
19918   if (constant_call_address_operand (operands[1], Pmode))
19919     return "jmp\t%P1";
19920   return "jmp\t%*%1";
19921 }
19922   [(set_attr "type" "callv")])
19923
19924 (define_insn "*call_value_1_rex64"
19925   [(set (match_operand 0 "" "")
19926         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19927               (match_operand:DI 2 "" "")))]
19928   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19929 {
19930   if (constant_call_address_operand (operands[1], Pmode))
19931     return "call\t%P1";
19932   return "call\t%A1";
19933 }
19934   [(set_attr "type" "callv")])
19935
19936 (define_insn "*sibcall_value_1_rex64"
19937   [(set (match_operand 0 "" "")
19938         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19939               (match_operand:DI 2 "" "")))]
19940   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19941   "jmp\t%P1"
19942   [(set_attr "type" "callv")])
19943
19944 (define_insn "*sibcall_value_1_rex64_v"
19945   [(set (match_operand 0 "" "")
19946         (call (mem:QI (reg:DI 40))
19947               (match_operand:DI 1 "" "")))]
19948   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19949   "jmp\t*%%r11"
19950   [(set_attr "type" "callv")])
19951 \f
19952 (define_insn "trap"
19953   [(trap_if (const_int 1) (const_int 5))]
19954   ""
19955   "int\t$5")
19956
19957 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19958 ;;; for the sake of bounds checking.  By emitting bounds checks as
19959 ;;; conditional traps rather than as conditional jumps around
19960 ;;; unconditional traps we avoid introducing spurious basic-block
19961 ;;; boundaries and facilitate elimination of redundant checks.  In
19962 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19963 ;;; interrupt 5.
19964 ;;; 
19965 ;;; FIXME: Static branch prediction rules for ix86 are such that
19966 ;;; forward conditional branches predict as untaken.  As implemented
19967 ;;; below, pseudo conditional traps violate that rule.  We should use
19968 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19969 ;;; section loaded at the end of the text segment and branch forward
19970 ;;; there on bounds-failure, and then jump back immediately (in case
19971 ;;; the system chooses to ignore bounds violations, or to report
19972 ;;; violations and continue execution).
19973
19974 (define_expand "conditional_trap"
19975   [(trap_if (match_operator 0 "comparison_operator"
19976              [(match_dup 2) (const_int 0)])
19977             (match_operand 1 "const_int_operand" ""))]
19978   ""
19979 {
19980   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19981                               ix86_expand_compare (GET_CODE (operands[0]),
19982                                                    NULL, NULL),
19983                               operands[1]));
19984   DONE;
19985 })
19986
19987 (define_insn "*conditional_trap_1"
19988   [(trap_if (match_operator 0 "comparison_operator"
19989              [(reg 17) (const_int 0)])
19990             (match_operand 1 "const_int_operand" ""))]
19991   ""
19992 {
19993   operands[2] = gen_label_rtx ();
19994   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19995   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19996                              CODE_LABEL_NUMBER (operands[2]));
19997   RET;
19998 })
19999
20000         ;; Pentium III SIMD instructions.
20001
20002 ;; Moves for SSE/MMX regs.
20003
20004 (define_insn "movv4sf_internal"
20005   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20006         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
20007   "TARGET_SSE"
20008   "@
20009     xorps\t%0, %0
20010     movaps\t{%1, %0|%0, %1}
20011     movaps\t{%1, %0|%0, %1}"
20012   [(set_attr "type" "ssemov")
20013    (set_attr "mode" "V4SF")])
20014
20015 (define_split
20016   [(set (match_operand:V4SF 0 "register_operand" "")
20017         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
20018   "TARGET_SSE"
20019   [(set (match_dup 0)
20020         (vec_merge:V4SF
20021          (vec_duplicate:V4SF (match_dup 1))
20022          (match_dup 2)
20023          (const_int 1)))]
20024 {
20025   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20026   operands[2] = CONST0_RTX (V4SFmode);
20027 })
20028
20029 (define_insn "movv4si_internal"
20030   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20031         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20032   "TARGET_SSE"
20033 {
20034   switch (which_alternative)
20035     {
20036     case 0:
20037       if (get_attr_mode (insn) == MODE_V4SF)
20038         return "xorps\t%0, %0";
20039       else
20040         return "pxor\t%0, %0";
20041     case 1:
20042     case 2:
20043       if (get_attr_mode (insn) == MODE_V4SF)
20044         return "movaps\t{%1, %0|%0, %1}";
20045       else
20046         return "movdqa\t{%1, %0|%0, %1}";
20047     default:
20048       abort ();
20049     }
20050 }
20051   [(set_attr "type" "ssemov")
20052    (set (attr "mode")
20053         (cond [(eq_attr "alternative" "0,1")
20054                  (if_then_else
20055                    (ne (symbol_ref "optimize_size")
20056                        (const_int 0))
20057                    (const_string "V4SF")
20058                    (const_string "TI"))
20059                (eq_attr "alternative" "2")
20060                  (if_then_else
20061                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20062                             (const_int 0))
20063                         (ne (symbol_ref "optimize_size")
20064                             (const_int 0)))
20065                    (const_string "V4SF")
20066                    (const_string "TI"))]
20067                (const_string "TI")))])
20068
20069 (define_insn "movv2di_internal"
20070   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20071         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20072   "TARGET_SSE"
20073 {
20074   switch (which_alternative)
20075     {
20076     case 0:
20077       if (get_attr_mode (insn) == MODE_V4SF)
20078         return "xorps\t%0, %0";
20079       else
20080         return "pxor\t%0, %0";
20081     case 1:
20082     case 2:
20083       if (get_attr_mode (insn) == MODE_V4SF)
20084         return "movaps\t{%1, %0|%0, %1}";
20085       else
20086         return "movdqa\t{%1, %0|%0, %1}";
20087     default:
20088       abort ();
20089     }
20090 }
20091   [(set_attr "type" "ssemov")
20092    (set (attr "mode")
20093         (cond [(eq_attr "alternative" "0,1")
20094                  (if_then_else
20095                    (ne (symbol_ref "optimize_size")
20096                        (const_int 0))
20097                    (const_string "V4SF")
20098                    (const_string "TI"))
20099                (eq_attr "alternative" "2")
20100                  (if_then_else
20101                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20102                             (const_int 0))
20103                         (ne (symbol_ref "optimize_size")
20104                             (const_int 0)))
20105                    (const_string "V4SF")
20106                    (const_string "TI"))]
20107                (const_string "TI")))])
20108
20109 (define_split
20110   [(set (match_operand:V2DF 0 "register_operand" "")
20111         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20112   "TARGET_SSE2"
20113   [(set (match_dup 0)
20114         (vec_merge:V2DF
20115          (vec_duplicate:V2DF (match_dup 1))
20116          (match_dup 2)
20117          (const_int 1)))]
20118 {
20119   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20120   operands[2] = CONST0_RTX (V2DFmode);
20121 })
20122
20123 (define_insn "movv8qi_internal"
20124   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20125         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20126   "TARGET_MMX
20127    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20128   "@
20129     pxor\t%0, %0
20130     movq\t{%1, %0|%0, %1}
20131     movq\t{%1, %0|%0, %1}
20132     movdq2q\t{%1, %0|%0, %1}
20133     movq2dq\t{%1, %0|%0, %1}
20134     movq\t{%1, %0|%0, %1}
20135     movq\t{%1, %0|%0, %1}"
20136   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20137    (set_attr "mode" "DI")])
20138
20139 (define_insn "movv4hi_internal"
20140   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20141         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20142   "TARGET_MMX
20143    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20144   "@
20145     pxor\t%0, %0
20146     movq\t{%1, %0|%0, %1}
20147     movq\t{%1, %0|%0, %1}
20148     movdq2q\t{%1, %0|%0, %1}
20149     movq2dq\t{%1, %0|%0, %1}
20150     movq\t{%1, %0|%0, %1}
20151     movq\t{%1, %0|%0, %1}"
20152   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20153    (set_attr "mode" "DI")])
20154
20155 (define_insn "*movv2si_internal"
20156   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20157         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20158   "TARGET_MMX
20159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20160   "@
20161     pxor\t%0, %0
20162     movq\t{%1, %0|%0, %1}
20163     movq\t{%1, %0|%0, %1}
20164     movdq2q\t{%1, %0|%0, %1}
20165     movq2dq\t{%1, %0|%0, %1}
20166     movq\t{%1, %0|%0, %1}
20167     movq\t{%1, %0|%0, %1}"
20168   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20169    (set_attr "mode" "DI")])
20170
20171 (define_insn "movv2sf_internal"
20172   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20173         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20174   "TARGET_3DNOW
20175    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20176   "@
20177     pxor\t%0, %0
20178     movq\t{%1, %0|%0, %1}
20179     movq\t{%1, %0|%0, %1}
20180     movdq2q\t{%1, %0|%0, %1}
20181     movq2dq\t{%1, %0|%0, %1}
20182     movlps\t{%1, %0|%0, %1}
20183     movlps\t{%1, %0|%0, %1}"
20184   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20185    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20186
20187 (define_expand "movti"
20188   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20189         (match_operand:TI 1 "nonimmediate_operand" ""))]
20190   "TARGET_SSE || TARGET_64BIT"
20191 {
20192   if (TARGET_64BIT)
20193     ix86_expand_move (TImode, operands);
20194   else
20195     ix86_expand_vector_move (TImode, operands);
20196   DONE;
20197 })
20198
20199 (define_expand "movtf"
20200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20201         (match_operand:TF 1 "nonimmediate_operand" ""))]
20202   "TARGET_64BIT"
20203 {
20204   if (TARGET_64BIT)
20205     ix86_expand_move (TFmode, operands);
20206   else
20207     ix86_expand_vector_move (TFmode, operands);
20208   DONE;
20209 })
20210
20211 (define_insn "movv2df_internal"
20212   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20213         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20214   "TARGET_SSE2
20215    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20216 {
20217   switch (which_alternative)
20218     {
20219     case 0:
20220       if (get_attr_mode (insn) == MODE_V4SF)
20221         return "xorps\t%0, %0";
20222       else
20223         return "xorpd\t%0, %0";
20224     case 1:
20225     case 2:
20226       if (get_attr_mode (insn) == MODE_V4SF)
20227         return "movaps\t{%1, %0|%0, %1}";
20228       else
20229         return "movapd\t{%1, %0|%0, %1}";
20230     default:
20231       abort ();
20232     }
20233 }
20234   [(set_attr "type" "ssemov")
20235    (set (attr "mode")
20236         (cond [(eq_attr "alternative" "0,1")
20237                  (if_then_else
20238                    (ne (symbol_ref "optimize_size")
20239                        (const_int 0))
20240                    (const_string "V4SF")
20241                    (const_string "V2DF"))
20242                (eq_attr "alternative" "2")
20243                  (if_then_else
20244                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20245                             (const_int 0))
20246                         (ne (symbol_ref "optimize_size")
20247                             (const_int 0)))
20248                    (const_string "V4SF")
20249                    (const_string "V2DF"))]
20250                (const_string "V2DF")))])
20251
20252 (define_insn "movv8hi_internal"
20253   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20254         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20255   "TARGET_SSE2
20256    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20257 {
20258   switch (which_alternative)
20259     {
20260     case 0:
20261       if (get_attr_mode (insn) == MODE_V4SF)
20262         return "xorps\t%0, %0";
20263       else
20264         return "pxor\t%0, %0";
20265     case 1:
20266     case 2:
20267       if (get_attr_mode (insn) == MODE_V4SF)
20268         return "movaps\t{%1, %0|%0, %1}";
20269       else
20270         return "movdqa\t{%1, %0|%0, %1}";
20271     default:
20272       abort ();
20273     }
20274 }
20275   [(set_attr "type" "ssemov")
20276    (set (attr "mode")
20277         (cond [(eq_attr "alternative" "0,1")
20278                  (if_then_else
20279                    (ne (symbol_ref "optimize_size")
20280                        (const_int 0))
20281                    (const_string "V4SF")
20282                    (const_string "TI"))
20283                (eq_attr "alternative" "2")
20284                  (if_then_else
20285                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20286                             (const_int 0))
20287                         (ne (symbol_ref "optimize_size")
20288                             (const_int 0)))
20289                    (const_string "V4SF")
20290                    (const_string "TI"))]
20291                (const_string "TI")))])
20292
20293 (define_insn "movv16qi_internal"
20294   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20295         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20296   "TARGET_SSE2
20297    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20298 {
20299   switch (which_alternative)
20300     {
20301     case 0:
20302       if (get_attr_mode (insn) == MODE_V4SF)
20303         return "xorps\t%0, %0";
20304       else
20305         return "pxor\t%0, %0";
20306     case 1:
20307     case 2:
20308       if (get_attr_mode (insn) == MODE_V4SF)
20309         return "movaps\t{%1, %0|%0, %1}";
20310       else
20311         return "movdqa\t{%1, %0|%0, %1}";
20312     default:
20313       abort ();
20314     }
20315 }
20316   [(set_attr "type" "ssemov")
20317    (set (attr "mode")
20318         (cond [(eq_attr "alternative" "0,1")
20319                  (if_then_else
20320                    (ne (symbol_ref "optimize_size")
20321                        (const_int 0))
20322                    (const_string "V4SF")
20323                    (const_string "TI"))
20324                (eq_attr "alternative" "2")
20325                  (if_then_else
20326                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20327                             (const_int 0))
20328                         (ne (symbol_ref "optimize_size")
20329                             (const_int 0)))
20330                    (const_string "V4SF")
20331                    (const_string "TI"))]
20332                (const_string "TI")))])
20333
20334 (define_expand "movv2df"
20335   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20336         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20337   "TARGET_SSE2"
20338 {
20339   ix86_expand_vector_move (V2DFmode, operands);
20340   DONE;
20341 })
20342
20343 (define_expand "movv8hi"
20344   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20345         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20346   "TARGET_SSE2"
20347 {
20348   ix86_expand_vector_move (V8HImode, operands);
20349   DONE;
20350 })
20351
20352 (define_expand "movv16qi"
20353   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20354         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20355   "TARGET_SSE2"
20356 {
20357   ix86_expand_vector_move (V16QImode, operands);
20358   DONE;
20359 })
20360
20361 (define_expand "movv4sf"
20362   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20363         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20364   "TARGET_SSE"
20365 {
20366   ix86_expand_vector_move (V4SFmode, operands);
20367   DONE;
20368 })
20369
20370 (define_expand "movv4si"
20371   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20372         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20373   "TARGET_SSE"
20374 {
20375   ix86_expand_vector_move (V4SImode, operands);
20376   DONE;
20377 })
20378
20379 (define_expand "movv2di"
20380   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20381         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20382   "TARGET_SSE"
20383 {
20384   ix86_expand_vector_move (V2DImode, operands);
20385   DONE;
20386 })
20387
20388 (define_expand "movv2si"
20389   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20390         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20391   "TARGET_MMX"
20392 {
20393   ix86_expand_vector_move (V2SImode, operands);
20394   DONE;
20395 })
20396
20397 (define_expand "movv4hi"
20398   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20399         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20400   "TARGET_MMX"
20401 {
20402   ix86_expand_vector_move (V4HImode, operands);
20403   DONE;
20404 })
20405
20406 (define_expand "movv8qi"
20407   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20408         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20409   "TARGET_MMX"
20410 {
20411   ix86_expand_vector_move (V8QImode, operands);
20412   DONE;
20413 })
20414
20415 (define_expand "movv2sf"
20416   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20417         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20418    "TARGET_3DNOW"
20419 {
20420   ix86_expand_vector_move (V2SFmode, operands);
20421   DONE;
20422 })
20423
20424 (define_insn "*pushti"
20425   [(set (match_operand:TI 0 "push_operand" "=<")
20426         (match_operand:TI 1 "register_operand" "x"))]
20427   "TARGET_SSE"
20428   "#")
20429
20430 (define_insn "*pushv2df"
20431   [(set (match_operand:V2DF 0 "push_operand" "=<")
20432         (match_operand:V2DF 1 "register_operand" "x"))]
20433   "TARGET_SSE"
20434   "#")
20435
20436 (define_insn "*pushv2di"
20437   [(set (match_operand:V2DI 0 "push_operand" "=<")
20438         (match_operand:V2DI 1 "register_operand" "x"))]
20439   "TARGET_SSE2"
20440   "#")
20441
20442 (define_insn "*pushv8hi"
20443   [(set (match_operand:V8HI 0 "push_operand" "=<")
20444         (match_operand:V8HI 1 "register_operand" "x"))]
20445   "TARGET_SSE2"
20446   "#")
20447
20448 (define_insn "*pushv16qi"
20449   [(set (match_operand:V16QI 0 "push_operand" "=<")
20450         (match_operand:V16QI 1 "register_operand" "x"))]
20451   "TARGET_SSE2"
20452   "#")
20453
20454 (define_insn "*pushv4sf"
20455   [(set (match_operand:V4SF 0 "push_operand" "=<")
20456         (match_operand:V4SF 1 "register_operand" "x"))]
20457   "TARGET_SSE"
20458   "#")
20459
20460 (define_insn "*pushv4si"
20461   [(set (match_operand:V4SI 0 "push_operand" "=<")
20462         (match_operand:V4SI 1 "register_operand" "x"))]
20463   "TARGET_SSE2"
20464   "#")
20465
20466 (define_insn "*pushv2si"
20467   [(set (match_operand:V2SI 0 "push_operand" "=<")
20468         (match_operand:V2SI 1 "register_operand" "y"))]
20469   "TARGET_MMX"
20470   "#")
20471
20472 (define_insn "*pushv4hi"
20473   [(set (match_operand:V4HI 0 "push_operand" "=<")
20474         (match_operand:V4HI 1 "register_operand" "y"))]
20475   "TARGET_MMX"
20476   "#")
20477
20478 (define_insn "*pushv8qi"
20479   [(set (match_operand:V8QI 0 "push_operand" "=<")
20480         (match_operand:V8QI 1 "register_operand" "y"))]
20481   "TARGET_MMX"
20482   "#")
20483
20484 (define_insn "*pushv2sf"
20485   [(set (match_operand:V2SF 0 "push_operand" "=<")
20486         (match_operand:V2SF 1 "register_operand" "y"))]
20487   "TARGET_3DNOW"
20488   "#")
20489
20490 (define_split
20491   [(set (match_operand 0 "push_operand" "")
20492         (match_operand 1 "register_operand" ""))]
20493   "!TARGET_64BIT && reload_completed
20494    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20495   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20496    (set (match_dup 2) (match_dup 1))]
20497   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20498                                  stack_pointer_rtx);
20499    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20500
20501 (define_split
20502   [(set (match_operand 0 "push_operand" "")
20503         (match_operand 1 "register_operand" ""))]
20504   "TARGET_64BIT && reload_completed
20505    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20506   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20507    (set (match_dup 2) (match_dup 1))]
20508   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20509                                  stack_pointer_rtx);
20510    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20511
20512
20513 (define_insn "movti_internal"
20514   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20515         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20516   "TARGET_SSE && !TARGET_64BIT
20517    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20518 {
20519   switch (which_alternative)
20520     {
20521     case 0:
20522       if (get_attr_mode (insn) == MODE_V4SF)
20523         return "xorps\t%0, %0";
20524       else
20525         return "pxor\t%0, %0";
20526     case 1:
20527     case 2:
20528       if (get_attr_mode (insn) == MODE_V4SF)
20529         return "movaps\t{%1, %0|%0, %1}";
20530       else
20531         return "movdqa\t{%1, %0|%0, %1}";
20532     default:
20533       abort ();
20534     }
20535 }
20536   [(set_attr "type" "ssemov,ssemov,ssemov")
20537    (set (attr "mode")
20538         (cond [(eq_attr "alternative" "0,1")
20539                  (if_then_else
20540                    (ne (symbol_ref "optimize_size")
20541                        (const_int 0))
20542                    (const_string "V4SF")
20543                    (const_string "TI"))
20544                (eq_attr "alternative" "2")
20545                  (if_then_else
20546                    (ne (symbol_ref "optimize_size")
20547                        (const_int 0))
20548                    (const_string "V4SF")
20549                    (const_string "TI"))]
20550                (const_string "TI")))])
20551
20552 (define_insn "*movti_rex64"
20553   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20554         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20555   "TARGET_64BIT
20556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20557 {
20558   switch (which_alternative)
20559     {
20560     case 0:
20561     case 1:
20562       return "#";
20563     case 2:
20564       if (get_attr_mode (insn) == MODE_V4SF)
20565         return "xorps\t%0, %0";
20566       else
20567         return "pxor\t%0, %0";
20568     case 3:
20569     case 4:
20570       if (get_attr_mode (insn) == MODE_V4SF)
20571         return "movaps\t{%1, %0|%0, %1}";
20572       else
20573         return "movdqa\t{%1, %0|%0, %1}";
20574     default:
20575       abort ();
20576     }
20577 }
20578   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20579    (set (attr "mode")
20580         (cond [(eq_attr "alternative" "2,3")
20581                  (if_then_else
20582                    (ne (symbol_ref "optimize_size")
20583                        (const_int 0))
20584                    (const_string "V4SF")
20585                    (const_string "TI"))
20586                (eq_attr "alternative" "4")
20587                  (if_then_else
20588                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20589                             (const_int 0))
20590                         (ne (symbol_ref "optimize_size")
20591                             (const_int 0)))
20592                    (const_string "V4SF")
20593                    (const_string "TI"))]
20594                (const_string "DI")))])
20595
20596 (define_insn "*movtf_rex64"
20597   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20598         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20599   "TARGET_64BIT
20600    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20601 {
20602   switch (which_alternative)
20603     {
20604     case 0:
20605     case 1:
20606       return "#";
20607     case 2:
20608       if (get_attr_mode (insn) == MODE_V4SF)
20609         return "xorps\t%0, %0";
20610       else
20611         return "pxor\t%0, %0";
20612     case 3:
20613     case 4:
20614       if (get_attr_mode (insn) == MODE_V4SF)
20615         return "movaps\t{%1, %0|%0, %1}";
20616       else
20617         return "movdqa\t{%1, %0|%0, %1}";
20618     default:
20619       abort ();
20620     }
20621 }
20622   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20623    (set (attr "mode")
20624         (cond [(eq_attr "alternative" "2,3")
20625                  (if_then_else
20626                    (ne (symbol_ref "optimize_size")
20627                        (const_int 0))
20628                    (const_string "V4SF")
20629                    (const_string "TI"))
20630                (eq_attr "alternative" "4")
20631                  (if_then_else
20632                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20633                             (const_int 0))
20634                         (ne (symbol_ref "optimize_size")
20635                             (const_int 0)))
20636                    (const_string "V4SF")
20637                    (const_string "TI"))]
20638                (const_string "DI")))])
20639
20640 (define_split
20641   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20642         (match_operand:TI 1 "general_operand" ""))]
20643   "reload_completed && !SSE_REG_P (operands[0])
20644    && !SSE_REG_P (operands[1])"
20645   [(const_int 0)]
20646   "ix86_split_long_move (operands); DONE;")
20647
20648 (define_split
20649   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20650         (match_operand:TF 1 "general_operand" ""))]
20651   "reload_completed && !SSE_REG_P (operands[0])
20652    && !SSE_REG_P (operands[1])"
20653   [(const_int 0)]
20654   "ix86_split_long_move (operands); DONE;")
20655
20656 ;; These two patterns are useful for specifying exactly whether to use
20657 ;; movaps or movups
20658 (define_expand "sse_movaps"
20659   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20660         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20661                      UNSPEC_MOVA))]
20662   "TARGET_SSE"
20663 {
20664   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20665     {
20666       rtx tmp = gen_reg_rtx (V4SFmode);
20667       emit_insn (gen_sse_movaps (tmp, operands[1]));
20668       emit_move_insn (operands[0], tmp);
20669       DONE;
20670     }
20671 })
20672
20673 (define_insn "*sse_movaps_1"
20674   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20675         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20676                      UNSPEC_MOVA))]
20677   "TARGET_SSE
20678    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20679   "movaps\t{%1, %0|%0, %1}"
20680   [(set_attr "type" "ssemov,ssemov")
20681    (set_attr "mode" "V4SF")])
20682
20683 (define_expand "sse_movups"
20684   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20685         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20686                      UNSPEC_MOVU))]
20687   "TARGET_SSE"
20688 {
20689   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20690     {
20691       rtx tmp = gen_reg_rtx (V4SFmode);
20692       emit_insn (gen_sse_movups (tmp, operands[1]));
20693       emit_move_insn (operands[0], tmp);
20694       DONE;
20695     }
20696 })
20697
20698 (define_insn "*sse_movups_1"
20699   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20700         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20701                      UNSPEC_MOVU))]
20702   "TARGET_SSE
20703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20704   "movups\t{%1, %0|%0, %1}"
20705   [(set_attr "type" "ssecvt,ssecvt")
20706    (set_attr "mode" "V4SF")])
20707
20708 ;; SSE Strange Moves.
20709
20710 (define_insn "sse_movmskps"
20711   [(set (match_operand:SI 0 "register_operand" "=r")
20712         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20713                    UNSPEC_MOVMSK))]
20714   "TARGET_SSE"
20715   "movmskps\t{%1, %0|%0, %1}"
20716   [(set_attr "type" "ssecvt")
20717    (set_attr "mode" "V4SF")])
20718
20719 (define_insn "mmx_pmovmskb"
20720   [(set (match_operand:SI 0 "register_operand" "=r")
20721         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20722                    UNSPEC_MOVMSK))]
20723   "TARGET_SSE || TARGET_3DNOW_A"
20724   "pmovmskb\t{%1, %0|%0, %1}"
20725   [(set_attr "type" "ssecvt")
20726    (set_attr "mode" "V4SF")])
20727
20728
20729 (define_insn "mmx_maskmovq"
20730   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20731         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20732                       (match_operand:V8QI 2 "register_operand" "y")]
20733                      UNSPEC_MASKMOV))]
20734   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20735   ;; @@@ check ordering of operands in intel/nonintel syntax
20736   "maskmovq\t{%2, %1|%1, %2}"
20737   [(set_attr "type" "mmxcvt")
20738    (set_attr "mode" "DI")])
20739
20740 (define_insn "mmx_maskmovq_rex"
20741   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20742         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20743                       (match_operand:V8QI 2 "register_operand" "y")]
20744                      UNSPEC_MASKMOV))]
20745   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20746   ;; @@@ check ordering of operands in intel/nonintel syntax
20747   "maskmovq\t{%2, %1|%1, %2}"
20748   [(set_attr "type" "mmxcvt")
20749    (set_attr "mode" "DI")])
20750
20751 (define_insn "sse_movntv4sf"
20752   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20753         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20754                      UNSPEC_MOVNT))]
20755   "TARGET_SSE"
20756   "movntps\t{%1, %0|%0, %1}"
20757   [(set_attr "type" "ssemov")
20758    (set_attr "mode" "V4SF")])
20759
20760 (define_insn "sse_movntdi"
20761   [(set (match_operand:DI 0 "memory_operand" "=m")
20762         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20763                    UNSPEC_MOVNT))]
20764   "TARGET_SSE || TARGET_3DNOW_A"
20765   "movntq\t{%1, %0|%0, %1}"
20766   [(set_attr "type" "mmxmov")
20767    (set_attr "mode" "DI")])
20768
20769 (define_insn "sse_movhlps"
20770   [(set (match_operand:V4SF 0 "register_operand" "=x")
20771         (vec_merge:V4SF
20772          (match_operand:V4SF 1 "register_operand" "0")
20773          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20774                           (parallel [(const_int 2)
20775                                      (const_int 3)
20776                                      (const_int 0)
20777                                      (const_int 1)]))
20778          (const_int 3)))]
20779   "TARGET_SSE"
20780   "movhlps\t{%2, %0|%0, %2}"
20781   [(set_attr "type" "ssecvt")
20782    (set_attr "mode" "V4SF")])
20783
20784 (define_insn "sse_movlhps"
20785   [(set (match_operand:V4SF 0 "register_operand" "=x")
20786         (vec_merge:V4SF
20787          (match_operand:V4SF 1 "register_operand" "0")
20788          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20789                           (parallel [(const_int 2)
20790                                      (const_int 3)
20791                                      (const_int 0)
20792                                      (const_int 1)]))
20793          (const_int 12)))]
20794   "TARGET_SSE"
20795   "movlhps\t{%2, %0|%0, %2}"
20796   [(set_attr "type" "ssecvt")
20797    (set_attr "mode" "V4SF")])
20798
20799 (define_insn "sse_movhps"
20800   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20801         (vec_merge:V4SF
20802          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20803          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20804          (const_int 12)))]
20805   "TARGET_SSE
20806    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20807   "movhps\t{%2, %0|%0, %2}"
20808   [(set_attr "type" "ssecvt")
20809    (set_attr "mode" "V4SF")])
20810
20811 (define_insn "sse_movlps"
20812   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20813         (vec_merge:V4SF
20814          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20815          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20816          (const_int 3)))]
20817   "TARGET_SSE
20818    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20819   "movlps\t{%2, %0|%0, %2}"
20820   [(set_attr "type" "ssecvt")
20821    (set_attr "mode" "V4SF")])
20822
20823 (define_expand "sse_loadss"
20824   [(match_operand:V4SF 0 "register_operand" "")
20825    (match_operand:SF 1 "memory_operand" "")]
20826   "TARGET_SSE"
20827 {
20828   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20829                                CONST0_RTX (V4SFmode)));
20830   DONE;
20831 })
20832
20833 (define_insn "sse_loadss_1"
20834   [(set (match_operand:V4SF 0 "register_operand" "=x")
20835         (vec_merge:V4SF
20836          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20837          (match_operand:V4SF 2 "const0_operand" "X")
20838          (const_int 1)))]
20839   "TARGET_SSE"
20840   "movss\t{%1, %0|%0, %1}"
20841   [(set_attr "type" "ssemov")
20842    (set_attr "mode" "SF")])
20843
20844 (define_insn "sse_movss"
20845   [(set (match_operand:V4SF 0 "register_operand" "=x")
20846         (vec_merge:V4SF
20847          (match_operand:V4SF 1 "register_operand" "0")
20848          (match_operand:V4SF 2 "register_operand" "x")
20849          (const_int 1)))]
20850   "TARGET_SSE"
20851   "movss\t{%2, %0|%0, %2}"
20852   [(set_attr "type" "ssemov")
20853    (set_attr "mode" "SF")])
20854
20855 (define_insn "sse_storess"
20856   [(set (match_operand:SF 0 "memory_operand" "=m")
20857         (vec_select:SF
20858          (match_operand:V4SF 1 "register_operand" "x")
20859          (parallel [(const_int 0)])))]
20860   "TARGET_SSE"
20861   "movss\t{%1, %0|%0, %1}"
20862   [(set_attr "type" "ssemov")
20863    (set_attr "mode" "SF")])
20864
20865 (define_insn "sse_shufps"
20866   [(set (match_operand:V4SF 0 "register_operand" "=x")
20867         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20868                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20869                       (match_operand:SI 3 "immediate_operand" "i")]
20870                      UNSPEC_SHUFFLE))]
20871   "TARGET_SSE"
20872   ;; @@@ check operand order for intel/nonintel syntax
20873   "shufps\t{%3, %2, %0|%0, %2, %3}"
20874   [(set_attr "type" "ssecvt")
20875    (set_attr "mode" "V4SF")])
20876
20877
20878 ;; SSE arithmetic
20879
20880 (define_insn "addv4sf3"
20881   [(set (match_operand:V4SF 0 "register_operand" "=x")
20882         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20883                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20884   "TARGET_SSE"
20885   "addps\t{%2, %0|%0, %2}"
20886   [(set_attr "type" "sseadd")
20887    (set_attr "mode" "V4SF")])
20888
20889 (define_insn "vmaddv4sf3"
20890   [(set (match_operand:V4SF 0 "register_operand" "=x")
20891         (vec_merge:V4SF
20892          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20893                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20894          (match_dup 1)
20895          (const_int 1)))]
20896   "TARGET_SSE"
20897   "addss\t{%2, %0|%0, %2}"
20898   [(set_attr "type" "sseadd")
20899    (set_attr "mode" "SF")])
20900
20901 (define_insn "subv4sf3"
20902   [(set (match_operand:V4SF 0 "register_operand" "=x")
20903         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20904                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20905   "TARGET_SSE"
20906   "subps\t{%2, %0|%0, %2}"
20907   [(set_attr "type" "sseadd")
20908    (set_attr "mode" "V4SF")])
20909
20910 (define_insn "vmsubv4sf3"
20911   [(set (match_operand:V4SF 0 "register_operand" "=x")
20912         (vec_merge:V4SF
20913          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20914                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20915          (match_dup 1)
20916          (const_int 1)))]
20917   "TARGET_SSE"
20918   "subss\t{%2, %0|%0, %2}"
20919   [(set_attr "type" "sseadd")
20920    (set_attr "mode" "SF")])
20921
20922 ;; ??? Should probably be done by generic code instead.
20923 (define_expand "negv4sf2"
20924   [(set (match_operand:V4SF 0 "register_operand" "")
20925         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20926                   (match_dup 2)))]
20927   "TARGET_SSE"
20928 {
20929   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20930   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20931   operands[2] = force_reg (V4SFmode, vm0);
20932 })
20933
20934 (define_insn "mulv4sf3"
20935   [(set (match_operand:V4SF 0 "register_operand" "=x")
20936         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20937                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20938   "TARGET_SSE"
20939   "mulps\t{%2, %0|%0, %2}"
20940   [(set_attr "type" "ssemul")
20941    (set_attr "mode" "V4SF")])
20942
20943 (define_insn "vmmulv4sf3"
20944   [(set (match_operand:V4SF 0 "register_operand" "=x")
20945         (vec_merge:V4SF
20946          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20947                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20948          (match_dup 1)
20949          (const_int 1)))]
20950   "TARGET_SSE"
20951   "mulss\t{%2, %0|%0, %2}"
20952   [(set_attr "type" "ssemul")
20953    (set_attr "mode" "SF")])
20954
20955 (define_insn "divv4sf3"
20956   [(set (match_operand:V4SF 0 "register_operand" "=x")
20957         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20958                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20959   "TARGET_SSE"
20960   "divps\t{%2, %0|%0, %2}"
20961   [(set_attr "type" "ssediv")
20962    (set_attr "mode" "V4SF")])
20963
20964 (define_insn "vmdivv4sf3"
20965   [(set (match_operand:V4SF 0 "register_operand" "=x")
20966         (vec_merge:V4SF
20967          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20968                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20969          (match_dup 1)
20970          (const_int 1)))]
20971   "TARGET_SSE"
20972   "divss\t{%2, %0|%0, %2}"
20973   [(set_attr "type" "ssediv")
20974    (set_attr "mode" "SF")])
20975
20976
20977 ;; SSE square root/reciprocal
20978
20979 (define_insn "rcpv4sf2"
20980   [(set (match_operand:V4SF 0 "register_operand" "=x")
20981         (unspec:V4SF
20982          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20983   "TARGET_SSE"
20984   "rcpps\t{%1, %0|%0, %1}"
20985   [(set_attr "type" "sse")
20986    (set_attr "mode" "V4SF")])
20987
20988 (define_insn "vmrcpv4sf2"
20989   [(set (match_operand:V4SF 0 "register_operand" "=x")
20990         (vec_merge:V4SF
20991          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20992                       UNSPEC_RCP)
20993          (match_operand:V4SF 2 "register_operand" "0")
20994          (const_int 1)))]
20995   "TARGET_SSE"
20996   "rcpss\t{%1, %0|%0, %1}"
20997   [(set_attr "type" "sse")
20998    (set_attr "mode" "SF")])
20999
21000 (define_insn "rsqrtv4sf2"
21001   [(set (match_operand:V4SF 0 "register_operand" "=x")
21002         (unspec:V4SF
21003          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
21004   "TARGET_SSE"
21005   "rsqrtps\t{%1, %0|%0, %1}"
21006   [(set_attr "type" "sse")
21007    (set_attr "mode" "V4SF")])
21008
21009 (define_insn "vmrsqrtv4sf2"
21010   [(set (match_operand:V4SF 0 "register_operand" "=x")
21011         (vec_merge:V4SF
21012          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21013                       UNSPEC_RSQRT)
21014          (match_operand:V4SF 2 "register_operand" "0")
21015          (const_int 1)))]
21016   "TARGET_SSE"
21017   "rsqrtss\t{%1, %0|%0, %1}"
21018   [(set_attr "type" "sse")
21019    (set_attr "mode" "SF")])
21020
21021 (define_insn "sqrtv4sf2"
21022   [(set (match_operand:V4SF 0 "register_operand" "=x")
21023         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21024   "TARGET_SSE"
21025   "sqrtps\t{%1, %0|%0, %1}"
21026   [(set_attr "type" "sse")
21027    (set_attr "mode" "V4SF")])
21028
21029 (define_insn "vmsqrtv4sf2"
21030   [(set (match_operand:V4SF 0 "register_operand" "=x")
21031         (vec_merge:V4SF
21032          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21033          (match_operand:V4SF 2 "register_operand" "0")
21034          (const_int 1)))]
21035   "TARGET_SSE"
21036   "sqrtss\t{%1, %0|%0, %1}"
21037   [(set_attr "type" "sse")
21038    (set_attr "mode" "SF")])
21039
21040 ;; SSE logical operations.
21041
21042 ;; SSE defines logical operations on floating point values.  This brings
21043 ;; interesting challenge to RTL representation where logicals are only valid
21044 ;; on integral types.  We deal with this by representing the floating point
21045 ;; logical as logical on arguments casted to TImode as this is what hardware
21046 ;; really does.  Unfortunately hardware requires the type information to be
21047 ;; present and thus we must avoid subregs from being simplified and eliminated
21048 ;; in later compilation phases.
21049 ;;
21050 ;; We have following variants from each instruction:
21051 ;; sse_andsf3 - the operation taking V4SF vector operands
21052 ;;              and doing TImode cast on them
21053 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21054 ;;                      TImode, since backend insist on eliminating casts
21055 ;;                      on memory operands
21056 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21057 ;;                   We cannot accept memory operand here as instruction reads
21058 ;;                   whole scalar.  This is generated only post reload by GCC
21059 ;;                   scalar float operations that expands to logicals (fabs)
21060 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21061 ;;                   memory operand.  Eventually combine can be able
21062 ;;                   to synthesize these using splitter.
21063 ;; sse2_anddf3, *sse2_anddf3_memory
21064 ;;              
21065 ;; 
21066 ;; These are not called andti3 etc. because we really really don't want
21067 ;; the compiler to widen DImode ands to TImode ands and then try to move
21068 ;; into DImode subregs of SSE registers, and them together, and move out
21069 ;; of DImode subregs again!
21070 ;; SSE1 single precision floating point logical operation
21071 (define_expand "sse_andv4sf3"
21072   [(set (match_operand:V4SF 0 "register_operand" "")
21073         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21074                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21075   "TARGET_SSE"
21076   "")
21077
21078 (define_insn "*sse_andv4sf3"
21079   [(set (match_operand:V4SF 0 "register_operand" "=x")
21080         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21081                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21082   "TARGET_SSE
21083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21084   "andps\t{%2, %0|%0, %2}"
21085   [(set_attr "type" "sselog")
21086    (set_attr "mode" "V4SF")])
21087
21088 (define_expand "sse_nandv4sf3"
21089   [(set (match_operand:V4SF 0 "register_operand" "")
21090         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21091                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21092   "TARGET_SSE"
21093   "")
21094
21095 (define_insn "*sse_nandv4sf3"
21096   [(set (match_operand:V4SF 0 "register_operand" "=x")
21097         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21098                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21099   "TARGET_SSE"
21100   "andnps\t{%2, %0|%0, %2}"
21101   [(set_attr "type" "sselog")
21102    (set_attr "mode" "V4SF")])
21103
21104 (define_expand "sse_iorv4sf3"
21105   [(set (match_operand:V4SF 0 "register_operand" "")
21106         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21107                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21108   "TARGET_SSE"
21109   "")
21110
21111 (define_insn "*sse_iorv4sf3"
21112   [(set (match_operand:V4SF 0 "register_operand" "=x")
21113         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21114                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21115   "TARGET_SSE
21116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21117   "orps\t{%2, %0|%0, %2}"
21118   [(set_attr "type" "sselog")
21119    (set_attr "mode" "V4SF")])
21120
21121 (define_expand "sse_xorv4sf3"
21122   [(set (match_operand:V4SF 0 "register_operand" "")
21123         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21124                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21125   "TARGET_SSE"
21126   "")
21127
21128 (define_insn "*sse_xorv4sf3"
21129   [(set (match_operand:V4SF 0 "register_operand" "=x")
21130         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21131                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21132   "TARGET_SSE
21133    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21134   "xorps\t{%2, %0|%0, %2}"
21135   [(set_attr "type" "sselog")
21136    (set_attr "mode" "V4SF")])
21137
21138 ;; SSE2 double precision floating point logical operation
21139
21140 (define_expand "sse2_andv2df3"
21141   [(set (match_operand:V2DF 0 "register_operand" "")
21142         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21143                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21144   "TARGET_SSE2"
21145   "")
21146
21147 (define_insn "*sse2_andv2df3"
21148   [(set (match_operand:V2DF 0 "register_operand" "=x")
21149         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21150                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21151   "TARGET_SSE2
21152    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21153   "andpd\t{%2, %0|%0, %2}"
21154   [(set_attr "type" "sselog")
21155    (set_attr "mode" "V2DF")])
21156
21157 (define_expand "sse2_nandv2df3"
21158   [(set (match_operand:V2DF 0 "register_operand" "")
21159         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21160                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21161   "TARGET_SSE2"
21162   "")
21163
21164 (define_insn "*sse2_nandv2df3"
21165   [(set (match_operand:V2DF 0 "register_operand" "=x")
21166         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21167                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21168   "TARGET_SSE2"
21169   "andnpd\t{%2, %0|%0, %2}"
21170   [(set_attr "type" "sselog")
21171    (set_attr "mode" "V2DF")])
21172
21173 (define_expand "sse2_iorv2df3"
21174   [(set (match_operand:V2DF 0 "register_operand" "")
21175         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21176                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21177   "TARGET_SSE2"
21178   "")
21179
21180 (define_insn "*sse2_iorv2df3"
21181   [(set (match_operand:V2DF 0 "register_operand" "=x")
21182         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21183                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21184   "TARGET_SSE2
21185    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21186   "orpd\t{%2, %0|%0, %2}"
21187   [(set_attr "type" "sselog")
21188    (set_attr "mode" "V2DF")])
21189
21190 (define_expand "sse2_xorv2df3"
21191   [(set (match_operand:V2DF 0 "register_operand" "")
21192         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21193                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21194   "TARGET_SSE2"
21195   "")
21196
21197 (define_insn "*sse2_xorv2df3"
21198   [(set (match_operand:V2DF 0 "register_operand" "=x")
21199         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21200                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21201   "TARGET_SSE2
21202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21203   "xorpd\t{%2, %0|%0, %2}"
21204   [(set_attr "type" "sselog")
21205    (set_attr "mode" "V2DF")])
21206
21207 ;; SSE2 integral logicals.  These patterns must always come after floating
21208 ;; point ones since we don't want compiler to use integer opcodes on floating
21209 ;; point SSE values to avoid matching of subregs in the match_operand.
21210 (define_insn "*sse2_andti3"
21211   [(set (match_operand:TI 0 "register_operand" "=x")
21212         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21213                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21214   "TARGET_SSE2
21215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21216   "pand\t{%2, %0|%0, %2}"
21217   [(set_attr "type" "sselog")
21218    (set_attr "mode" "TI")])
21219
21220 (define_insn "sse2_andv2di3"
21221   [(set (match_operand:V2DI 0 "register_operand" "=x")
21222         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21223                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21224   "TARGET_SSE2
21225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21226   "pand\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "sselog")
21228    (set_attr "mode" "TI")])
21229
21230 (define_insn "*sse2_nandti3"
21231   [(set (match_operand:TI 0 "register_operand" "=x")
21232         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21233                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21234   "TARGET_SSE2"
21235   "pandn\t{%2, %0|%0, %2}"
21236   [(set_attr "type" "sselog")
21237    (set_attr "mode" "TI")])
21238
21239 (define_insn "sse2_nandv2di3"
21240   [(set (match_operand:V2DI 0 "register_operand" "=x")
21241         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21242                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21243   "TARGET_SSE2
21244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21245   "pandn\t{%2, %0|%0, %2}"
21246   [(set_attr "type" "sselog")
21247    (set_attr "mode" "TI")])
21248
21249 (define_insn "*sse2_iorti3"
21250   [(set (match_operand:TI 0 "register_operand" "=x")
21251         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21252                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21253   "TARGET_SSE2
21254    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21255   "por\t{%2, %0|%0, %2}"
21256   [(set_attr "type" "sselog")
21257    (set_attr "mode" "TI")])
21258
21259 (define_insn "sse2_iorv2di3"
21260   [(set (match_operand:V2DI 0 "register_operand" "=x")
21261         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21262                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21263   "TARGET_SSE2
21264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21265   "por\t{%2, %0|%0, %2}"
21266   [(set_attr "type" "sselog")
21267    (set_attr "mode" "TI")])
21268
21269 (define_insn "*sse2_xorti3"
21270   [(set (match_operand:TI 0 "register_operand" "=x")
21271         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21272                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21273   "TARGET_SSE2
21274    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21275   "pxor\t{%2, %0|%0, %2}"
21276   [(set_attr "type" "sselog")
21277    (set_attr "mode" "TI")])
21278
21279 (define_insn "sse2_xorv2di3"
21280   [(set (match_operand:V2DI 0 "register_operand" "=x")
21281         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21282                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21283   "TARGET_SSE2
21284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21285   "pxor\t{%2, %0|%0, %2}"
21286   [(set_attr "type" "sselog")
21287    (set_attr "mode" "TI")])
21288
21289 ;; Use xor, but don't show input operands so they aren't live before
21290 ;; this insn.
21291 (define_insn "sse_clrv4sf"
21292   [(set (match_operand:V4SF 0 "register_operand" "=x")
21293         (match_operand:V4SF 1 "const0_operand" "X"))]
21294   "TARGET_SSE"
21295 {
21296   if (get_attr_mode (insn) == MODE_TI)
21297     return "pxor\t{%0, %0|%0, %0}";
21298   else
21299     return "xorps\t{%0, %0|%0, %0}";
21300 }
21301   [(set_attr "type" "sselog")
21302    (set_attr "memory" "none")
21303    (set (attr "mode")
21304         (if_then_else
21305            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21306                          (const_int 0))
21307                      (ne (symbol_ref "TARGET_SSE2")
21308                          (const_int 0)))
21309                 (eq (symbol_ref "optimize_size")
21310                     (const_int 0)))
21311          (const_string "TI")
21312          (const_string "V4SF")))])
21313
21314 ;; Use xor, but don't show input operands so they aren't live before
21315 ;; this insn.
21316 (define_insn "sse_clrv2df"
21317   [(set (match_operand:V2DF 0 "register_operand" "=x")
21318         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21319   "TARGET_SSE2"
21320   "xorpd\t{%0, %0|%0, %0}"
21321   [(set_attr "type" "sselog")
21322    (set_attr "memory" "none")
21323    (set_attr "mode" "V4SF")])
21324
21325 ;; SSE mask-generating compares
21326
21327 (define_insn "maskcmpv4sf3"
21328   [(set (match_operand:V4SI 0 "register_operand" "=x")
21329         (match_operator:V4SI 3 "sse_comparison_operator"
21330                 [(match_operand:V4SF 1 "register_operand" "0")
21331                  (match_operand:V4SF 2 "register_operand" "x")]))]
21332   "TARGET_SSE"
21333   "cmp%D3ps\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "ssecmp")
21335    (set_attr "mode" "V4SF")])
21336
21337 (define_insn "maskncmpv4sf3"
21338   [(set (match_operand:V4SI 0 "register_operand" "=x")
21339         (not:V4SI
21340          (match_operator:V4SI 3 "sse_comparison_operator"
21341                 [(match_operand:V4SF 1 "register_operand" "0")
21342                  (match_operand:V4SF 2 "register_operand" "x")])))]
21343   "TARGET_SSE"
21344 {
21345   if (GET_CODE (operands[3]) == UNORDERED)
21346     return "cmpordps\t{%2, %0|%0, %2}";
21347   else
21348     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21349 }
21350   [(set_attr "type" "ssecmp")
21351    (set_attr "mode" "V4SF")])
21352
21353 (define_insn "vmmaskcmpv4sf3"
21354   [(set (match_operand:V4SI 0 "register_operand" "=x")
21355         (vec_merge:V4SI
21356          (match_operator:V4SI 3 "sse_comparison_operator"
21357                 [(match_operand:V4SF 1 "register_operand" "0")
21358                  (match_operand:V4SF 2 "register_operand" "x")])
21359          (subreg:V4SI (match_dup 1) 0)
21360          (const_int 1)))]
21361   "TARGET_SSE"
21362   "cmp%D3ss\t{%2, %0|%0, %2}"
21363   [(set_attr "type" "ssecmp")
21364    (set_attr "mode" "SF")])
21365
21366 (define_insn "vmmaskncmpv4sf3"
21367   [(set (match_operand:V4SI 0 "register_operand" "=x")
21368         (vec_merge:V4SI
21369          (not:V4SI
21370           (match_operator:V4SI 3 "sse_comparison_operator"
21371                 [(match_operand:V4SF 1 "register_operand" "0")
21372                  (match_operand:V4SF 2 "register_operand" "x")]))
21373          (subreg:V4SI (match_dup 1) 0)
21374          (const_int 1)))]
21375   "TARGET_SSE"
21376 {
21377   if (GET_CODE (operands[3]) == UNORDERED)
21378     return "cmpordss\t{%2, %0|%0, %2}";
21379   else
21380     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21381 }
21382   [(set_attr "type" "ssecmp")
21383    (set_attr "mode" "SF")])
21384
21385 (define_insn "sse_comi"
21386   [(set (reg:CCFP FLAGS_REG)
21387         (compare:CCFP (vec_select:SF
21388                        (match_operand:V4SF 0 "register_operand" "x")
21389                        (parallel [(const_int 0)]))
21390                       (vec_select:SF
21391                        (match_operand:V4SF 1 "register_operand" "x")
21392                        (parallel [(const_int 0)]))))]
21393   "TARGET_SSE"
21394   "comiss\t{%1, %0|%0, %1}"
21395   [(set_attr "type" "ssecomi")
21396    (set_attr "mode" "SF")])
21397
21398 (define_insn "sse_ucomi"
21399   [(set (reg:CCFPU FLAGS_REG)
21400         (compare:CCFPU (vec_select:SF
21401                         (match_operand:V4SF 0 "register_operand" "x")
21402                         (parallel [(const_int 0)]))
21403                        (vec_select:SF
21404                         (match_operand:V4SF 1 "register_operand" "x")
21405                         (parallel [(const_int 0)]))))]
21406   "TARGET_SSE"
21407   "ucomiss\t{%1, %0|%0, %1}"
21408   [(set_attr "type" "ssecomi")
21409    (set_attr "mode" "SF")])
21410
21411
21412 ;; SSE unpack
21413
21414 (define_insn "sse_unpckhps"
21415   [(set (match_operand:V4SF 0 "register_operand" "=x")
21416         (vec_merge:V4SF
21417          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21418                           (parallel [(const_int 2)
21419                                      (const_int 0)
21420                                      (const_int 3)
21421                                      (const_int 1)]))
21422          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21423                           (parallel [(const_int 0)
21424                                      (const_int 2)
21425                                      (const_int 1)
21426                                      (const_int 3)]))
21427          (const_int 5)))]
21428   "TARGET_SSE"
21429   "unpckhps\t{%2, %0|%0, %2}"
21430   [(set_attr "type" "ssecvt")
21431    (set_attr "mode" "V4SF")])
21432
21433 (define_insn "sse_unpcklps"
21434   [(set (match_operand:V4SF 0 "register_operand" "=x")
21435         (vec_merge:V4SF
21436          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21437                           (parallel [(const_int 0)
21438                                      (const_int 2)
21439                                      (const_int 1)
21440                                      (const_int 3)]))
21441          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21442                           (parallel [(const_int 2)
21443                                      (const_int 0)
21444                                      (const_int 3)
21445                                      (const_int 1)]))
21446          (const_int 5)))]
21447   "TARGET_SSE"
21448   "unpcklps\t{%2, %0|%0, %2}"
21449   [(set_attr "type" "ssecvt")
21450    (set_attr "mode" "V4SF")])
21451
21452
21453 ;; SSE min/max
21454
21455 (define_insn "smaxv4sf3"
21456   [(set (match_operand:V4SF 0 "register_operand" "=x")
21457         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21458                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21459   "TARGET_SSE"
21460   "maxps\t{%2, %0|%0, %2}"
21461   [(set_attr "type" "sse")
21462    (set_attr "mode" "V4SF")])
21463
21464 (define_insn "vmsmaxv4sf3"
21465   [(set (match_operand:V4SF 0 "register_operand" "=x")
21466         (vec_merge:V4SF
21467          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21468                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21469          (match_dup 1)
21470          (const_int 1)))]
21471   "TARGET_SSE"
21472   "maxss\t{%2, %0|%0, %2}"
21473   [(set_attr "type" "sse")
21474    (set_attr "mode" "SF")])
21475
21476 (define_insn "sminv4sf3"
21477   [(set (match_operand:V4SF 0 "register_operand" "=x")
21478         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21479                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21480   "TARGET_SSE"
21481   "minps\t{%2, %0|%0, %2}"
21482   [(set_attr "type" "sse")
21483    (set_attr "mode" "V4SF")])
21484
21485 (define_insn "vmsminv4sf3"
21486   [(set (match_operand:V4SF 0 "register_operand" "=x")
21487         (vec_merge:V4SF
21488          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21489                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21490          (match_dup 1)
21491          (const_int 1)))]
21492   "TARGET_SSE"
21493   "minss\t{%2, %0|%0, %2}"
21494   [(set_attr "type" "sse")
21495    (set_attr "mode" "SF")])
21496
21497 ;; SSE <-> integer/MMX conversions
21498
21499 (define_insn "cvtpi2ps"
21500   [(set (match_operand:V4SF 0 "register_operand" "=x")
21501         (vec_merge:V4SF
21502          (match_operand:V4SF 1 "register_operand" "0")
21503          (vec_duplicate:V4SF
21504           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21505          (const_int 12)))]
21506   "TARGET_SSE"
21507   "cvtpi2ps\t{%2, %0|%0, %2}"
21508   [(set_attr "type" "ssecvt")
21509    (set_attr "mode" "V4SF")])
21510
21511 (define_insn "cvtps2pi"
21512   [(set (match_operand:V2SI 0 "register_operand" "=y")
21513         (vec_select:V2SI
21514          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21515          (parallel [(const_int 0) (const_int 1)])))]
21516   "TARGET_SSE"
21517   "cvtps2pi\t{%1, %0|%0, %1}"
21518   [(set_attr "type" "ssecvt")
21519    (set_attr "mode" "V4SF")])
21520
21521 (define_insn "cvttps2pi"
21522   [(set (match_operand:V2SI 0 "register_operand" "=y")
21523         (vec_select:V2SI
21524          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21525                       UNSPEC_FIX)
21526          (parallel [(const_int 0) (const_int 1)])))]
21527   "TARGET_SSE"
21528   "cvttps2pi\t{%1, %0|%0, %1}"
21529   [(set_attr "type" "ssecvt")
21530    (set_attr "mode" "SF")])
21531
21532 (define_insn "cvtsi2ss"
21533   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21534         (vec_merge:V4SF
21535          (match_operand:V4SF 1 "register_operand" "0,0")
21536          (vec_duplicate:V4SF
21537           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21538          (const_int 14)))]
21539   "TARGET_SSE"
21540   "cvtsi2ss\t{%2, %0|%0, %2}"
21541   [(set_attr "type" "sseicvt")
21542    (set_attr "athlon_decode" "vector,double")
21543    (set_attr "mode" "SF")])
21544
21545 (define_insn "cvtsi2ssq"
21546   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21547         (vec_merge:V4SF
21548          (match_operand:V4SF 1 "register_operand" "0,0")
21549          (vec_duplicate:V4SF
21550           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21551          (const_int 14)))]
21552   "TARGET_SSE && TARGET_64BIT"
21553   "cvtsi2ssq\t{%2, %0|%0, %2}"
21554   [(set_attr "type" "sseicvt")
21555    (set_attr "athlon_decode" "vector,double")
21556    (set_attr "mode" "SF")])
21557
21558 (define_insn "cvtss2si"
21559   [(set (match_operand:SI 0 "register_operand" "=r,r")
21560         (vec_select:SI
21561          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21562          (parallel [(const_int 0)])))]
21563   "TARGET_SSE"
21564   "cvtss2si\t{%1, %0|%0, %1}"
21565   [(set_attr "type" "sseicvt")
21566    (set_attr "athlon_decode" "double,vector")
21567    (set_attr "mode" "SI")])
21568
21569 (define_insn "cvtss2siq"
21570   [(set (match_operand:DI 0 "register_operand" "=r,r")
21571         (vec_select:DI
21572          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21573          (parallel [(const_int 0)])))]
21574   "TARGET_SSE"
21575   "cvtss2siq\t{%1, %0|%0, %1}"
21576   [(set_attr "type" "sseicvt")
21577    (set_attr "athlon_decode" "double,vector")
21578    (set_attr "mode" "DI")])
21579
21580 (define_insn "cvttss2si"
21581   [(set (match_operand:SI 0 "register_operand" "=r,r")
21582         (vec_select:SI
21583          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21584                       UNSPEC_FIX)
21585          (parallel [(const_int 0)])))]
21586   "TARGET_SSE"
21587   "cvttss2si\t{%1, %0|%0, %1}"
21588   [(set_attr "type" "sseicvt")
21589    (set_attr "mode" "SF")
21590    (set_attr "athlon_decode" "double,vector")])
21591
21592 (define_insn "cvttss2siq"
21593   [(set (match_operand:DI 0 "register_operand" "=r,r")
21594         (vec_select:DI
21595          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21596                       UNSPEC_FIX)
21597          (parallel [(const_int 0)])))]
21598   "TARGET_SSE && TARGET_64BIT"
21599   "cvttss2siq\t{%1, %0|%0, %1}"
21600   [(set_attr "type" "sseicvt")
21601    (set_attr "mode" "SF")
21602    (set_attr "athlon_decode" "double,vector")])
21603
21604
21605 ;; MMX insns
21606
21607 ;; MMX arithmetic
21608
21609 (define_insn "addv8qi3"
21610   [(set (match_operand:V8QI 0 "register_operand" "=y")
21611         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21612                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21613   "TARGET_MMX"
21614   "paddb\t{%2, %0|%0, %2}"
21615   [(set_attr "type" "mmxadd")
21616    (set_attr "mode" "DI")])
21617
21618 (define_insn "addv4hi3"
21619   [(set (match_operand:V4HI 0 "register_operand" "=y")
21620         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21621                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21622   "TARGET_MMX"
21623   "paddw\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxadd")
21625    (set_attr "mode" "DI")])
21626
21627 (define_insn "addv2si3"
21628   [(set (match_operand:V2SI 0 "register_operand" "=y")
21629         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21630                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21631   "TARGET_MMX"
21632   "paddd\t{%2, %0|%0, %2}"
21633   [(set_attr "type" "mmxadd")
21634    (set_attr "mode" "DI")])
21635
21636 (define_insn "mmx_adddi3"
21637   [(set (match_operand:DI 0 "register_operand" "=y")
21638         (unspec:DI
21639          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21640                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21641          UNSPEC_NOP))]
21642   "TARGET_MMX"
21643   "paddq\t{%2, %0|%0, %2}"
21644   [(set_attr "type" "mmxadd")
21645    (set_attr "mode" "DI")])
21646
21647 (define_insn "ssaddv8qi3"
21648   [(set (match_operand:V8QI 0 "register_operand" "=y")
21649         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21650                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21651   "TARGET_MMX"
21652   "paddsb\t{%2, %0|%0, %2}"
21653   [(set_attr "type" "mmxadd")
21654    (set_attr "mode" "DI")])
21655
21656 (define_insn "ssaddv4hi3"
21657   [(set (match_operand:V4HI 0 "register_operand" "=y")
21658         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21659                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21660   "TARGET_MMX"
21661   "paddsw\t{%2, %0|%0, %2}"
21662   [(set_attr "type" "mmxadd")
21663    (set_attr "mode" "DI")])
21664
21665 (define_insn "usaddv8qi3"
21666   [(set (match_operand:V8QI 0 "register_operand" "=y")
21667         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21668                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21669   "TARGET_MMX"
21670   "paddusb\t{%2, %0|%0, %2}"
21671   [(set_attr "type" "mmxadd")
21672    (set_attr "mode" "DI")])
21673
21674 (define_insn "usaddv4hi3"
21675   [(set (match_operand:V4HI 0 "register_operand" "=y")
21676         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21677                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21678   "TARGET_MMX"
21679   "paddusw\t{%2, %0|%0, %2}"
21680   [(set_attr "type" "mmxadd")
21681    (set_attr "mode" "DI")])
21682
21683 (define_insn "subv8qi3"
21684   [(set (match_operand:V8QI 0 "register_operand" "=y")
21685         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21686                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21687   "TARGET_MMX"
21688   "psubb\t{%2, %0|%0, %2}"
21689   [(set_attr "type" "mmxadd")
21690    (set_attr "mode" "DI")])
21691
21692 (define_insn "subv4hi3"
21693   [(set (match_operand:V4HI 0 "register_operand" "=y")
21694         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21695                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21696   "TARGET_MMX"
21697   "psubw\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxadd")
21699    (set_attr "mode" "DI")])
21700
21701 (define_insn "subv2si3"
21702   [(set (match_operand:V2SI 0 "register_operand" "=y")
21703         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21704                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21705   "TARGET_MMX"
21706   "psubd\t{%2, %0|%0, %2}"
21707   [(set_attr "type" "mmxadd")
21708    (set_attr "mode" "DI")])
21709
21710 (define_insn "mmx_subdi3"
21711   [(set (match_operand:DI 0 "register_operand" "=y")
21712         (unspec:DI
21713          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21714                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21715          UNSPEC_NOP))]
21716   "TARGET_MMX"
21717   "psubq\t{%2, %0|%0, %2}"
21718   [(set_attr "type" "mmxadd")
21719    (set_attr "mode" "DI")])
21720
21721 (define_insn "sssubv8qi3"
21722   [(set (match_operand:V8QI 0 "register_operand" "=y")
21723         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21724                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21725   "TARGET_MMX"
21726   "psubsb\t{%2, %0|%0, %2}"
21727   [(set_attr "type" "mmxadd")
21728    (set_attr "mode" "DI")])
21729
21730 (define_insn "sssubv4hi3"
21731   [(set (match_operand:V4HI 0 "register_operand" "=y")
21732         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21733                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21734   "TARGET_MMX"
21735   "psubsw\t{%2, %0|%0, %2}"
21736   [(set_attr "type" "mmxadd")
21737    (set_attr "mode" "DI")])
21738
21739 (define_insn "ussubv8qi3"
21740   [(set (match_operand:V8QI 0 "register_operand" "=y")
21741         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21742                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21743   "TARGET_MMX"
21744   "psubusb\t{%2, %0|%0, %2}"
21745   [(set_attr "type" "mmxadd")
21746    (set_attr "mode" "DI")])
21747
21748 (define_insn "ussubv4hi3"
21749   [(set (match_operand:V4HI 0 "register_operand" "=y")
21750         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21751                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21752   "TARGET_MMX"
21753   "psubusw\t{%2, %0|%0, %2}"
21754   [(set_attr "type" "mmxadd")
21755    (set_attr "mode" "DI")])
21756
21757 (define_insn "mulv4hi3"
21758   [(set (match_operand:V4HI 0 "register_operand" "=y")
21759         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21760                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21761   "TARGET_MMX"
21762   "pmullw\t{%2, %0|%0, %2}"
21763   [(set_attr "type" "mmxmul")
21764    (set_attr "mode" "DI")])
21765
21766 (define_insn "smulv4hi3_highpart"
21767   [(set (match_operand:V4HI 0 "register_operand" "=y")
21768         (truncate:V4HI
21769          (lshiftrt:V4SI
21770           (mult:V4SI (sign_extend:V4SI
21771                       (match_operand:V4HI 1 "register_operand" "0"))
21772                      (sign_extend:V4SI
21773                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21774           (const_int 16))))]
21775   "TARGET_MMX"
21776   "pmulhw\t{%2, %0|%0, %2}"
21777   [(set_attr "type" "mmxmul")
21778    (set_attr "mode" "DI")])
21779
21780 (define_insn "umulv4hi3_highpart"
21781   [(set (match_operand:V4HI 0 "register_operand" "=y")
21782         (truncate:V4HI
21783          (lshiftrt:V4SI
21784           (mult:V4SI (zero_extend:V4SI
21785                       (match_operand:V4HI 1 "register_operand" "0"))
21786                      (zero_extend:V4SI
21787                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21788           (const_int 16))))]
21789   "TARGET_SSE || TARGET_3DNOW_A"
21790   "pmulhuw\t{%2, %0|%0, %2}"
21791   [(set_attr "type" "mmxmul")
21792    (set_attr "mode" "DI")])
21793
21794 (define_insn "mmx_pmaddwd"
21795   [(set (match_operand:V2SI 0 "register_operand" "=y")
21796         (plus:V2SI
21797          (mult:V2SI
21798           (sign_extend:V2SI
21799            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21800                             (parallel [(const_int 0) (const_int 2)])))
21801           (sign_extend:V2SI
21802            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21803                             (parallel [(const_int 0) (const_int 2)]))))
21804          (mult:V2SI
21805           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21806                                              (parallel [(const_int 1)
21807                                                         (const_int 3)])))
21808           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21809                                              (parallel [(const_int 1)
21810                                                         (const_int 3)]))))))]
21811   "TARGET_MMX"
21812   "pmaddwd\t{%2, %0|%0, %2}"
21813   [(set_attr "type" "mmxmul")
21814    (set_attr "mode" "DI")])
21815
21816
21817 ;; MMX logical operations
21818 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21819 ;; normal code that also wants to use the FPU from getting broken.
21820 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21821 (define_insn "mmx_iordi3"
21822   [(set (match_operand:DI 0 "register_operand" "=y")
21823         (unspec:DI
21824          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21825                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21826          UNSPEC_NOP))]
21827   "TARGET_MMX"
21828   "por\t{%2, %0|%0, %2}"
21829   [(set_attr "type" "mmxadd")
21830    (set_attr "mode" "DI")])
21831
21832 (define_insn "mmx_xordi3"
21833   [(set (match_operand:DI 0 "register_operand" "=y")
21834         (unspec:DI
21835          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21836                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21837          UNSPEC_NOP))]
21838   "TARGET_MMX"
21839   "pxor\t{%2, %0|%0, %2}"
21840   [(set_attr "type" "mmxadd")
21841    (set_attr "mode" "DI")
21842    (set_attr "memory" "none")])
21843
21844 ;; Same as pxor, but don't show input operands so that we don't think
21845 ;; they are live.
21846 (define_insn "mmx_clrdi"
21847   [(set (match_operand:DI 0 "register_operand" "=y")
21848         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21849   "TARGET_MMX"
21850   "pxor\t{%0, %0|%0, %0}"
21851   [(set_attr "type" "mmxadd")
21852    (set_attr "mode" "DI")
21853    (set_attr "memory" "none")])
21854
21855 (define_insn "mmx_anddi3"
21856   [(set (match_operand:DI 0 "register_operand" "=y")
21857         (unspec:DI
21858          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21859                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21860          UNSPEC_NOP))]
21861   "TARGET_MMX"
21862   "pand\t{%2, %0|%0, %2}"
21863   [(set_attr "type" "mmxadd")
21864    (set_attr "mode" "DI")])
21865
21866 (define_insn "mmx_nanddi3"
21867   [(set (match_operand:DI 0 "register_operand" "=y")
21868         (unspec:DI
21869          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21870                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21871          UNSPEC_NOP))]
21872   "TARGET_MMX"
21873   "pandn\t{%2, %0|%0, %2}"
21874   [(set_attr "type" "mmxadd")
21875    (set_attr "mode" "DI")])
21876
21877
21878 ;; MMX unsigned averages/sum of absolute differences
21879
21880 (define_insn "mmx_uavgv8qi3"
21881   [(set (match_operand:V8QI 0 "register_operand" "=y")
21882         (ashiftrt:V8QI
21883          (plus:V8QI (plus:V8QI
21884                      (match_operand:V8QI 1 "register_operand" "0")
21885                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21886                     (const_vector:V8QI [(const_int 1)
21887                                         (const_int 1)
21888                                         (const_int 1)
21889                                         (const_int 1)
21890                                         (const_int 1)
21891                                         (const_int 1)
21892                                         (const_int 1)
21893                                         (const_int 1)]))
21894          (const_int 1)))]
21895   "TARGET_SSE || TARGET_3DNOW_A"
21896   "pavgb\t{%2, %0|%0, %2}"
21897   [(set_attr "type" "mmxshft")
21898    (set_attr "mode" "DI")])
21899
21900 (define_insn "mmx_uavgv4hi3"
21901   [(set (match_operand:V4HI 0 "register_operand" "=y")
21902         (ashiftrt:V4HI
21903          (plus:V4HI (plus:V4HI
21904                      (match_operand:V4HI 1 "register_operand" "0")
21905                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21906                     (const_vector:V4HI [(const_int 1)
21907                                         (const_int 1)
21908                                         (const_int 1)
21909                                         (const_int 1)]))
21910          (const_int 1)))]
21911   "TARGET_SSE || TARGET_3DNOW_A"
21912   "pavgw\t{%2, %0|%0, %2}"
21913   [(set_attr "type" "mmxshft")
21914    (set_attr "mode" "DI")])
21915
21916 (define_insn "mmx_psadbw"
21917   [(set (match_operand:DI 0 "register_operand" "=y")
21918         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21919                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21920                    UNSPEC_PSADBW))]
21921   "TARGET_SSE || TARGET_3DNOW_A"
21922   "psadbw\t{%2, %0|%0, %2}"
21923   [(set_attr "type" "mmxshft")
21924    (set_attr "mode" "DI")])
21925
21926
21927 ;; MMX insert/extract/shuffle
21928
21929 (define_insn "mmx_pinsrw"
21930   [(set (match_operand:V4HI 0 "register_operand" "=y")
21931         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21932                         (vec_duplicate:V4HI
21933                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21934                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21935   "TARGET_SSE || TARGET_3DNOW_A"
21936   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21937   [(set_attr "type" "mmxcvt")
21938    (set_attr "mode" "DI")])
21939
21940 (define_insn "mmx_pextrw"
21941   [(set (match_operand:SI 0 "register_operand" "=r")
21942         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21943                                        (parallel
21944                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21945   "TARGET_SSE || TARGET_3DNOW_A"
21946   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21947   [(set_attr "type" "mmxcvt")
21948    (set_attr "mode" "DI")])
21949
21950 (define_insn "mmx_pshufw"
21951   [(set (match_operand:V4HI 0 "register_operand" "=y")
21952         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21953                       (match_operand:SI 2 "immediate_operand" "i")]
21954                      UNSPEC_SHUFFLE))]
21955   "TARGET_SSE || TARGET_3DNOW_A"
21956   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21957   [(set_attr "type" "mmxcvt")
21958    (set_attr "mode" "DI")])
21959
21960
21961 ;; MMX mask-generating comparisons
21962
21963 (define_insn "eqv8qi3"
21964   [(set (match_operand:V8QI 0 "register_operand" "=y")
21965         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21966                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21967   "TARGET_MMX"
21968   "pcmpeqb\t{%2, %0|%0, %2}"
21969   [(set_attr "type" "mmxcmp")
21970    (set_attr "mode" "DI")])
21971
21972 (define_insn "eqv4hi3"
21973   [(set (match_operand:V4HI 0 "register_operand" "=y")
21974         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21975                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21976   "TARGET_MMX"
21977   "pcmpeqw\t{%2, %0|%0, %2}"
21978   [(set_attr "type" "mmxcmp")
21979    (set_attr "mode" "DI")])
21980
21981 (define_insn "eqv2si3"
21982   [(set (match_operand:V2SI 0 "register_operand" "=y")
21983         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21984                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21985   "TARGET_MMX"
21986   "pcmpeqd\t{%2, %0|%0, %2}"
21987   [(set_attr "type" "mmxcmp")
21988    (set_attr "mode" "DI")])
21989
21990 (define_insn "gtv8qi3"
21991   [(set (match_operand:V8QI 0 "register_operand" "=y")
21992         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21993                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21994   "TARGET_MMX"
21995   "pcmpgtb\t{%2, %0|%0, %2}"
21996   [(set_attr "type" "mmxcmp")
21997    (set_attr "mode" "DI")])
21998
21999 (define_insn "gtv4hi3"
22000   [(set (match_operand:V4HI 0 "register_operand" "=y")
22001         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22002                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22003   "TARGET_MMX"
22004   "pcmpgtw\t{%2, %0|%0, %2}"
22005   [(set_attr "type" "mmxcmp")
22006    (set_attr "mode" "DI")])
22007
22008 (define_insn "gtv2si3"
22009   [(set (match_operand:V2SI 0 "register_operand" "=y")
22010         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22011                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22012   "TARGET_MMX"
22013   "pcmpgtd\t{%2, %0|%0, %2}"
22014   [(set_attr "type" "mmxcmp")
22015    (set_attr "mode" "DI")])
22016
22017
22018 ;; MMX max/min insns
22019
22020 (define_insn "umaxv8qi3"
22021   [(set (match_operand:V8QI 0 "register_operand" "=y")
22022         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22023                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22024   "TARGET_SSE || TARGET_3DNOW_A"
22025   "pmaxub\t{%2, %0|%0, %2}"
22026   [(set_attr "type" "mmxadd")
22027    (set_attr "mode" "DI")])
22028
22029 (define_insn "smaxv4hi3"
22030   [(set (match_operand:V4HI 0 "register_operand" "=y")
22031         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22032                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22033   "TARGET_SSE || TARGET_3DNOW_A"
22034   "pmaxsw\t{%2, %0|%0, %2}"
22035   [(set_attr "type" "mmxadd")
22036    (set_attr "mode" "DI")])
22037
22038 (define_insn "uminv8qi3"
22039   [(set (match_operand:V8QI 0 "register_operand" "=y")
22040         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22041                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22042   "TARGET_SSE || TARGET_3DNOW_A"
22043   "pminub\t{%2, %0|%0, %2}"
22044   [(set_attr "type" "mmxadd")
22045    (set_attr "mode" "DI")])
22046
22047 (define_insn "sminv4hi3"
22048   [(set (match_operand:V4HI 0 "register_operand" "=y")
22049         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22050                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22051   "TARGET_SSE || TARGET_3DNOW_A"
22052   "pminsw\t{%2, %0|%0, %2}"
22053   [(set_attr "type" "mmxadd")
22054    (set_attr "mode" "DI")])
22055
22056
22057 ;; MMX shifts
22058
22059 (define_insn "ashrv4hi3"
22060   [(set (match_operand:V4HI 0 "register_operand" "=y")
22061         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22062                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22063   "TARGET_MMX"
22064   "psraw\t{%2, %0|%0, %2}"
22065   [(set_attr "type" "mmxshft")
22066    (set_attr "mode" "DI")])
22067
22068 (define_insn "ashrv2si3"
22069   [(set (match_operand:V2SI 0 "register_operand" "=y")
22070         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22071                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22072   "TARGET_MMX"
22073   "psrad\t{%2, %0|%0, %2}"
22074   [(set_attr "type" "mmxshft")
22075    (set_attr "mode" "DI")])
22076
22077 (define_insn "lshrv4hi3"
22078   [(set (match_operand:V4HI 0 "register_operand" "=y")
22079         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22080                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22081   "TARGET_MMX"
22082   "psrlw\t{%2, %0|%0, %2}"
22083   [(set_attr "type" "mmxshft")
22084    (set_attr "mode" "DI")])
22085
22086 (define_insn "lshrv2si3"
22087   [(set (match_operand:V2SI 0 "register_operand" "=y")
22088         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22089                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22090   "TARGET_MMX"
22091   "psrld\t{%2, %0|%0, %2}"
22092   [(set_attr "type" "mmxshft")
22093    (set_attr "mode" "DI")])
22094
22095 ;; See logical MMX insns.
22096 (define_insn "mmx_lshrdi3"
22097   [(set (match_operand:DI 0 "register_operand" "=y")
22098         (unspec:DI
22099           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22100                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22101           UNSPEC_NOP))]
22102   "TARGET_MMX"
22103   "psrlq\t{%2, %0|%0, %2}"
22104   [(set_attr "type" "mmxshft")
22105    (set_attr "mode" "DI")])
22106
22107 (define_insn "ashlv4hi3"
22108   [(set (match_operand:V4HI 0 "register_operand" "=y")
22109         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22110                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22111   "TARGET_MMX"
22112   "psllw\t{%2, %0|%0, %2}"
22113   [(set_attr "type" "mmxshft")
22114    (set_attr "mode" "DI")])
22115
22116 (define_insn "ashlv2si3"
22117   [(set (match_operand:V2SI 0 "register_operand" "=y")
22118         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22119                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22120   "TARGET_MMX"
22121   "pslld\t{%2, %0|%0, %2}"
22122   [(set_attr "type" "mmxshft")
22123    (set_attr "mode" "DI")])
22124
22125 ;; See logical MMX insns.
22126 (define_insn "mmx_ashldi3"
22127   [(set (match_operand:DI 0 "register_operand" "=y")
22128         (unspec:DI
22129          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22130                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22131          UNSPEC_NOP))]
22132   "TARGET_MMX"
22133   "psllq\t{%2, %0|%0, %2}"
22134   [(set_attr "type" "mmxshft")
22135    (set_attr "mode" "DI")])
22136
22137
22138 ;; MMX pack/unpack insns.
22139
22140 (define_insn "mmx_packsswb"
22141   [(set (match_operand:V8QI 0 "register_operand" "=y")
22142         (vec_concat:V8QI
22143          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22144          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22145   "TARGET_MMX"
22146   "packsswb\t{%2, %0|%0, %2}"
22147   [(set_attr "type" "mmxshft")
22148    (set_attr "mode" "DI")])
22149
22150 (define_insn "mmx_packssdw"
22151   [(set (match_operand:V4HI 0 "register_operand" "=y")
22152         (vec_concat:V4HI
22153          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22154          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22155   "TARGET_MMX"
22156   "packssdw\t{%2, %0|%0, %2}"
22157   [(set_attr "type" "mmxshft")
22158    (set_attr "mode" "DI")])
22159
22160 (define_insn "mmx_packuswb"
22161   [(set (match_operand:V8QI 0 "register_operand" "=y")
22162         (vec_concat:V8QI
22163          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22164          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22165   "TARGET_MMX"
22166   "packuswb\t{%2, %0|%0, %2}"
22167   [(set_attr "type" "mmxshft")
22168    (set_attr "mode" "DI")])
22169
22170 (define_insn "mmx_punpckhbw"
22171   [(set (match_operand:V8QI 0 "register_operand" "=y")
22172         (vec_merge:V8QI
22173          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22174                           (parallel [(const_int 4)
22175                                      (const_int 0)
22176                                      (const_int 5)
22177                                      (const_int 1)
22178                                      (const_int 6)
22179                                      (const_int 2)
22180                                      (const_int 7)
22181                                      (const_int 3)]))
22182          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22183                           (parallel [(const_int 0)
22184                                      (const_int 4)
22185                                      (const_int 1)
22186                                      (const_int 5)
22187                                      (const_int 2)
22188                                      (const_int 6)
22189                                      (const_int 3)
22190                                      (const_int 7)]))
22191          (const_int 85)))]
22192   "TARGET_MMX"
22193   "punpckhbw\t{%2, %0|%0, %2}"
22194   [(set_attr "type" "mmxcvt")
22195    (set_attr "mode" "DI")])
22196
22197 (define_insn "mmx_punpckhwd"
22198   [(set (match_operand:V4HI 0 "register_operand" "=y")
22199         (vec_merge:V4HI
22200          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22201                           (parallel [(const_int 0)
22202                                      (const_int 2)
22203                                      (const_int 1)
22204                                      (const_int 3)]))
22205          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22206                           (parallel [(const_int 2)
22207                                      (const_int 0)
22208                                      (const_int 3)
22209                                      (const_int 1)]))
22210          (const_int 5)))]
22211   "TARGET_MMX"
22212   "punpckhwd\t{%2, %0|%0, %2}"
22213   [(set_attr "type" "mmxcvt")
22214    (set_attr "mode" "DI")])
22215
22216 (define_insn "mmx_punpckhdq"
22217   [(set (match_operand:V2SI 0 "register_operand" "=y")
22218         (vec_merge:V2SI
22219          (match_operand:V2SI 1 "register_operand" "0")
22220          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22221                           (parallel [(const_int 1)
22222                                      (const_int 0)]))
22223          (const_int 1)))]
22224   "TARGET_MMX"
22225   "punpckhdq\t{%2, %0|%0, %2}"
22226   [(set_attr "type" "mmxcvt")
22227    (set_attr "mode" "DI")])
22228
22229 (define_insn "mmx_punpcklbw"
22230   [(set (match_operand:V8QI 0 "register_operand" "=y")
22231         (vec_merge:V8QI
22232          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22233                           (parallel [(const_int 0)
22234                                      (const_int 4)
22235                                      (const_int 1)
22236                                      (const_int 5)
22237                                      (const_int 2)
22238                                      (const_int 6)
22239                                      (const_int 3)
22240                                      (const_int 7)]))
22241          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22242                           (parallel [(const_int 4)
22243                                      (const_int 0)
22244                                      (const_int 5)
22245                                      (const_int 1)
22246                                      (const_int 6)
22247                                      (const_int 2)
22248                                      (const_int 7)
22249                                      (const_int 3)]))
22250          (const_int 85)))]
22251   "TARGET_MMX"
22252   "punpcklbw\t{%2, %0|%0, %2}"
22253   [(set_attr "type" "mmxcvt")
22254    (set_attr "mode" "DI")])
22255
22256 (define_insn "mmx_punpcklwd"
22257   [(set (match_operand:V4HI 0 "register_operand" "=y")
22258         (vec_merge:V4HI
22259          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22260                           (parallel [(const_int 2)
22261                                      (const_int 0)
22262                                      (const_int 3)
22263                                      (const_int 1)]))
22264          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22265                           (parallel [(const_int 0)
22266                                      (const_int 2)
22267                                      (const_int 1)
22268                                      (const_int 3)]))
22269          (const_int 5)))]
22270   "TARGET_MMX"
22271   "punpcklwd\t{%2, %0|%0, %2}"
22272   [(set_attr "type" "mmxcvt")
22273    (set_attr "mode" "DI")])
22274
22275 (define_insn "mmx_punpckldq"
22276   [(set (match_operand:V2SI 0 "register_operand" "=y")
22277         (vec_merge:V2SI
22278          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22279                            (parallel [(const_int 1)
22280                                       (const_int 0)]))
22281          (match_operand:V2SI 2 "register_operand" "y")
22282          (const_int 1)))]
22283   "TARGET_MMX"
22284   "punpckldq\t{%2, %0|%0, %2}"
22285   [(set_attr "type" "mmxcvt")
22286    (set_attr "mode" "DI")])
22287
22288
22289 ;; Miscellaneous stuff
22290
22291 (define_insn "emms"
22292   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22293    (clobber (reg:XF 8))
22294    (clobber (reg:XF 9))
22295    (clobber (reg:XF 10))
22296    (clobber (reg:XF 11))
22297    (clobber (reg:XF 12))
22298    (clobber (reg:XF 13))
22299    (clobber (reg:XF 14))
22300    (clobber (reg:XF 15))
22301    (clobber (reg:DI 29))
22302    (clobber (reg:DI 30))
22303    (clobber (reg:DI 31))
22304    (clobber (reg:DI 32))
22305    (clobber (reg:DI 33))
22306    (clobber (reg:DI 34))
22307    (clobber (reg:DI 35))
22308    (clobber (reg:DI 36))]
22309   "TARGET_MMX"
22310   "emms"
22311   [(set_attr "type" "mmx")
22312    (set_attr "memory" "unknown")])
22313
22314 (define_insn "ldmxcsr"
22315   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22316                     UNSPECV_LDMXCSR)]
22317   "TARGET_SSE"
22318   "ldmxcsr\t%0"
22319   [(set_attr "type" "sse")
22320    (set_attr "memory" "load")])
22321
22322 (define_insn "stmxcsr"
22323   [(set (match_operand:SI 0 "memory_operand" "=m")
22324         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22325   "TARGET_SSE"
22326   "stmxcsr\t%0"
22327   [(set_attr "type" "sse")
22328    (set_attr "memory" "store")])
22329
22330 (define_expand "sfence"
22331   [(set (match_dup 0)
22332         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22333   "TARGET_SSE || TARGET_3DNOW_A"
22334 {
22335   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22336   MEM_VOLATILE_P (operands[0]) = 1;
22337 })
22338
22339 (define_insn "*sfence_insn"
22340   [(set (match_operand:BLK 0 "" "")
22341         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22342   "TARGET_SSE || TARGET_3DNOW_A"
22343   "sfence"
22344   [(set_attr "type" "sse")
22345    (set_attr "memory" "unknown")])
22346
22347 (define_expand "sse_prologue_save"
22348   [(parallel [(set (match_operand:BLK 0 "" "")
22349                    (unspec:BLK [(reg:DI 21)
22350                                 (reg:DI 22)
22351                                 (reg:DI 23)
22352                                 (reg:DI 24)
22353                                 (reg:DI 25)
22354                                 (reg:DI 26)
22355                                 (reg:DI 27)
22356                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22357               (use (match_operand:DI 1 "register_operand" ""))
22358               (use (match_operand:DI 2 "immediate_operand" ""))
22359               (use (label_ref:DI (match_operand 3 "" "")))])]
22360   "TARGET_64BIT"
22361   "")
22362
22363 (define_insn "*sse_prologue_save_insn"
22364   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22365                           (match_operand:DI 4 "const_int_operand" "n")))
22366         (unspec:BLK [(reg:DI 21)
22367                      (reg:DI 22)
22368                      (reg:DI 23)
22369                      (reg:DI 24)
22370                      (reg:DI 25)
22371                      (reg:DI 26)
22372                      (reg:DI 27)
22373                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22374    (use (match_operand:DI 1 "register_operand" "r"))
22375    (use (match_operand:DI 2 "const_int_operand" "i"))
22376    (use (label_ref:DI (match_operand 3 "" "X")))]
22377   "TARGET_64BIT
22378    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22379    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22380   "*
22381 {
22382   int i;
22383   operands[0] = gen_rtx_MEM (Pmode,
22384                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22385   output_asm_insn (\"jmp\\t%A1\", operands);
22386   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22387     {
22388       operands[4] = adjust_address (operands[0], DImode, i*16);
22389       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22390       PUT_MODE (operands[4], TImode);
22391       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22392         output_asm_insn (\"rex\", operands);
22393       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22394     }
22395   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22396                              CODE_LABEL_NUMBER (operands[3]));
22397   RET;
22398 }
22399   "
22400   [(set_attr "type" "other")
22401    (set_attr "length_immediate" "0")
22402    (set_attr "length_address" "0")
22403    (set_attr "length" "135")
22404    (set_attr "memory" "store")
22405    (set_attr "modrm" "0")
22406    (set_attr "mode" "DI")])
22407
22408 ;; 3Dnow! instructions
22409
22410 (define_insn "addv2sf3"
22411   [(set (match_operand:V2SF 0 "register_operand" "=y")
22412         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22413                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22414   "TARGET_3DNOW"
22415   "pfadd\\t{%2, %0|%0, %2}"
22416   [(set_attr "type" "mmxadd")
22417    (set_attr "mode" "V2SF")])
22418
22419 (define_insn "subv2sf3"
22420   [(set (match_operand:V2SF 0 "register_operand" "=y")
22421         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22422                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22423   "TARGET_3DNOW"
22424   "pfsub\\t{%2, %0|%0, %2}"
22425   [(set_attr "type" "mmxadd")
22426    (set_attr "mode" "V2SF")])
22427
22428 (define_insn "subrv2sf3"
22429   [(set (match_operand:V2SF 0 "register_operand" "=y")
22430         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22431                     (match_operand:V2SF 1 "register_operand" "0")))]
22432   "TARGET_3DNOW"
22433   "pfsubr\\t{%2, %0|%0, %2}"
22434   [(set_attr "type" "mmxadd")
22435    (set_attr "mode" "V2SF")])
22436
22437 (define_insn "gtv2sf3"
22438   [(set (match_operand:V2SI 0 "register_operand" "=y")
22439         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22440                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22441  "TARGET_3DNOW"
22442   "pfcmpgt\\t{%2, %0|%0, %2}"
22443   [(set_attr "type" "mmxcmp")
22444    (set_attr "mode" "V2SF")])
22445
22446 (define_insn "gev2sf3"
22447   [(set (match_operand:V2SI 0 "register_operand" "=y")
22448         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22449                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22450   "TARGET_3DNOW"
22451   "pfcmpge\\t{%2, %0|%0, %2}"
22452   [(set_attr "type" "mmxcmp")
22453    (set_attr "mode" "V2SF")])
22454
22455 (define_insn "eqv2sf3"
22456   [(set (match_operand:V2SI 0 "register_operand" "=y")
22457         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22458                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22459   "TARGET_3DNOW"
22460   "pfcmpeq\\t{%2, %0|%0, %2}"
22461   [(set_attr "type" "mmxcmp")
22462    (set_attr "mode" "V2SF")])
22463
22464 (define_insn "pfmaxv2sf3"
22465   [(set (match_operand:V2SF 0 "register_operand" "=y")
22466         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22467                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22468   "TARGET_3DNOW"
22469   "pfmax\\t{%2, %0|%0, %2}"
22470   [(set_attr "type" "mmxadd")
22471    (set_attr "mode" "V2SF")])
22472
22473 (define_insn "pfminv2sf3"
22474   [(set (match_operand:V2SF 0 "register_operand" "=y")
22475         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22476                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22477   "TARGET_3DNOW"
22478   "pfmin\\t{%2, %0|%0, %2}"
22479   [(set_attr "type" "mmxadd")
22480    (set_attr "mode" "V2SF")])
22481
22482 (define_insn "mulv2sf3"
22483   [(set (match_operand:V2SF 0 "register_operand" "=y")
22484         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22485                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22486   "TARGET_3DNOW"
22487   "pfmul\\t{%2, %0|%0, %2}"
22488   [(set_attr "type" "mmxmul")
22489    (set_attr "mode" "V2SF")])
22490
22491 (define_insn "femms"
22492   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22493    (clobber (reg:XF 8))
22494    (clobber (reg:XF 9))
22495    (clobber (reg:XF 10))
22496    (clobber (reg:XF 11))
22497    (clobber (reg:XF 12))
22498    (clobber (reg:XF 13))
22499    (clobber (reg:XF 14))
22500    (clobber (reg:XF 15))
22501    (clobber (reg:DI 29))
22502    (clobber (reg:DI 30))
22503    (clobber (reg:DI 31))
22504    (clobber (reg:DI 32))
22505    (clobber (reg:DI 33))
22506    (clobber (reg:DI 34))
22507    (clobber (reg:DI 35))
22508    (clobber (reg:DI 36))]
22509   "TARGET_3DNOW"
22510   "femms"
22511   [(set_attr "type" "mmx")
22512    (set_attr "memory" "none")]) 
22513
22514 (define_insn "pf2id"
22515   [(set (match_operand:V2SI 0 "register_operand" "=y")
22516         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22517   "TARGET_3DNOW"
22518   "pf2id\\t{%1, %0|%0, %1}"
22519   [(set_attr "type" "mmxcvt")
22520    (set_attr "mode" "V2SF")])
22521
22522 (define_insn "pf2iw"
22523   [(set (match_operand:V2SI 0 "register_operand" "=y")
22524         (sign_extend:V2SI
22525            (ss_truncate:V2HI
22526               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22527   "TARGET_3DNOW_A"
22528   "pf2iw\\t{%1, %0|%0, %1}"
22529   [(set_attr "type" "mmxcvt")
22530    (set_attr "mode" "V2SF")])
22531
22532 (define_insn "pfacc"
22533   [(set (match_operand:V2SF 0 "register_operand" "=y")
22534         (vec_concat:V2SF
22535            (plus:SF
22536               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22537                              (parallel [(const_int  0)]))
22538               (vec_select:SF (match_dup 1)
22539                              (parallel [(const_int 1)])))
22540            (plus:SF
22541               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22542                              (parallel [(const_int  0)]))
22543               (vec_select:SF (match_dup 2)
22544                              (parallel [(const_int 1)])))))]
22545   "TARGET_3DNOW"
22546   "pfacc\\t{%2, %0|%0, %2}"
22547   [(set_attr "type" "mmxadd")
22548    (set_attr "mode" "V2SF")])
22549
22550 (define_insn "pfnacc"
22551   [(set (match_operand:V2SF 0 "register_operand" "=y")
22552         (vec_concat:V2SF
22553            (minus:SF
22554               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22555                              (parallel [(const_int 0)]))
22556               (vec_select:SF (match_dup 1)
22557                              (parallel [(const_int 1)])))
22558            (minus:SF
22559               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22560                              (parallel [(const_int  0)]))
22561               (vec_select:SF (match_dup 2)
22562                              (parallel [(const_int 1)])))))]
22563   "TARGET_3DNOW_A"
22564   "pfnacc\\t{%2, %0|%0, %2}"
22565   [(set_attr "type" "mmxadd")
22566    (set_attr "mode" "V2SF")])
22567
22568 (define_insn "pfpnacc"
22569   [(set (match_operand:V2SF 0 "register_operand" "=y")
22570         (vec_concat:V2SF
22571            (minus:SF
22572               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22573                              (parallel [(const_int 0)]))
22574               (vec_select:SF (match_dup 1)
22575                              (parallel [(const_int 1)])))
22576            (plus:SF
22577               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22578                              (parallel [(const_int 0)]))
22579               (vec_select:SF (match_dup 2)
22580                              (parallel [(const_int 1)])))))]
22581   "TARGET_3DNOW_A"
22582   "pfpnacc\\t{%2, %0|%0, %2}"
22583   [(set_attr "type" "mmxadd")
22584    (set_attr "mode" "V2SF")])
22585
22586 (define_insn "pi2fw"
22587   [(set (match_operand:V2SF 0 "register_operand" "=y")
22588         (float:V2SF
22589            (vec_concat:V2SI
22590               (sign_extend:SI
22591                  (truncate:HI
22592                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22593                                    (parallel [(const_int 0)]))))
22594               (sign_extend:SI
22595                  (truncate:HI
22596                     (vec_select:SI (match_dup 1)
22597                                    (parallel [(const_int  1)])))))))]
22598   "TARGET_3DNOW_A"
22599   "pi2fw\\t{%1, %0|%0, %1}"
22600   [(set_attr "type" "mmxcvt")
22601    (set_attr "mode" "V2SF")])
22602
22603 (define_insn "floatv2si2"
22604   [(set (match_operand:V2SF 0 "register_operand" "=y")
22605         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22606   "TARGET_3DNOW"
22607   "pi2fd\\t{%1, %0|%0, %1}"
22608   [(set_attr "type" "mmxcvt")
22609    (set_attr "mode" "V2SF")])
22610
22611 ;; This insn is identical to pavgb in operation, but the opcode is
22612 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22613
22614 (define_insn "pavgusb"
22615  [(set (match_operand:V8QI 0 "register_operand" "=y")
22616        (unspec:V8QI
22617           [(match_operand:V8QI 1 "register_operand" "0")
22618            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22619           UNSPEC_PAVGUSB))]
22620   "TARGET_3DNOW"
22621   "pavgusb\\t{%2, %0|%0, %2}"
22622   [(set_attr "type" "mmxshft")
22623    (set_attr "mode" "TI")])
22624
22625 ;; 3DNow reciprocal and sqrt
22626  
22627 (define_insn "pfrcpv2sf2"
22628   [(set (match_operand:V2SF 0 "register_operand" "=y")
22629         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22630         UNSPEC_PFRCP))]
22631   "TARGET_3DNOW"
22632   "pfrcp\\t{%1, %0|%0, %1}"
22633   [(set_attr "type" "mmx")
22634    (set_attr "mode" "TI")])
22635
22636 (define_insn "pfrcpit1v2sf3"
22637   [(set (match_operand:V2SF 0 "register_operand" "=y")
22638         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22639                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22640                      UNSPEC_PFRCPIT1))]
22641   "TARGET_3DNOW"
22642   "pfrcpit1\\t{%2, %0|%0, %2}"
22643   [(set_attr "type" "mmx")
22644    (set_attr "mode" "TI")])
22645
22646 (define_insn "pfrcpit2v2sf3"
22647   [(set (match_operand:V2SF 0 "register_operand" "=y")
22648         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22649                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22650                      UNSPEC_PFRCPIT2))]
22651   "TARGET_3DNOW"
22652   "pfrcpit2\\t{%2, %0|%0, %2}"
22653   [(set_attr "type" "mmx")
22654    (set_attr "mode" "TI")])
22655
22656 (define_insn "pfrsqrtv2sf2"
22657   [(set (match_operand:V2SF 0 "register_operand" "=y")
22658         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22659                      UNSPEC_PFRSQRT))]
22660   "TARGET_3DNOW"
22661   "pfrsqrt\\t{%1, %0|%0, %1}"
22662   [(set_attr "type" "mmx")
22663    (set_attr "mode" "TI")])
22664                 
22665 (define_insn "pfrsqit1v2sf3"
22666   [(set (match_operand:V2SF 0 "register_operand" "=y")
22667         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22668                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22669                      UNSPEC_PFRSQIT1))]
22670   "TARGET_3DNOW"
22671   "pfrsqit1\\t{%2, %0|%0, %2}"
22672   [(set_attr "type" "mmx")
22673    (set_attr "mode" "TI")])
22674
22675 (define_insn "pmulhrwv4hi3"
22676   [(set (match_operand:V4HI 0 "register_operand" "=y")
22677         (truncate:V4HI
22678            (lshiftrt:V4SI
22679               (plus:V4SI
22680                  (mult:V4SI
22681                     (sign_extend:V4SI
22682                        (match_operand:V4HI 1 "register_operand" "0"))
22683                     (sign_extend:V4SI
22684                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22685                  (const_vector:V4SI [(const_int 32768)
22686                                      (const_int 32768)
22687                                      (const_int 32768)
22688                                      (const_int 32768)]))
22689               (const_int 16))))]
22690   "TARGET_3DNOW"
22691   "pmulhrw\\t{%2, %0|%0, %2}"
22692   [(set_attr "type" "mmxmul")
22693    (set_attr "mode" "TI")])
22694
22695 (define_insn "pswapdv2si2"
22696   [(set (match_operand:V2SI 0 "register_operand" "=y")
22697         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22698                          (parallel [(const_int 1) (const_int 0)])))]
22699   "TARGET_3DNOW_A"
22700   "pswapd\\t{%1, %0|%0, %1}"
22701   [(set_attr "type" "mmxcvt")
22702    (set_attr "mode" "TI")])
22703
22704 (define_insn "pswapdv2sf2"
22705   [(set (match_operand:V2SF 0 "register_operand" "=y")
22706         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22707                          (parallel [(const_int 1) (const_int 0)])))]
22708   "TARGET_3DNOW_A"
22709   "pswapd\\t{%1, %0|%0, %1}"
22710   [(set_attr "type" "mmxcvt")
22711    (set_attr "mode" "TI")])
22712
22713 (define_expand "prefetch"
22714   [(prefetch (match_operand 0 "address_operand" "")
22715              (match_operand:SI 1 "const_int_operand" "")
22716              (match_operand:SI 2 "const_int_operand" ""))]
22717   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22718 {
22719   int rw = INTVAL (operands[1]);
22720   int locality = INTVAL (operands[2]);
22721
22722   if (rw != 0 && rw != 1)
22723     abort ();
22724   if (locality < 0 || locality > 3)
22725     abort ();
22726   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22727     abort ();
22728
22729   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22730      suported by SSE counterpart or the SSE prefetch is not available
22731      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22732      of locality.  */
22733   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22734     operands[2] = GEN_INT (3);
22735   else
22736     operands[1] = const0_rtx;
22737 })
22738
22739 (define_insn "*prefetch_sse"
22740   [(prefetch (match_operand:SI 0 "address_operand" "p")
22741              (const_int 0)
22742              (match_operand:SI 1 "const_int_operand" ""))]
22743   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22744 {
22745   static const char * const patterns[4] = {
22746    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22747   };
22748
22749   int locality = INTVAL (operands[1]);
22750   if (locality < 0 || locality > 3)
22751     abort ();
22752
22753   return patterns[locality];  
22754 }
22755   [(set_attr "type" "sse")
22756    (set_attr "memory" "none")])
22757
22758 (define_insn "*prefetch_sse_rex"
22759   [(prefetch (match_operand:DI 0 "address_operand" "p")
22760              (const_int 0)
22761              (match_operand:SI 1 "const_int_operand" ""))]
22762   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22763 {
22764   static const char * const patterns[4] = {
22765    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22766   };
22767
22768   int locality = INTVAL (operands[1]);
22769   if (locality < 0 || locality > 3)
22770     abort ();
22771
22772   return patterns[locality];  
22773 }
22774   [(set_attr "type" "sse")
22775    (set_attr "memory" "none")])
22776
22777 (define_insn "*prefetch_3dnow"
22778   [(prefetch (match_operand:SI 0 "address_operand" "p")
22779              (match_operand:SI 1 "const_int_operand" "n")
22780              (const_int 3))]
22781   "TARGET_3DNOW && !TARGET_64BIT"
22782 {
22783   if (INTVAL (operands[1]) == 0)
22784     return "prefetch\t%a0";
22785   else
22786     return "prefetchw\t%a0";
22787 }
22788   [(set_attr "type" "mmx")
22789    (set_attr "memory" "none")])
22790
22791 (define_insn "*prefetch_3dnow_rex"
22792   [(prefetch (match_operand:DI 0 "address_operand" "p")
22793              (match_operand:SI 1 "const_int_operand" "n")
22794              (const_int 3))]
22795   "TARGET_3DNOW && TARGET_64BIT"
22796 {
22797   if (INTVAL (operands[1]) == 0)
22798     return "prefetch\t%a0";
22799   else
22800     return "prefetchw\t%a0";
22801 }
22802   [(set_attr "type" "mmx")
22803    (set_attr "memory" "none")])
22804
22805 ;; SSE2 support
22806
22807 (define_insn "addv2df3"
22808   [(set (match_operand:V2DF 0 "register_operand" "=x")
22809         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22810                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22811   "TARGET_SSE2"
22812   "addpd\t{%2, %0|%0, %2}"
22813   [(set_attr "type" "sseadd")
22814    (set_attr "mode" "V2DF")])
22815
22816 (define_insn "vmaddv2df3"
22817   [(set (match_operand:V2DF 0 "register_operand" "=x")
22818         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22819                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22820                         (match_dup 1)
22821                         (const_int 1)))]
22822   "TARGET_SSE2"
22823   "addsd\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "sseadd")
22825    (set_attr "mode" "DF")])
22826
22827 (define_insn "subv2df3"
22828   [(set (match_operand:V2DF 0 "register_operand" "=x")
22829         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22830                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22831   "TARGET_SSE2"
22832   "subpd\t{%2, %0|%0, %2}"
22833   [(set_attr "type" "sseadd")
22834    (set_attr "mode" "V2DF")])
22835
22836 (define_insn "vmsubv2df3"
22837   [(set (match_operand:V2DF 0 "register_operand" "=x")
22838         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22839                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22840                         (match_dup 1)
22841                         (const_int 1)))]
22842   "TARGET_SSE2"
22843   "subsd\t{%2, %0|%0, %2}"
22844   [(set_attr "type" "sseadd")
22845    (set_attr "mode" "DF")])
22846
22847 (define_insn "mulv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22851   "TARGET_SSE2"
22852   "mulpd\t{%2, %0|%0, %2}"
22853   [(set_attr "type" "ssemul")
22854    (set_attr "mode" "V2DF")])
22855
22856 (define_insn "vmmulv2df3"
22857   [(set (match_operand:V2DF 0 "register_operand" "=x")
22858         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22859                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22860                         (match_dup 1)
22861                         (const_int 1)))]
22862   "TARGET_SSE2"
22863   "mulsd\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "ssemul")
22865    (set_attr "mode" "DF")])
22866
22867 (define_insn "divv2df3"
22868   [(set (match_operand:V2DF 0 "register_operand" "=x")
22869         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22870                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22871   "TARGET_SSE2"
22872   "divpd\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "ssediv")
22874    (set_attr "mode" "V2DF")])
22875
22876 (define_insn "vmdivv2df3"
22877   [(set (match_operand:V2DF 0 "register_operand" "=x")
22878         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22879                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22880                         (match_dup 1)
22881                         (const_int 1)))]
22882   "TARGET_SSE2"
22883   "divsd\t{%2, %0|%0, %2}"
22884   [(set_attr "type" "ssediv")
22885    (set_attr "mode" "DF")])
22886
22887 ;; SSE min/max
22888
22889 (define_insn "smaxv2df3"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x")
22891         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22892                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22893   "TARGET_SSE2"
22894   "maxpd\t{%2, %0|%0, %2}"
22895   [(set_attr "type" "sseadd")
22896    (set_attr "mode" "V2DF")])
22897
22898 (define_insn "vmsmaxv2df3"
22899   [(set (match_operand:V2DF 0 "register_operand" "=x")
22900         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22901                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22902                         (match_dup 1)
22903                         (const_int 1)))]
22904   "TARGET_SSE2"
22905   "maxsd\t{%2, %0|%0, %2}"
22906   [(set_attr "type" "sseadd")
22907    (set_attr "mode" "DF")])
22908
22909 (define_insn "sminv2df3"
22910   [(set (match_operand:V2DF 0 "register_operand" "=x")
22911         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22912                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22913   "TARGET_SSE2"
22914   "minpd\t{%2, %0|%0, %2}"
22915   [(set_attr "type" "sseadd")
22916    (set_attr "mode" "V2DF")])
22917
22918 (define_insn "vmsminv2df3"
22919   [(set (match_operand:V2DF 0 "register_operand" "=x")
22920         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22921                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22922                         (match_dup 1)
22923                         (const_int 1)))]
22924   "TARGET_SSE2"
22925   "minsd\t{%2, %0|%0, %2}"
22926   [(set_attr "type" "sseadd")
22927    (set_attr "mode" "DF")])
22928 ;; SSE2 square root.  There doesn't appear to be an extension for the
22929 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22930
22931 (define_insn "sqrtv2df2"
22932   [(set (match_operand:V2DF 0 "register_operand" "=x")
22933         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22934   "TARGET_SSE2"
22935   "sqrtpd\t{%1, %0|%0, %1}"
22936   [(set_attr "type" "sse")
22937    (set_attr "mode" "V2DF")])
22938
22939 (define_insn "vmsqrtv2df2"
22940   [(set (match_operand:V2DF 0 "register_operand" "=x")
22941         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22942                         (match_operand:V2DF 2 "register_operand" "0")
22943                         (const_int 1)))]
22944   "TARGET_SSE2"
22945   "sqrtsd\t{%1, %0|%0, %1}"
22946   [(set_attr "type" "sse")
22947    (set_attr "mode" "SF")])
22948
22949 ;; SSE mask-generating compares
22950
22951 (define_insn "maskcmpv2df3"
22952   [(set (match_operand:V2DI 0 "register_operand" "=x")
22953         (match_operator:V2DI 3 "sse_comparison_operator"
22954                              [(match_operand:V2DF 1 "register_operand" "0")
22955                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22956   "TARGET_SSE2"
22957   "cmp%D3pd\t{%2, %0|%0, %2}"
22958   [(set_attr "type" "ssecmp")
22959    (set_attr "mode" "V2DF")])
22960
22961 (define_insn "maskncmpv2df3"
22962   [(set (match_operand:V2DI 0 "register_operand" "=x")
22963         (not:V2DI
22964          (match_operator:V2DI 3 "sse_comparison_operator"
22965                               [(match_operand:V2DF 1 "register_operand" "0")
22966                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22967   "TARGET_SSE2"
22968 {
22969   if (GET_CODE (operands[3]) == UNORDERED)
22970     return "cmpordps\t{%2, %0|%0, %2}";
22971   else
22972     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22973 }
22974   [(set_attr "type" "ssecmp")
22975    (set_attr "mode" "V2DF")])
22976
22977 (define_insn "vmmaskcmpv2df3"
22978   [(set (match_operand:V2DI 0 "register_operand" "=x")
22979         (vec_merge:V2DI
22980          (match_operator:V2DI 3 "sse_comparison_operator"
22981                               [(match_operand:V2DF 1 "register_operand" "0")
22982                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22983          (subreg:V2DI (match_dup 1) 0)
22984          (const_int 1)))]
22985   "TARGET_SSE2"
22986   "cmp%D3sd\t{%2, %0|%0, %2}"
22987   [(set_attr "type" "ssecmp")
22988    (set_attr "mode" "DF")])
22989
22990 (define_insn "vmmaskncmpv2df3"
22991   [(set (match_operand:V2DI 0 "register_operand" "=x")
22992         (vec_merge:V2DI
22993          (not:V2DI
22994           (match_operator:V2DI 3 "sse_comparison_operator"
22995                                [(match_operand:V2DF 1 "register_operand" "0")
22996                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22997          (subreg:V2DI (match_dup 1) 0)
22998          (const_int 1)))]
22999   "TARGET_SSE2"
23000 {
23001   if (GET_CODE (operands[3]) == UNORDERED)
23002     return "cmpordsd\t{%2, %0|%0, %2}";
23003   else
23004     return "cmpn%D3sd\t{%2, %0|%0, %2}";
23005 }
23006   [(set_attr "type" "ssecmp")
23007    (set_attr "mode" "DF")])
23008
23009 (define_insn "sse2_comi"
23010   [(set (reg:CCFP FLAGS_REG)
23011         (compare:CCFP (vec_select:DF
23012                        (match_operand:V2DF 0 "register_operand" "x")
23013                        (parallel [(const_int 0)]))
23014                       (vec_select:DF
23015                        (match_operand:V2DF 1 "register_operand" "x")
23016                        (parallel [(const_int 0)]))))]
23017   "TARGET_SSE2"
23018   "comisd\t{%1, %0|%0, %1}"
23019   [(set_attr "type" "ssecomi")
23020    (set_attr "mode" "DF")])
23021
23022 (define_insn "sse2_ucomi"
23023   [(set (reg:CCFPU FLAGS_REG)
23024         (compare:CCFPU (vec_select:DF
23025                          (match_operand:V2DF 0 "register_operand" "x")
23026                          (parallel [(const_int 0)]))
23027                         (vec_select:DF
23028                          (match_operand:V2DF 1 "register_operand" "x")
23029                          (parallel [(const_int 0)]))))]
23030   "TARGET_SSE2"
23031   "ucomisd\t{%1, %0|%0, %1}"
23032   [(set_attr "type" "ssecomi")
23033    (set_attr "mode" "DF")])
23034
23035 ;; SSE Strange Moves.
23036
23037 (define_insn "sse2_movmskpd"
23038   [(set (match_operand:SI 0 "register_operand" "=r")
23039         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23040                    UNSPEC_MOVMSK))]
23041   "TARGET_SSE2"
23042   "movmskpd\t{%1, %0|%0, %1}"
23043   [(set_attr "type" "ssecvt")
23044    (set_attr "mode" "V2DF")])
23045
23046 (define_insn "sse2_pmovmskb"
23047   [(set (match_operand:SI 0 "register_operand" "=r")
23048         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23049                    UNSPEC_MOVMSK))]
23050   "TARGET_SSE2"
23051   "pmovmskb\t{%1, %0|%0, %1}"
23052   [(set_attr "type" "ssecvt")
23053    (set_attr "mode" "V2DF")])
23054
23055 (define_insn "sse2_maskmovdqu"
23056   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23057         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23058                        (match_operand:V16QI 2 "register_operand" "x")]
23059                       UNSPEC_MASKMOV))]
23060   "TARGET_SSE2"
23061   ;; @@@ check ordering of operands in intel/nonintel syntax
23062   "maskmovdqu\t{%2, %1|%1, %2}"
23063   [(set_attr "type" "ssecvt")
23064    (set_attr "mode" "TI")])
23065
23066 (define_insn "sse2_maskmovdqu_rex64"
23067   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23068         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23069                        (match_operand:V16QI 2 "register_operand" "x")]
23070                       UNSPEC_MASKMOV))]
23071   "TARGET_SSE2"
23072   ;; @@@ check ordering of operands in intel/nonintel syntax
23073   "maskmovdqu\t{%2, %1|%1, %2}"
23074   [(set_attr "type" "ssecvt")
23075    (set_attr "mode" "TI")])
23076
23077 (define_insn "sse2_movntv2df"
23078   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23079         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23080                      UNSPEC_MOVNT))]
23081   "TARGET_SSE2"
23082   "movntpd\t{%1, %0|%0, %1}"
23083   [(set_attr "type" "ssecvt")
23084    (set_attr "mode" "V2DF")])
23085
23086 (define_insn "sse2_movntv2di"
23087   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23088         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23089                      UNSPEC_MOVNT))]
23090   "TARGET_SSE2"
23091   "movntdq\t{%1, %0|%0, %1}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "TI")])
23094
23095 (define_insn "sse2_movntsi"
23096   [(set (match_operand:SI 0 "memory_operand" "=m")
23097         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23098                    UNSPEC_MOVNT))]
23099   "TARGET_SSE2"
23100   "movnti\t{%1, %0|%0, %1}"
23101   [(set_attr "type" "ssecvt")
23102    (set_attr "mode" "V2DF")])
23103
23104 ;; SSE <-> integer/MMX conversions
23105
23106 ;; Conversions between SI and SF
23107
23108 (define_insn "cvtdq2ps"
23109   [(set (match_operand:V4SF 0 "register_operand" "=x")
23110         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23111   "TARGET_SSE2"
23112   "cvtdq2ps\t{%1, %0|%0, %1}"
23113   [(set_attr "type" "ssecvt")
23114    (set_attr "mode" "V2DF")])
23115
23116 (define_insn "cvtps2dq"
23117   [(set (match_operand:V4SI 0 "register_operand" "=x")
23118         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23119   "TARGET_SSE2"
23120   "cvtps2dq\t{%1, %0|%0, %1}"
23121   [(set_attr "type" "ssecvt")
23122    (set_attr "mode" "TI")])
23123
23124 (define_insn "cvttps2dq"
23125   [(set (match_operand:V4SI 0 "register_operand" "=x")
23126         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23127                      UNSPEC_FIX))]
23128   "TARGET_SSE2"
23129   "cvttps2dq\t{%1, %0|%0, %1}"
23130   [(set_attr "type" "ssecvt")
23131    (set_attr "mode" "TI")])
23132
23133 ;; Conversions between SI and DF
23134
23135 (define_insn "cvtdq2pd"
23136   [(set (match_operand:V2DF 0 "register_operand" "=x")
23137         (float:V2DF (vec_select:V2SI
23138                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23139                      (parallel
23140                       [(const_int 0)
23141                        (const_int 1)]))))]
23142   "TARGET_SSE2"
23143   "cvtdq2pd\t{%1, %0|%0, %1}"
23144   [(set_attr "type" "ssecvt")
23145    (set_attr "mode" "V2DF")])
23146
23147 (define_insn "cvtpd2dq"
23148   [(set (match_operand:V4SI 0 "register_operand" "=x")
23149         (vec_concat:V4SI
23150          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23151          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23152   "TARGET_SSE2"
23153   "cvtpd2dq\t{%1, %0|%0, %1}"
23154   [(set_attr "type" "ssecvt")
23155    (set_attr "mode" "TI")])
23156
23157 (define_insn "cvttpd2dq"
23158   [(set (match_operand:V4SI 0 "register_operand" "=x")
23159         (vec_concat:V4SI
23160          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23161                       UNSPEC_FIX)
23162          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23163   "TARGET_SSE2"
23164   "cvttpd2dq\t{%1, %0|%0, %1}"
23165   [(set_attr "type" "ssecvt")
23166    (set_attr "mode" "TI")])
23167
23168 (define_insn "cvtpd2pi"
23169   [(set (match_operand:V2SI 0 "register_operand" "=y")
23170         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23171   "TARGET_SSE2"
23172   "cvtpd2pi\t{%1, %0|%0, %1}"
23173   [(set_attr "type" "ssecvt")
23174    (set_attr "mode" "TI")])
23175
23176 (define_insn "cvttpd2pi"
23177   [(set (match_operand:V2SI 0 "register_operand" "=y")
23178         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23179                      UNSPEC_FIX))]
23180   "TARGET_SSE2"
23181   "cvttpd2pi\t{%1, %0|%0, %1}"
23182   [(set_attr "type" "ssecvt")
23183    (set_attr "mode" "TI")])
23184
23185 (define_insn "cvtpi2pd"
23186   [(set (match_operand:V2DF 0 "register_operand" "=x")
23187         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23188   "TARGET_SSE2"
23189   "cvtpi2pd\t{%1, %0|%0, %1}"
23190   [(set_attr "type" "ssecvt")
23191    (set_attr "mode" "TI")])
23192
23193 ;; Conversions between SI and DF
23194
23195 (define_insn "cvtsd2si"
23196   [(set (match_operand:SI 0 "register_operand" "=r,r")
23197         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23198                                (parallel [(const_int 0)]))))]
23199   "TARGET_SSE2"
23200   "cvtsd2si\t{%1, %0|%0, %1}"
23201   [(set_attr "type" "sseicvt")
23202    (set_attr "athlon_decode" "double,vector")
23203    (set_attr "mode" "SI")])
23204
23205 (define_insn "cvtsd2siq"
23206   [(set (match_operand:DI 0 "register_operand" "=r,r")
23207         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23208                                (parallel [(const_int 0)]))))]
23209   "TARGET_SSE2 && TARGET_64BIT"
23210   "cvtsd2siq\t{%1, %0|%0, %1}"
23211   [(set_attr "type" "sseicvt")
23212    (set_attr "athlon_decode" "double,vector")
23213    (set_attr "mode" "DI")])
23214
23215 (define_insn "cvttsd2si"
23216   [(set (match_operand:SI 0 "register_operand" "=r,r")
23217         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23218                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23219   "TARGET_SSE2"
23220   "cvttsd2si\t{%1, %0|%0, %1}"
23221   [(set_attr "type" "sseicvt")
23222    (set_attr "mode" "SI")
23223    (set_attr "athlon_decode" "double,vector")])
23224
23225 (define_insn "cvttsd2siq"
23226   [(set (match_operand:DI 0 "register_operand" "=r,r")
23227         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23228                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23229   "TARGET_SSE2 && TARGET_64BIT"
23230   "cvttsd2siq\t{%1, %0|%0, %1}"
23231   [(set_attr "type" "sseicvt")
23232    (set_attr "mode" "DI")
23233    (set_attr "athlon_decode" "double,vector")])
23234
23235 (define_insn "cvtsi2sd"
23236   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23237         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23238                         (vec_duplicate:V2DF
23239                           (float:DF
23240                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23241                         (const_int 2)))]
23242   "TARGET_SSE2"
23243   "cvtsi2sd\t{%2, %0|%0, %2}"
23244   [(set_attr "type" "sseicvt")
23245    (set_attr "mode" "DF")
23246    (set_attr "athlon_decode" "double,direct")])
23247
23248 (define_insn "cvtsi2sdq"
23249   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23250         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23251                         (vec_duplicate:V2DF
23252                           (float:DF
23253                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23254                         (const_int 2)))]
23255   "TARGET_SSE2 && TARGET_64BIT"
23256   "cvtsi2sdq\t{%2, %0|%0, %2}"
23257   [(set_attr "type" "sseicvt")
23258    (set_attr "mode" "DF")
23259    (set_attr "athlon_decode" "double,direct")])
23260
23261 ;; Conversions between SF and DF
23262
23263 (define_insn "cvtsd2ss"
23264   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23265         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23266                         (vec_duplicate:V4SF
23267                           (float_truncate:V2SF
23268                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23269                         (const_int 14)))]
23270   "TARGET_SSE2"
23271   "cvtsd2ss\t{%2, %0|%0, %2}"
23272   [(set_attr "type" "ssecvt")
23273    (set_attr "athlon_decode" "vector,double")
23274    (set_attr "mode" "SF")])
23275
23276 (define_insn "cvtss2sd"
23277   [(set (match_operand:V2DF 0 "register_operand" "=x")
23278         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23279                         (float_extend:V2DF
23280                           (vec_select:V2SF
23281                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23282                             (parallel [(const_int 0)
23283                                        (const_int 1)])))
23284                         (const_int 2)))]
23285   "TARGET_SSE2"
23286   "cvtss2sd\t{%2, %0|%0, %2}"
23287   [(set_attr "type" "ssecvt")
23288    (set_attr "mode" "DF")])
23289
23290 (define_insn "cvtpd2ps"
23291   [(set (match_operand:V4SF 0 "register_operand" "=x")
23292         (subreg:V4SF
23293           (vec_concat:V4SI
23294             (subreg:V2SI (float_truncate:V2SF
23295                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23296             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23297   "TARGET_SSE2"
23298   "cvtpd2ps\t{%1, %0|%0, %1}"
23299   [(set_attr "type" "ssecvt")
23300    (set_attr "mode" "V4SF")])
23301
23302 (define_insn "cvtps2pd"
23303   [(set (match_operand:V2DF 0 "register_operand" "=x")
23304         (float_extend:V2DF
23305           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23306                            (parallel [(const_int 0)
23307                                       (const_int 1)]))))]
23308   "TARGET_SSE2"
23309   "cvtps2pd\t{%1, %0|%0, %1}"
23310   [(set_attr "type" "ssecvt")
23311    (set_attr "mode" "V2DF")])
23312
23313 ;; SSE2 variants of MMX insns
23314
23315 ;; MMX arithmetic
23316
23317 (define_insn "addv16qi3"
23318   [(set (match_operand:V16QI 0 "register_operand" "=x")
23319         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23320                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23321   "TARGET_SSE2"
23322   "paddb\t{%2, %0|%0, %2}"
23323   [(set_attr "type" "sseiadd")
23324    (set_attr "mode" "TI")])
23325
23326 (define_insn "addv8hi3"
23327   [(set (match_operand:V8HI 0 "register_operand" "=x")
23328         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23329                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23330   "TARGET_SSE2"
23331   "paddw\t{%2, %0|%0, %2}"
23332   [(set_attr "type" "sseiadd")
23333    (set_attr "mode" "TI")])
23334
23335 (define_insn "addv4si3"
23336   [(set (match_operand:V4SI 0 "register_operand" "=x")
23337         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23338                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23339   "TARGET_SSE2"
23340   "paddd\t{%2, %0|%0, %2}"
23341   [(set_attr "type" "sseiadd")
23342    (set_attr "mode" "TI")])
23343
23344 (define_insn "addv2di3"
23345   [(set (match_operand:V2DI 0 "register_operand" "=x")
23346         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23347                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23348   "TARGET_SSE2"
23349   "paddq\t{%2, %0|%0, %2}"
23350   [(set_attr "type" "sseiadd")
23351    (set_attr "mode" "TI")])
23352
23353 (define_insn "ssaddv16qi3"
23354   [(set (match_operand:V16QI 0 "register_operand" "=x")
23355         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23356                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23357   "TARGET_SSE2"
23358   "paddsb\t{%2, %0|%0, %2}"
23359   [(set_attr "type" "sseiadd")
23360    (set_attr "mode" "TI")])
23361
23362 (define_insn "ssaddv8hi3"
23363   [(set (match_operand:V8HI 0 "register_operand" "=x")
23364         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23365                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23366   "TARGET_SSE2"
23367   "paddsw\t{%2, %0|%0, %2}"
23368   [(set_attr "type" "sseiadd")
23369    (set_attr "mode" "TI")])
23370
23371 (define_insn "usaddv16qi3"
23372   [(set (match_operand:V16QI 0 "register_operand" "=x")
23373         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23374                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23375   "TARGET_SSE2"
23376   "paddusb\t{%2, %0|%0, %2}"
23377   [(set_attr "type" "sseiadd")
23378    (set_attr "mode" "TI")])
23379
23380 (define_insn "usaddv8hi3"
23381   [(set (match_operand:V8HI 0 "register_operand" "=x")
23382         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23383                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23384   "TARGET_SSE2"
23385   "paddusw\t{%2, %0|%0, %2}"
23386   [(set_attr "type" "sseiadd")
23387    (set_attr "mode" "TI")])
23388
23389 (define_insn "subv16qi3"
23390   [(set (match_operand:V16QI 0 "register_operand" "=x")
23391         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23392                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23393   "TARGET_SSE2"
23394   "psubb\t{%2, %0|%0, %2}"
23395   [(set_attr "type" "sseiadd")
23396    (set_attr "mode" "TI")])
23397
23398 (define_insn "subv8hi3"
23399   [(set (match_operand:V8HI 0 "register_operand" "=x")
23400         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23401                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23402   "TARGET_SSE2"
23403   "psubw\t{%2, %0|%0, %2}"
23404   [(set_attr "type" "sseiadd")
23405    (set_attr "mode" "TI")])
23406
23407 (define_insn "subv4si3"
23408   [(set (match_operand:V4SI 0 "register_operand" "=x")
23409         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23410                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23411   "TARGET_SSE2"
23412   "psubd\t{%2, %0|%0, %2}"
23413   [(set_attr "type" "sseiadd")
23414    (set_attr "mode" "TI")])
23415
23416 (define_insn "subv2di3"
23417   [(set (match_operand:V2DI 0 "register_operand" "=x")
23418         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23419                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23420   "TARGET_SSE2"
23421   "psubq\t{%2, %0|%0, %2}"
23422   [(set_attr "type" "sseiadd")
23423    (set_attr "mode" "TI")])
23424
23425 (define_insn "sssubv16qi3"
23426   [(set (match_operand:V16QI 0 "register_operand" "=x")
23427         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23428                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23429   "TARGET_SSE2"
23430   "psubsb\t{%2, %0|%0, %2}"
23431   [(set_attr "type" "sseiadd")
23432    (set_attr "mode" "TI")])
23433
23434 (define_insn "sssubv8hi3"
23435   [(set (match_operand:V8HI 0 "register_operand" "=x")
23436         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23437                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23438   "TARGET_SSE2"
23439   "psubsw\t{%2, %0|%0, %2}"
23440   [(set_attr "type" "sseiadd")
23441    (set_attr "mode" "TI")])
23442
23443 (define_insn "ussubv16qi3"
23444   [(set (match_operand:V16QI 0 "register_operand" "=x")
23445         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23446                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23447   "TARGET_SSE2"
23448   "psubusb\t{%2, %0|%0, %2}"
23449   [(set_attr "type" "sseiadd")
23450    (set_attr "mode" "TI")])
23451
23452 (define_insn "ussubv8hi3"
23453   [(set (match_operand:V8HI 0 "register_operand" "=x")
23454         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23455                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23456   "TARGET_SSE2"
23457   "psubusw\t{%2, %0|%0, %2}"
23458   [(set_attr "type" "sseiadd")
23459    (set_attr "mode" "TI")])
23460
23461 (define_insn "mulv8hi3"
23462   [(set (match_operand:V8HI 0 "register_operand" "=x")
23463         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23464                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23465   "TARGET_SSE2"
23466   "pmullw\t{%2, %0|%0, %2}"
23467   [(set_attr "type" "sseimul")
23468    (set_attr "mode" "TI")])
23469
23470 (define_insn "smulv8hi3_highpart"
23471   [(set (match_operand:V8HI 0 "register_operand" "=x")
23472         (truncate:V8HI
23473          (lshiftrt:V8SI
23474           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23475                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23476           (const_int 16))))]
23477   "TARGET_SSE2"
23478   "pmulhw\t{%2, %0|%0, %2}"
23479   [(set_attr "type" "sseimul")
23480    (set_attr "mode" "TI")])
23481
23482 (define_insn "umulv8hi3_highpart"
23483   [(set (match_operand:V8HI 0 "register_operand" "=x")
23484         (truncate:V8HI
23485          (lshiftrt:V8SI
23486           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23487                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23488           (const_int 16))))]
23489   "TARGET_SSE2"
23490   "pmulhuw\t{%2, %0|%0, %2}"
23491   [(set_attr "type" "sseimul")
23492    (set_attr "mode" "TI")])
23493
23494 (define_insn "sse2_umulsidi3"
23495   [(set (match_operand:DI 0 "register_operand" "=y")
23496         (mult:DI (zero_extend:DI (vec_select:SI
23497                                   (match_operand:V2SI 1 "register_operand" "0")
23498                                   (parallel [(const_int 0)])))
23499                  (zero_extend:DI (vec_select:SI
23500                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23501                                   (parallel [(const_int 0)])))))]
23502   "TARGET_SSE2"
23503   "pmuludq\t{%2, %0|%0, %2}"
23504   [(set_attr "type" "mmxmul")
23505    (set_attr "mode" "DI")])
23506
23507 (define_insn "sse2_umulv2siv2di3"
23508   [(set (match_operand:V2DI 0 "register_operand" "=x")
23509         (mult:V2DI (zero_extend:V2DI
23510                      (vec_select:V2SI
23511                        (match_operand:V4SI 1 "register_operand" "0")
23512                        (parallel [(const_int 0) (const_int 2)])))
23513                    (zero_extend:V2DI
23514                      (vec_select:V2SI
23515                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23516                        (parallel [(const_int 0) (const_int 2)])))))]
23517   "TARGET_SSE2"
23518   "pmuludq\t{%2, %0|%0, %2}"
23519   [(set_attr "type" "sseimul")
23520    (set_attr "mode" "TI")])
23521
23522 (define_insn "sse2_pmaddwd"
23523   [(set (match_operand:V4SI 0 "register_operand" "=x")
23524         (plus:V4SI
23525          (mult:V4SI
23526           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23527                                              (parallel [(const_int 0)
23528                                                         (const_int 2)
23529                                                         (const_int 4)
23530                                                         (const_int 6)])))
23531           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23532                                              (parallel [(const_int 0)
23533                                                         (const_int 2)
23534                                                         (const_int 4)
23535                                                         (const_int 6)]))))
23536          (mult:V4SI
23537           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23538                                              (parallel [(const_int 1)
23539                                                         (const_int 3)
23540                                                         (const_int 5)
23541                                                         (const_int 7)])))
23542           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23543                                              (parallel [(const_int 1)
23544                                                         (const_int 3)
23545                                                         (const_int 5)
23546                                                         (const_int 7)]))))))]
23547   "TARGET_SSE2"
23548   "pmaddwd\t{%2, %0|%0, %2}"
23549   [(set_attr "type" "sseiadd")
23550    (set_attr "mode" "TI")])
23551
23552 ;; Same as pxor, but don't show input operands so that we don't think
23553 ;; they are live.
23554 (define_insn "sse2_clrti"
23555   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23556   "TARGET_SSE2"
23557 {
23558   if (get_attr_mode (insn) == MODE_TI)
23559     return "pxor\t%0, %0";
23560   else
23561     return "xorps\t%0, %0";
23562 }
23563   [(set_attr "type" "ssemov")
23564    (set_attr "memory" "none")
23565    (set (attr "mode")
23566               (if_then_else
23567                 (ne (symbol_ref "optimize_size")
23568                     (const_int 0))
23569                 (const_string "V4SF")
23570                 (const_string "TI")))])
23571
23572 ;; MMX unsigned averages/sum of absolute differences
23573
23574 (define_insn "sse2_uavgv16qi3"
23575   [(set (match_operand:V16QI 0 "register_operand" "=x")
23576         (ashiftrt:V16QI
23577          (plus:V16QI (plus:V16QI
23578                      (match_operand:V16QI 1 "register_operand" "0")
23579                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23580                      (const_vector:V16QI [(const_int 1) (const_int 1)
23581                                           (const_int 1) (const_int 1)
23582                                           (const_int 1) (const_int 1)
23583                                           (const_int 1) (const_int 1)
23584                                           (const_int 1) (const_int 1)
23585                                           (const_int 1) (const_int 1)
23586                                           (const_int 1) (const_int 1)
23587                                           (const_int 1) (const_int 1)]))
23588          (const_int 1)))]
23589   "TARGET_SSE2"
23590   "pavgb\t{%2, %0|%0, %2}"
23591   [(set_attr "type" "sseiadd")
23592    (set_attr "mode" "TI")])
23593
23594 (define_insn "sse2_uavgv8hi3"
23595   [(set (match_operand:V8HI 0 "register_operand" "=x")
23596         (ashiftrt:V8HI
23597          (plus:V8HI (plus:V8HI
23598                      (match_operand:V8HI 1 "register_operand" "0")
23599                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23600                     (const_vector:V8HI [(const_int 1) (const_int 1)
23601                                         (const_int 1) (const_int 1)
23602                                         (const_int 1) (const_int 1)
23603                                         (const_int 1) (const_int 1)]))
23604          (const_int 1)))]
23605   "TARGET_SSE2"
23606   "pavgw\t{%2, %0|%0, %2}"
23607   [(set_attr "type" "sseiadd")
23608    (set_attr "mode" "TI")])
23609
23610 ;; @@@ this isn't the right representation.
23611 (define_insn "sse2_psadbw"
23612   [(set (match_operand:V2DI 0 "register_operand" "=x")
23613         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23614                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23615                      UNSPEC_PSADBW))]
23616   "TARGET_SSE2"
23617   "psadbw\t{%2, %0|%0, %2}"
23618   [(set_attr "type" "sseiadd")
23619    (set_attr "mode" "TI")])
23620
23621
23622 ;; MMX insert/extract/shuffle
23623
23624 (define_insn "sse2_pinsrw"
23625   [(set (match_operand:V8HI 0 "register_operand" "=x")
23626         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23627                         (vec_duplicate:V8HI
23628                          (truncate:HI
23629                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23630                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23631   "TARGET_SSE2"
23632   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23633   [(set_attr "type" "ssecvt")
23634    (set_attr "mode" "TI")])
23635
23636 (define_insn "sse2_pextrw"
23637   [(set (match_operand:SI 0 "register_operand" "=r")
23638         (zero_extend:SI
23639           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23640                          (parallel
23641                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23642   "TARGET_SSE2"
23643   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23644   [(set_attr "type" "ssecvt")
23645    (set_attr "mode" "TI")])
23646
23647 (define_insn "sse2_pshufd"
23648   [(set (match_operand:V4SI 0 "register_operand" "=x")
23649         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23650                       (match_operand:SI 2 "immediate_operand" "i")]
23651                      UNSPEC_SHUFFLE))]
23652   "TARGET_SSE2"
23653   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23654   [(set_attr "type" "ssecvt")
23655    (set_attr "mode" "TI")])
23656
23657 (define_insn "sse2_pshuflw"
23658   [(set (match_operand:V8HI 0 "register_operand" "=x")
23659         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23660                       (match_operand:SI 2 "immediate_operand" "i")]
23661                      UNSPEC_PSHUFLW))]
23662   "TARGET_SSE2"
23663   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23664   [(set_attr "type" "ssecvt")
23665    (set_attr "mode" "TI")])
23666
23667 (define_insn "sse2_pshufhw"
23668   [(set (match_operand:V8HI 0 "register_operand" "=x")
23669         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23670                       (match_operand:SI 2 "immediate_operand" "i")]
23671                      UNSPEC_PSHUFHW))]
23672   "TARGET_SSE2"
23673   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23674   [(set_attr "type" "ssecvt")
23675    (set_attr "mode" "TI")])
23676
23677 ;; MMX mask-generating comparisons
23678
23679 (define_insn "eqv16qi3"
23680   [(set (match_operand:V16QI 0 "register_operand" "=x")
23681         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23682                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23683   "TARGET_SSE2"
23684   "pcmpeqb\t{%2, %0|%0, %2}"
23685   [(set_attr "type" "ssecmp")
23686    (set_attr "mode" "TI")])
23687
23688 (define_insn "eqv8hi3"
23689   [(set (match_operand:V8HI 0 "register_operand" "=x")
23690         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23691                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23692   "TARGET_SSE2"
23693   "pcmpeqw\t{%2, %0|%0, %2}"
23694   [(set_attr "type" "ssecmp")
23695    (set_attr "mode" "TI")])
23696
23697 (define_insn "eqv4si3"
23698   [(set (match_operand:V4SI 0 "register_operand" "=x")
23699         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23700                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23701   "TARGET_SSE2"
23702   "pcmpeqd\t{%2, %0|%0, %2}"
23703   [(set_attr "type" "ssecmp")
23704    (set_attr "mode" "TI")])
23705
23706 (define_insn "gtv16qi3"
23707   [(set (match_operand:V16QI 0 "register_operand" "=x")
23708         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23709                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23710   "TARGET_SSE2"
23711   "pcmpgtb\t{%2, %0|%0, %2}"
23712   [(set_attr "type" "ssecmp")
23713    (set_attr "mode" "TI")])
23714
23715 (define_insn "gtv8hi3"
23716   [(set (match_operand:V8HI 0 "register_operand" "=x")
23717         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23718                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23719   "TARGET_SSE2"
23720   "pcmpgtw\t{%2, %0|%0, %2}"
23721   [(set_attr "type" "ssecmp")
23722    (set_attr "mode" "TI")])
23723
23724 (define_insn "gtv4si3"
23725   [(set (match_operand:V4SI 0 "register_operand" "=x")
23726         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23727                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23728   "TARGET_SSE2"
23729   "pcmpgtd\t{%2, %0|%0, %2}"
23730   [(set_attr "type" "ssecmp")
23731    (set_attr "mode" "TI")])
23732
23733
23734 ;; MMX max/min insns
23735
23736 (define_insn "umaxv16qi3"
23737   [(set (match_operand:V16QI 0 "register_operand" "=x")
23738         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23739                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23740   "TARGET_SSE2"
23741   "pmaxub\t{%2, %0|%0, %2}"
23742   [(set_attr "type" "sseiadd")
23743    (set_attr "mode" "TI")])
23744
23745 (define_insn "smaxv8hi3"
23746   [(set (match_operand:V8HI 0 "register_operand" "=x")
23747         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23748                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23749   "TARGET_SSE2"
23750   "pmaxsw\t{%2, %0|%0, %2}"
23751   [(set_attr "type" "sseiadd")
23752    (set_attr "mode" "TI")])
23753
23754 (define_insn "uminv16qi3"
23755   [(set (match_operand:V16QI 0 "register_operand" "=x")
23756         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23757                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23758   "TARGET_SSE2"
23759   "pminub\t{%2, %0|%0, %2}"
23760   [(set_attr "type" "sseiadd")
23761    (set_attr "mode" "TI")])
23762
23763 (define_insn "sminv8hi3"
23764   [(set (match_operand:V8HI 0 "register_operand" "=x")
23765         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23766                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23767   "TARGET_SSE2"
23768   "pminsw\t{%2, %0|%0, %2}"
23769   [(set_attr "type" "sseiadd")
23770    (set_attr "mode" "TI")])
23771
23772
23773 ;; MMX shifts
23774
23775 (define_insn "ashrv8hi3"
23776   [(set (match_operand:V8HI 0 "register_operand" "=x")
23777         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23778                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23779   "TARGET_SSE2"
23780   "psraw\t{%2, %0|%0, %2}"
23781   [(set_attr "type" "sseishft")
23782    (set_attr "mode" "TI")])
23783
23784 (define_insn "ashrv4si3"
23785   [(set (match_operand:V4SI 0 "register_operand" "=x")
23786         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23787                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23788   "TARGET_SSE2"
23789   "psrad\t{%2, %0|%0, %2}"
23790   [(set_attr "type" "sseishft")
23791    (set_attr "mode" "TI")])
23792
23793 (define_insn "lshrv8hi3"
23794   [(set (match_operand:V8HI 0 "register_operand" "=x")
23795         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23796                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23797   "TARGET_SSE2"
23798   "psrlw\t{%2, %0|%0, %2}"
23799   [(set_attr "type" "sseishft")
23800    (set_attr "mode" "TI")])
23801
23802 (define_insn "lshrv4si3"
23803   [(set (match_operand:V4SI 0 "register_operand" "=x")
23804         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23805                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23806   "TARGET_SSE2"
23807   "psrld\t{%2, %0|%0, %2}"
23808   [(set_attr "type" "sseishft")
23809    (set_attr "mode" "TI")])
23810
23811 (define_insn "lshrv2di3"
23812   [(set (match_operand:V2DI 0 "register_operand" "=x")
23813         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23814                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23815   "TARGET_SSE2"
23816   "psrlq\t{%2, %0|%0, %2}"
23817   [(set_attr "type" "sseishft")
23818    (set_attr "mode" "TI")])
23819
23820 (define_insn "ashlv8hi3"
23821   [(set (match_operand:V8HI 0 "register_operand" "=x")
23822         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23823                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23824   "TARGET_SSE2"
23825   "psllw\t{%2, %0|%0, %2}"
23826   [(set_attr "type" "sseishft")
23827    (set_attr "mode" "TI")])
23828
23829 (define_insn "ashlv4si3"
23830   [(set (match_operand:V4SI 0 "register_operand" "=x")
23831         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23832                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23833   "TARGET_SSE2"
23834   "pslld\t{%2, %0|%0, %2}"
23835   [(set_attr "type" "sseishft")
23836    (set_attr "mode" "TI")])
23837
23838 (define_insn "ashlv2di3"
23839   [(set (match_operand:V2DI 0 "register_operand" "=x")
23840         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23841                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23842   "TARGET_SSE2"
23843   "psllq\t{%2, %0|%0, %2}"
23844   [(set_attr "type" "sseishft")
23845    (set_attr "mode" "TI")])
23846
23847 (define_insn "ashrv8hi3_ti"
23848   [(set (match_operand:V8HI 0 "register_operand" "=x")
23849         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23850                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23851   "TARGET_SSE2"
23852   "psraw\t{%2, %0|%0, %2}"
23853   [(set_attr "type" "sseishft")
23854    (set_attr "mode" "TI")])
23855
23856 (define_insn "ashrv4si3_ti"
23857   [(set (match_operand:V4SI 0 "register_operand" "=x")
23858         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23859                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23860   "TARGET_SSE2"
23861   "psrad\t{%2, %0|%0, %2}"
23862   [(set_attr "type" "sseishft")
23863    (set_attr "mode" "TI")])
23864
23865 (define_insn "lshrv8hi3_ti"
23866   [(set (match_operand:V8HI 0 "register_operand" "=x")
23867         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23868                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23869   "TARGET_SSE2"
23870   "psrlw\t{%2, %0|%0, %2}"
23871   [(set_attr "type" "sseishft")
23872    (set_attr "mode" "TI")])
23873
23874 (define_insn "lshrv4si3_ti"
23875   [(set (match_operand:V4SI 0 "register_operand" "=x")
23876         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23877                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23878   "TARGET_SSE2"
23879   "psrld\t{%2, %0|%0, %2}"
23880   [(set_attr "type" "sseishft")
23881    (set_attr "mode" "TI")])
23882
23883 (define_insn "lshrv2di3_ti"
23884   [(set (match_operand:V2DI 0 "register_operand" "=x")
23885         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23886                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23887   "TARGET_SSE2"
23888   "psrlq\t{%2, %0|%0, %2}"
23889   [(set_attr "type" "sseishft")
23890    (set_attr "mode" "TI")])
23891
23892 (define_insn "ashlv8hi3_ti"
23893   [(set (match_operand:V8HI 0 "register_operand" "=x")
23894         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23895                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23896   "TARGET_SSE2"
23897   "psllw\t{%2, %0|%0, %2}"
23898   [(set_attr "type" "sseishft")
23899    (set_attr "mode" "TI")])
23900
23901 (define_insn "ashlv4si3_ti"
23902   [(set (match_operand:V4SI 0 "register_operand" "=x")
23903         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23904                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23905   "TARGET_SSE2"
23906   "pslld\t{%2, %0|%0, %2}"
23907   [(set_attr "type" "sseishft")
23908    (set_attr "mode" "TI")])
23909
23910 (define_insn "ashlv2di3_ti"
23911   [(set (match_operand:V2DI 0 "register_operand" "=x")
23912         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23913                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23914   "TARGET_SSE2"
23915   "psllq\t{%2, %0|%0, %2}"
23916   [(set_attr "type" "sseishft")
23917    (set_attr "mode" "TI")])
23918
23919 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23920 ;; we wouldn't need here it since we never generate TImode arithmetic.
23921
23922 ;; There has to be some kind of prize for the weirdest new instruction...
23923 (define_insn "sse2_ashlti3"
23924   [(set (match_operand:TI 0 "register_operand" "=x")
23925         (unspec:TI
23926          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23927                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23928                                (const_int 8)))] UNSPEC_NOP))]
23929   "TARGET_SSE2"
23930   "pslldq\t{%2, %0|%0, %2}"
23931   [(set_attr "type" "sseishft")
23932    (set_attr "mode" "TI")])
23933
23934 (define_insn "sse2_lshrti3"
23935   [(set (match_operand:TI 0 "register_operand" "=x")
23936         (unspec:TI
23937          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23938                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23939                                 (const_int 8)))] UNSPEC_NOP))]
23940   "TARGET_SSE2"
23941   "psrldq\t{%2, %0|%0, %2}"
23942   [(set_attr "type" "sseishft")
23943    (set_attr "mode" "TI")])
23944
23945 ;; SSE unpack
23946
23947 (define_insn "sse2_unpckhpd"
23948   [(set (match_operand:V2DF 0 "register_operand" "=x")
23949         (vec_concat:V2DF
23950          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23951                         (parallel [(const_int 1)]))
23952          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23953                         (parallel [(const_int 1)]))))]
23954   "TARGET_SSE2"
23955   "unpckhpd\t{%2, %0|%0, %2}"
23956   [(set_attr "type" "ssecvt")
23957    (set_attr "mode" "V2DF")])
23958
23959 (define_insn "sse2_unpcklpd"
23960   [(set (match_operand:V2DF 0 "register_operand" "=x")
23961         (vec_concat:V2DF
23962          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23963                         (parallel [(const_int 0)]))
23964          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23965                         (parallel [(const_int 0)]))))]
23966   "TARGET_SSE2"
23967   "unpcklpd\t{%2, %0|%0, %2}"
23968   [(set_attr "type" "ssecvt")
23969    (set_attr "mode" "V2DF")])
23970
23971 ;; MMX pack/unpack insns.
23972
23973 (define_insn "sse2_packsswb"
23974   [(set (match_operand:V16QI 0 "register_operand" "=x")
23975         (vec_concat:V16QI
23976          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23977          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23978   "TARGET_SSE2"
23979   "packsswb\t{%2, %0|%0, %2}"
23980   [(set_attr "type" "ssecvt")
23981    (set_attr "mode" "TI")])
23982
23983 (define_insn "sse2_packssdw"
23984   [(set (match_operand:V8HI 0 "register_operand" "=x")
23985         (vec_concat:V8HI
23986          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23987          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23988   "TARGET_SSE2"
23989   "packssdw\t{%2, %0|%0, %2}"
23990   [(set_attr "type" "ssecvt")
23991    (set_attr "mode" "TI")])
23992
23993 (define_insn "sse2_packuswb"
23994   [(set (match_operand:V16QI 0 "register_operand" "=x")
23995         (vec_concat:V16QI
23996          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23997          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23998   "TARGET_SSE2"
23999   "packuswb\t{%2, %0|%0, %2}"
24000   [(set_attr "type" "ssecvt")
24001    (set_attr "mode" "TI")])
24002
24003 (define_insn "sse2_punpckhbw"
24004   [(set (match_operand:V16QI 0 "register_operand" "=x")
24005         (vec_merge:V16QI
24006          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24007                            (parallel [(const_int 8) (const_int 0)
24008                                       (const_int 9) (const_int 1)
24009                                       (const_int 10) (const_int 2)
24010                                       (const_int 11) (const_int 3)
24011                                       (const_int 12) (const_int 4)
24012                                       (const_int 13) (const_int 5)
24013                                       (const_int 14) (const_int 6)
24014                                       (const_int 15) (const_int 7)]))
24015          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24016                            (parallel [(const_int 0) (const_int 8)
24017                                       (const_int 1) (const_int 9)
24018                                       (const_int 2) (const_int 10)
24019                                       (const_int 3) (const_int 11)
24020                                       (const_int 4) (const_int 12)
24021                                       (const_int 5) (const_int 13)
24022                                       (const_int 6) (const_int 14)
24023                                       (const_int 7) (const_int 15)]))
24024          (const_int 21845)))]
24025   "TARGET_SSE2"
24026   "punpckhbw\t{%2, %0|%0, %2}"
24027   [(set_attr "type" "ssecvt")
24028    (set_attr "mode" "TI")])
24029
24030 (define_insn "sse2_punpckhwd"
24031   [(set (match_operand:V8HI 0 "register_operand" "=x")
24032         (vec_merge:V8HI
24033          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24034                           (parallel [(const_int 4) (const_int 0)
24035                                      (const_int 5) (const_int 1)
24036                                      (const_int 6) (const_int 2)
24037                                      (const_int 7) (const_int 3)]))
24038          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24039                           (parallel [(const_int 0) (const_int 4)
24040                                      (const_int 1) (const_int 5)
24041                                      (const_int 2) (const_int 6)
24042                                      (const_int 3) (const_int 7)]))
24043          (const_int 85)))]
24044   "TARGET_SSE2"
24045   "punpckhwd\t{%2, %0|%0, %2}"
24046   [(set_attr "type" "ssecvt")
24047    (set_attr "mode" "TI")])
24048
24049 (define_insn "sse2_punpckhdq"
24050   [(set (match_operand:V4SI 0 "register_operand" "=x")
24051         (vec_merge:V4SI
24052          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24053                           (parallel [(const_int 2) (const_int 0)
24054                                      (const_int 3) (const_int 1)]))
24055          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24056                           (parallel [(const_int 0) (const_int 2)
24057                                      (const_int 1) (const_int 3)]))
24058          (const_int 5)))]
24059   "TARGET_SSE2"
24060   "punpckhdq\t{%2, %0|%0, %2}"
24061   [(set_attr "type" "ssecvt")
24062    (set_attr "mode" "TI")])
24063
24064 (define_insn "sse2_punpcklbw"
24065   [(set (match_operand:V16QI 0 "register_operand" "=x")
24066         (vec_merge:V16QI
24067          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24068                            (parallel [(const_int 0) (const_int 8)
24069                                       (const_int 1) (const_int 9)
24070                                       (const_int 2) (const_int 10)
24071                                       (const_int 3) (const_int 11)
24072                                       (const_int 4) (const_int 12)
24073                                       (const_int 5) (const_int 13)
24074                                       (const_int 6) (const_int 14)
24075                                       (const_int 7) (const_int 15)]))
24076          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24077                            (parallel [(const_int 8) (const_int 0)
24078                                       (const_int 9) (const_int 1)
24079                                       (const_int 10) (const_int 2)
24080                                       (const_int 11) (const_int 3)
24081                                       (const_int 12) (const_int 4)
24082                                       (const_int 13) (const_int 5)
24083                                       (const_int 14) (const_int 6)
24084                                       (const_int 15) (const_int 7)]))
24085          (const_int 21845)))]
24086   "TARGET_SSE2"
24087   "punpcklbw\t{%2, %0|%0, %2}"
24088   [(set_attr "type" "ssecvt")
24089    (set_attr "mode" "TI")])
24090
24091 (define_insn "sse2_punpcklwd"
24092   [(set (match_operand:V8HI 0 "register_operand" "=x")
24093         (vec_merge:V8HI
24094          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24095                           (parallel [(const_int 0) (const_int 4)
24096                                      (const_int 1) (const_int 5)
24097                                      (const_int 2) (const_int 6)
24098                                      (const_int 3) (const_int 7)]))
24099          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24100                           (parallel [(const_int 4) (const_int 0)
24101                                      (const_int 5) (const_int 1)
24102                                      (const_int 6) (const_int 2)
24103                                      (const_int 7) (const_int 3)]))
24104          (const_int 85)))]
24105   "TARGET_SSE2"
24106   "punpcklwd\t{%2, %0|%0, %2}"
24107   [(set_attr "type" "ssecvt")
24108    (set_attr "mode" "TI")])
24109
24110 (define_insn "sse2_punpckldq"
24111   [(set (match_operand:V4SI 0 "register_operand" "=x")
24112         (vec_merge:V4SI
24113          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24114                           (parallel [(const_int 0) (const_int 2)
24115                                      (const_int 1) (const_int 3)]))
24116          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24117                           (parallel [(const_int 2) (const_int 0)
24118                                      (const_int 3) (const_int 1)]))
24119          (const_int 5)))]
24120   "TARGET_SSE2"
24121   "punpckldq\t{%2, %0|%0, %2}"
24122   [(set_attr "type" "ssecvt")
24123    (set_attr "mode" "TI")])
24124
24125 (define_insn "sse2_punpcklqdq"
24126   [(set (match_operand:V2DI 0 "register_operand" "=x")
24127         (vec_merge:V2DI
24128          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24129                           (parallel [(const_int 1)
24130                                      (const_int 0)]))
24131          (match_operand:V2DI 1 "register_operand" "0")
24132          (const_int 1)))]
24133   "TARGET_SSE2"
24134   "punpcklqdq\t{%2, %0|%0, %2}"
24135   [(set_attr "type" "ssecvt")
24136    (set_attr "mode" "TI")])
24137
24138 (define_insn "sse2_punpckhqdq"
24139   [(set (match_operand:V2DI 0 "register_operand" "=x")
24140         (vec_merge:V2DI
24141          (match_operand:V2DI 1 "register_operand" "0")
24142          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24143                           (parallel [(const_int 1)
24144                                      (const_int 0)]))
24145          (const_int 1)))]
24146   "TARGET_SSE2"
24147   "punpckhqdq\t{%2, %0|%0, %2}"
24148   [(set_attr "type" "ssecvt")
24149    (set_attr "mode" "TI")])
24150
24151 ;; SSE2 moves
24152
24153 (define_insn "sse2_movapd"
24154   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24155         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24156                      UNSPEC_MOVA))]
24157   "TARGET_SSE2
24158    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24159   "movapd\t{%1, %0|%0, %1}"
24160   [(set_attr "type" "ssemov")
24161    (set_attr "mode" "V2DF")])
24162
24163 (define_insn "sse2_movupd"
24164   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24165         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24166                      UNSPEC_MOVU))]
24167   "TARGET_SSE2
24168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24169   "movupd\t{%1, %0|%0, %1}"
24170   [(set_attr "type" "ssecvt")
24171    (set_attr "mode" "V2DF")])
24172
24173 (define_insn "sse2_movdqa"
24174   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24175         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24176                        UNSPEC_MOVA))]
24177   "TARGET_SSE2
24178    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24179   "movdqa\t{%1, %0|%0, %1}"
24180   [(set_attr "type" "ssemov")
24181    (set_attr "mode" "TI")])
24182
24183 (define_insn "sse2_movdqu"
24184   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24185         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24186                        UNSPEC_MOVU))]
24187   "TARGET_SSE2
24188    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24189   "movdqu\t{%1, %0|%0, %1}"
24190   [(set_attr "type" "ssecvt")
24191    (set_attr "mode" "TI")])
24192
24193 (define_insn "sse2_movdq2q"
24194   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24195         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24196                        (parallel [(const_int 0)])))]
24197   "TARGET_SSE2 && !TARGET_64BIT"
24198   "@
24199    movq\t{%1, %0|%0, %1}
24200    movdq2q\t{%1, %0|%0, %1}"
24201   [(set_attr "type" "ssecvt")
24202    (set_attr "mode" "TI")])
24203
24204 (define_insn "sse2_movdq2q_rex64"
24205   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24206         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24207                        (parallel [(const_int 0)])))]
24208   "TARGET_SSE2 && TARGET_64BIT"
24209   "@
24210    movq\t{%1, %0|%0, %1}
24211    movdq2q\t{%1, %0|%0, %1}
24212    movd\t{%1, %0|%0, %1}"
24213   [(set_attr "type" "ssecvt")
24214    (set_attr "mode" "TI")])
24215
24216 (define_insn "sse2_movq2dq"
24217   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24218         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24219                          (const_int 0)))]
24220   "TARGET_SSE2 && !TARGET_64BIT"
24221   "@
24222    movq\t{%1, %0|%0, %1}
24223    movq2dq\t{%1, %0|%0, %1}"
24224   [(set_attr "type" "ssecvt,ssemov")
24225    (set_attr "mode" "TI")])
24226
24227 (define_insn "sse2_movq2dq_rex64"
24228   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24229         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24230                          (const_int 0)))]
24231   "TARGET_SSE2 && TARGET_64BIT"
24232   "@
24233    movq\t{%1, %0|%0, %1}
24234    movq2dq\t{%1, %0|%0, %1}
24235    movd\t{%1, %0|%0, %1}"
24236   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24237    (set_attr "mode" "TI")])
24238
24239 (define_insn "sse2_movq"
24240   [(set (match_operand:V2DI 0 "register_operand" "=x")
24241         (vec_concat:V2DI (vec_select:DI
24242                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24243                           (parallel [(const_int 0)]))
24244                          (const_int 0)))]
24245   "TARGET_SSE2"
24246   "movq\t{%1, %0|%0, %1}"
24247   [(set_attr "type" "ssemov")
24248    (set_attr "mode" "TI")])
24249
24250 (define_insn "sse2_loadd"
24251   [(set (match_operand:V4SI 0 "register_operand" "=x")
24252         (vec_merge:V4SI
24253          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24254          (const_vector:V4SI [(const_int 0)
24255                              (const_int 0)
24256                              (const_int 0)
24257                              (const_int 0)])
24258          (const_int 1)))]
24259   "TARGET_SSE2"
24260   "movd\t{%1, %0|%0, %1}"
24261   [(set_attr "type" "ssemov")
24262    (set_attr "mode" "TI")])
24263
24264 (define_insn "sse2_stored"
24265   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24266         (vec_select:SI
24267          (match_operand:V4SI 1 "register_operand" "x")
24268          (parallel [(const_int 0)])))]
24269   "TARGET_SSE2"
24270   "movd\t{%1, %0|%0, %1}"
24271   [(set_attr "type" "ssemov")
24272    (set_attr "mode" "TI")])
24273
24274 (define_insn "sse2_movhpd"
24275   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24276         (vec_merge:V2DF
24277          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24278          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24279          (const_int 2)))]
24280   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24281   "movhpd\t{%2, %0|%0, %2}"
24282   [(set_attr "type" "ssecvt")
24283    (set_attr "mode" "V2DF")])
24284
24285 (define_expand "sse2_loadsd"
24286   [(match_operand:V2DF 0 "register_operand" "")
24287    (match_operand:DF 1 "memory_operand" "")]
24288   "TARGET_SSE2"
24289 {
24290   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24291                                 CONST0_RTX (V2DFmode)));
24292   DONE;
24293 })
24294
24295 (define_insn "sse2_loadsd_1"
24296   [(set (match_operand:V2DF 0 "register_operand" "=x")
24297         (vec_merge:V2DF
24298          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24299          (match_operand:V2DF 2 "const0_operand" "X")
24300          (const_int 1)))]
24301   "TARGET_SSE2"
24302   "movsd\t{%1, %0|%0, %1}"
24303   [(set_attr "type" "ssecvt")
24304    (set_attr "mode" "DF")])
24305
24306 (define_insn "sse2_movsd"
24307   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24308         (vec_merge:V2DF
24309          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24310          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24311          (const_int 1)))]
24312   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24313   "@movsd\t{%2, %0|%0, %2}
24314     movlpd\t{%2, %0|%0, %2}
24315     movlpd\t{%2, %0|%0, %2}"
24316   [(set_attr "type" "ssecvt")
24317    (set_attr "mode" "DF,V2DF,V2DF")])
24318
24319 (define_insn "sse2_storesd"
24320   [(set (match_operand:DF 0 "memory_operand" "=m")
24321         (vec_select:DF
24322          (match_operand:V2DF 1 "register_operand" "x")
24323          (parallel [(const_int 0)])))]
24324   "TARGET_SSE2"
24325   "movsd\t{%1, %0|%0, %1}"
24326   [(set_attr "type" "ssecvt")
24327    (set_attr "mode" "DF")])
24328
24329 (define_insn "sse2_shufpd"
24330   [(set (match_operand:V2DF 0 "register_operand" "=x")
24331         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24332                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24333                       (match_operand:SI 3 "immediate_operand" "i")]
24334                      UNSPEC_SHUFFLE))]
24335   "TARGET_SSE2"
24336   ;; @@@ check operand order for intel/nonintel syntax
24337   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24338   [(set_attr "type" "ssecvt")
24339    (set_attr "mode" "V2DF")])
24340
24341 (define_insn "sse2_clflush"
24342   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24343                     UNSPECV_CLFLUSH)]
24344   "TARGET_SSE2"
24345   "clflush\t%a0"
24346   [(set_attr "type" "sse")
24347    (set_attr "memory" "unknown")])
24348
24349 (define_expand "sse2_mfence"
24350   [(set (match_dup 0)
24351         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24352   "TARGET_SSE2"
24353 {
24354   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24355   MEM_VOLATILE_P (operands[0]) = 1;
24356 })
24357
24358 (define_insn "*mfence_insn"
24359   [(set (match_operand:BLK 0 "" "")
24360         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24361   "TARGET_SSE2"
24362   "mfence"
24363   [(set_attr "type" "sse")
24364    (set_attr "memory" "unknown")])
24365
24366 (define_expand "sse2_lfence"
24367   [(set (match_dup 0)
24368         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24369   "TARGET_SSE2"
24370 {
24371   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24372   MEM_VOLATILE_P (operands[0]) = 1;
24373 })
24374
24375 (define_insn "*lfence_insn"
24376   [(set (match_operand:BLK 0 "" "")
24377         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24378   "TARGET_SSE2"
24379   "lfence"
24380   [(set_attr "type" "sse")
24381    (set_attr "memory" "unknown")])
24382
24383 ;; SSE3
24384
24385 (define_insn "mwait"
24386   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24387                      (match_operand:SI 1 "register_operand" "c")]
24388                     UNSPECV_MWAIT)]
24389   "TARGET_SSE3"
24390   "mwait\t%0, %1"
24391   [(set_attr "length" "3")])
24392
24393 (define_insn "monitor"
24394   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24395                      (match_operand:SI 1 "register_operand" "c")
24396                      (match_operand:SI 2 "register_operand" "d")]
24397                     UNSPECV_MONITOR)]
24398   "TARGET_SSE3"
24399   "monitor\t%0, %1, %2"
24400   [(set_attr "length" "3")])
24401
24402 ;; SSE3 arithmetic
24403
24404 (define_insn "addsubv4sf3"
24405   [(set (match_operand:V4SF 0 "register_operand" "=x")
24406         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24407                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24408                      UNSPEC_ADDSUB))]
24409   "TARGET_SSE3"
24410   "addsubps\t{%2, %0|%0, %2}"
24411   [(set_attr "type" "sseadd")
24412    (set_attr "mode" "V4SF")])
24413
24414 (define_insn "addsubv2df3"
24415   [(set (match_operand:V2DF 0 "register_operand" "=x")
24416         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24417                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24418                      UNSPEC_ADDSUB))]
24419   "TARGET_SSE3"
24420   "addsubpd\t{%2, %0|%0, %2}"
24421   [(set_attr "type" "sseadd")
24422    (set_attr "mode" "V2DF")])
24423
24424 (define_insn "haddv4sf3"
24425   [(set (match_operand:V4SF 0 "register_operand" "=x")
24426         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24427                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24428                      UNSPEC_HADD))]
24429   "TARGET_SSE3"
24430   "haddps\t{%2, %0|%0, %2}"
24431   [(set_attr "type" "sseadd")
24432    (set_attr "mode" "V4SF")])
24433
24434 (define_insn "haddv2df3"
24435   [(set (match_operand:V2DF 0 "register_operand" "=x")
24436         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24437                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24438                      UNSPEC_HADD))]
24439   "TARGET_SSE3"
24440   "haddpd\t{%2, %0|%0, %2}"
24441   [(set_attr "type" "sseadd")
24442    (set_attr "mode" "V2DF")])
24443
24444 (define_insn "hsubv4sf3"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24447                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24448                      UNSPEC_HSUB))]
24449   "TARGET_SSE3"
24450   "hsubps\t{%2, %0|%0, %2}"
24451   [(set_attr "type" "sseadd")
24452    (set_attr "mode" "V4SF")])
24453
24454 (define_insn "hsubv2df3"
24455   [(set (match_operand:V2DF 0 "register_operand" "=x")
24456         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24457                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24458                      UNSPEC_HSUB))]
24459   "TARGET_SSE3"
24460   "hsubpd\t{%2, %0|%0, %2}"
24461   [(set_attr "type" "sseadd")
24462    (set_attr "mode" "V2DF")])
24463
24464 (define_insn "movshdup"
24465   [(set (match_operand:V4SF 0 "register_operand" "=x")
24466         (unspec:V4SF
24467          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24468   "TARGET_SSE3"
24469   "movshdup\t{%1, %0|%0, %1}"
24470   [(set_attr "type" "sse")
24471    (set_attr "mode" "V4SF")])
24472
24473 (define_insn "movsldup"
24474   [(set (match_operand:V4SF 0 "register_operand" "=x")
24475         (unspec:V4SF
24476          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24477   "TARGET_SSE3"
24478   "movsldup\t{%1, %0|%0, %1}"
24479   [(set_attr "type" "sse")
24480    (set_attr "mode" "V4SF")])
24481
24482 (define_insn "lddqu"
24483   [(set (match_operand:V16QI 0 "register_operand" "=x")
24484         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24485                        UNSPEC_LDQQU))]
24486   "TARGET_SSE3"
24487   "lddqu\t{%1, %0|%0, %1}"
24488   [(set_attr "type" "ssecvt")
24489    (set_attr "mode" "TI")])
24490
24491 (define_insn "loadddup"
24492   [(set (match_operand:V2DF 0 "register_operand" "=x")
24493         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24494   "TARGET_SSE3"
24495   "movddup\t{%1, %0|%0, %1}"
24496   [(set_attr "type" "ssecvt")
24497    (set_attr "mode" "DF")])
24498
24499 (define_insn "movddup"
24500   [(set (match_operand:V2DF 0 "register_operand" "=x")
24501         (vec_duplicate:V2DF
24502          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24503                         (parallel [(const_int 0)]))))]
24504   "TARGET_SSE3"
24505   "movddup\t{%1, %0|%0, %1}"
24506   [(set_attr "type" "ssecvt")
24507    (set_attr "mode" "DF")])