OSDN Git Service

* configure/i386/i386.md (*fix_trunch_1): Add "&& 1" to
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg 17)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg 17)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg 17)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg 17)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg 17)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg 17)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg 17)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg 17)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg 17)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg 17)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg 17)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg 17)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg 17)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg 17)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg 17)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg 17)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg 17)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg 17)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 (define_insn "*cmpfp_0_sf"
801   [(set (match_operand:HI 0 "register_operand" "=a")
802         (unspec:HI
803           [(compare:CCFP
804              (match_operand:SF 1 "register_operand" "f")
805              (match_operand:SF 2 "const0_operand" "X"))]
806         UNSPEC_FNSTSW))]
807   "TARGET_80387"
808   "* return output_fp_compare (insn, operands, 2, 0);"
809   [(set_attr "type" "multi")
810    (set_attr "mode" "SF")])
811
812 (define_insn "*cmpfp_0_df"
813   [(set (match_operand:HI 0 "register_operand" "=a")
814         (unspec:HI
815           [(compare:CCFP
816              (match_operand:DF 1 "register_operand" "f")
817              (match_operand:DF 2 "const0_operand" "X"))]
818         UNSPEC_FNSTSW))]
819   "TARGET_80387"
820   "* return output_fp_compare (insn, operands, 2, 0);"
821   [(set_attr "type" "multi")
822    (set_attr "mode" "DF")])
823
824 (define_insn "*cmpfp_0_xf"
825   [(set (match_operand:HI 0 "register_operand" "=a")
826         (unspec:HI
827           [(compare:CCFP
828              (match_operand:XF 1 "register_operand" "f")
829              (match_operand:XF 2 "const0_operand" "X"))]
830         UNSPEC_FNSTSW))]
831   "TARGET_80387"
832   "* return output_fp_compare (insn, operands, 2, 0);"
833   [(set_attr "type" "multi")
834    (set_attr "mode" "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[1])"
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[1])"
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[1])"
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)"
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 && (flag_peephole2 ? flow2_completed : reload_completed)
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)"
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 && (flag_peephole2 ? flow2_completed : reload_completed)
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   "* 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   "&& 1"
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 1 "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 FLAGS_REG)
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   [(set (match_operand:DI 0 "shiftdi_operand" "")
10603         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10604                    (match_operand:QI 2 "nonmemory_operand" "")))]
10605   ""
10606   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10607
10608 (define_insn "*ashldi3_1_rex64"
10609   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10610         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10611                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10612    (clobber (reg:CC FLAGS_REG))]
10613   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10614 {
10615   switch (get_attr_type (insn))
10616     {
10617     case TYPE_ALU:
10618       if (operands[2] != const1_rtx)
10619         abort ();
10620       if (!rtx_equal_p (operands[0], operands[1]))
10621         abort ();
10622       return "add{q}\t{%0, %0|%0, %0}";
10623
10624     case TYPE_LEA:
10625       if (GET_CODE (operands[2]) != CONST_INT
10626           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10627         abort ();
10628       operands[1] = gen_rtx_MULT (DImode, operands[1],
10629                                   GEN_INT (1 << INTVAL (operands[2])));
10630       return "lea{q}\t{%a1, %0|%0, %a1}";
10631
10632     default:
10633       if (REG_P (operands[2]))
10634         return "sal{q}\t{%b2, %0|%0, %b2}";
10635       else if (operands[2] == const1_rtx
10636                && (TARGET_SHIFT1 || optimize_size))
10637         return "sal{q}\t%0";
10638       else
10639         return "sal{q}\t{%2, %0|%0, %2}";
10640     }
10641 }
10642   [(set (attr "type")
10643      (cond [(eq_attr "alternative" "1")
10644               (const_string "lea")
10645             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10646                           (const_int 0))
10647                       (match_operand 0 "register_operand" ""))
10648                  (match_operand 2 "const1_operand" ""))
10649               (const_string "alu")
10650            ]
10651            (const_string "ishift")))
10652    (set_attr "mode" "DI")])
10653
10654 ;; Convert lea to the lea pattern to avoid flags dependency.
10655 (define_split
10656   [(set (match_operand:DI 0 "register_operand" "")
10657         (ashift:DI (match_operand:DI 1 "register_operand" "")
10658                    (match_operand:QI 2 "immediate_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "TARGET_64BIT && reload_completed
10661    && true_regnum (operands[0]) != true_regnum (operands[1])"
10662   [(set (match_dup 0)
10663         (mult:DI (match_dup 1)
10664                  (match_dup 2)))]
10665   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10666
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashldi3_cmp_rex64"
10671   [(set (reg 17)
10672         (compare
10673           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "immediate_operand" "e"))
10675           (const_int 0)))
10676    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10677         (ashift:DI (match_dup 1) (match_dup 2)))]
10678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10680 {
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       if (operands[2] != const1_rtx)
10685         abort ();
10686       return "add{q}\t{%0, %0|%0, %0}";
10687
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{q}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{q}\t%0";
10694       else
10695         return "sal{q}\t{%2, %0|%0, %2}";
10696     }
10697 }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "DI")])
10707
10708 (define_insn "*ashldi3_1"
10709   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10710         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10711                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "!TARGET_64BIT"
10714   "#"
10715   [(set_attr "type" "multi")])
10716
10717 ;; By default we don't ask for a scratch register, because when DImode
10718 ;; values are manipulated, registers are already at a premium.  But if
10719 ;; we have one handy, we won't turn it away.
10720 (define_peephole2
10721   [(match_scratch:SI 3 "r")
10722    (parallel [(set (match_operand:DI 0 "register_operand" "")
10723                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10724                               (match_operand:QI 2 "nonmemory_operand" "")))
10725               (clobber (reg:CC FLAGS_REG))])
10726    (match_dup 3)]
10727   "!TARGET_64BIT && TARGET_CMOVE"
10728   [(const_int 0)]
10729   "ix86_split_ashldi (operands, operands[3]); DONE;")
10730
10731 (define_split
10732   [(set (match_operand:DI 0 "register_operand" "")
10733         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10734                    (match_operand:QI 2 "nonmemory_operand" "")))
10735    (clobber (reg:CC FLAGS_REG))]
10736   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10737   [(const_int 0)]
10738   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10739
10740 (define_insn "x86_shld_1"
10741   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10742         (ior:SI (ashift:SI (match_dup 0)
10743                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10744                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10745                   (minus:QI (const_int 32) (match_dup 2)))))
10746    (clobber (reg:CC FLAGS_REG))]
10747   ""
10748   "@
10749    shld{l}\t{%2, %1, %0|%0, %1, %2}
10750    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10751   [(set_attr "type" "ishift")
10752    (set_attr "prefix_0f" "1")
10753    (set_attr "mode" "SI")
10754    (set_attr "pent_pair" "np")
10755    (set_attr "athlon_decode" "vector")])
10756
10757 (define_expand "x86_shift_adj_1"
10758   [(set (reg:CCZ FLAGS_REG)
10759         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10760                              (const_int 32))
10761                      (const_int 0)))
10762    (set (match_operand:SI 0 "register_operand" "")
10763         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10764                          (match_operand:SI 1 "register_operand" "")
10765                          (match_dup 0)))
10766    (set (match_dup 1)
10767         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10768                          (match_operand:SI 3 "register_operand" "r")
10769                          (match_dup 1)))]
10770   "TARGET_CMOVE"
10771   "")
10772
10773 (define_expand "x86_shift_adj_2"
10774   [(use (match_operand:SI 0 "register_operand" ""))
10775    (use (match_operand:SI 1 "register_operand" ""))
10776    (use (match_operand:QI 2 "register_operand" ""))]
10777   ""
10778 {
10779   rtx label = gen_label_rtx ();
10780   rtx tmp;
10781
10782   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10783
10784   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10785   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10786   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10787                               gen_rtx_LABEL_REF (VOIDmode, label),
10788                               pc_rtx);
10789   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10790   JUMP_LABEL (tmp) = label;
10791
10792   emit_move_insn (operands[0], operands[1]);
10793   ix86_expand_clear (operands[1]);
10794
10795   emit_label (label);
10796   LABEL_NUSES (label) = 1;
10797
10798   DONE;
10799 })
10800
10801 (define_expand "ashlsi3"
10802   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10803         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10804                    (match_operand:QI 2 "nonmemory_operand" "")))
10805    (clobber (reg:CC FLAGS_REG))]
10806   ""
10807   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10808
10809 (define_insn "*ashlsi3_1"
10810   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10811         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10812                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10813    (clobber (reg:CC FLAGS_REG))]
10814   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10815 {
10816   switch (get_attr_type (insn))
10817     {
10818     case TYPE_ALU:
10819       if (operands[2] != const1_rtx)
10820         abort ();
10821       if (!rtx_equal_p (operands[0], operands[1]))
10822         abort ();
10823       return "add{l}\t{%0, %0|%0, %0}";
10824
10825     case TYPE_LEA:
10826       return "#";
10827
10828     default:
10829       if (REG_P (operands[2]))
10830         return "sal{l}\t{%b2, %0|%0, %b2}";
10831       else if (operands[2] == const1_rtx
10832                && (TARGET_SHIFT1 || optimize_size))
10833         return "sal{l}\t%0";
10834       else
10835         return "sal{l}\t{%2, %0|%0, %2}";
10836     }
10837 }
10838   [(set (attr "type")
10839      (cond [(eq_attr "alternative" "1")
10840               (const_string "lea")
10841             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842                           (const_int 0))
10843                       (match_operand 0 "register_operand" ""))
10844                  (match_operand 2 "const1_operand" ""))
10845               (const_string "alu")
10846            ]
10847            (const_string "ishift")))
10848    (set_attr "mode" "SI")])
10849
10850 ;; Convert lea to the lea pattern to avoid flags dependency.
10851 (define_split
10852   [(set (match_operand 0 "register_operand" "")
10853         (ashift (match_operand 1 "index_register_operand" "")
10854                 (match_operand:QI 2 "const_int_operand" "")))
10855    (clobber (reg:CC FLAGS_REG))]
10856   "reload_completed
10857    && true_regnum (operands[0]) != true_regnum (operands[1])"
10858   [(const_int 0)]
10859 {
10860   rtx pat;
10861   operands[0] = gen_lowpart (SImode, operands[0]);
10862   operands[1] = gen_lowpart (Pmode, operands[1]);
10863   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10864   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10865   if (Pmode != SImode)
10866     pat = gen_rtx_SUBREG (SImode, pat, 0);
10867   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10868   DONE;
10869 })
10870
10871 ;; Rare case of shifting RSP is handled by generating move and shift
10872 (define_split
10873   [(set (match_operand 0 "register_operand" "")
10874         (ashift (match_operand 1 "register_operand" "")
10875                 (match_operand:QI 2 "const_int_operand" "")))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "reload_completed
10878    && true_regnum (operands[0]) != true_regnum (operands[1])"
10879   [(const_int 0)]
10880 {
10881   rtx pat, clob;
10882   emit_move_insn (operands[1], operands[0]);
10883   pat = gen_rtx_SET (VOIDmode, operands[0],
10884                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10885                                      operands[0], operands[2]));
10886   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10887   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10888   DONE;
10889 })
10890
10891 (define_insn "*ashlsi3_1_zext"
10892   [(set (match_operand:DI 0 "register_operand" "=r,r")
10893         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10894                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10895    (clobber (reg:CC FLAGS_REG))]
10896   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10897 {
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       if (operands[2] != const1_rtx)
10902         abort ();
10903       return "add{l}\t{%k0, %k0|%k0, %k0}";
10904
10905     case TYPE_LEA:
10906       return "#";
10907
10908     default:
10909       if (REG_P (operands[2]))
10910         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10911       else if (operands[2] == const1_rtx
10912                && (TARGET_SHIFT1 || optimize_size))
10913         return "sal{l}\t%k0";
10914       else
10915         return "sal{l}\t{%2, %k0|%k0, %2}";
10916     }
10917 }
10918   [(set (attr "type")
10919      (cond [(eq_attr "alternative" "1")
10920               (const_string "lea")
10921             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922                      (const_int 0))
10923                  (match_operand 2 "const1_operand" ""))
10924               (const_string "alu")
10925            ]
10926            (const_string "ishift")))
10927    (set_attr "mode" "SI")])
10928
10929 ;; Convert lea to the lea pattern to avoid flags dependency.
10930 (define_split
10931   [(set (match_operand:DI 0 "register_operand" "")
10932         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10933                                 (match_operand:QI 2 "const_int_operand" ""))))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_64BIT && reload_completed
10936    && true_regnum (operands[0]) != true_regnum (operands[1])"
10937   [(set (match_dup 0) (zero_extend:DI
10938                         (subreg:SI (mult:SI (match_dup 1)
10939                                             (match_dup 2)) 0)))]
10940 {
10941   operands[1] = gen_lowpart (Pmode, operands[1]);
10942   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10943 })
10944
10945 ;; This pattern can't accept a variable shift count, since shifts by
10946 ;; zero don't affect the flags.  We assume that shifts by constant
10947 ;; zero are optimized away.
10948 (define_insn "*ashlsi3_cmp"
10949   [(set (reg 17)
10950         (compare
10951           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10952                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10953           (const_int 0)))
10954    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10955         (ashift:SI (match_dup 1) (match_dup 2)))]
10956   "ix86_match_ccmode (insn, CCGOCmode)
10957    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10958 {
10959   switch (get_attr_type (insn))
10960     {
10961     case TYPE_ALU:
10962       if (operands[2] != const1_rtx)
10963         abort ();
10964       return "add{l}\t{%0, %0|%0, %0}";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{l}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{l}\t%0";
10972       else
10973         return "sal{l}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10978                           (const_int 0))
10979                       (match_operand 0 "register_operand" ""))
10980                  (match_operand 2 "const1_operand" ""))
10981               (const_string "alu")
10982            ]
10983            (const_string "ishift")))
10984    (set_attr "mode" "SI")])
10985
10986 (define_insn "*ashlsi3_cmp_zext"
10987   [(set (reg 17)
10988         (compare
10989           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10990                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10991           (const_int 0)))
10992    (set (match_operand:DI 0 "register_operand" "=r")
10993         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10994   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10995    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10996 {
10997   switch (get_attr_type (insn))
10998     {
10999     case TYPE_ALU:
11000       if (operands[2] != const1_rtx)
11001         abort ();
11002       return "add{l}\t{%k0, %k0|%k0, %k0}";
11003
11004     default:
11005       if (REG_P (operands[2]))
11006         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11007       else if (operands[2] == const1_rtx
11008                && (TARGET_SHIFT1 || optimize_size))
11009         return "sal{l}\t%k0";
11010       else
11011         return "sal{l}\t{%2, %k0|%k0, %2}";
11012     }
11013 }
11014   [(set (attr "type")
11015      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11016                      (const_int 0))
11017                  (match_operand 2 "const1_operand" ""))
11018               (const_string "alu")
11019            ]
11020            (const_string "ishift")))
11021    (set_attr "mode" "SI")])
11022
11023 (define_expand "ashlhi3"
11024   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11025         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11026                    (match_operand:QI 2 "nonmemory_operand" "")))
11027    (clobber (reg:CC FLAGS_REG))]
11028   "TARGET_HIMODE_MATH"
11029   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11030
11031 (define_insn "*ashlhi3_1_lea"
11032   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11033         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11034                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11035    (clobber (reg:CC FLAGS_REG))]
11036   "!TARGET_PARTIAL_REG_STALL
11037    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11038 {
11039   switch (get_attr_type (insn))
11040     {
11041     case TYPE_LEA:
11042       return "#";
11043     case TYPE_ALU:
11044       if (operands[2] != const1_rtx)
11045         abort ();
11046       return "add{w}\t{%0, %0|%0, %0}";
11047
11048     default:
11049       if (REG_P (operands[2]))
11050         return "sal{w}\t{%b2, %0|%0, %b2}";
11051       else if (operands[2] == const1_rtx
11052                && (TARGET_SHIFT1 || optimize_size))
11053         return "sal{w}\t%0";
11054       else
11055         return "sal{w}\t{%2, %0|%0, %2}";
11056     }
11057 }
11058   [(set (attr "type")
11059      (cond [(eq_attr "alternative" "1")
11060               (const_string "lea")
11061             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11062                           (const_int 0))
11063                       (match_operand 0 "register_operand" ""))
11064                  (match_operand 2 "const1_operand" ""))
11065               (const_string "alu")
11066            ]
11067            (const_string "ishift")))
11068    (set_attr "mode" "HI,SI")])
11069
11070 (define_insn "*ashlhi3_1"
11071   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11072         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11073                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "TARGET_PARTIAL_REG_STALL
11076    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11077 {
11078   switch (get_attr_type (insn))
11079     {
11080     case TYPE_ALU:
11081       if (operands[2] != const1_rtx)
11082         abort ();
11083       return "add{w}\t{%0, %0|%0, %0}";
11084
11085     default:
11086       if (REG_P (operands[2]))
11087         return "sal{w}\t{%b2, %0|%0, %b2}";
11088       else if (operands[2] == const1_rtx
11089                && (TARGET_SHIFT1 || optimize_size))
11090         return "sal{w}\t%0";
11091       else
11092         return "sal{w}\t{%2, %0|%0, %2}";
11093     }
11094 }
11095   [(set (attr "type")
11096      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11097                           (const_int 0))
11098                       (match_operand 0 "register_operand" ""))
11099                  (match_operand 2 "const1_operand" ""))
11100               (const_string "alu")
11101            ]
11102            (const_string "ishift")))
11103    (set_attr "mode" "HI")])
11104
11105 ;; This pattern can't accept a variable shift count, since shifts by
11106 ;; zero don't affect the flags.  We assume that shifts by constant
11107 ;; zero are optimized away.
11108 (define_insn "*ashlhi3_cmp"
11109   [(set (reg 17)
11110         (compare
11111           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11112                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11113           (const_int 0)))
11114    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11115         (ashift:HI (match_dup 1) (match_dup 2)))]
11116   "ix86_match_ccmode (insn, CCGOCmode)
11117    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11118 {
11119   switch (get_attr_type (insn))
11120     {
11121     case TYPE_ALU:
11122       if (operands[2] != const1_rtx)
11123         abort ();
11124       return "add{w}\t{%0, %0|%0, %0}";
11125
11126     default:
11127       if (REG_P (operands[2]))
11128         return "sal{w}\t{%b2, %0|%0, %b2}";
11129       else if (operands[2] == const1_rtx
11130                && (TARGET_SHIFT1 || optimize_size))
11131         return "sal{w}\t%0";
11132       else
11133         return "sal{w}\t{%2, %0|%0, %2}";
11134     }
11135 }
11136   [(set (attr "type")
11137      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11138                           (const_int 0))
11139                       (match_operand 0 "register_operand" ""))
11140                  (match_operand 2 "const1_operand" ""))
11141               (const_string "alu")
11142            ]
11143            (const_string "ishift")))
11144    (set_attr "mode" "HI")])
11145
11146 (define_expand "ashlqi3"
11147   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11148         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11149                    (match_operand:QI 2 "nonmemory_operand" "")))
11150    (clobber (reg:CC FLAGS_REG))]
11151   "TARGET_QIMODE_MATH"
11152   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11153
11154 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11155
11156 (define_insn "*ashlqi3_1_lea"
11157   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11158         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11159                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11160    (clobber (reg:CC FLAGS_REG))]
11161   "!TARGET_PARTIAL_REG_STALL
11162    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11163 {
11164   switch (get_attr_type (insn))
11165     {
11166     case TYPE_LEA:
11167       return "#";
11168     case TYPE_ALU:
11169       if (operands[2] != const1_rtx)
11170         abort ();
11171       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11172         return "add{l}\t{%k0, %k0|%k0, %k0}";
11173       else
11174         return "add{b}\t{%0, %0|%0, %0}";
11175
11176     default:
11177       if (REG_P (operands[2]))
11178         {
11179           if (get_attr_mode (insn) == MODE_SI)
11180             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11181           else
11182             return "sal{b}\t{%b2, %0|%0, %b2}";
11183         }
11184       else if (operands[2] == const1_rtx
11185                && (TARGET_SHIFT1 || optimize_size))
11186         {
11187           if (get_attr_mode (insn) == MODE_SI)
11188             return "sal{l}\t%0";
11189           else
11190             return "sal{b}\t%0";
11191         }
11192       else
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t{%2, %k0|%k0, %2}";
11196           else
11197             return "sal{b}\t{%2, %0|%0, %2}";
11198         }
11199     }
11200 }
11201   [(set (attr "type")
11202      (cond [(eq_attr "alternative" "2")
11203               (const_string "lea")
11204             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11205                           (const_int 0))
11206                       (match_operand 0 "register_operand" ""))
11207                  (match_operand 2 "const1_operand" ""))
11208               (const_string "alu")
11209            ]
11210            (const_string "ishift")))
11211    (set_attr "mode" "QI,SI,SI")])
11212
11213 (define_insn "*ashlqi3_1"
11214   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11215         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11216                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11217    (clobber (reg:CC FLAGS_REG))]
11218   "TARGET_PARTIAL_REG_STALL
11219    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11220 {
11221   switch (get_attr_type (insn))
11222     {
11223     case TYPE_ALU:
11224       if (operands[2] != const1_rtx)
11225         abort ();
11226       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11227         return "add{l}\t{%k0, %k0|%k0, %k0}";
11228       else
11229         return "add{b}\t{%0, %0|%0, %0}";
11230
11231     default:
11232       if (REG_P (operands[2]))
11233         {
11234           if (get_attr_mode (insn) == MODE_SI)
11235             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11236           else
11237             return "sal{b}\t{%b2, %0|%0, %b2}";
11238         }
11239       else if (operands[2] == const1_rtx
11240                && (TARGET_SHIFT1 || optimize_size))
11241         {
11242           if (get_attr_mode (insn) == MODE_SI)
11243             return "sal{l}\t%0";
11244           else
11245             return "sal{b}\t%0";
11246         }
11247       else
11248         {
11249           if (get_attr_mode (insn) == MODE_SI)
11250             return "sal{l}\t{%2, %k0|%k0, %2}";
11251           else
11252             return "sal{b}\t{%2, %0|%0, %2}";
11253         }
11254     }
11255 }
11256   [(set (attr "type")
11257      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258                           (const_int 0))
11259                       (match_operand 0 "register_operand" ""))
11260                  (match_operand 2 "const1_operand" ""))
11261               (const_string "alu")
11262            ]
11263            (const_string "ishift")))
11264    (set_attr "mode" "QI,SI")])
11265
11266 ;; This pattern can't accept a variable shift count, since shifts by
11267 ;; zero don't affect the flags.  We assume that shifts by constant
11268 ;; zero are optimized away.
11269 (define_insn "*ashlqi3_cmp"
11270   [(set (reg 17)
11271         (compare
11272           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11273                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11274           (const_int 0)))
11275    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11276         (ashift:QI (match_dup 1) (match_dup 2)))]
11277   "ix86_match_ccmode (insn, CCGOCmode)
11278    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11279 {
11280   switch (get_attr_type (insn))
11281     {
11282     case TYPE_ALU:
11283       if (operands[2] != const1_rtx)
11284         abort ();
11285       return "add{b}\t{%0, %0|%0, %0}";
11286
11287     default:
11288       if (REG_P (operands[2]))
11289         return "sal{b}\t{%b2, %0|%0, %b2}";
11290       else if (operands[2] == const1_rtx
11291                && (TARGET_SHIFT1 || optimize_size))
11292         return "sal{b}\t%0";
11293       else
11294         return "sal{b}\t{%2, %0|%0, %2}";
11295     }
11296 }
11297   [(set (attr "type")
11298      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11299                           (const_int 0))
11300                       (match_operand 0 "register_operand" ""))
11301                  (match_operand 2 "const1_operand" ""))
11302               (const_string "alu")
11303            ]
11304            (const_string "ishift")))
11305    (set_attr "mode" "QI")])
11306
11307 ;; See comment above `ashldi3' about how this works.
11308
11309 (define_expand "ashrdi3"
11310   [(set (match_operand:DI 0 "shiftdi_operand" "")
11311         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11312                      (match_operand:QI 2 "nonmemory_operand" "")))]
11313   ""
11314   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11315
11316 (define_insn "*ashrdi3_63_rex64"
11317   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11318         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11319                      (match_operand:DI 2 "const_int_operand" "i,i")))
11320    (clobber (reg:CC FLAGS_REG))]
11321   "TARGET_64BIT && INTVAL (operands[2]) == 63
11322    && (TARGET_USE_CLTD || optimize_size)
11323    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11324   "@
11325    {cqto|cqo}
11326    sar{q}\t{%2, %0|%0, %2}"
11327   [(set_attr "type" "imovx,ishift")
11328    (set_attr "prefix_0f" "0,*")
11329    (set_attr "length_immediate" "0,*")
11330    (set_attr "modrm" "0,1")
11331    (set_attr "mode" "DI")])
11332
11333 (define_insn "*ashrdi3_1_one_bit_rex64"
11334   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11335         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11336                      (match_operand:QI 2 "const1_operand" "")))
11337    (clobber (reg:CC FLAGS_REG))]
11338   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11339    && (TARGET_SHIFT1 || optimize_size)"
11340   "sar{q}\t%0"
11341   [(set_attr "type" "ishift")
11342    (set (attr "length") 
11343      (if_then_else (match_operand:DI 0 "register_operand" "") 
11344         (const_string "2")
11345         (const_string "*")))])
11346
11347 (define_insn "*ashrdi3_1_rex64"
11348   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11349         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11350                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11351    (clobber (reg:CC FLAGS_REG))]
11352   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "@
11354    sar{q}\t{%2, %0|%0, %2}
11355    sar{q}\t{%b2, %0|%0, %b2}"
11356   [(set_attr "type" "ishift")
11357    (set_attr "mode" "DI")])
11358
11359 ;; This pattern can't accept a variable shift count, since shifts by
11360 ;; zero don't affect the flags.  We assume that shifts by constant
11361 ;; zero are optimized away.
11362 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11363   [(set (reg 17)
11364         (compare
11365           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11366                        (match_operand:QI 2 "const1_operand" ""))
11367           (const_int 0)))
11368    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11369         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11370   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11371    && (TARGET_SHIFT1 || optimize_size)
11372    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11373   "sar{q}\t%0"
11374   [(set_attr "type" "ishift")
11375    (set (attr "length") 
11376      (if_then_else (match_operand:DI 0 "register_operand" "") 
11377         (const_string "2")
11378         (const_string "*")))])
11379
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags.  We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashrdi3_cmp_rex64"
11384   [(set (reg 17)
11385         (compare
11386           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387                        (match_operand:QI 2 "const_int_operand" "n"))
11388           (const_int 0)))
11389    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11391   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11393   "sar{q}\t{%2, %0|%0, %2}"
11394   [(set_attr "type" "ishift")
11395    (set_attr "mode" "DI")])
11396
11397 (define_insn "*ashrdi3_1"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11400                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "!TARGET_64BIT"
11403   "#"
11404   [(set_attr "type" "multi")])
11405
11406 ;; By default we don't ask for a scratch register, because when DImode
11407 ;; values are manipulated, registers are already at a premium.  But if
11408 ;; we have one handy, we won't turn it away.
11409 (define_peephole2
11410   [(match_scratch:SI 3 "r")
11411    (parallel [(set (match_operand:DI 0 "register_operand" "")
11412                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11413                                 (match_operand:QI 2 "nonmemory_operand" "")))
11414               (clobber (reg:CC FLAGS_REG))])
11415    (match_dup 3)]
11416   "!TARGET_64BIT && TARGET_CMOVE"
11417   [(const_int 0)]
11418   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11419
11420 (define_split
11421   [(set (match_operand:DI 0 "register_operand" "")
11422         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11423                      (match_operand:QI 2 "nonmemory_operand" "")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11426   [(const_int 0)]
11427   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11428
11429 (define_insn "x86_shrd_1"
11430   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11431         (ior:SI (ashiftrt:SI (match_dup 0)
11432                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11433                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11434                   (minus:QI (const_int 32) (match_dup 2)))))
11435    (clobber (reg:CC FLAGS_REG))]
11436   ""
11437   "@
11438    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11439    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11440   [(set_attr "type" "ishift")
11441    (set_attr "prefix_0f" "1")
11442    (set_attr "pent_pair" "np")
11443    (set_attr "mode" "SI")])
11444
11445 (define_expand "x86_shift_adj_3"
11446   [(use (match_operand:SI 0 "register_operand" ""))
11447    (use (match_operand:SI 1 "register_operand" ""))
11448    (use (match_operand:QI 2 "register_operand" ""))]
11449   ""
11450 {
11451   rtx label = gen_label_rtx ();
11452   rtx tmp;
11453
11454   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11455
11456   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11457   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11458   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11459                               gen_rtx_LABEL_REF (VOIDmode, label),
11460                               pc_rtx);
11461   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11462   JUMP_LABEL (tmp) = label;
11463
11464   emit_move_insn (operands[0], operands[1]);
11465   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11466
11467   emit_label (label);
11468   LABEL_NUSES (label) = 1;
11469
11470   DONE;
11471 })
11472
11473 (define_insn "ashrsi3_31"
11474   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11475         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11476                      (match_operand:SI 2 "const_int_operand" "i,i")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11479    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11480   "@
11481    {cltd|cdq}
11482    sar{l}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "imovx,ishift")
11484    (set_attr "prefix_0f" "0,*")
11485    (set_attr "length_immediate" "0,*")
11486    (set_attr "modrm" "0,1")
11487    (set_attr "mode" "SI")])
11488
11489 (define_insn "*ashrsi3_31_zext"
11490   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11491         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11492                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11493    (clobber (reg:CC FLAGS_REG))]
11494   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11495    && INTVAL (operands[2]) == 31
11496    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11497   "@
11498    {cltd|cdq}
11499    sar{l}\t{%2, %k0|%k0, %2}"
11500   [(set_attr "type" "imovx,ishift")
11501    (set_attr "prefix_0f" "0,*")
11502    (set_attr "length_immediate" "0,*")
11503    (set_attr "modrm" "0,1")
11504    (set_attr "mode" "SI")])
11505
11506 (define_expand "ashrsi3"
11507   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11508         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11509                      (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   ""
11512   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11513
11514 (define_insn "*ashrsi3_1_one_bit"
11515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11516         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11517                      (match_operand:QI 2 "const1_operand" "")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11520    && (TARGET_SHIFT1 || optimize_size)"
11521   "sar{l}\t%0"
11522   [(set_attr "type" "ishift")
11523    (set (attr "length") 
11524      (if_then_else (match_operand:SI 0 "register_operand" "") 
11525         (const_string "2")
11526         (const_string "*")))])
11527
11528 (define_insn "*ashrsi3_1_one_bit_zext"
11529   [(set (match_operand:DI 0 "register_operand" "=r")
11530         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11531                                      (match_operand:QI 2 "const1_operand" ""))))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11534    && (TARGET_SHIFT1 || optimize_size)"
11535   "sar{l}\t%k0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length" "2")])
11538
11539 (define_insn "*ashrsi3_1"
11540   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11541         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11542                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11545   "@
11546    sar{l}\t{%2, %0|%0, %2}
11547    sar{l}\t{%b2, %0|%0, %b2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "SI")])
11550
11551 (define_insn "*ashrsi3_1_zext"
11552   [(set (match_operand:DI 0 "register_operand" "=r,r")
11553         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11554                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11555    (clobber (reg:CC FLAGS_REG))]
11556   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557   "@
11558    sar{l}\t{%2, %k0|%k0, %2}
11559    sar{l}\t{%b2, %k0|%k0, %b2}"
11560   [(set_attr "type" "ishift")
11561    (set_attr "mode" "SI")])
11562
11563 ;; This pattern can't accept a variable shift count, since shifts by
11564 ;; zero don't affect the flags.  We assume that shifts by constant
11565 ;; zero are optimized away.
11566 (define_insn "*ashrsi3_one_bit_cmp"
11567   [(set (reg 17)
11568         (compare
11569           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11570                        (match_operand:QI 2 "const1_operand" ""))
11571           (const_int 0)))
11572    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11573         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11574   "ix86_match_ccmode (insn, CCGOCmode)
11575    && (TARGET_SHIFT1 || optimize_size)
11576    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11577   "sar{l}\t%0"
11578   [(set_attr "type" "ishift")
11579    (set (attr "length") 
11580      (if_then_else (match_operand:SI 0 "register_operand" "") 
11581         (const_string "2")
11582         (const_string "*")))])
11583
11584 (define_insn "*ashrsi3_one_bit_cmp_zext"
11585   [(set (reg 17)
11586         (compare
11587           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11588                        (match_operand:QI 2 "const1_operand" ""))
11589           (const_int 0)))
11590    (set (match_operand:DI 0 "register_operand" "=r")
11591         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11592   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11593    && (TARGET_SHIFT1 || optimize_size)
11594    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11595   "sar{l}\t%k0"
11596   [(set_attr "type" "ishift")
11597    (set_attr "length" "2")])
11598
11599 ;; This pattern can't accept a variable shift count, since shifts by
11600 ;; zero don't affect the flags.  We assume that shifts by constant
11601 ;; zero are optimized away.
11602 (define_insn "*ashrsi3_cmp"
11603   [(set (reg 17)
11604         (compare
11605           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11606                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11607           (const_int 0)))
11608    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11609         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11610   "ix86_match_ccmode (insn, CCGOCmode)
11611    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11612   "sar{l}\t{%2, %0|%0, %2}"
11613   [(set_attr "type" "ishift")
11614    (set_attr "mode" "SI")])
11615
11616 (define_insn "*ashrsi3_cmp_zext"
11617   [(set (reg 17)
11618         (compare
11619           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11620                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11621           (const_int 0)))
11622    (set (match_operand:DI 0 "register_operand" "=r")
11623         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11624   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11625    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11626   "sar{l}\t{%2, %k0|%k0, %2}"
11627   [(set_attr "type" "ishift")
11628    (set_attr "mode" "SI")])
11629
11630 (define_expand "ashrhi3"
11631   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11632         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11633                      (match_operand:QI 2 "nonmemory_operand" "")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "TARGET_HIMODE_MATH"
11636   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11637
11638 (define_insn "*ashrhi3_1_one_bit"
11639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11640         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11641                      (match_operand:QI 2 "const1_operand" "")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11644    && (TARGET_SHIFT1 || optimize_size)"
11645   "sar{w}\t%0"
11646   [(set_attr "type" "ishift")
11647    (set (attr "length") 
11648      (if_then_else (match_operand 0 "register_operand" "") 
11649         (const_string "2")
11650         (const_string "*")))])
11651
11652 (define_insn "*ashrhi3_1"
11653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11654         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11655                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11658   "@
11659    sar{w}\t{%2, %0|%0, %2}
11660    sar{w}\t{%b2, %0|%0, %b2}"
11661   [(set_attr "type" "ishift")
11662    (set_attr "mode" "HI")])
11663
11664 ;; This pattern can't accept a variable shift count, since shifts by
11665 ;; zero don't affect the flags.  We assume that shifts by constant
11666 ;; zero are optimized away.
11667 (define_insn "*ashrhi3_one_bit_cmp"
11668   [(set (reg 17)
11669         (compare
11670           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11671                        (match_operand:QI 2 "const1_operand" ""))
11672           (const_int 0)))
11673    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11674         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11675   "ix86_match_ccmode (insn, CCGOCmode)
11676    && (TARGET_SHIFT1 || optimize_size)
11677    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11678   "sar{w}\t%0"
11679   [(set_attr "type" "ishift")
11680    (set (attr "length") 
11681      (if_then_else (match_operand 0 "register_operand" "") 
11682         (const_string "2")
11683         (const_string "*")))])
11684
11685 ;; This pattern can't accept a variable shift count, since shifts by
11686 ;; zero don't affect the flags.  We assume that shifts by constant
11687 ;; zero are optimized away.
11688 (define_insn "*ashrhi3_cmp"
11689   [(set (reg 17)
11690         (compare
11691           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11692                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11693           (const_int 0)))
11694    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11695         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11696   "ix86_match_ccmode (insn, CCGOCmode)
11697    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11698   "sar{w}\t{%2, %0|%0, %2}"
11699   [(set_attr "type" "ishift")
11700    (set_attr "mode" "HI")])
11701
11702 (define_expand "ashrqi3"
11703   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11704         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11705                      (match_operand:QI 2 "nonmemory_operand" "")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "TARGET_QIMODE_MATH"
11708   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11709
11710 (define_insn "*ashrqi3_1_one_bit"
11711   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11712         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11713                      (match_operand:QI 2 "const1_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11716    && (TARGET_SHIFT1 || optimize_size)"
11717   "sar{b}\t%0"
11718   [(set_attr "type" "ishift")
11719    (set (attr "length") 
11720      (if_then_else (match_operand 0 "register_operand" "") 
11721         (const_string "2")
11722         (const_string "*")))])
11723
11724 (define_insn "*ashrqi3_1_one_bit_slp"
11725   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11726         (ashiftrt:QI (match_dup 0)
11727                      (match_operand:QI 1 "const1_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11730    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11731    && (TARGET_SHIFT1 || optimize_size)"
11732   "sar{b}\t%0"
11733   [(set_attr "type" "ishift1")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 (define_insn "*ashrqi3_1"
11740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11741         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11742                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11745   "@
11746    sar{b}\t{%2, %0|%0, %2}
11747    sar{b}\t{%b2, %0|%0, %b2}"
11748   [(set_attr "type" "ishift")
11749    (set_attr "mode" "QI")])
11750
11751 (define_insn "*ashrqi3_1_slp"
11752   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11753         (ashiftrt:QI (match_dup 0)
11754                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11758   "@
11759    sar{b}\t{%1, %0|%0, %1}
11760    sar{b}\t{%b1, %0|%0, %b1}"
11761   [(set_attr "type" "ishift1")
11762    (set_attr "mode" "QI")])
11763
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags.  We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*ashrqi3_one_bit_cmp"
11768   [(set (reg 17)
11769         (compare
11770           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771                        (match_operand:QI 2 "const1_operand" "I"))
11772           (const_int 0)))
11773    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11775   "ix86_match_ccmode (insn, CCGOCmode)
11776    && (TARGET_SHIFT1 || optimize_size)
11777    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11778   "sar{b}\t%0"
11779   [(set_attr "type" "ishift")
11780    (set (attr "length") 
11781      (if_then_else (match_operand 0 "register_operand" "") 
11782         (const_string "2")
11783         (const_string "*")))])
11784
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags.  We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashrqi3_cmp"
11789   [(set (reg 17)
11790         (compare
11791           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11792                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11793           (const_int 0)))
11794    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11795         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11796   "ix86_match_ccmode (insn, CCGOCmode)
11797    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11798   "sar{b}\t{%2, %0|%0, %2}"
11799   [(set_attr "type" "ishift")
11800    (set_attr "mode" "QI")])
11801 \f
11802 ;; Logical shift instructions
11803
11804 ;; See comment above `ashldi3' about how this works.
11805
11806 (define_expand "lshrdi3"
11807   [(set (match_operand:DI 0 "shiftdi_operand" "")
11808         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11809                      (match_operand:QI 2 "nonmemory_operand" "")))]
11810   ""
11811   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11812
11813 (define_insn "*lshrdi3_1_one_bit_rex64"
11814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11815         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11816                      (match_operand:QI 2 "const1_operand" "")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11819    && (TARGET_SHIFT1 || optimize_size)"
11820   "shr{q}\t%0"
11821   [(set_attr "type" "ishift")
11822    (set (attr "length") 
11823      (if_then_else (match_operand:DI 0 "register_operand" "") 
11824         (const_string "2")
11825         (const_string "*")))])
11826
11827 (define_insn "*lshrdi3_1_rex64"
11828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11829         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11833   "@
11834    shr{q}\t{%2, %0|%0, %2}
11835    shr{q}\t{%b2, %0|%0, %b2}"
11836   [(set_attr "type" "ishift")
11837    (set_attr "mode" "DI")])
11838
11839 ;; This pattern can't accept a variable shift count, since shifts by
11840 ;; zero don't affect the flags.  We assume that shifts by constant
11841 ;; zero are optimized away.
11842 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11843   [(set (reg 17)
11844         (compare
11845           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11846                        (match_operand:QI 2 "const1_operand" ""))
11847           (const_int 0)))
11848    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11849         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11850   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11851    && (TARGET_SHIFT1 || optimize_size)
11852    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11853   "shr{q}\t%0"
11854   [(set_attr "type" "ishift")
11855    (set (attr "length") 
11856      (if_then_else (match_operand:DI 0 "register_operand" "") 
11857         (const_string "2")
11858         (const_string "*")))])
11859
11860 ;; This pattern can't accept a variable shift count, since shifts by
11861 ;; zero don't affect the flags.  We assume that shifts by constant
11862 ;; zero are optimized away.
11863 (define_insn "*lshrdi3_cmp_rex64"
11864   [(set (reg 17)
11865         (compare
11866           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11867                        (match_operand:QI 2 "const_int_operand" "e"))
11868           (const_int 0)))
11869    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11870         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11871   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11872    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873   "shr{q}\t{%2, %0|%0, %2}"
11874   [(set_attr "type" "ishift")
11875    (set_attr "mode" "DI")])
11876
11877 (define_insn "*lshrdi3_1"
11878   [(set (match_operand:DI 0 "register_operand" "=r")
11879         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11880                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "!TARGET_64BIT"
11883   "#"
11884   [(set_attr "type" "multi")])
11885
11886 ;; By default we don't ask for a scratch register, because when DImode
11887 ;; values are manipulated, registers are already at a premium.  But if
11888 ;; we have one handy, we won't turn it away.
11889 (define_peephole2
11890   [(match_scratch:SI 3 "r")
11891    (parallel [(set (match_operand:DI 0 "register_operand" "")
11892                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11893                                 (match_operand:QI 2 "nonmemory_operand" "")))
11894               (clobber (reg:CC FLAGS_REG))])
11895    (match_dup 3)]
11896   "!TARGET_64BIT && TARGET_CMOVE"
11897   [(const_int 0)]
11898   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11899
11900 (define_split 
11901   [(set (match_operand:DI 0 "register_operand" "")
11902         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11903                      (match_operand:QI 2 "nonmemory_operand" "")))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11906   [(const_int 0)]
11907   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11908
11909 (define_expand "lshrsi3"
11910   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11911         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11912                      (match_operand:QI 2 "nonmemory_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   ""
11915   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11916
11917 (define_insn "*lshrsi3_1_one_bit"
11918   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11919         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11920                      (match_operand:QI 2 "const1_operand" "")))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11923    && (TARGET_SHIFT1 || optimize_size)"
11924   "shr{l}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set (attr "length") 
11927      (if_then_else (match_operand:SI 0 "register_operand" "") 
11928         (const_string "2")
11929         (const_string "*")))])
11930
11931 (define_insn "*lshrsi3_1_one_bit_zext"
11932   [(set (match_operand:DI 0 "register_operand" "=r")
11933         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11934                      (match_operand:QI 2 "const1_operand" "")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11937    && (TARGET_SHIFT1 || optimize_size)"
11938   "shr{l}\t%k0"
11939   [(set_attr "type" "ishift")
11940    (set_attr "length" "2")])
11941
11942 (define_insn "*lshrsi3_1"
11943   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11944         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11945                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11948   "@
11949    shr{l}\t{%2, %0|%0, %2}
11950    shr{l}\t{%b2, %0|%0, %b2}"
11951   [(set_attr "type" "ishift")
11952    (set_attr "mode" "SI")])
11953
11954 (define_insn "*lshrsi3_1_zext"
11955   [(set (match_operand:DI 0 "register_operand" "=r,r")
11956         (zero_extend:DI
11957           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11958                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11961   "@
11962    shr{l}\t{%2, %k0|%k0, %2}
11963    shr{l}\t{%b2, %k0|%k0, %b2}"
11964   [(set_attr "type" "ishift")
11965    (set_attr "mode" "SI")])
11966
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags.  We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*lshrsi3_one_bit_cmp"
11971   [(set (reg 17)
11972         (compare
11973           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const1_operand" ""))
11975           (const_int 0)))
11976    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11978   "ix86_match_ccmode (insn, CCGOCmode)
11979    && (TARGET_SHIFT1 || optimize_size)
11980    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11981   "shr{l}\t%0"
11982   [(set_attr "type" "ishift")
11983    (set (attr "length") 
11984      (if_then_else (match_operand:SI 0 "register_operand" "") 
11985         (const_string "2")
11986         (const_string "*")))])
11987
11988 (define_insn "*lshrsi3_cmp_one_bit_zext"
11989   [(set (reg 17)
11990         (compare
11991           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11992                        (match_operand:QI 2 "const1_operand" ""))
11993           (const_int 0)))
11994    (set (match_operand:DI 0 "register_operand" "=r")
11995         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11996   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11997    && (TARGET_SHIFT1 || optimize_size)
11998    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11999   "shr{l}\t%k0"
12000   [(set_attr "type" "ishift")
12001    (set_attr "length" "2")])
12002
12003 ;; This pattern can't accept a variable shift count, since shifts by
12004 ;; zero don't affect the flags.  We assume that shifts by constant
12005 ;; zero are optimized away.
12006 (define_insn "*lshrsi3_cmp"
12007   [(set (reg 17)
12008         (compare
12009           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12010                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12011           (const_int 0)))
12012    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12013         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12014   "ix86_match_ccmode (insn, CCGOCmode)
12015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12016   "shr{l}\t{%2, %0|%0, %2}"
12017   [(set_attr "type" "ishift")
12018    (set_attr "mode" "SI")])
12019
12020 (define_insn "*lshrsi3_cmp_zext"
12021   [(set (reg 17)
12022         (compare
12023           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12024                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12025           (const_int 0)))
12026    (set (match_operand:DI 0 "register_operand" "=r")
12027         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12028   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12029    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12030   "shr{l}\t{%2, %k0|%k0, %2}"
12031   [(set_attr "type" "ishift")
12032    (set_attr "mode" "SI")])
12033
12034 (define_expand "lshrhi3"
12035   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12036         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12037                      (match_operand:QI 2 "nonmemory_operand" "")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "TARGET_HIMODE_MATH"
12040   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12041
12042 (define_insn "*lshrhi3_1_one_bit"
12043   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12044         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12045                      (match_operand:QI 2 "const1_operand" "")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12048    && (TARGET_SHIFT1 || optimize_size)"
12049   "shr{w}\t%0"
12050   [(set_attr "type" "ishift")
12051    (set (attr "length") 
12052      (if_then_else (match_operand 0 "register_operand" "") 
12053         (const_string "2")
12054         (const_string "*")))])
12055
12056 (define_insn "*lshrhi3_1"
12057   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12058         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12059                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12060    (clobber (reg:CC FLAGS_REG))]
12061   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12062   "@
12063    shr{w}\t{%2, %0|%0, %2}
12064    shr{w}\t{%b2, %0|%0, %b2}"
12065   [(set_attr "type" "ishift")
12066    (set_attr "mode" "HI")])
12067
12068 ;; This pattern can't accept a variable shift count, since shifts by
12069 ;; zero don't affect the flags.  We assume that shifts by constant
12070 ;; zero are optimized away.
12071 (define_insn "*lshrhi3_one_bit_cmp"
12072   [(set (reg 17)
12073         (compare
12074           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12075                        (match_operand:QI 2 "const1_operand" ""))
12076           (const_int 0)))
12077    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12078         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12079   "ix86_match_ccmode (insn, CCGOCmode)
12080    && (TARGET_SHIFT1 || optimize_size)
12081    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12082   "shr{w}\t%0"
12083   [(set_attr "type" "ishift")
12084    (set (attr "length") 
12085      (if_then_else (match_operand:SI 0 "register_operand" "") 
12086         (const_string "2")
12087         (const_string "*")))])
12088
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags.  We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrhi3_cmp"
12093   [(set (reg 17)
12094         (compare
12095           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12096                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12097           (const_int 0)))
12098    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12099         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12100   "ix86_match_ccmode (insn, CCGOCmode)
12101    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102   "shr{w}\t{%2, %0|%0, %2}"
12103   [(set_attr "type" "ishift")
12104    (set_attr "mode" "HI")])
12105
12106 (define_expand "lshrqi3"
12107   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12108         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12109                      (match_operand:QI 2 "nonmemory_operand" "")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_QIMODE_MATH"
12112   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12113
12114 (define_insn "*lshrqi3_1_one_bit"
12115   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12116         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12117                      (match_operand:QI 2 "const1_operand" "")))
12118    (clobber (reg:CC FLAGS_REG))]
12119   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12120    && (TARGET_SHIFT1 || optimize_size)"
12121   "shr{b}\t%0"
12122   [(set_attr "type" "ishift")
12123    (set (attr "length") 
12124      (if_then_else (match_operand 0 "register_operand" "") 
12125         (const_string "2")
12126         (const_string "*")))])
12127
12128 (define_insn "*lshrqi3_1_one_bit_slp"
12129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12130         (lshiftrt:QI (match_dup 0)
12131                      (match_operand:QI 1 "const1_operand" "")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12134    && (TARGET_SHIFT1 || optimize_size)"
12135   "shr{b}\t%0"
12136   [(set_attr "type" "ishift1")
12137    (set (attr "length") 
12138      (if_then_else (match_operand 0 "register_operand" "") 
12139         (const_string "2")
12140         (const_string "*")))])
12141
12142 (define_insn "*lshrqi3_1"
12143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12144         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12145                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12148   "@
12149    shr{b}\t{%2, %0|%0, %2}
12150    shr{b}\t{%b2, %0|%0, %b2}"
12151   [(set_attr "type" "ishift")
12152    (set_attr "mode" "QI")])
12153
12154 (define_insn "*lshrqi3_1_slp"
12155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12156         (lshiftrt:QI (match_dup 0)
12157                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12158    (clobber (reg:CC FLAGS_REG))]
12159   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12161   "@
12162    shr{b}\t{%1, %0|%0, %1}
12163    shr{b}\t{%b1, %0|%0, %b1}"
12164   [(set_attr "type" "ishift1")
12165    (set_attr "mode" "QI")])
12166
12167 ;; This pattern can't accept a variable shift count, since shifts by
12168 ;; zero don't affect the flags.  We assume that shifts by constant
12169 ;; zero are optimized away.
12170 (define_insn "*lshrqi2_one_bit_cmp"
12171   [(set (reg 17)
12172         (compare
12173           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12174                        (match_operand:QI 2 "const1_operand" ""))
12175           (const_int 0)))
12176    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12177         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12178   "ix86_match_ccmode (insn, CCGOCmode)
12179    && (TARGET_SHIFT1 || optimize_size)
12180    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12181   "shr{b}\t%0"
12182   [(set_attr "type" "ishift")
12183    (set (attr "length") 
12184      (if_then_else (match_operand:SI 0 "register_operand" "") 
12185         (const_string "2")
12186         (const_string "*")))])
12187
12188 ;; This pattern can't accept a variable shift count, since shifts by
12189 ;; zero don't affect the flags.  We assume that shifts by constant
12190 ;; zero are optimized away.
12191 (define_insn "*lshrqi2_cmp"
12192   [(set (reg 17)
12193         (compare
12194           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12195                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12196           (const_int 0)))
12197    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12198         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12199   "ix86_match_ccmode (insn, CCGOCmode)
12200    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12201   "shr{b}\t{%2, %0|%0, %2}"
12202   [(set_attr "type" "ishift")
12203    (set_attr "mode" "QI")])
12204 \f
12205 ;; Rotate instructions
12206
12207 (define_expand "rotldi3"
12208   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12209         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12210                    (match_operand:QI 2 "nonmemory_operand" "")))
12211    (clobber (reg:CC FLAGS_REG))]
12212   "TARGET_64BIT"
12213   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12214
12215 (define_insn "*rotlsi3_1_one_bit_rex64"
12216   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12218                    (match_operand:QI 2 "const1_operand" "")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12221    && (TARGET_SHIFT1 || optimize_size)"
12222   "rol{q}\t%0"
12223   [(set_attr "type" "rotate")
12224    (set (attr "length") 
12225      (if_then_else (match_operand:DI 0 "register_operand" "") 
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*rotldi3_1_rex64"
12230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12231         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12232                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12235   "@
12236    rol{q}\t{%2, %0|%0, %2}
12237    rol{q}\t{%b2, %0|%0, %b2}"
12238   [(set_attr "type" "rotate")
12239    (set_attr "mode" "DI")])
12240
12241 (define_expand "rotlsi3"
12242   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12243         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12244                    (match_operand:QI 2 "nonmemory_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   ""
12247   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12248
12249 (define_insn "*rotlsi3_1_one_bit"
12250   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12251         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252                    (match_operand:QI 2 "const1_operand" "")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12255    && (TARGET_SHIFT1 || optimize_size)"
12256   "rol{l}\t%0"
12257   [(set_attr "type" "rotate")
12258    (set (attr "length") 
12259      (if_then_else (match_operand:SI 0 "register_operand" "") 
12260         (const_string "2")
12261         (const_string "*")))])
12262
12263 (define_insn "*rotlsi3_1_one_bit_zext"
12264   [(set (match_operand:DI 0 "register_operand" "=r")
12265         (zero_extend:DI
12266           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12267                      (match_operand:QI 2 "const1_operand" ""))))
12268    (clobber (reg:CC FLAGS_REG))]
12269   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12270    && (TARGET_SHIFT1 || optimize_size)"
12271   "rol{l}\t%k0"
12272   [(set_attr "type" "rotate")
12273    (set_attr "length" "2")])
12274
12275 (define_insn "*rotlsi3_1"
12276   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12277         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12278                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12279    (clobber (reg:CC FLAGS_REG))]
12280   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12281   "@
12282    rol{l}\t{%2, %0|%0, %2}
12283    rol{l}\t{%b2, %0|%0, %b2}"
12284   [(set_attr "type" "rotate")
12285    (set_attr "mode" "SI")])
12286
12287 (define_insn "*rotlsi3_1_zext"
12288   [(set (match_operand:DI 0 "register_operand" "=r,r")
12289         (zero_extend:DI
12290           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12291                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12294   "@
12295    rol{l}\t{%2, %k0|%k0, %2}
12296    rol{l}\t{%b2, %k0|%k0, %b2}"
12297   [(set_attr "type" "rotate")
12298    (set_attr "mode" "SI")])
12299
12300 (define_expand "rotlhi3"
12301   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12302         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12303                    (match_operand:QI 2 "nonmemory_operand" "")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_HIMODE_MATH"
12306   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12307
12308 (define_insn "*rotlhi3_1_one_bit"
12309   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12310         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311                    (match_operand:QI 2 "const1_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12314    && (TARGET_SHIFT1 || optimize_size)"
12315   "rol{w}\t%0"
12316   [(set_attr "type" "rotate")
12317    (set (attr "length") 
12318      (if_then_else (match_operand 0 "register_operand" "") 
12319         (const_string "2")
12320         (const_string "*")))])
12321
12322 (define_insn "*rotlhi3_1"
12323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12324         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12325                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12326    (clobber (reg:CC FLAGS_REG))]
12327   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12328   "@
12329    rol{w}\t{%2, %0|%0, %2}
12330    rol{w}\t{%b2, %0|%0, %b2}"
12331   [(set_attr "type" "rotate")
12332    (set_attr "mode" "HI")])
12333
12334 (define_expand "rotlqi3"
12335   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12336         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12337                    (match_operand:QI 2 "nonmemory_operand" "")))
12338    (clobber (reg:CC FLAGS_REG))]
12339   "TARGET_QIMODE_MATH"
12340   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12341
12342 (define_insn "*rotlqi3_1_one_bit_slp"
12343   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12344         (rotate:QI (match_dup 0)
12345                    (match_operand:QI 1 "const1_operand" "")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12348    && (TARGET_SHIFT1 || optimize_size)"
12349   "rol{b}\t%0"
12350   [(set_attr "type" "rotate1")
12351    (set (attr "length") 
12352      (if_then_else (match_operand 0 "register_operand" "") 
12353         (const_string "2")
12354         (const_string "*")))])
12355
12356 (define_insn "*rotlqi3_1_one_bit"
12357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12358         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12359                    (match_operand:QI 2 "const1_operand" "")))
12360    (clobber (reg:CC FLAGS_REG))]
12361   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12362    && (TARGET_SHIFT1 || optimize_size)"
12363   "rol{b}\t%0"
12364   [(set_attr "type" "rotate")
12365    (set (attr "length") 
12366      (if_then_else (match_operand 0 "register_operand" "") 
12367         (const_string "2")
12368         (const_string "*")))])
12369
12370 (define_insn "*rotlqi3_1_slp"
12371   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12372         (rotate:QI (match_dup 0)
12373                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12376    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12377   "@
12378    rol{b}\t{%1, %0|%0, %1}
12379    rol{b}\t{%b1, %0|%0, %b1}"
12380   [(set_attr "type" "rotate1")
12381    (set_attr "mode" "QI")])
12382
12383 (define_insn "*rotlqi3_1"
12384   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12385         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12386                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12389   "@
12390    rol{b}\t{%2, %0|%0, %2}
12391    rol{b}\t{%b2, %0|%0, %b2}"
12392   [(set_attr "type" "rotate")
12393    (set_attr "mode" "QI")])
12394
12395 (define_expand "rotrdi3"
12396   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12397         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "TARGET_64BIT"
12401   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12402
12403 (define_insn "*rotrdi3_1_one_bit_rex64"
12404   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12405         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12406                      (match_operand:QI 2 "const1_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12409    && (TARGET_SHIFT1 || optimize_size)"
12410   "ror{q}\t%0"
12411   [(set_attr "type" "rotate")
12412    (set (attr "length") 
12413      (if_then_else (match_operand:DI 0 "register_operand" "") 
12414         (const_string "2")
12415         (const_string "*")))])
12416
12417 (define_insn "*rotrdi3_1_rex64"
12418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12419         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12420                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12423   "@
12424    ror{q}\t{%2, %0|%0, %2}
12425    ror{q}\t{%b2, %0|%0, %b2}"
12426   [(set_attr "type" "rotate")
12427    (set_attr "mode" "DI")])
12428
12429 (define_expand "rotrsi3"
12430   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12431         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12432                      (match_operand:QI 2 "nonmemory_operand" "")))
12433    (clobber (reg:CC FLAGS_REG))]
12434   ""
12435   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12436
12437 (define_insn "*rotrsi3_1_one_bit"
12438   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12439         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12440                      (match_operand:QI 2 "const1_operand" "")))
12441    (clobber (reg:CC FLAGS_REG))]
12442   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12443    && (TARGET_SHIFT1 || optimize_size)"
12444   "ror{l}\t%0"
12445   [(set_attr "type" "rotate")
12446    (set (attr "length") 
12447      (if_then_else (match_operand:SI 0 "register_operand" "") 
12448         (const_string "2")
12449         (const_string "*")))])
12450
12451 (define_insn "*rotrsi3_1_one_bit_zext"
12452   [(set (match_operand:DI 0 "register_operand" "=r")
12453         (zero_extend:DI
12454           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12455                        (match_operand:QI 2 "const1_operand" ""))))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12458    && (TARGET_SHIFT1 || optimize_size)"
12459   "ror{l}\t%k0"
12460   [(set_attr "type" "rotate")
12461    (set (attr "length") 
12462      (if_then_else (match_operand:SI 0 "register_operand" "") 
12463         (const_string "2")
12464         (const_string "*")))])
12465
12466 (define_insn "*rotrsi3_1"
12467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12468         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12469                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12472   "@
12473    ror{l}\t{%2, %0|%0, %2}
12474    ror{l}\t{%b2, %0|%0, %b2}"
12475   [(set_attr "type" "rotate")
12476    (set_attr "mode" "SI")])
12477
12478 (define_insn "*rotrsi3_1_zext"
12479   [(set (match_operand:DI 0 "register_operand" "=r,r")
12480         (zero_extend:DI
12481           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12482                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12485   "@
12486    ror{l}\t{%2, %k0|%k0, %2}
12487    ror{l}\t{%b2, %k0|%k0, %b2}"
12488   [(set_attr "type" "rotate")
12489    (set_attr "mode" "SI")])
12490
12491 (define_expand "rotrhi3"
12492   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12493         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12494                      (match_operand:QI 2 "nonmemory_operand" "")))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "TARGET_HIMODE_MATH"
12497   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12498
12499 (define_insn "*rotrhi3_one_bit"
12500   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12501         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12502                      (match_operand:QI 2 "const1_operand" "")))
12503    (clobber (reg:CC FLAGS_REG))]
12504   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12505    && (TARGET_SHIFT1 || optimize_size)"
12506   "ror{w}\t%0"
12507   [(set_attr "type" "rotate")
12508    (set (attr "length") 
12509      (if_then_else (match_operand 0 "register_operand" "") 
12510         (const_string "2")
12511         (const_string "*")))])
12512
12513 (define_insn "*rotrhi3"
12514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12515         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12516                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12517    (clobber (reg:CC FLAGS_REG))]
12518   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12519   "@
12520    ror{w}\t{%2, %0|%0, %2}
12521    ror{w}\t{%b2, %0|%0, %b2}"
12522   [(set_attr "type" "rotate")
12523    (set_attr "mode" "HI")])
12524
12525 (define_expand "rotrqi3"
12526   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12527         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12528                      (match_operand:QI 2 "nonmemory_operand" "")))
12529    (clobber (reg:CC FLAGS_REG))]
12530   "TARGET_QIMODE_MATH"
12531   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12532
12533 (define_insn "*rotrqi3_1_one_bit"
12534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12535         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536                      (match_operand:QI 2 "const1_operand" "")))
12537    (clobber (reg:CC FLAGS_REG))]
12538   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12539    && (TARGET_SHIFT1 || optimize_size)"
12540   "ror{b}\t%0"
12541   [(set_attr "type" "rotate")
12542    (set (attr "length") 
12543      (if_then_else (match_operand 0 "register_operand" "") 
12544         (const_string "2")
12545         (const_string "*")))])
12546
12547 (define_insn "*rotrqi3_1_one_bit_slp"
12548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12549         (rotatert:QI (match_dup 0)
12550                      (match_operand:QI 1 "const1_operand" "")))
12551    (clobber (reg:CC FLAGS_REG))]
12552   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12553    && (TARGET_SHIFT1 || optimize_size)"
12554   "ror{b}\t%0"
12555   [(set_attr "type" "rotate1")
12556    (set (attr "length") 
12557      (if_then_else (match_operand 0 "register_operand" "") 
12558         (const_string "2")
12559         (const_string "*")))])
12560
12561 (define_insn "*rotrqi3_1"
12562   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12563         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12564                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12565    (clobber (reg:CC FLAGS_REG))]
12566   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12567   "@
12568    ror{b}\t{%2, %0|%0, %2}
12569    ror{b}\t{%b2, %0|%0, %b2}"
12570   [(set_attr "type" "rotate")
12571    (set_attr "mode" "QI")])
12572
12573 (define_insn "*rotrqi3_1_slp"
12574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12575         (rotatert:QI (match_dup 0)
12576                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12580   "@
12581    ror{b}\t{%1, %0|%0, %1}
12582    ror{b}\t{%b1, %0|%0, %b1}"
12583   [(set_attr "type" "rotate1")
12584    (set_attr "mode" "QI")])
12585 \f
12586 ;; Bit set / bit test instructions
12587
12588 (define_expand "extv"
12589   [(set (match_operand:SI 0 "register_operand" "")
12590         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12591                          (match_operand:SI 2 "immediate_operand" "")
12592                          (match_operand:SI 3 "immediate_operand" "")))]
12593   ""
12594 {
12595   /* Handle extractions from %ah et al.  */
12596   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12597     FAIL;
12598
12599   /* From mips.md: extract_bit_field doesn't verify that our source
12600      matches the predicate, so check it again here.  */
12601   if (! register_operand (operands[1], VOIDmode))
12602     FAIL;
12603 })
12604
12605 (define_expand "extzv"
12606   [(set (match_operand:SI 0 "register_operand" "")
12607         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12608                          (match_operand:SI 2 "immediate_operand" "")
12609                          (match_operand:SI 3 "immediate_operand" "")))]
12610   ""
12611 {
12612   /* Handle extractions from %ah et al.  */
12613   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12614     FAIL;
12615
12616   /* From mips.md: extract_bit_field doesn't verify that our source
12617      matches the predicate, so check it again here.  */
12618   if (! register_operand (operands[1], VOIDmode))
12619     FAIL;
12620 })
12621
12622 (define_expand "insv"
12623   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12624                       (match_operand 1 "immediate_operand" "")
12625                       (match_operand 2 "immediate_operand" ""))
12626         (match_operand 3 "register_operand" ""))]
12627   ""
12628 {
12629   /* Handle extractions from %ah et al.  */
12630   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12631     FAIL;
12632
12633   /* From mips.md: insert_bit_field doesn't verify that our source
12634      matches the predicate, so check it again here.  */
12635   if (! register_operand (operands[0], VOIDmode))
12636     FAIL;
12637
12638   if (TARGET_64BIT)
12639     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12640   else
12641     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12642
12643   DONE;
12644 })
12645
12646 ;; %%% bts, btr, btc, bt.
12647 \f
12648 ;; Store-flag instructions.
12649
12650 ;; For all sCOND expanders, also expand the compare or test insn that
12651 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12652
12653 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12654 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12655 ;; way, which can later delete the movzx if only QImode is needed.
12656
12657 (define_expand "seq"
12658   [(set (match_operand:QI 0 "register_operand" "")
12659         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12660   ""
12661   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12662
12663 (define_expand "sne"
12664   [(set (match_operand:QI 0 "register_operand" "")
12665         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12666   ""
12667   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12668
12669 (define_expand "sgt"
12670   [(set (match_operand:QI 0 "register_operand" "")
12671         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12672   ""
12673   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12674
12675 (define_expand "sgtu"
12676   [(set (match_operand:QI 0 "register_operand" "")
12677         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12678   ""
12679   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "slt"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sltu"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sge"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sgeu"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sle"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sleu"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sunordered"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   "TARGET_80387 || TARGET_SSE"
12721   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sordered"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   "TARGET_80387"
12727   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "suneq"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   "TARGET_80387 || TARGET_SSE"
12733   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sunge"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   "TARGET_80387 || TARGET_SSE"
12739   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sungt"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387 || TARGET_SSE"
12745   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "sunle"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387 || TARGET_SSE"
12751   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "sunlt"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sltgt"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12764
12765 (define_insn "*setcc_1"
12766   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12767         (match_operator:QI 1 "ix86_comparison_operator"
12768           [(reg 17) (const_int 0)]))]
12769   ""
12770   "set%C1\t%0"
12771   [(set_attr "type" "setcc")
12772    (set_attr "mode" "QI")])
12773
12774 (define_insn "*setcc_2"
12775   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12776         (match_operator:QI 1 "ix86_comparison_operator"
12777           [(reg 17) (const_int 0)]))]
12778   ""
12779   "set%C1\t%0"
12780   [(set_attr "type" "setcc")
12781    (set_attr "mode" "QI")])
12782
12783 ;; In general it is not safe to assume too much about CCmode registers,
12784 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12785 ;; conditions this is safe on x86, so help combine not create
12786 ;;
12787 ;;      seta    %al
12788 ;;      testb   %al, %al
12789 ;;      sete    %al
12790
12791 (define_split 
12792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12793         (ne:QI (match_operator 1 "ix86_comparison_operator"
12794                  [(reg 17) (const_int 0)])
12795             (const_int 0)))]
12796   ""
12797   [(set (match_dup 0) (match_dup 1))]
12798 {
12799   PUT_MODE (operands[1], QImode);
12800 })
12801
12802 (define_split 
12803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12804         (ne:QI (match_operator 1 "ix86_comparison_operator"
12805                  [(reg 17) (const_int 0)])
12806             (const_int 0)))]
12807   ""
12808   [(set (match_dup 0) (match_dup 1))]
12809 {
12810   PUT_MODE (operands[1], QImode);
12811 })
12812
12813 (define_split 
12814   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12815         (eq:QI (match_operator 1 "ix86_comparison_operator"
12816                  [(reg 17) (const_int 0)])
12817             (const_int 0)))]
12818   ""
12819   [(set (match_dup 0) (match_dup 1))]
12820 {
12821   rtx new_op1 = copy_rtx (operands[1]);
12822   operands[1] = new_op1;
12823   PUT_MODE (new_op1, QImode);
12824   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12825                                              GET_MODE (XEXP (new_op1, 0))));
12826
12827   /* Make sure that (a) the CCmode we have for the flags is strong
12828      enough for the reversed compare or (b) we have a valid FP compare.  */
12829   if (! ix86_comparison_operator (new_op1, VOIDmode))
12830     FAIL;
12831 })
12832
12833 (define_split 
12834   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12835         (eq:QI (match_operator 1 "ix86_comparison_operator"
12836                  [(reg 17) (const_int 0)])
12837             (const_int 0)))]
12838   ""
12839   [(set (match_dup 0) (match_dup 1))]
12840 {
12841   rtx new_op1 = copy_rtx (operands[1]);
12842   operands[1] = new_op1;
12843   PUT_MODE (new_op1, QImode);
12844   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12845                                              GET_MODE (XEXP (new_op1, 0))));
12846
12847   /* Make sure that (a) the CCmode we have for the flags is strong
12848      enough for the reversed compare or (b) we have a valid FP compare.  */
12849   if (! ix86_comparison_operator (new_op1, VOIDmode))
12850     FAIL;
12851 })
12852
12853 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12854 ;; subsequent logical operations are used to imitate conditional moves.
12855 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12856 ;; it directly.  Further holding this value in pseudo register might bring
12857 ;; problem in implicit normalization in spill code.
12858 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12859 ;; instructions after reload by splitting the conditional move patterns.
12860
12861 (define_insn "*sse_setccsf"
12862   [(set (match_operand:SF 0 "register_operand" "=x")
12863         (match_operator:SF 1 "sse_comparison_operator"
12864           [(match_operand:SF 2 "register_operand" "0")
12865            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12866   "TARGET_SSE && reload_completed"
12867   "cmp%D1ss\t{%3, %0|%0, %3}"
12868   [(set_attr "type" "ssecmp")
12869    (set_attr "mode" "SF")])
12870
12871 (define_insn "*sse_setccdf"
12872   [(set (match_operand:DF 0 "register_operand" "=Y")
12873         (match_operator:DF 1 "sse_comparison_operator"
12874           [(match_operand:DF 2 "register_operand" "0")
12875            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12876   "TARGET_SSE2 && reload_completed"
12877   "cmp%D1sd\t{%3, %0|%0, %3}"
12878   [(set_attr "type" "ssecmp")
12879    (set_attr "mode" "DF")])
12880 \f
12881 ;; Basic conditional jump instructions.
12882 ;; We ignore the overflow flag for signed branch instructions.
12883
12884 ;; For all bCOND expanders, also expand the compare or test insn that
12885 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12886
12887 (define_expand "beq"
12888   [(set (pc)
12889         (if_then_else (match_dup 1)
12890                       (label_ref (match_operand 0 "" ""))
12891                       (pc)))]
12892   ""
12893   "ix86_expand_branch (EQ, operands[0]); DONE;")
12894
12895 (define_expand "bne"
12896   [(set (pc)
12897         (if_then_else (match_dup 1)
12898                       (label_ref (match_operand 0 "" ""))
12899                       (pc)))]
12900   ""
12901   "ix86_expand_branch (NE, operands[0]); DONE;")
12902
12903 (define_expand "bgt"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (GT, operands[0]); DONE;")
12910
12911 (define_expand "bgtu"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (GTU, operands[0]); DONE;")
12918
12919 (define_expand "blt"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (LT, operands[0]); DONE;")
12926
12927 (define_expand "bltu"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (LTU, operands[0]); DONE;")
12934
12935 (define_expand "bge"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (GE, operands[0]); DONE;")
12942
12943 (define_expand "bgeu"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (GEU, operands[0]); DONE;")
12950
12951 (define_expand "ble"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (LE, operands[0]); DONE;")
12958
12959 (define_expand "bleu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (LEU, operands[0]); DONE;")
12966
12967 (define_expand "bunordered"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   "TARGET_80387 || TARGET_SSE"
12973   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12974
12975 (define_expand "bordered"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   "TARGET_80387 || TARGET_SSE"
12981   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12982
12983 (define_expand "buneq"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE"
12989   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12990
12991 (define_expand "bunge"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE"
12997   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12998
12999 (define_expand "bungt"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE"
13005   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13006
13007 (define_expand "bunle"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13014
13015 (define_expand "bunlt"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13022
13023 (define_expand "bltgt"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13030
13031 (define_insn "*jcc_1"
13032   [(set (pc)
13033         (if_then_else (match_operator 1 "ix86_comparison_operator"
13034                                       [(reg 17) (const_int 0)])
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   ""
13038   "%+j%C1\t%l0"
13039   [(set_attr "type" "ibr")
13040    (set_attr "modrm" "0")
13041    (set (attr "length")
13042            (if_then_else (and (ge (minus (match_dup 0) (pc))
13043                                   (const_int -126))
13044                               (lt (minus (match_dup 0) (pc))
13045                                   (const_int 128)))
13046              (const_int 2)
13047              (const_int 6)))])
13048
13049 (define_insn "*jcc_2"
13050   [(set (pc)
13051         (if_then_else (match_operator 1 "ix86_comparison_operator"
13052                                       [(reg 17) (const_int 0)])
13053                       (pc)
13054                       (label_ref (match_operand 0 "" ""))))]
13055   ""
13056   "%+j%c1\t%l0"
13057   [(set_attr "type" "ibr")
13058    (set_attr "modrm" "0")
13059    (set (attr "length")
13060            (if_then_else (and (ge (minus (match_dup 0) (pc))
13061                                   (const_int -126))
13062                               (lt (minus (match_dup 0) (pc))
13063                                   (const_int 128)))
13064              (const_int 2)
13065              (const_int 6)))])
13066
13067 ;; In general it is not safe to assume too much about CCmode registers,
13068 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13069 ;; conditions this is safe on x86, so help combine not create
13070 ;;
13071 ;;      seta    %al
13072 ;;      testb   %al, %al
13073 ;;      je      Lfoo
13074
13075 (define_split 
13076   [(set (pc)
13077         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13078                                       [(reg 17) (const_int 0)])
13079                           (const_int 0))
13080                       (label_ref (match_operand 1 "" ""))
13081                       (pc)))]
13082   ""
13083   [(set (pc)
13084         (if_then_else (match_dup 0)
13085                       (label_ref (match_dup 1))
13086                       (pc)))]
13087 {
13088   PUT_MODE (operands[0], VOIDmode);
13089 })
13090   
13091 (define_split 
13092   [(set (pc)
13093         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13094                                       [(reg 17) (const_int 0)])
13095                           (const_int 0))
13096                       (label_ref (match_operand 1 "" ""))
13097                       (pc)))]
13098   ""
13099   [(set (pc)
13100         (if_then_else (match_dup 0)
13101                       (label_ref (match_dup 1))
13102                       (pc)))]
13103 {
13104   rtx new_op0 = copy_rtx (operands[0]);
13105   operands[0] = new_op0;
13106   PUT_MODE (new_op0, VOIDmode);
13107   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13108                                              GET_MODE (XEXP (new_op0, 0))));
13109
13110   /* Make sure that (a) the CCmode we have for the flags is strong
13111      enough for the reversed compare or (b) we have a valid FP compare.  */
13112   if (! ix86_comparison_operator (new_op0, VOIDmode))
13113     FAIL;
13114 })
13115
13116 ;; Define combination compare-and-branch fp compare instructions to use
13117 ;; during early optimization.  Splitting the operation apart early makes
13118 ;; for bad code when we want to reverse the operation.
13119
13120 (define_insn "*fp_jcc_1"
13121   [(set (pc)
13122         (if_then_else (match_operator 0 "comparison_operator"
13123                         [(match_operand 1 "register_operand" "f")
13124                          (match_operand 2 "register_operand" "f")])
13125           (label_ref (match_operand 3 "" ""))
13126           (pc)))
13127    (clobber (reg:CCFP FPSR_REG))
13128    (clobber (reg:CCFP FLAGS_REG))]
13129   "TARGET_CMOVE && TARGET_80387
13130    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13131    && FLOAT_MODE_P (GET_MODE (operands[1]))
13132    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13133    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13134   "#")
13135
13136 (define_insn "*fp_jcc_1_sse"
13137   [(set (pc)
13138         (if_then_else (match_operator 0 "comparison_operator"
13139                         [(match_operand 1 "register_operand" "f#x,x#f")
13140                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13141           (label_ref (match_operand 3 "" ""))
13142           (pc)))
13143    (clobber (reg:CCFP FPSR_REG))
13144    (clobber (reg:CCFP FLAGS_REG))]
13145   "TARGET_80387
13146    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13147    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13148    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13149   "#")
13150
13151 (define_insn "*fp_jcc_1_sse_only"
13152   [(set (pc)
13153         (if_then_else (match_operator 0 "comparison_operator"
13154                         [(match_operand 1 "register_operand" "x")
13155                          (match_operand 2 "nonimmediate_operand" "xm")])
13156           (label_ref (match_operand 3 "" ""))
13157           (pc)))
13158    (clobber (reg:CCFP FPSR_REG))
13159    (clobber (reg:CCFP FLAGS_REG))]
13160   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13164
13165 (define_insn "*fp_jcc_2"
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           (pc)
13171           (label_ref (match_operand 3 "" ""))))
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_2_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           (pc)
13187           (label_ref (match_operand 3 "" ""))))
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_2_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           (pc)
13202           (label_ref (match_operand 3 "" ""))))
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_3"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "nonimmediate_operand" "fm")])
13215           (label_ref (match_operand 3 "" ""))
13216           (pc)))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))
13219    (clobber (match_scratch:HI 4 "=a"))]
13220   "TARGET_80387
13221    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13224    && SELECT_CC_MODE (GET_CODE (operands[0]),
13225                       operands[1], operands[2]) == CCFPmode
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13228
13229 (define_insn "*fp_jcc_4"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "f")
13233                          (match_operand 2 "nonimmediate_operand" "fm")])
13234           (pc)
13235           (label_ref (match_operand 3 "" ""))))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))
13238    (clobber (match_scratch:HI 4 "=a"))]
13239   "TARGET_80387
13240    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13243    && SELECT_CC_MODE (GET_CODE (operands[0]),
13244                       operands[1], operands[2]) == CCFPmode
13245    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13246   "#")
13247
13248 (define_insn "*fp_jcc_5"
13249   [(set (pc)
13250         (if_then_else (match_operator 0 "comparison_operator"
13251                         [(match_operand 1 "register_operand" "f")
13252                          (match_operand 2 "register_operand" "f")])
13253           (label_ref (match_operand 3 "" ""))
13254           (pc)))
13255    (clobber (reg:CCFP FPSR_REG))
13256    (clobber (reg:CCFP FLAGS_REG))
13257    (clobber (match_scratch:HI 4 "=a"))]
13258   "TARGET_80387
13259    && FLOAT_MODE_P (GET_MODE (operands[1]))
13260    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13261    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262   "#")
13263
13264 (define_insn "*fp_jcc_6"
13265   [(set (pc)
13266         (if_then_else (match_operator 0 "comparison_operator"
13267                         [(match_operand 1 "register_operand" "f")
13268                          (match_operand 2 "register_operand" "f")])
13269           (pc)
13270           (label_ref (match_operand 3 "" ""))))
13271    (clobber (reg:CCFP FPSR_REG))
13272    (clobber (reg:CCFP FLAGS_REG))
13273    (clobber (match_scratch:HI 4 "=a"))]
13274   "TARGET_80387
13275    && FLOAT_MODE_P (GET_MODE (operands[1]))
13276    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13279
13280 (define_insn "*fp_jcc_7"
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "f")
13284                          (match_operand 2 "const_double_operand" "C")])
13285           (label_ref (match_operand 3 "" ""))
13286           (pc)))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 4 "=a"))]
13290   "TARGET_80387
13291    && FLOAT_MODE_P (GET_MODE (operands[1]))
13292    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13293    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13294    && SELECT_CC_MODE (GET_CODE (operands[0]),
13295                       operands[1], operands[2]) == CCFPmode
13296    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13297   "#")
13298
13299 (define_split
13300   [(set (pc)
13301         (if_then_else (match_operator 0 "comparison_operator"
13302                         [(match_operand 1 "register_operand" "")
13303                          (match_operand 2 "nonimmediate_operand" "")])
13304           (match_operand 3 "" "")
13305           (match_operand 4 "" "")))
13306    (clobber (reg:CCFP FPSR_REG))
13307    (clobber (reg:CCFP FLAGS_REG))]
13308   "reload_completed"
13309   [(const_int 0)]
13310 {
13311   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13312                         operands[3], operands[4], NULL_RTX);
13313   DONE;
13314 })
13315
13316 (define_split
13317   [(set (pc)
13318         (if_then_else (match_operator 0 "comparison_operator"
13319                         [(match_operand 1 "register_operand" "")
13320                          (match_operand 2 "general_operand" "")])
13321           (match_operand 3 "" "")
13322           (match_operand 4 "" "")))
13323    (clobber (reg:CCFP FPSR_REG))
13324    (clobber (reg:CCFP FLAGS_REG))
13325    (clobber (match_scratch:HI 5 "=a"))]
13326   "reload_completed"
13327   [(const_int 0)]
13328 {
13329   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330                         operands[3], operands[4], operands[5]);
13331   DONE;
13332 })
13333 \f
13334 ;; Unconditional and other jump instructions
13335
13336 (define_insn "jump"
13337   [(set (pc)
13338         (label_ref (match_operand 0 "" "")))]
13339   ""
13340   "jmp\t%l0"
13341   [(set_attr "type" "ibr")
13342    (set (attr "length")
13343            (if_then_else (and (ge (minus (match_dup 0) (pc))
13344                                   (const_int -126))
13345                               (lt (minus (match_dup 0) (pc))
13346                                   (const_int 128)))
13347              (const_int 2)
13348              (const_int 5)))
13349    (set_attr "modrm" "0")])
13350
13351 (define_expand "indirect_jump"
13352   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13353   ""
13354   "")
13355
13356 (define_insn "*indirect_jump"
13357   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13358   "!TARGET_64BIT"
13359   "jmp\t%A0"
13360   [(set_attr "type" "ibr")
13361    (set_attr "length_immediate" "0")])
13362
13363 (define_insn "*indirect_jump_rtx64"
13364   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13365   "TARGET_64BIT"
13366   "jmp\t%A0"
13367   [(set_attr "type" "ibr")
13368    (set_attr "length_immediate" "0")])
13369
13370 (define_expand "tablejump"
13371   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13372               (use (label_ref (match_operand 1 "" "")))])]
13373   ""
13374 {
13375   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13376      relative.  Convert the relative address to an absolute address.  */
13377   if (flag_pic)
13378     {
13379       rtx op0, op1;
13380       enum rtx_code code;
13381
13382       if (TARGET_64BIT)
13383         {
13384           code = PLUS;
13385           op0 = operands[0];
13386           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13387         }
13388       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13389         {
13390           code = PLUS;
13391           op0 = operands[0];
13392           op1 = pic_offset_table_rtx;
13393         }
13394       else
13395         {
13396           code = MINUS;
13397           op0 = pic_offset_table_rtx;
13398           op1 = operands[0];
13399         }
13400
13401       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13402                                          OPTAB_DIRECT);
13403     }
13404 })
13405
13406 (define_insn "*tablejump_1"
13407   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13408    (use (label_ref (match_operand 1 "" "")))]
13409   "!TARGET_64BIT"
13410   "jmp\t%A0"
13411   [(set_attr "type" "ibr")
13412    (set_attr "length_immediate" "0")])
13413
13414 (define_insn "*tablejump_1_rtx64"
13415   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13416    (use (label_ref (match_operand 1 "" "")))]
13417   "TARGET_64BIT"
13418   "jmp\t%A0"
13419   [(set_attr "type" "ibr")
13420    (set_attr "length_immediate" "0")])
13421 \f
13422 ;; Loop instruction
13423 ;;
13424 ;; This is all complicated by the fact that since this is a jump insn
13425 ;; we must handle our own reloads.
13426
13427 (define_expand "doloop_end"
13428   [(use (match_operand 0 "" ""))        ; loop pseudo
13429    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13430    (use (match_operand 2 "" ""))        ; max iterations
13431    (use (match_operand 3 "" ""))        ; loop level 
13432    (use (match_operand 4 "" ""))]       ; label
13433   "!TARGET_64BIT && TARGET_USE_LOOP"
13434   "                                 
13435 {
13436   /* Only use cloop on innermost loops.  */
13437   if (INTVAL (operands[3]) > 1)
13438     FAIL;
13439   if (GET_MODE (operands[0]) != SImode)
13440     FAIL;
13441   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13442                                            operands[0]));
13443   DONE;
13444 }")
13445
13446 (define_insn "doloop_end_internal"
13447   [(set (pc)
13448         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13449                           (const_int 1))
13450                       (label_ref (match_operand 0 "" ""))
13451                       (pc)))
13452    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13453         (plus:SI (match_dup 1)
13454                  (const_int -1)))
13455    (clobber (match_scratch:SI 3 "=X,X,r"))
13456    (clobber (reg:CC FLAGS_REG))]
13457   "!TARGET_64BIT && TARGET_USE_LOOP
13458    && (reload_in_progress || reload_completed
13459        || register_operand (operands[2], VOIDmode))"
13460 {
13461   if (which_alternative != 0)
13462     return "#";
13463   if (get_attr_length (insn) == 2)
13464     return "%+loop\t%l0";
13465   else
13466     return "dec{l}\t%1\;%+jne\t%l0";
13467 }
13468   [(set (attr "length")
13469         (if_then_else (and (eq_attr "alternative" "0")
13470                            (and (ge (minus (match_dup 0) (pc))
13471                                     (const_int -126))
13472                                 (lt (minus (match_dup 0) (pc))
13473                                     (const_int 128))))
13474                       (const_int 2)
13475                       (const_int 16)))
13476    ;; We don't know the type before shorten branches.  Optimistically expect
13477    ;; the loop instruction to match.
13478    (set (attr "type") (const_string "ibr"))])
13479
13480 (define_split
13481   [(set (pc)
13482         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13483                           (const_int 1))
13484                       (match_operand 0 "" "")
13485                       (pc)))
13486    (set (match_dup 1)
13487         (plus:SI (match_dup 1)
13488                  (const_int -1)))
13489    (clobber (match_scratch:SI 2 ""))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "!TARGET_64BIT && TARGET_USE_LOOP
13492    && reload_completed
13493    && REGNO (operands[1]) != 2"
13494   [(parallel [(set (reg:CCZ FLAGS_REG)
13495                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13496                                  (const_int 0)))
13497               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13498    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13499                            (match_dup 0)
13500                            (pc)))]
13501   "")
13502   
13503 (define_split
13504   [(set (pc)
13505         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13506                           (const_int 1))
13507                       (match_operand 0 "" "")
13508                       (pc)))
13509    (set (match_operand:SI 2 "nonimmediate_operand" "")
13510         (plus:SI (match_dup 1)
13511                  (const_int -1)))
13512    (clobber (match_scratch:SI 3 ""))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "!TARGET_64BIT && TARGET_USE_LOOP
13515    && reload_completed
13516    && (! REG_P (operands[2])
13517        || ! rtx_equal_p (operands[1], operands[2]))"
13518   [(set (match_dup 3) (match_dup 1))
13519    (parallel [(set (reg:CCZ FLAGS_REG)
13520                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13521                                 (const_int 0)))
13522               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13523    (set (match_dup 2) (match_dup 3))
13524    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13525                            (match_dup 0)
13526                            (pc)))]
13527   "")
13528
13529 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13530
13531 (define_peephole2
13532   [(set (reg 17) (match_operand 0 "" ""))
13533    (set (match_operand:QI 1 "register_operand" "")
13534         (match_operator:QI 2 "ix86_comparison_operator"
13535           [(reg 17) (const_int 0)]))
13536    (set (match_operand 3 "q_regs_operand" "")
13537         (zero_extend (match_dup 1)))]
13538   "(peep2_reg_dead_p (3, operands[1])
13539     || operands_match_p (operands[1], operands[3]))
13540    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541   [(set (match_dup 4) (match_dup 0))
13542    (set (strict_low_part (match_dup 5))
13543         (match_dup 2))]
13544 {
13545   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13546   operands[5] = gen_lowpart (QImode, operands[3]);
13547   ix86_expand_clear (operands[3]);
13548 })
13549
13550 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13551
13552 (define_peephole2
13553   [(set (reg 17) (match_operand 0 "" ""))
13554    (set (match_operand:QI 1 "register_operand" "")
13555         (match_operator:QI 2 "ix86_comparison_operator"
13556           [(reg 17) (const_int 0)]))
13557    (parallel [(set (match_operand 3 "q_regs_operand" "")
13558                    (zero_extend (match_dup 1)))
13559               (clobber (reg:CC FLAGS_REG))])]
13560   "(peep2_reg_dead_p (3, operands[1])
13561     || operands_match_p (operands[1], operands[3]))
13562    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13563   [(set (match_dup 4) (match_dup 0))
13564    (set (strict_low_part (match_dup 5))
13565         (match_dup 2))]
13566 {
13567   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13568   operands[5] = gen_lowpart (QImode, operands[3]);
13569   ix86_expand_clear (operands[3]);
13570 })
13571 \f
13572 ;; Call instructions.
13573
13574 ;; The predicates normally associated with named expanders are not properly
13575 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13576 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13577
13578 ;; Call subroutine returning no value.
13579
13580 (define_expand "call_pop"
13581   [(parallel [(call (match_operand:QI 0 "" "")
13582                     (match_operand:SI 1 "" ""))
13583               (set (reg:SI SP_REG)
13584                    (plus:SI (reg:SI SP_REG)
13585                             (match_operand:SI 3 "" "")))])]
13586   "!TARGET_64BIT"
13587 {
13588   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13589   DONE;
13590 })
13591
13592 (define_insn "*call_pop_0"
13593   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13594          (match_operand:SI 1 "" ""))
13595    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 2 "immediate_operand" "")))]
13597   "!TARGET_64BIT"
13598 {
13599   if (SIBLING_CALL_P (insn))
13600     return "jmp\t%P0";
13601   else
13602     return "call\t%P0";
13603 }
13604   [(set_attr "type" "call")])
13605   
13606 (define_insn "*call_pop_1"
13607   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13608          (match_operand:SI 1 "" ""))
13609    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13610                             (match_operand:SI 2 "immediate_operand" "i")))]
13611   "!TARGET_64BIT"
13612 {
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     {
13615       if (SIBLING_CALL_P (insn))
13616         return "jmp\t%P0";
13617       else
13618         return "call\t%P0";
13619     }
13620   if (SIBLING_CALL_P (insn))
13621     return "jmp\t%A0";
13622   else
13623     return "call\t%A0";
13624 }
13625   [(set_attr "type" "call")])
13626
13627 (define_expand "call"
13628   [(call (match_operand:QI 0 "" "")
13629          (match_operand 1 "" ""))
13630    (use (match_operand 2 "" ""))]
13631   ""
13632 {
13633   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13634   DONE;
13635 })
13636
13637 (define_expand "sibcall"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13642 {
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13644   DONE;
13645 })
13646
13647 (define_insn "*call_0"
13648   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13649          (match_operand 1 "" ""))]
13650   ""
13651 {
13652   if (SIBLING_CALL_P (insn))
13653     return "jmp\t%P0";
13654   else
13655     return "call\t%P0";
13656 }
13657   [(set_attr "type" "call")])
13658
13659 (define_insn "*call_1"
13660   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13661          (match_operand 1 "" ""))]
13662   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13663 {
13664   if (constant_call_address_operand (operands[0], Pmode))
13665     return "call\t%P0";
13666   return "call\t%A0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*sibcall_1"
13671   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13672          (match_operand 1 "" ""))]
13673   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674 {
13675   if (constant_call_address_operand (operands[0], Pmode))
13676     return "jmp\t%P0";
13677   return "jmp\t%A0";
13678 }
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*call_1_rex64"
13682   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13683          (match_operand 1 "" ""))]
13684   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13685 {
13686   if (constant_call_address_operand (operands[0], Pmode))
13687     return "call\t%P0";
13688   return "call\t%A0";
13689 }
13690   [(set_attr "type" "call")])
13691
13692 (define_insn "*sibcall_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13694          (match_operand 1 "" ""))]
13695   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13696   "jmp\t%P0"
13697   [(set_attr "type" "call")])
13698
13699 (define_insn "*sibcall_1_rex64_v"
13700   [(call (mem:QI (reg:DI 40))
13701          (match_operand 0 "" ""))]
13702   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13703   "jmp\t*%%r11"
13704   [(set_attr "type" "call")])
13705
13706
13707 ;; Call subroutine, returning value in operand 0
13708
13709 (define_expand "call_value_pop"
13710   [(parallel [(set (match_operand 0 "" "")
13711                    (call (match_operand:QI 1 "" "")
13712                          (match_operand:SI 2 "" "")))
13713               (set (reg:SI SP_REG)
13714                    (plus:SI (reg:SI SP_REG)
13715                             (match_operand:SI 4 "" "")))])]
13716   "!TARGET_64BIT"
13717 {
13718   ix86_expand_call (operands[0], operands[1], operands[2],
13719                     operands[3], operands[4], 0);
13720   DONE;
13721 })
13722
13723 (define_expand "call_value"
13724   [(set (match_operand 0 "" "")
13725         (call (match_operand:QI 1 "" "")
13726               (match_operand:SI 2 "" "")))
13727    (use (match_operand:SI 3 "" ""))]
13728   ;; Operand 2 not used on the i386.
13729   ""
13730 {
13731   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13732   DONE;
13733 })
13734
13735 (define_expand "sibcall_value"
13736   [(set (match_operand 0 "" "")
13737         (call (match_operand:QI 1 "" "")
13738               (match_operand:SI 2 "" "")))
13739    (use (match_operand:SI 3 "" ""))]
13740   ;; Operand 2 not used on the i386.
13741   ""
13742 {
13743   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13744   DONE;
13745 })
13746
13747 ;; Call subroutine returning any type.
13748
13749 (define_expand "untyped_call"
13750   [(parallel [(call (match_operand 0 "" "")
13751                     (const_int 0))
13752               (match_operand 1 "" "")
13753               (match_operand 2 "" "")])]
13754   ""
13755 {
13756   int i;
13757
13758   /* In order to give reg-stack an easier job in validating two
13759      coprocessor registers as containing a possible return value,
13760      simply pretend the untyped call returns a complex long double
13761      value.  */
13762
13763   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13764                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13765                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13766                     NULL, 0);
13767
13768   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13769     {
13770       rtx set = XVECEXP (operands[2], 0, i);
13771       emit_move_insn (SET_DEST (set), SET_SRC (set));
13772     }
13773
13774   /* The optimizer does not know that the call sets the function value
13775      registers we stored in the result block.  We avoid problems by
13776      claiming that all hard registers are used and clobbered at this
13777      point.  */
13778   emit_insn (gen_blockage (const0_rtx));
13779
13780   DONE;
13781 })
13782 \f
13783 ;; Prologue and epilogue instructions
13784
13785 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13786 ;; all of memory.  This blocks insns from being moved across this point.
13787
13788 (define_insn "blockage"
13789   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13790   ""
13791   ""
13792   [(set_attr "length" "0")])
13793
13794 ;; Insn emitted into the body of a function to return from a function.
13795 ;; This is only done if the function's epilogue is known to be simple.
13796 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13797
13798 (define_expand "return"
13799   [(return)]
13800   "ix86_can_use_return_insn_p ()"
13801 {
13802   if (current_function_pops_args)
13803     {
13804       rtx popc = GEN_INT (current_function_pops_args);
13805       emit_jump_insn (gen_return_pop_internal (popc));
13806       DONE;
13807     }
13808 })
13809
13810 (define_insn "return_internal"
13811   [(return)]
13812   "reload_completed"
13813   "ret"
13814   [(set_attr "length" "1")
13815    (set_attr "length_immediate" "0")
13816    (set_attr "modrm" "0")])
13817
13818 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13819 ;; instruction Athlon and K8 have.
13820
13821 (define_insn "return_internal_long"
13822   [(return)
13823    (unspec [(const_int 0)] UNSPEC_REP)]
13824   "reload_completed"
13825   "rep {;} ret"
13826   [(set_attr "length" "1")
13827    (set_attr "length_immediate" "0")
13828    (set_attr "prefix_rep" "1")
13829    (set_attr "modrm" "0")])
13830
13831 (define_insn "return_pop_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "const_int_operand" ""))]
13834   "reload_completed"
13835   "ret\t%0"
13836   [(set_attr "length" "3")
13837    (set_attr "length_immediate" "2")
13838    (set_attr "modrm" "0")])
13839
13840 (define_insn "return_indirect_internal"
13841   [(return)
13842    (use (match_operand:SI 0 "register_operand" "r"))]
13843   "reload_completed"
13844   "jmp\t%A0"
13845   [(set_attr "type" "ibr")
13846    (set_attr "length_immediate" "0")])
13847
13848 (define_insn "nop"
13849   [(const_int 0)]
13850   ""
13851   "nop"
13852   [(set_attr "length" "1")
13853    (set_attr "length_immediate" "0")
13854    (set_attr "modrm" "0")])
13855
13856 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13858 ;; block on K8.
13859
13860 (define_insn "align"
13861   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13862   ""
13863 {
13864 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13865   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13866 #else
13867   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868      The align insn is used to avoid 3 jump instructions in the row to improve
13869      branch prediction and the benefits hardly outweight the cost of extra 8
13870      nops on the average inserted by full alignment pseudo operation.  */
13871 #endif
13872   return "";
13873 }
13874   [(set_attr "length" "16")])
13875
13876 (define_expand "prologue"
13877   [(const_int 1)]
13878   ""
13879   "ix86_expand_prologue (); DONE;")
13880
13881 (define_insn "set_got"
13882   [(set (match_operand:SI 0 "register_operand" "=r")
13883         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884    (clobber (reg:CC FLAGS_REG))]
13885   "!TARGET_64BIT"
13886   { return output_set_got (operands[0]); }
13887   [(set_attr "type" "multi")
13888    (set_attr "length" "12")])
13889
13890 (define_expand "epilogue"
13891   [(const_int 1)]
13892   ""
13893   "ix86_expand_epilogue (1); DONE;")
13894
13895 (define_expand "sibcall_epilogue"
13896   [(const_int 1)]
13897   ""
13898   "ix86_expand_epilogue (0); DONE;")
13899
13900 (define_expand "eh_return"
13901   [(use (match_operand 0 "register_operand" ""))]
13902   ""
13903 {
13904   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13905
13906   /* Tricky bit: we write the address of the handler to which we will
13907      be returning into someone else's stack frame, one word below the
13908      stack address we wish to restore.  */
13909   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911   tmp = gen_rtx_MEM (Pmode, tmp);
13912   emit_move_insn (tmp, ra);
13913
13914   if (Pmode == SImode)
13915     emit_jump_insn (gen_eh_return_si (sa));
13916   else
13917     emit_jump_insn (gen_eh_return_di (sa));
13918   emit_barrier ();
13919   DONE;
13920 })
13921
13922 (define_insn_and_split "eh_return_si"
13923   [(set (pc) 
13924         (unspec [(match_operand:SI 0 "register_operand" "c")]
13925                  UNSPEC_EH_RETURN))]
13926   "!TARGET_64BIT"
13927   "#"
13928   "reload_completed"
13929   [(const_int 1)]
13930   "ix86_expand_epilogue (2); DONE;")
13931
13932 (define_insn_and_split "eh_return_di"
13933   [(set (pc) 
13934         (unspec [(match_operand:DI 0 "register_operand" "c")]
13935                  UNSPEC_EH_RETURN))]
13936   "TARGET_64BIT"
13937   "#"
13938   "reload_completed"
13939   [(const_int 1)]
13940   "ix86_expand_epilogue (2); DONE;")
13941
13942 (define_insn "leave"
13943   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945    (clobber (mem:BLK (scratch)))]
13946   "!TARGET_64BIT"
13947   "leave"
13948   [(set_attr "type" "leave")])
13949
13950 (define_insn "leave_rex64"
13951   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953    (clobber (mem:BLK (scratch)))]
13954   "TARGET_64BIT"
13955   "leave"
13956   [(set_attr "type" "leave")])
13957 \f
13958 (define_expand "ffssi2"
13959   [(parallel
13960      [(set (match_operand:SI 0 "register_operand" "") 
13961            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962       (clobber (match_scratch:SI 2 ""))
13963       (clobber (reg:CC FLAGS_REG))])]
13964   ""
13965   "")
13966
13967 (define_insn_and_split "*ffs_cmove"
13968   [(set (match_operand:SI 0 "register_operand" "=r") 
13969         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970    (clobber (match_scratch:SI 2 "=&r"))
13971    (clobber (reg:CC FLAGS_REG))]
13972   "TARGET_CMOVE"
13973   "#"
13974   "&& reload_completed"
13975   [(set (match_dup 2) (const_int -1))
13976    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978    (set (match_dup 0) (if_then_else:SI
13979                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13980                         (match_dup 2)
13981                         (match_dup 0)))
13982    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983               (clobber (reg:CC FLAGS_REG))])]
13984   "")
13985
13986 (define_insn_and_split "*ffs_no_cmove"
13987   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13988         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989    (clobber (match_scratch:SI 2 "=&q"))
13990    (clobber (reg:CC FLAGS_REG))]
13991   ""
13992   "#"
13993   "reload_completed"
13994   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996    (set (strict_low_part (match_dup 3))
13997         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999               (clobber (reg:CC FLAGS_REG))])
14000    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001               (clobber (reg:CC FLAGS_REG))])
14002    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003               (clobber (reg:CC FLAGS_REG))])]
14004 {
14005   operands[3] = gen_lowpart (QImode, operands[2]);
14006   ix86_expand_clear (operands[2]);
14007 })
14008
14009 (define_insn "*ffssi_1"
14010   [(set (reg:CCZ FLAGS_REG)
14011         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14012                      (const_int 0)))
14013    (set (match_operand:SI 0 "register_operand" "=r")
14014         (ctz:SI (match_dup 1)))]
14015   ""
14016   "bsf{l}\t{%1, %0|%0, %1}"
14017   [(set_attr "prefix_0f" "1")])
14018
14019 (define_expand "ffsdi2"
14020   [(parallel
14021      [(set (match_operand:DI 0 "register_operand" "") 
14022            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023       (clobber (match_scratch:DI 2 ""))
14024       (clobber (reg:CC 17))])]
14025   "TARGET_64BIT && TARGET_CMOVE"
14026   "")
14027
14028 (define_insn_and_split "*ffs_rex64"
14029   [(set (match_operand:DI 0 "register_operand" "=r") 
14030         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031    (clobber (match_scratch:DI 2 "=&r"))
14032    (clobber (reg:CC 17))]
14033   "TARGET_64BIT && TARGET_CMOVE"
14034   "#"
14035   "&& reload_completed"
14036   [(set (match_dup 2) (const_int -1))
14037    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14038               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14039    (set (match_dup 0) (if_then_else:DI
14040                         (eq (reg:CCZ 17) (const_int 0))
14041                         (match_dup 2)
14042                         (match_dup 0)))
14043    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14044               (clobber (reg:CC 17))])]
14045   "")
14046
14047 (define_insn "*ffsdi_1"
14048   [(set (reg:CCZ 17)
14049         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14050                      (const_int 0)))
14051    (set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_dup 1)))]
14053   "TARGET_64BIT"
14054   "bsf{q}\t{%1, %0|%0, %1}"
14055   [(set_attr "prefix_0f" "1")])
14056
14057 (define_insn "ctzsi2"
14058   [(set (match_operand:SI 0 "register_operand" "=r")
14059         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14060    (clobber (reg:CC FLAGS_REG))]
14061   ""
14062   "bsf{l}\t{%1, %0|%0, %1}"
14063   [(set_attr "prefix_0f" "1")])
14064
14065 (define_insn "ctzdi2"
14066   [(set (match_operand:DI 0 "register_operand" "=r")
14067         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14068    (clobber (reg:CC 17))]
14069   "TARGET_64BIT"
14070   "bsf{q}\t{%1, %0|%0, %1}"
14071   [(set_attr "prefix_0f" "1")])
14072
14073 (define_expand "clzsi2"
14074   [(parallel
14075      [(set (match_operand:SI 0 "register_operand" "")
14076            (minus:SI (const_int 31)
14077                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14078       (clobber (reg:CC FLAGS_REG))])
14079    (parallel
14080      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14081       (clobber (reg:CC FLAGS_REG))])]
14082   ""
14083   "")
14084
14085 (define_insn "*bsr"
14086   [(set (match_operand:SI 0 "register_operand" "=r")
14087         (minus:SI (const_int 31)
14088                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsr{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14093
14094 (define_expand "clzdi2"
14095   [(parallel
14096      [(set (match_operand:DI 0 "register_operand" "")
14097            (minus:DI (const_int 63)
14098                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14099       (clobber (reg:CC 17))])
14100    (parallel
14101      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14102       (clobber (reg:CC 17))])]
14103   "TARGET_64BIT"
14104   "")
14105
14106 (define_insn "*bsr_rex64"
14107   [(set (match_operand:DI 0 "register_operand" "=r")
14108         (minus:DI (const_int 63)
14109                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14110    (clobber (reg:CC 17))]
14111   "TARGET_64BIT"
14112   "bsr{q}\t{%1, %0|%0, %1}"
14113   [(set_attr "prefix_0f" "1")])
14114 \f
14115 ;; Thread-local storage patterns for ELF.
14116 ;;
14117 ;; Note that these code sequences must appear exactly as shown
14118 ;; in order to allow linker relaxation.
14119
14120 (define_insn "*tls_global_dynamic_32_gnu"
14121   [(set (match_operand:SI 0 "register_operand" "=a")
14122         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14123                     (match_operand:SI 2 "tls_symbolic_operand" "")
14124                     (match_operand:SI 3 "call_insn_operand" "")]
14125                     UNSPEC_TLS_GD))
14126    (clobber (match_scratch:SI 4 "=d"))
14127    (clobber (match_scratch:SI 5 "=c"))
14128    (clobber (reg:CC FLAGS_REG))]
14129   "!TARGET_64BIT && TARGET_GNU_TLS"
14130   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "12")])
14133
14134 (define_insn "*tls_global_dynamic_32_sun"
14135   [(set (match_operand:SI 0 "register_operand" "=a")
14136         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14137                     (match_operand:SI 2 "tls_symbolic_operand" "")
14138                     (match_operand:SI 3 "call_insn_operand" "")]
14139                     UNSPEC_TLS_GD))
14140    (clobber (match_scratch:SI 4 "=d"))
14141    (clobber (match_scratch:SI 5 "=c"))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "!TARGET_64BIT && TARGET_SUN_TLS"
14144   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14145         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14146   [(set_attr "type" "multi")
14147    (set_attr "length" "14")])
14148
14149 (define_expand "tls_global_dynamic_32"
14150   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14151                    (unspec:SI
14152                     [(match_dup 2)
14153                      (match_operand:SI 1 "tls_symbolic_operand" "")
14154                      (match_dup 3)]
14155                     UNSPEC_TLS_GD))
14156               (clobber (match_scratch:SI 4 ""))
14157               (clobber (match_scratch:SI 5 ""))
14158               (clobber (reg:CC FLAGS_REG))])]
14159   ""
14160 {
14161   if (flag_pic)
14162     operands[2] = pic_offset_table_rtx;
14163   else
14164     {
14165       operands[2] = gen_reg_rtx (Pmode);
14166       emit_insn (gen_set_got (operands[2]));
14167     }
14168   operands[3] = ix86_tls_get_addr ();
14169 })
14170
14171 (define_insn "*tls_global_dynamic_64"
14172   [(set (match_operand:DI 0 "register_operand" "=a")
14173         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14174                       (match_operand:DI 3 "" "")))
14175    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14176               UNSPEC_TLS_GD)]
14177   "TARGET_64BIT"
14178   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14179   [(set_attr "type" "multi")
14180    (set_attr "length" "16")])
14181
14182 (define_expand "tls_global_dynamic_64"
14183   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14184                    (call (mem:QI (match_dup 2)) (const_int 0)))
14185               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14186                          UNSPEC_TLS_GD)])]
14187   ""
14188 {
14189   operands[2] = ix86_tls_get_addr ();
14190 })
14191
14192 (define_insn "*tls_local_dynamic_base_32_gnu"
14193   [(set (match_operand:SI 0 "register_operand" "=a")
14194         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14195                     (match_operand:SI 2 "call_insn_operand" "")]
14196                    UNSPEC_TLS_LD_BASE))
14197    (clobber (match_scratch:SI 3 "=d"))
14198    (clobber (match_scratch:SI 4 "=c"))
14199    (clobber (reg:CC FLAGS_REG))]
14200   "!TARGET_64BIT && TARGET_GNU_TLS"
14201   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14202   [(set_attr "type" "multi")
14203    (set_attr "length" "11")])
14204
14205 (define_insn "*tls_local_dynamic_base_32_sun"
14206   [(set (match_operand:SI 0 "register_operand" "=a")
14207         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208                     (match_operand:SI 2 "call_insn_operand" "")]
14209                    UNSPEC_TLS_LD_BASE))
14210    (clobber (match_scratch:SI 3 "=d"))
14211    (clobber (match_scratch:SI 4 "=c"))
14212    (clobber (reg:CC FLAGS_REG))]
14213   "!TARGET_64BIT && TARGET_SUN_TLS"
14214   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14215         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14216   [(set_attr "type" "multi")
14217    (set_attr "length" "13")])
14218
14219 (define_expand "tls_local_dynamic_base_32"
14220   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14221                    (unspec:SI [(match_dup 1) (match_dup 2)]
14222                               UNSPEC_TLS_LD_BASE))
14223               (clobber (match_scratch:SI 3 ""))
14224               (clobber (match_scratch:SI 4 ""))
14225               (clobber (reg:CC FLAGS_REG))])]
14226   ""
14227 {
14228   if (flag_pic)
14229     operands[1] = pic_offset_table_rtx;
14230   else
14231     {
14232       operands[1] = gen_reg_rtx (Pmode);
14233       emit_insn (gen_set_got (operands[1]));
14234     }
14235   operands[2] = ix86_tls_get_addr ();
14236 })
14237
14238 (define_insn "*tls_local_dynamic_base_64"
14239   [(set (match_operand:DI 0 "register_operand" "=a")
14240         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14241                       (match_operand:DI 2 "" "")))
14242    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14243   "TARGET_64BIT"
14244   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "12")])
14247
14248 (define_expand "tls_local_dynamic_base_64"
14249   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14250                    (call (mem:QI (match_dup 1)) (const_int 0)))
14251               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14252   ""
14253 {
14254   operands[1] = ix86_tls_get_addr ();
14255 })
14256
14257 ;; Local dynamic of a single variable is a lose.  Show combine how
14258 ;; to convert that back to global dynamic.
14259
14260 (define_insn_and_split "*tls_local_dynamic_32_once"
14261   [(set (match_operand:SI 0 "register_operand" "=a")
14262         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14263                              (match_operand:SI 2 "call_insn_operand" "")]
14264                             UNSPEC_TLS_LD_BASE)
14265                  (const:SI (unspec:SI
14266                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14267                             UNSPEC_DTPOFF))))
14268    (clobber (match_scratch:SI 4 "=d"))
14269    (clobber (match_scratch:SI 5 "=c"))
14270    (clobber (reg:CC FLAGS_REG))]
14271   ""
14272   "#"
14273   ""
14274   [(parallel [(set (match_dup 0)
14275                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14276                               UNSPEC_TLS_GD))
14277               (clobber (match_dup 4))
14278               (clobber (match_dup 5))
14279               (clobber (reg:CC FLAGS_REG))])]
14280   "")
14281
14282 ;; Load and add the thread base pointer from %gs:0.
14283
14284 (define_insn "*load_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14287   "!TARGET_64BIT"
14288   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14289   [(set_attr "type" "imov")
14290    (set_attr "modrm" "0")
14291    (set_attr "length" "7")
14292    (set_attr "memory" "load")
14293    (set_attr "imm_disp" "false")])
14294
14295 (define_insn "*add_tp_si"
14296   [(set (match_operand:SI 0 "register_operand" "=r")
14297         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14298                  (match_operand:SI 1 "register_operand" "0")))
14299    (clobber (reg:CC FLAGS_REG))]
14300   "!TARGET_64BIT"
14301   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14302   [(set_attr "type" "alu")
14303    (set_attr "modrm" "0")
14304    (set_attr "length" "7")
14305    (set_attr "memory" "load")
14306    (set_attr "imm_disp" "false")])
14307
14308 (define_insn "*load_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14311   "TARGET_64BIT"
14312   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14313   [(set_attr "type" "imov")
14314    (set_attr "modrm" "0")
14315    (set_attr "length" "7")
14316    (set_attr "memory" "load")
14317    (set_attr "imm_disp" "false")])
14318
14319 (define_insn "*add_tp_di"
14320   [(set (match_operand:DI 0 "register_operand" "=r")
14321         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14322                  (match_operand:DI 1 "register_operand" "0")))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "TARGET_64BIT"
14325   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14326   [(set_attr "type" "alu")
14327    (set_attr "modrm" "0")
14328    (set_attr "length" "7")
14329    (set_attr "memory" "load")
14330    (set_attr "imm_disp" "false")])
14331 \f
14332 ;; These patterns match the binary 387 instructions for addM3, subM3,
14333 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14334 ;; SFmode.  The first is the normal insn, the second the same insn but
14335 ;; with one operand a conversion, and the third the same insn but with
14336 ;; the other operand a conversion.  The conversion may be SFmode or
14337 ;; SImode if the target mode DFmode, but only SImode if the target mode
14338 ;; is SFmode.
14339
14340 ;; Gcc is slightly more smart about handling normal two address instructions
14341 ;; so use special patterns for add and mull.
14342 (define_insn "*fop_sf_comm_nosse"
14343   [(set (match_operand:SF 0 "register_operand" "=f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14353            (const_string "fmul")
14354            (const_string "fop")))
14355    (set_attr "mode" "SF")])
14356
14357 (define_insn "*fop_sf_comm"
14358   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14359         (match_operator:SF 3 "binary_fp_operator"
14360                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14361                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14362   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14363    && COMMUTATIVE_ARITH_P (operands[3])
14364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14365   "* return output_387_binary_op (insn, operands);"
14366   [(set (attr "type") 
14367         (if_then_else (eq_attr "alternative" "1")
14368            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14369               (const_string "ssemul")
14370               (const_string "sseadd"))
14371            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14372               (const_string "fmul")
14373               (const_string "fop"))))
14374    (set_attr "mode" "SF")])
14375
14376 (define_insn "*fop_sf_comm_sse"
14377   [(set (match_operand:SF 0 "register_operand" "=x")
14378         (match_operator:SF 3 "binary_fp_operator"
14379                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14380                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14381   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14382    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14383   "* return output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14386            (const_string "ssemul")
14387            (const_string "sseadd")))
14388    (set_attr "mode" "SF")])
14389
14390 (define_insn "*fop_df_comm_nosse"
14391   [(set (match_operand:DF 0 "register_operand" "=f")
14392         (match_operator:DF 3 "binary_fp_operator"
14393                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14394                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14395   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14396    && COMMUTATIVE_ARITH_P (operands[3])
14397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set (attr "type") 
14400         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14401            (const_string "fmul")
14402            (const_string "fop")))
14403    (set_attr "mode" "DF")])
14404
14405 (define_insn "*fop_df_comm"
14406   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14407         (match_operator:DF 3 "binary_fp_operator"
14408                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14409                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14410   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14411    && COMMUTATIVE_ARITH_P (operands[3])
14412    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (if_then_else (eq_attr "alternative" "1")
14416            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14417               (const_string "ssemul")
14418               (const_string "sseadd"))
14419            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14420               (const_string "fmul")
14421               (const_string "fop"))))
14422    (set_attr "mode" "DF")])
14423
14424 (define_insn "*fop_df_comm_sse"
14425   [(set (match_operand:DF 0 "register_operand" "=Y")
14426         (match_operator:DF 3 "binary_fp_operator"
14427                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14428                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14429   "TARGET_SSE2 && TARGET_SSE_MATH
14430    && COMMUTATIVE_ARITH_P (operands[3])
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14435            (const_string "ssemul")
14436            (const_string "sseadd")))
14437    (set_attr "mode" "DF")])
14438
14439 (define_insn "*fop_xf_comm"
14440   [(set (match_operand:XF 0 "register_operand" "=f")
14441         (match_operator:XF 3 "binary_fp_operator"
14442                         [(match_operand:XF 1 "register_operand" "%0")
14443                          (match_operand:XF 2 "register_operand" "f")]))]
14444   "TARGET_80387
14445    && COMMUTATIVE_ARITH_P (operands[3])"
14446   "* return output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14449            (const_string "fmul")
14450            (const_string "fop")))
14451    (set_attr "mode" "XF")])
14452
14453 (define_insn "*fop_sf_1_nosse"
14454   [(set (match_operand:SF 0 "register_operand" "=f,f")
14455         (match_operator:SF 3 "binary_fp_operator"
14456                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14457                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14458   "TARGET_80387 && !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         (cond [(match_operand:SF 3 "mult_operator" "") 
14464                  (const_string "fmul")
14465                (match_operand:SF 3 "div_operator" "") 
14466                  (const_string "fdiv")
14467               ]
14468               (const_string "fop")))
14469    (set_attr "mode" "SF")])
14470
14471 (define_insn "*fop_sf_1"
14472   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14473         (match_operator:SF 3 "binary_fp_operator"
14474                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14475                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14476   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14477    && !COMMUTATIVE_ARITH_P (operands[3])
14478    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14479   "* return output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (cond [(and (eq_attr "alternative" "2")
14482                     (match_operand:SF 3 "mult_operator" ""))
14483                  (const_string "ssemul")
14484                (and (eq_attr "alternative" "2")
14485                     (match_operand:SF 3 "div_operator" ""))
14486                  (const_string "ssediv")
14487                (eq_attr "alternative" "2")
14488                  (const_string "sseadd")
14489                (match_operand:SF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:SF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "mode" "SF")])
14496
14497 (define_insn "*fop_sf_1_sse"
14498   [(set (match_operand:SF 0 "register_operand" "=x")
14499         (match_operator:SF 3 "binary_fp_operator"
14500                         [(match_operand:SF 1 "register_operand" "0")
14501                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14502   "TARGET_SSE_MATH
14503    && !COMMUTATIVE_ARITH_P (operands[3])"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:SF 3 "mult_operator" "")
14507                  (const_string "ssemul")
14508                (match_operand:SF 3 "div_operator" "")
14509                  (const_string "ssediv")
14510               ]
14511               (const_string "sseadd")))
14512    (set_attr "mode" "SF")])
14513
14514 ;; ??? Add SSE splitters for these!
14515 (define_insn "*fop_sf_2"
14516   [(set (match_operand:SF 0 "register_operand" "=f,f")
14517         (match_operator:SF 3 "binary_fp_operator"
14518           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14519            (match_operand:SF 2 "register_operand" "0,0")]))]
14520   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14521   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (cond [(match_operand:SF 3 "mult_operator" "") 
14524                  (const_string "fmul")
14525                (match_operand:SF 3 "div_operator" "") 
14526                  (const_string "fdiv")
14527               ]
14528               (const_string "fop")))
14529    (set_attr "fp_int_src" "true")
14530    (set_attr "mode" "SI")])
14531
14532 (define_insn "*fop_sf_3"
14533   [(set (match_operand:SF 0 "register_operand" "=f,f")
14534         (match_operator:SF 3 "binary_fp_operator"
14535           [(match_operand:SF 1 "register_operand" "0,0")
14536            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14537   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14538   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14539   [(set (attr "type") 
14540         (cond [(match_operand:SF 3 "mult_operator" "") 
14541                  (const_string "fmul")
14542                (match_operand:SF 3 "div_operator" "") 
14543                  (const_string "fdiv")
14544               ]
14545               (const_string "fop")))
14546    (set_attr "fp_int_src" "true")
14547    (set_attr "mode" "SI")])
14548
14549 (define_insn "*fop_df_1_nosse"
14550   [(set (match_operand:DF 0 "register_operand" "=f,f")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14553                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14554   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14555    && !COMMUTATIVE_ARITH_P (operands[3])
14556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14557   "* return output_387_binary_op (insn, operands);"
14558   [(set (attr "type") 
14559         (cond [(match_operand:DF 3 "mult_operator" "") 
14560                  (const_string "fmul")
14561                (match_operand:DF 3 "div_operator" "")
14562                  (const_string "fdiv")
14563               ]
14564               (const_string "fop")))
14565    (set_attr "mode" "DF")])
14566
14567
14568 (define_insn "*fop_df_1"
14569   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14570         (match_operator:DF 3 "binary_fp_operator"
14571                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14572                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14573   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14574    && !COMMUTATIVE_ARITH_P (operands[3])
14575    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14576   "* return output_387_binary_op (insn, operands);"
14577   [(set (attr "type") 
14578         (cond [(and (eq_attr "alternative" "2")
14579                     (match_operand:SF 3 "mult_operator" ""))
14580                  (const_string "ssemul")
14581                (and (eq_attr "alternative" "2")
14582                     (match_operand:SF 3 "div_operator" ""))
14583                  (const_string "ssediv")
14584                (eq_attr "alternative" "2")
14585                  (const_string "sseadd")
14586                (match_operand:DF 3 "mult_operator" "") 
14587                  (const_string "fmul")
14588                (match_operand:DF 3 "div_operator" "") 
14589                  (const_string "fdiv")
14590               ]
14591               (const_string "fop")))
14592    (set_attr "mode" "DF")])
14593
14594 (define_insn "*fop_df_1_sse"
14595   [(set (match_operand:DF 0 "register_operand" "=Y")
14596         (match_operator:DF 3 "binary_fp_operator"
14597                         [(match_operand:DF 1 "register_operand" "0")
14598                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14599   "TARGET_SSE2 && TARGET_SSE_MATH
14600    && !COMMUTATIVE_ARITH_P (operands[3])"
14601   "* return output_387_binary_op (insn, operands);"
14602   [(set_attr "mode" "DF")
14603    (set (attr "type") 
14604         (cond [(match_operand:SF 3 "mult_operator" "")
14605                  (const_string "ssemul")
14606                (match_operand:SF 3 "div_operator" "")
14607                  (const_string "ssediv")
14608               ]
14609               (const_string "sseadd")))])
14610
14611 ;; ??? Add SSE splitters for these!
14612 (define_insn "*fop_df_2"
14613   [(set (match_operand:DF 0 "register_operand" "=f,f")
14614         (match_operator:DF 3 "binary_fp_operator"
14615            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616             (match_operand:DF 2 "register_operand" "0,0")]))]
14617   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14618   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:DF 3 "mult_operator" "") 
14621                  (const_string "fmul")
14622                (match_operand:DF 3 "div_operator" "") 
14623                  (const_string "fdiv")
14624               ]
14625               (const_string "fop")))
14626    (set_attr "fp_int_src" "true")
14627    (set_attr "mode" "SI")])
14628
14629 (define_insn "*fop_df_3"
14630   [(set (match_operand:DF 0 "register_operand" "=f,f")
14631         (match_operator:DF 3 "binary_fp_operator"
14632            [(match_operand:DF 1 "register_operand" "0,0")
14633             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14635   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:DF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:DF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "fp_int_src" "true")
14644    (set_attr "mode" "SI")])
14645
14646 (define_insn "*fop_df_4"
14647   [(set (match_operand:DF 0 "register_operand" "=f,f")
14648         (match_operator:DF 3 "binary_fp_operator"
14649            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14650             (match_operand:DF 2 "register_operand" "0,f")]))]
14651   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14653   "* return output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(match_operand:DF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:DF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "mode" "SF")])
14662
14663 (define_insn "*fop_df_5"
14664   [(set (match_operand:DF 0 "register_operand" "=f,f")
14665         (match_operator:DF 3 "binary_fp_operator"
14666           [(match_operand:DF 1 "register_operand" "0,f")
14667            (float_extend:DF
14668             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:DF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:DF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14679
14680 (define_insn "*fop_df_6"
14681   [(set (match_operand:DF 0 "register_operand" "=f,f")
14682         (match_operator:DF 3 "binary_fp_operator"
14683           [(float_extend:DF
14684             (match_operand:SF 1 "register_operand" "0,f"))
14685            (float_extend:DF
14686             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14687   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14688   "* return output_387_binary_op (insn, operands);"
14689   [(set (attr "type") 
14690         (cond [(match_operand:DF 3 "mult_operator" "") 
14691                  (const_string "fmul")
14692                (match_operand:DF 3 "div_operator" "") 
14693                  (const_string "fdiv")
14694               ]
14695               (const_string "fop")))
14696    (set_attr "mode" "SF")])
14697
14698 (define_insn "*fop_xf_1"
14699   [(set (match_operand:XF 0 "register_operand" "=f,f")
14700         (match_operator:XF 3 "binary_fp_operator"
14701                         [(match_operand:XF 1 "register_operand" "0,f")
14702                          (match_operand:XF 2 "register_operand" "f,0")]))]
14703   "TARGET_80387
14704    && !COMMUTATIVE_ARITH_P (operands[3])"
14705   "* return output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "mode" "XF")])
14714
14715 (define_insn "*fop_xf_2"
14716   [(set (match_operand:XF 0 "register_operand" "=f,f")
14717         (match_operator:XF 3 "binary_fp_operator"
14718            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14719             (match_operand:XF 2 "register_operand" "0,0")]))]
14720   "TARGET_80387 && TARGET_USE_FIOP"
14721   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14722   [(set (attr "type") 
14723         (cond [(match_operand:XF 3 "mult_operator" "") 
14724                  (const_string "fmul")
14725                (match_operand:XF 3 "div_operator" "") 
14726                  (const_string "fdiv")
14727               ]
14728               (const_string "fop")))
14729    (set_attr "fp_int_src" "true")
14730    (set_attr "mode" "SI")])
14731
14732 (define_insn "*fop_xf_3"
14733   [(set (match_operand:XF 0 "register_operand" "=f,f")
14734         (match_operator:XF 3 "binary_fp_operator"
14735           [(match_operand:XF 1 "register_operand" "0,0")
14736            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14737   "TARGET_80387 && TARGET_USE_FIOP"
14738   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:XF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:XF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "fp_int_src" "true")
14747    (set_attr "mode" "SI")])
14748
14749 (define_insn "*fop_xf_4"
14750   [(set (match_operand:XF 0 "register_operand" "=f,f")
14751         (match_operator:XF 3 "binary_fp_operator"
14752            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14753             (match_operand:XF 2 "register_operand" "0,f")]))]
14754   "TARGET_80387"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "SF")])
14764
14765 (define_insn "*fop_xf_5"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768           [(match_operand:XF 1 "register_operand" "0,f")
14769            (float_extend:XF
14770             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14771   "TARGET_80387"
14772   "* return output_387_binary_op (insn, operands);"
14773   [(set (attr "type") 
14774         (cond [(match_operand:XF 3 "mult_operator" "") 
14775                  (const_string "fmul")
14776                (match_operand:XF 3 "div_operator" "") 
14777                  (const_string "fdiv")
14778               ]
14779               (const_string "fop")))
14780    (set_attr "mode" "SF")])
14781
14782 (define_insn "*fop_xf_6"
14783   [(set (match_operand:XF 0 "register_operand" "=f,f")
14784         (match_operator:XF 3 "binary_fp_operator"
14785           [(float_extend:XF
14786             (match_operand 1 "register_operand" "0,f"))
14787            (float_extend:XF
14788             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14789   "TARGET_80387"
14790   "* return output_387_binary_op (insn, operands);"
14791   [(set (attr "type") 
14792         (cond [(match_operand:XF 3 "mult_operator" "") 
14793                  (const_string "fmul")
14794                (match_operand:XF 3 "div_operator" "") 
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "mode" "SF")])
14799
14800 (define_split
14801   [(set (match_operand 0 "register_operand" "")
14802         (match_operator 3 "binary_fp_operator"
14803            [(float (match_operand:SI 1 "register_operand" ""))
14804             (match_operand 2 "register_operand" "")]))]
14805   "TARGET_80387 && reload_completed
14806    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14807   [(const_int 0)]
14808
14809   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14810   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14811   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14812                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14813                                           GET_MODE (operands[3]),
14814                                           operands[4],
14815                                           operands[2])));
14816   ix86_free_from_memory (GET_MODE (operands[1]));
14817   DONE;
14818 })
14819
14820 (define_split
14821   [(set (match_operand 0 "register_operand" "")
14822         (match_operator 3 "binary_fp_operator"
14823            [(match_operand 1 "register_operand" "")
14824             (float (match_operand:SI 2 "register_operand" ""))]))]
14825   "TARGET_80387 && reload_completed
14826    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14827   [(const_int 0)]
14828 {
14829   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14831   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14832                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14833                                           GET_MODE (operands[3]),
14834                                           operands[1],
14835                                           operands[4])));
14836   ix86_free_from_memory (GET_MODE (operands[2]));
14837   DONE;
14838 })
14839 \f
14840 ;; FPU special functions.
14841
14842 (define_expand "sqrtsf2"
14843   [(set (match_operand:SF 0 "register_operand" "")
14844         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14845   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14846 {
14847   if (!TARGET_SSE_MATH)
14848     operands[1] = force_reg (SFmode, operands[1]);
14849 })
14850
14851 (define_insn "sqrtsf2_1"
14852   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14853         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14854   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14855    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14856   "@
14857    fsqrt
14858    sqrtss\t{%1, %0|%0, %1}"
14859   [(set_attr "type" "fpspc,sse")
14860    (set_attr "mode" "SF,SF")
14861    (set_attr "athlon_decode" "direct,*")])
14862
14863 (define_insn "sqrtsf2_1_sse_only"
14864   [(set (match_operand:SF 0 "register_operand" "=x")
14865         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14866   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14867   "sqrtss\t{%1, %0|%0, %1}"
14868   [(set_attr "type" "sse")
14869    (set_attr "mode" "SF")
14870    (set_attr "athlon_decode" "*")])
14871
14872 (define_insn "sqrtsf2_i387"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14875   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14876    && !TARGET_SSE_MATH"
14877   "fsqrt"
14878   [(set_attr "type" "fpspc")
14879    (set_attr "mode" "SF")
14880    (set_attr "athlon_decode" "direct")])
14881
14882 (define_expand "sqrtdf2"
14883   [(set (match_operand:DF 0 "register_operand" "")
14884         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14885   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14886    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14887 {
14888   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14889     operands[1] = force_reg (DFmode, operands[1]);
14890 })
14891
14892 (define_insn "sqrtdf2_1"
14893   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14894         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14895   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14896    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14897   "@
14898    fsqrt
14899    sqrtsd\t{%1, %0|%0, %1}"
14900   [(set_attr "type" "fpspc,sse")
14901    (set_attr "mode" "DF,DF")
14902    (set_attr "athlon_decode" "direct,*")])
14903
14904 (define_insn "sqrtdf2_1_sse_only"
14905   [(set (match_operand:DF 0 "register_operand" "=Y")
14906         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14907   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14908   "sqrtsd\t{%1, %0|%0, %1}"
14909   [(set_attr "type" "sse")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "*")])
14912
14913 (define_insn "sqrtdf2_i387"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14917    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")
14921    (set_attr "athlon_decode" "direct")])
14922
14923 (define_insn "*sqrtextendsfdf2"
14924   [(set (match_operand:DF 0 "register_operand" "=f")
14925         (sqrt:DF (float_extend:DF
14926                   (match_operand:SF 1 "register_operand" "0"))))]
14927   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14928    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14929   "fsqrt"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "DF")
14932    (set_attr "athlon_decode" "direct")])
14933
14934 (define_insn "sqrtxf2"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14937   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14938    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14939   "fsqrt"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "XF")
14942    (set_attr "athlon_decode" "direct")])
14943
14944 (define_insn "*sqrtextenddfxf2"
14945   [(set (match_operand:XF 0 "register_operand" "=f")
14946         (sqrt:XF (float_extend:XF
14947                   (match_operand:DF 1 "register_operand" "0"))))]
14948   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14949   "fsqrt"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "XF")
14952    (set_attr "athlon_decode" "direct")])
14953
14954 (define_insn "*sqrtextendsfxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (sqrt:XF (float_extend:XF
14957                   (match_operand:SF 1 "register_operand" "0"))))]
14958   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14959   "fsqrt"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")
14962    (set_attr "athlon_decode" "direct")])
14963
14964 (define_insn "fpremxf4"
14965   [(set (match_operand:XF 0 "register_operand" "=f")
14966         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14967                     (match_operand:XF 3 "register_operand" "1")]
14968                    UNSPEC_FPREM_F))
14969    (set (match_operand:XF 1 "register_operand" "=u")
14970         (unspec:XF [(match_dup 2) (match_dup 3)]
14971                    UNSPEC_FPREM_U))
14972    (set (reg:CCFP FPSR_REG)
14973         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14974   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14975    && flag_unsafe_math_optimizations"
14976   "fprem"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "XF")])
14979
14980 (define_expand "fmodsf3"
14981   [(use (match_operand:SF 0 "register_operand" ""))
14982    (use (match_operand:SF 1 "register_operand" ""))
14983    (use (match_operand:SF 2 "register_operand" ""))]
14984   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14985    && flag_unsafe_math_optimizations"
14986 {
14987   rtx label = gen_label_rtx ();
14988
14989   rtx op1 = gen_reg_rtx (XFmode);
14990   rtx op2 = gen_reg_rtx (XFmode);
14991
14992   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14993   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14994
14995   emit_label (label);
14996
14997   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14998   ix86_emit_fp_unordered_jump (label);
14999
15000   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15001   DONE;
15002 })
15003
15004 (define_expand "fmoddf3"
15005   [(use (match_operand:DF 0 "register_operand" ""))
15006    (use (match_operand:DF 1 "register_operand" ""))
15007    (use (match_operand:DF 2 "register_operand" ""))]
15008   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009    && flag_unsafe_math_optimizations"
15010 {
15011   rtx label = gen_label_rtx ();
15012
15013   rtx op1 = gen_reg_rtx (XFmode);
15014   rtx op2 = gen_reg_rtx (XFmode);
15015
15016   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15017   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15018
15019   emit_label (label);
15020
15021   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022   ix86_emit_fp_unordered_jump (label);
15023
15024   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15025   DONE;
15026 })
15027
15028 (define_expand "fmodxf3"
15029   [(use (match_operand:XF 0 "register_operand" ""))
15030    (use (match_operand:XF 1 "register_operand" ""))
15031    (use (match_operand:XF 2 "register_operand" ""))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15034 {
15035   rtx label = gen_label_rtx ();
15036
15037   emit_label (label);
15038
15039   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15040                            operands[1], operands[2]));
15041   ix86_emit_fp_unordered_jump (label);
15042
15043   emit_move_insn (operands[0], operands[1]);
15044   DONE;
15045 })
15046
15047 (define_insn "fprem1xf4"
15048   [(set (match_operand:XF 0 "register_operand" "=f")
15049         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15050                     (match_operand:XF 3 "register_operand" "1")]
15051                    UNSPEC_FPREM1_F))
15052    (set (match_operand:XF 1 "register_operand" "=u")
15053         (unspec:XF [(match_dup 2) (match_dup 3)]
15054                    UNSPEC_FPREM1_U))
15055    (set (reg:CCFP FPSR_REG)
15056         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15058    && flag_unsafe_math_optimizations"
15059   "fprem1"
15060   [(set_attr "type" "fpspc")
15061    (set_attr "mode" "XF")])
15062
15063 (define_expand "dremsf3"
15064   [(use (match_operand:SF 0 "register_operand" ""))
15065    (use (match_operand:SF 1 "register_operand" ""))
15066    (use (match_operand:SF 2 "register_operand" ""))]
15067   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068    && flag_unsafe_math_optimizations"
15069 {
15070   rtx label = gen_label_rtx ();
15071
15072   rtx op1 = gen_reg_rtx (XFmode);
15073   rtx op2 = gen_reg_rtx (XFmode);
15074
15075   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15076   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15077
15078   emit_label (label);
15079
15080   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15081   ix86_emit_fp_unordered_jump (label);
15082
15083   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15084   DONE;
15085 })
15086
15087 (define_expand "dremdf3"
15088   [(use (match_operand:DF 0 "register_operand" ""))
15089    (use (match_operand:DF 1 "register_operand" ""))
15090    (use (match_operand:DF 2 "register_operand" ""))]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15093 {
15094   rtx label = gen_label_rtx ();
15095
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15098
15099   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15100   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15101
15102   emit_label (label);
15103
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15106
15107   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15108   DONE;
15109 })
15110
15111 (define_expand "dremxf3"
15112   [(use (match_operand:XF 0 "register_operand" ""))
15113    (use (match_operand:XF 1 "register_operand" ""))
15114    (use (match_operand:XF 2 "register_operand" ""))]
15115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116    && flag_unsafe_math_optimizations"
15117 {
15118   rtx label = gen_label_rtx ();
15119
15120   emit_label (label);
15121
15122   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15123                             operands[1], operands[2]));
15124   ix86_emit_fp_unordered_jump (label);
15125
15126   emit_move_insn (operands[0], operands[1]);
15127   DONE;
15128 })
15129
15130 (define_insn "*sindf2"
15131   [(set (match_operand:DF 0 "register_operand" "=f")
15132         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15133   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "DF")])
15138
15139 (define_insn "*sinsf2"
15140   [(set (match_operand:SF 0 "register_operand" "=f")
15141         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15142   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15143    && flag_unsafe_math_optimizations"
15144   "fsin"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "SF")])
15147
15148 (define_insn "*sinextendsfdf2"
15149   [(set (match_operand:DF 0 "register_operand" "=f")
15150         (unspec:DF [(float_extend:DF
15151                      (match_operand:SF 1 "register_operand" "0"))]
15152                    UNSPEC_SIN))]
15153   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15154    && flag_unsafe_math_optimizations"
15155   "fsin"
15156   [(set_attr "type" "fpspc")
15157    (set_attr "mode" "DF")])
15158
15159 (define_insn "*sinxf2"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15162   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164   "fsin"
15165   [(set_attr "type" "fpspc")
15166    (set_attr "mode" "XF")])
15167
15168 (define_insn "*cosdf2"
15169   [(set (match_operand:DF 0 "register_operand" "=f")
15170         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15171   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15172    && flag_unsafe_math_optimizations"
15173   "fcos"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "DF")])
15176
15177 (define_insn "*cossf2"
15178   [(set (match_operand:SF 0 "register_operand" "=f")
15179         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15180   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "SF")])
15185
15186 (define_insn "*cosextendsfdf2"
15187   [(set (match_operand:DF 0 "register_operand" "=f")
15188         (unspec:DF [(float_extend:DF
15189                      (match_operand:SF 1 "register_operand" "0"))]
15190                    UNSPEC_COS))]
15191   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15192    && flag_unsafe_math_optimizations"
15193   "fcos"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "DF")])
15196
15197 (define_insn "*cosxf2"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 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" "XF")])
15205
15206 ;; With sincos pattern defined, sin and cos builtin function will be
15207 ;; expanded to sincos pattern with one of its outputs left unused. 
15208 ;; Cse pass  will detected, if two sincos patterns can be combined,
15209 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15210 ;; depending on the unused output.
15211
15212 (define_insn "sincosdf3"
15213   [(set (match_operand:DF 0 "register_operand" "=f")
15214         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15215                    UNSPEC_SINCOS_COS))
15216    (set (match_operand:DF 1 "register_operand" "=u")
15217         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15218   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15219    && flag_unsafe_math_optimizations"
15220   "fsincos"
15221   [(set_attr "type" "fpspc")
15222    (set_attr "mode" "DF")])
15223
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15233   "")
15234
15235 (define_split
15236   [(set (match_operand:DF 0 "register_operand" "")
15237         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:DF 1 "register_operand" "")
15240         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242    && !reload_completed && !reload_in_progress"
15243   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15244   "")
15245
15246 (define_insn "sincossf3"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249                    UNSPEC_SINCOS_COS))
15250    (set (match_operand:SF 1 "register_operand" "=u")
15251         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15253    && flag_unsafe_math_optimizations"
15254   "fsincos"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "SF")])
15257
15258 (define_split
15259   [(set (match_operand:SF 0 "register_operand" "")
15260         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15261                    UNSPEC_SINCOS_COS))
15262    (set (match_operand:SF 1 "register_operand" "")
15263         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267   "")
15268
15269 (define_split
15270   [(set (match_operand:SF 0 "register_operand" "")
15271         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15272                    UNSPEC_SINCOS_COS))
15273    (set (match_operand:SF 1 "register_operand" "")
15274         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15275   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15276    && !reload_completed && !reload_in_progress"
15277   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15278   "")
15279
15280 (define_insn "*sincosextendsfdf3"
15281   [(set (match_operand:DF 0 "register_operand" "=f")
15282         (unspec:DF [(float_extend:DF
15283                      (match_operand:SF 2 "register_operand" "0"))]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(float_extend:DF
15287                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15288   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15289    && flag_unsafe_math_optimizations"
15290   "fsincos"
15291   [(set_attr "type" "fpspc")
15292    (set_attr "mode" "DF")])
15293
15294 (define_split
15295   [(set (match_operand:DF 0 "register_operand" "")
15296         (unspec:DF [(float_extend:DF
15297                      (match_operand:SF 2 "register_operand" ""))]
15298                    UNSPEC_SINCOS_COS))
15299    (set (match_operand:DF 1 "register_operand" "")
15300         (unspec:DF [(float_extend:DF
15301                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15302   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15303    && !reload_completed && !reload_in_progress"
15304   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15305                                    (match_dup 2))] UNSPEC_SIN))]
15306   "")
15307
15308 (define_split
15309   [(set (match_operand:DF 0 "register_operand" "")
15310         (unspec:DF [(float_extend:DF
15311                      (match_operand:SF 2 "register_operand" ""))]
15312                    UNSPEC_SINCOS_COS))
15313    (set (match_operand:DF 1 "register_operand" "")
15314         (unspec:DF [(float_extend:DF
15315                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15316   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15317    && !reload_completed && !reload_in_progress"
15318   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15319                                    (match_dup 2))] UNSPEC_COS))]
15320   "")
15321
15322 (define_insn "sincosxf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15325                    UNSPEC_SINCOS_COS))
15326    (set (match_operand:XF 1 "register_operand" "=u")
15327         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15328   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15329    && flag_unsafe_math_optimizations"
15330   "fsincos"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15333
15334 (define_split
15335   [(set (match_operand:XF 0 "register_operand" "")
15336         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15337                    UNSPEC_SINCOS_COS))
15338    (set (match_operand:XF 1 "register_operand" "")
15339         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15340   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15343   "")
15344
15345 (define_split
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15348                    UNSPEC_SINCOS_COS))
15349    (set (match_operand:XF 1 "register_operand" "")
15350         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15351   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15352    && !reload_completed && !reload_in_progress"
15353   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354   "")
15355
15356 (define_insn "*tandf3_1"
15357   [(set (match_operand:DF 0 "register_operand" "=f")
15358         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15359                    UNSPEC_TAN_ONE))
15360    (set (match_operand:DF 1 "register_operand" "=u")
15361         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15362   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15363    && flag_unsafe_math_optimizations"
15364   "fptan"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "DF")])
15367
15368 ;; optimize sequence: fptan
15369 ;;                    fstp    %st(0)
15370 ;;                    fld1
15371 ;; into fptan insn.
15372
15373 (define_peephole2
15374   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15375                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376                              UNSPEC_TAN_ONE))
15377              (set (match_operand:DF 1 "register_operand" "")
15378                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379    (set (match_dup 0)
15380         (match_operand:DF 3 "immediate_operand" ""))]
15381   "standard_80387_constant_p (operands[3]) == 2"
15382   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15383              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15384   "")
15385
15386 (define_expand "tandf2"
15387   [(parallel [(set (match_dup 2)
15388                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389                               UNSPEC_TAN_ONE))
15390               (set (match_operand:DF 0 "register_operand" "")
15391                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15393    && flag_unsafe_math_optimizations"
15394 {
15395   operands[2] = gen_reg_rtx (DFmode);
15396 })
15397
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15405    && flag_unsafe_math_optimizations"
15406   "fptan"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "SF")])
15409
15410 ;; optimize sequence: fptan
15411 ;;                    fstp    %st(0)
15412 ;;                    fld1
15413 ;; into fptan insn.
15414
15415 (define_peephole2
15416   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15417                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15418                              UNSPEC_TAN_ONE))
15419              (set (match_operand:SF 1 "register_operand" "")
15420                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15421    (set (match_dup 0)
15422         (match_operand:SF 3 "immediate_operand" ""))]
15423   "standard_80387_constant_p (operands[3]) == 2"
15424   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15425              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15426   "")
15427
15428 (define_expand "tansf2"
15429   [(parallel [(set (match_dup 2)
15430                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15431                               UNSPEC_TAN_ONE))
15432               (set (match_operand:SF 0 "register_operand" "")
15433                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15434   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15435    && flag_unsafe_math_optimizations"
15436 {
15437   operands[2] = gen_reg_rtx (SFmode);
15438 })
15439
15440 (define_insn "*tanxf3_1"
15441   [(set (match_operand:XF 0 "register_operand" "=f")
15442         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15443                    UNSPEC_TAN_ONE))
15444    (set (match_operand:XF 1 "register_operand" "=u")
15445         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15446   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15447    && flag_unsafe_math_optimizations"
15448   "fptan"
15449   [(set_attr "type" "fpspc")
15450    (set_attr "mode" "XF")])
15451
15452 ;; optimize sequence: fptan
15453 ;;                    fstp    %st(0)
15454 ;;                    fld1
15455 ;; into fptan insn.
15456
15457 (define_peephole2
15458   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15459                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15460                              UNSPEC_TAN_ONE))
15461              (set (match_operand:XF 1 "register_operand" "")
15462                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15463    (set (match_dup 0)
15464         (match_operand:XF 3 "immediate_operand" ""))]
15465   "standard_80387_constant_p (operands[3]) == 2"
15466   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15467              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15468   "")
15469
15470 (define_expand "tanxf2"
15471   [(parallel [(set (match_dup 2)
15472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15473                               UNSPEC_TAN_ONE))
15474               (set (match_operand:XF 0 "register_operand" "")
15475                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15476   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15477    && flag_unsafe_math_optimizations"
15478 {
15479   operands[2] = gen_reg_rtx (XFmode);
15480 })
15481
15482 (define_insn "atan2df3_1"
15483   [(set (match_operand:DF 0 "register_operand" "=f")
15484         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15485                     (match_operand:DF 1 "register_operand" "u")]
15486                    UNSPEC_FPATAN))
15487    (clobber (match_scratch:DF 3 "=1"))]
15488   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15489    && flag_unsafe_math_optimizations"
15490   "fpatan"
15491   [(set_attr "type" "fpspc")
15492    (set_attr "mode" "DF")])
15493
15494 (define_expand "atan2df3"
15495   [(use (match_operand:DF 0 "register_operand" "=f"))
15496    (use (match_operand:DF 2 "register_operand" "0"))
15497    (use (match_operand:DF 1 "register_operand" "u"))]
15498   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15499    && flag_unsafe_math_optimizations"
15500 {
15501   rtx copy = gen_reg_rtx (DFmode);
15502   emit_move_insn (copy, operands[1]);
15503   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15504   DONE;
15505 })
15506
15507 (define_expand "atandf2"
15508   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15509                    (unspec:DF [(match_dup 2)
15510                                (match_operand:DF 1 "register_operand" "")]
15511                     UNSPEC_FPATAN))
15512               (clobber (match_scratch:DF 3 ""))])]
15513   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15514    && flag_unsafe_math_optimizations"
15515 {
15516   operands[2] = gen_reg_rtx (DFmode);
15517   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15518 })
15519
15520 (define_insn "atan2sf3_1"
15521   [(set (match_operand:SF 0 "register_operand" "=f")
15522         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15523                     (match_operand:SF 1 "register_operand" "u")]
15524                    UNSPEC_FPATAN))
15525    (clobber (match_scratch:SF 3 "=1"))]
15526   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15527    && flag_unsafe_math_optimizations"
15528   "fpatan"
15529   [(set_attr "type" "fpspc")
15530    (set_attr "mode" "SF")])
15531
15532 (define_expand "atan2sf3"
15533   [(use (match_operand:SF 0 "register_operand" "=f"))
15534    (use (match_operand:SF 2 "register_operand" "0"))
15535    (use (match_operand:SF 1 "register_operand" "u"))]
15536   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15537    && flag_unsafe_math_optimizations"
15538 {
15539   rtx copy = gen_reg_rtx (SFmode);
15540   emit_move_insn (copy, operands[1]);
15541   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15542   DONE;
15543 })
15544
15545 (define_expand "atansf2"
15546   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15547                    (unspec:SF [(match_dup 2)
15548                                (match_operand:SF 1 "register_operand" "")]
15549                     UNSPEC_FPATAN))
15550               (clobber (match_scratch:SF 3 ""))])]
15551   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15552    && flag_unsafe_math_optimizations"
15553 {
15554   operands[2] = gen_reg_rtx (SFmode);
15555   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15556 })
15557
15558 (define_insn "atan2xf3_1"
15559   [(set (match_operand:XF 0 "register_operand" "=f")
15560         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15561                     (match_operand:XF 1 "register_operand" "u")]
15562                    UNSPEC_FPATAN))
15563    (clobber (match_scratch:XF 3 "=1"))]
15564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15565    && flag_unsafe_math_optimizations"
15566   "fpatan"
15567   [(set_attr "type" "fpspc")
15568    (set_attr "mode" "XF")])
15569
15570 (define_expand "atan2xf3"
15571   [(use (match_operand:XF 0 "register_operand" "=f"))
15572    (use (match_operand:XF 2 "register_operand" "0"))
15573    (use (match_operand:XF 1 "register_operand" "u"))]
15574   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15575    && flag_unsafe_math_optimizations"
15576 {
15577   rtx copy = gen_reg_rtx (XFmode);
15578   emit_move_insn (copy, operands[1]);
15579   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15580   DONE;
15581 })
15582
15583 (define_expand "atanxf2"
15584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585                    (unspec:XF [(match_dup 2)
15586                                (match_operand:XF 1 "register_operand" "")]
15587                     UNSPEC_FPATAN))
15588               (clobber (match_scratch:XF 3 ""))])]
15589   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15590    && flag_unsafe_math_optimizations"
15591 {
15592   operands[2] = gen_reg_rtx (XFmode);
15593   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15594 })
15595
15596 (define_expand "asindf2"
15597   [(set (match_dup 2)
15598         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15599    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15600    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15601    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15602    (parallel [(set (match_dup 7)
15603                    (unspec:XF [(match_dup 6) (match_dup 2)]
15604                               UNSPEC_FPATAN))
15605               (clobber (match_scratch:XF 8 ""))])
15606    (set (match_operand:DF 0 "register_operand" "")
15607         (float_truncate:DF (match_dup 7)))]
15608   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15609    && flag_unsafe_math_optimizations"
15610 {
15611   int i;
15612
15613   for (i=2; i<8; i++)
15614     operands[i] = gen_reg_rtx (XFmode);
15615
15616   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15617 })
15618
15619 (define_expand "asinsf2"
15620   [(set (match_dup 2)
15621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15622    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15623    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15624    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15625    (parallel [(set (match_dup 7)
15626                    (unspec:XF [(match_dup 6) (match_dup 2)]
15627                               UNSPEC_FPATAN))
15628               (clobber (match_scratch:XF 8 ""))])
15629    (set (match_operand:SF 0 "register_operand" "")
15630         (float_truncate:SF (match_dup 7)))]
15631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15632    && flag_unsafe_math_optimizations"
15633 {
15634   int i;
15635
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15638
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15640 })
15641
15642 (define_expand "asinxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 5) (match_dup 1)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653    && flag_unsafe_math_optimizations"
15654 {
15655   int i;
15656
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15659
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15661 })
15662
15663 (define_expand "acosdf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15667    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15668    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15669    (parallel [(set (match_dup 7)
15670                    (unspec:XF [(match_dup 2) (match_dup 6)]
15671                               UNSPEC_FPATAN))
15672               (clobber (match_scratch:XF 8 ""))])
15673    (set (match_operand:DF 0 "register_operand" "")
15674         (float_truncate:DF (match_dup 7)))]
15675   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676    && flag_unsafe_math_optimizations"
15677 {
15678   int i;
15679
15680   for (i=2; i<8; i++)
15681     operands[i] = gen_reg_rtx (XFmode);
15682
15683   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15684 })
15685
15686 (define_expand "acossf2"
15687   [(set (match_dup 2)
15688         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15689    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15690    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15691    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15692    (parallel [(set (match_dup 7)
15693                    (unspec:XF [(match_dup 2) (match_dup 6)]
15694                               UNSPEC_FPATAN))
15695               (clobber (match_scratch:XF 8 ""))])
15696    (set (match_operand:SF 0 "register_operand" "")
15697         (float_truncate:SF (match_dup 7)))]
15698   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15699    && flag_unsafe_math_optimizations"
15700 {
15701   int i;
15702
15703   for (i=2; i<8; i++)
15704     operands[i] = gen_reg_rtx (XFmode);
15705
15706   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15707 })
15708
15709 (define_expand "acosxf2"
15710   [(set (match_dup 2)
15711         (mult:XF (match_operand:XF 1 "register_operand" "")
15712                  (match_dup 1)))
15713    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15714    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15715    (parallel [(set (match_operand:XF 0 "register_operand" "")
15716                    (unspec:XF [(match_dup 1) (match_dup 5)]
15717                               UNSPEC_FPATAN))
15718               (clobber (match_scratch:XF 6 ""))])]
15719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15720    && flag_unsafe_math_optimizations"
15721 {
15722   int i;
15723
15724   for (i=2; i<6; i++)
15725     operands[i] = gen_reg_rtx (XFmode);
15726
15727   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15728 })
15729
15730 (define_insn "fyl2x_xf3"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15733                     (match_operand:XF 1 "register_operand" "u")]
15734                    UNSPEC_FYL2X))
15735    (clobber (match_scratch:XF 3 "=1"))]
15736   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15737    && flag_unsafe_math_optimizations"
15738   "fyl2x"
15739   [(set_attr "type" "fpspc")
15740    (set_attr "mode" "XF")])
15741
15742 (define_expand "logsf2"
15743   [(set (match_dup 2)
15744         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15745    (parallel [(set (match_dup 4)
15746                    (unspec:XF [(match_dup 2)
15747                                (match_dup 3)] UNSPEC_FYL2X))
15748               (clobber (match_scratch:XF 5 ""))])
15749    (set (match_operand:SF 0 "register_operand" "")
15750         (float_truncate:SF (match_dup 4)))]
15751   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15752    && flag_unsafe_math_optimizations"
15753 {
15754   rtx temp;
15755
15756   operands[2] = gen_reg_rtx (XFmode);
15757   operands[3] = gen_reg_rtx (XFmode);
15758   operands[4] = gen_reg_rtx (XFmode);
15759
15760   temp = standard_80387_constant_rtx (4); /* fldln2 */
15761   emit_move_insn (operands[3], temp);
15762 })
15763
15764 (define_expand "logdf2"
15765   [(set (match_dup 2)
15766         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15767    (parallel [(set (match_dup 4)
15768                    (unspec:XF [(match_dup 2)
15769                                (match_dup 3)] UNSPEC_FYL2X))
15770               (clobber (match_scratch:XF 5 ""))])
15771    (set (match_operand:DF 0 "register_operand" "")
15772         (float_truncate:DF (match_dup 4)))]
15773   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15774    && flag_unsafe_math_optimizations"
15775 {
15776   rtx temp;
15777
15778   operands[2] = gen_reg_rtx (XFmode);
15779   operands[3] = gen_reg_rtx (XFmode);
15780   operands[4] = gen_reg_rtx (XFmode);
15781
15782   temp = standard_80387_constant_rtx (4); /* fldln2 */
15783   emit_move_insn (operands[3], temp);
15784 })
15785
15786 (define_expand "logxf2"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15789                                (match_dup 2)] UNSPEC_FYL2X))
15790               (clobber (match_scratch:XF 3 ""))])]
15791   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792    && flag_unsafe_math_optimizations"
15793 {
15794   rtx temp;
15795
15796   operands[2] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (4); /* fldln2 */
15798   emit_move_insn (operands[2], temp);
15799 })
15800
15801 (define_expand "log10sf2"
15802   [(set (match_dup 2)
15803         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15804    (parallel [(set (match_dup 4)
15805                    (unspec:XF [(match_dup 2)
15806                                (match_dup 3)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 5 ""))])
15808    (set (match_operand:SF 0 "register_operand" "")
15809         (float_truncate:SF (match_dup 4)))]
15810   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15811    && flag_unsafe_math_optimizations"
15812 {
15813   rtx temp;
15814
15815   operands[2] = gen_reg_rtx (XFmode);
15816   operands[3] = gen_reg_rtx (XFmode);
15817   operands[4] = gen_reg_rtx (XFmode);
15818
15819   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15820   emit_move_insn (operands[3], temp);
15821 })
15822
15823 (define_expand "log10df2"
15824   [(set (match_dup 2)
15825         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15826    (parallel [(set (match_dup 4)
15827                    (unspec:XF [(match_dup 2)
15828                                (match_dup 3)] UNSPEC_FYL2X))
15829               (clobber (match_scratch:XF 5 ""))])
15830    (set (match_operand:DF 0 "register_operand" "")
15831         (float_truncate:DF (match_dup 4)))]
15832   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15833    && flag_unsafe_math_optimizations"
15834 {
15835   rtx temp;
15836
15837   operands[2] = gen_reg_rtx (XFmode);
15838   operands[3] = gen_reg_rtx (XFmode);
15839   operands[4] = gen_reg_rtx (XFmode);
15840
15841   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15842   emit_move_insn (operands[3], temp);
15843 })
15844
15845 (define_expand "log10xf2"
15846   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15847                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15848                                (match_dup 2)] UNSPEC_FYL2X))
15849               (clobber (match_scratch:XF 3 ""))])]
15850   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15851    && flag_unsafe_math_optimizations"
15852 {
15853   rtx temp;
15854
15855   operands[2] = gen_reg_rtx (XFmode);
15856   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15857   emit_move_insn (operands[2], temp);
15858 })
15859
15860 (define_expand "log2sf2"
15861   [(set (match_dup 2)
15862         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15863    (parallel [(set (match_dup 4)
15864                    (unspec:XF [(match_dup 2)
15865                                (match_dup 3)] UNSPEC_FYL2X))
15866               (clobber (match_scratch:XF 5 ""))])
15867    (set (match_operand:SF 0 "register_operand" "")
15868         (float_truncate:SF (match_dup 4)))]
15869   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15870    && flag_unsafe_math_optimizations"
15871 {
15872   operands[2] = gen_reg_rtx (XFmode);
15873   operands[3] = gen_reg_rtx (XFmode);
15874   operands[4] = gen_reg_rtx (XFmode);
15875
15876   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15877 })
15878
15879 (define_expand "log2df2"
15880   [(set (match_dup 2)
15881         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15882    (parallel [(set (match_dup 4)
15883                    (unspec:XF [(match_dup 2)
15884                                (match_dup 3)] UNSPEC_FYL2X))
15885               (clobber (match_scratch:XF 5 ""))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 4)))]
15888   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15889    && flag_unsafe_math_optimizations"
15890 {
15891   operands[2] = gen_reg_rtx (XFmode);
15892   operands[3] = gen_reg_rtx (XFmode);
15893   operands[4] = gen_reg_rtx (XFmode);
15894
15895   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15896 })
15897
15898 (define_expand "log2xf2"
15899   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15900                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15901                                (match_dup 2)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 3 ""))])]
15903   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15904    && flag_unsafe_math_optimizations"
15905 {
15906   operands[2] = gen_reg_rtx (XFmode);
15907   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15908 })
15909
15910 (define_insn "fyl2xp1_xf3"
15911   [(set (match_operand:XF 0 "register_operand" "=f")
15912         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15913                     (match_operand:XF 1 "register_operand" "u")]
15914                    UNSPEC_FYL2XP1))
15915    (clobber (match_scratch:XF 3 "=1"))]
15916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15917    && flag_unsafe_math_optimizations"
15918   "fyl2xp1"
15919   [(set_attr "type" "fpspc")
15920    (set_attr "mode" "XF")])
15921
15922 (define_expand "log1psf2"
15923   [(use (match_operand:XF 0 "register_operand" ""))
15924    (use (match_operand:XF 1 "register_operand" ""))]
15925   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15926    && flag_unsafe_math_optimizations"
15927 {
15928   rtx op0 = gen_reg_rtx (XFmode);
15929   rtx op1 = gen_reg_rtx (XFmode);
15930
15931   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15932   ix86_emit_i387_log1p (op0, op1);
15933   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15934   DONE;
15935 })
15936
15937 (define_expand "log1pdf2"
15938   [(use (match_operand:XF 0 "register_operand" ""))
15939    (use (match_operand:XF 1 "register_operand" ""))]
15940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941    && flag_unsafe_math_optimizations"
15942 {
15943   rtx op0 = gen_reg_rtx (XFmode);
15944   rtx op1 = gen_reg_rtx (XFmode);
15945
15946   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15947   ix86_emit_i387_log1p (op0, op1);
15948   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15949   DONE;
15950 })
15951
15952 (define_expand "log1pxf2"
15953   [(use (match_operand:XF 0 "register_operand" ""))
15954    (use (match_operand:XF 1 "register_operand" ""))]
15955   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15956    && flag_unsafe_math_optimizations"
15957 {
15958   ix86_emit_i387_log1p (operands[0], operands[1]);
15959   DONE;
15960 })
15961
15962 (define_insn "*fxtractxf3"
15963   [(set (match_operand:XF 0 "register_operand" "=f")
15964         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15965                    UNSPEC_XTRACT_FRACT))
15966    (set (match_operand:XF 1 "register_operand" "=u")
15967         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15968   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15969    && flag_unsafe_math_optimizations"
15970   "fxtract"
15971   [(set_attr "type" "fpspc")
15972    (set_attr "mode" "XF")])
15973
15974 (define_expand "logbsf2"
15975   [(set (match_dup 2)
15976         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15977    (parallel [(set (match_dup 3)
15978                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15979               (set (match_dup 4)
15980                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15981    (set (match_operand:SF 0 "register_operand" "")
15982         (float_truncate:SF (match_dup 4)))]
15983   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15984    && flag_unsafe_math_optimizations"
15985 {
15986   operands[2] = gen_reg_rtx (XFmode);
15987   operands[3] = gen_reg_rtx (XFmode);
15988   operands[4] = gen_reg_rtx (XFmode);
15989 })
15990
15991 (define_expand "logbdf2"
15992   [(set (match_dup 2)
15993         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15994    (parallel [(set (match_dup 3)
15995                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15996               (set (match_dup 4)
15997                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15998    (set (match_operand:DF 0 "register_operand" "")
15999         (float_truncate:DF (match_dup 4)))]
16000   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16001    && flag_unsafe_math_optimizations"
16002 {
16003   operands[2] = gen_reg_rtx (XFmode);
16004   operands[3] = gen_reg_rtx (XFmode);
16005   operands[4] = gen_reg_rtx (XFmode);
16006 })
16007
16008 (define_expand "logbxf2"
16009   [(parallel [(set (match_dup 2)
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16011                               UNSPEC_XTRACT_FRACT))
16012               (set (match_operand:XF 0 "register_operand" "")
16013                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16014   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16015    && flag_unsafe_math_optimizations"
16016 {
16017   operands[2] = gen_reg_rtx (XFmode);
16018 })
16019
16020 (define_expand "ilogbsi2"
16021   [(parallel [(set (match_dup 2)
16022                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16023                               UNSPEC_XTRACT_FRACT))
16024               (set (match_operand:XF 3 "register_operand" "")
16025                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16026    (parallel [(set (match_operand:SI 0 "register_operand" "")
16027                    (fix:SI (match_dup 3)))
16028               (clobber (reg:CC FLAGS_REG))])]
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 })
16035
16036 (define_insn "*f2xm1xf2"
16037   [(set (match_operand:XF 0 "register_operand" "=f")
16038         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16039          UNSPEC_F2XM1))]
16040   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16041    && flag_unsafe_math_optimizations"
16042   "f2xm1"
16043   [(set_attr "type" "fpspc")
16044    (set_attr "mode" "XF")])
16045
16046 (define_insn "*fscalexf4"
16047   [(set (match_operand:XF 0 "register_operand" "=f")
16048         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16049                     (match_operand:XF 3 "register_operand" "1")]
16050                    UNSPEC_FSCALE_FRACT))
16051    (set (match_operand:XF 1 "register_operand" "=u")
16052         (unspec:XF [(match_dup 2) (match_dup 3)]
16053                    UNSPEC_FSCALE_EXP))]
16054   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16055    && flag_unsafe_math_optimizations"
16056   "fscale"
16057   [(set_attr "type" "fpspc")
16058    (set_attr "mode" "XF")])
16059
16060 (define_expand "expsf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16063    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16064    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16065    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16066    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16067    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16068    (parallel [(set (match_dup 10)
16069                    (unspec:XF [(match_dup 9) (match_dup 5)]
16070                               UNSPEC_FSCALE_FRACT))
16071               (set (match_dup 11)
16072                    (unspec:XF [(match_dup 9) (match_dup 5)]
16073                               UNSPEC_FSCALE_EXP))])
16074    (set (match_operand:SF 0 "register_operand" "")
16075         (float_truncate:SF (match_dup 10)))]
16076   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16077    && flag_unsafe_math_optimizations"
16078 {
16079   rtx temp;
16080   int i;
16081
16082   for (i=2; i<12; i++)
16083     operands[i] = gen_reg_rtx (XFmode);
16084   temp = standard_80387_constant_rtx (5); /* fldl2e */
16085   emit_move_insn (operands[3], temp);
16086   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16087 })
16088
16089 (define_expand "expdf2"
16090   [(set (match_dup 2)
16091         (float_extend:XF (match_operand:DF 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:DF 0 "register_operand" "")
16104         (float_truncate:DF (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 "expxf2"
16119   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16120                                (match_dup 2)))
16121    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16122    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16123    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16124    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16125    (parallel [(set (match_operand:XF 0 "register_operand" "")
16126                    (unspec:XF [(match_dup 8) (match_dup 4)]
16127                               UNSPEC_FSCALE_FRACT))
16128               (set (match_dup 9)
16129                    (unspec:XF [(match_dup 8) (match_dup 4)]
16130                               UNSPEC_FSCALE_EXP))])]
16131   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16132    && flag_unsafe_math_optimizations"
16133 {
16134   rtx temp;
16135   int i;
16136
16137   for (i=2; i<10; i++)
16138     operands[i] = gen_reg_rtx (XFmode);
16139   temp = standard_80387_constant_rtx (5); /* fldl2e */
16140   emit_move_insn (operands[2], temp);
16141   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16142 })
16143
16144 (define_expand "exp10sf2"
16145   [(set (match_dup 2)
16146         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16147    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16148    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16149    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16150    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16151    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16152    (parallel [(set (match_dup 10)
16153                    (unspec:XF [(match_dup 9) (match_dup 5)]
16154                               UNSPEC_FSCALE_FRACT))
16155               (set (match_dup 11)
16156                    (unspec:XF [(match_dup 9) (match_dup 5)]
16157                               UNSPEC_FSCALE_EXP))])
16158    (set (match_operand:SF 0 "register_operand" "")
16159         (float_truncate:SF (match_dup 10)))]
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<12; i++)
16167     operands[i] = gen_reg_rtx (XFmode);
16168   temp = standard_80387_constant_rtx (6); /* fldl2t */
16169   emit_move_insn (operands[3], temp);
16170   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16171 })
16172
16173 (define_expand "exp10df2"
16174   [(set (match_dup 2)
16175         (float_extend:XF (match_operand:DF 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:DF 0 "register_operand" "")
16188         (float_truncate:DF (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 "exp10xf2"
16203   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16204                                (match_dup 2)))
16205    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16206    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16207    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16208    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16209    (parallel [(set (match_operand:XF 0 "register_operand" "")
16210                    (unspec:XF [(match_dup 8) (match_dup 4)]
16211                               UNSPEC_FSCALE_FRACT))
16212               (set (match_dup 9)
16213                    (unspec:XF [(match_dup 8) (match_dup 4)]
16214                               UNSPEC_FSCALE_EXP))])]
16215   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16216    && flag_unsafe_math_optimizations"
16217 {
16218   rtx temp;
16219   int i;
16220
16221   for (i=2; i<10; i++)
16222     operands[i] = gen_reg_rtx (XFmode);
16223   temp = standard_80387_constant_rtx (6); /* fldl2t */
16224   emit_move_insn (operands[2], temp);
16225   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16226 })
16227
16228 (define_expand "exp2sf2"
16229   [(set (match_dup 2)
16230         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16231    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16232    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16233    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16234    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16235    (parallel [(set (match_dup 8)
16236                    (unspec:XF [(match_dup 7) (match_dup 3)]
16237                               UNSPEC_FSCALE_FRACT))
16238               (set (match_dup 9)
16239                    (unspec:XF [(match_dup 7) (match_dup 3)]
16240                               UNSPEC_FSCALE_EXP))])
16241    (set (match_operand:SF 0 "register_operand" "")
16242         (float_truncate:SF (match_dup 8)))]
16243   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16244    && flag_unsafe_math_optimizations"
16245 {
16246   int i;
16247
16248   for (i=2; i<10; i++)
16249     operands[i] = gen_reg_rtx (XFmode);
16250   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16251 })
16252
16253 (define_expand "exp2df2"
16254   [(set (match_dup 2)
16255         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16256    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16257    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16258    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16259    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16260    (parallel [(set (match_dup 8)
16261                    (unspec:XF [(match_dup 7) (match_dup 3)]
16262                               UNSPEC_FSCALE_FRACT))
16263               (set (match_dup 9)
16264                    (unspec:XF [(match_dup 7) (match_dup 3)]
16265                               UNSPEC_FSCALE_EXP))])
16266    (set (match_operand:DF 0 "register_operand" "")
16267         (float_truncate:DF (match_dup 8)))]
16268   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16269    && flag_unsafe_math_optimizations"
16270 {
16271   int i;
16272
16273   for (i=2; i<10; i++)
16274     operands[i] = gen_reg_rtx (XFmode);
16275   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16276 })
16277
16278 (define_expand "exp2xf2"
16279   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16280    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16281    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16282    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16283    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16284    (parallel [(set (match_operand:XF 0 "register_operand" "")
16285                    (unspec:XF [(match_dup 7) (match_dup 3)]
16286                               UNSPEC_FSCALE_FRACT))
16287               (set (match_dup 8)
16288                    (unspec:XF [(match_dup 7) (match_dup 3)]
16289                               UNSPEC_FSCALE_EXP))])]
16290   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16291    && flag_unsafe_math_optimizations"
16292 {
16293   int i;
16294
16295   for (i=2; i<9; i++)
16296     operands[i] = gen_reg_rtx (XFmode);
16297   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16298 })
16299
16300 (define_expand "expm1df2"
16301   [(set (match_dup 2)
16302         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16303    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16304    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16305    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16306    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16307    (parallel [(set (match_dup 8)
16308                    (unspec:XF [(match_dup 7) (match_dup 5)]
16309                               UNSPEC_FSCALE_FRACT))
16310                    (set (match_dup 9)
16311                    (unspec:XF [(match_dup 7) (match_dup 5)]
16312                               UNSPEC_FSCALE_EXP))])
16313    (parallel [(set (match_dup 11)
16314                    (unspec:XF [(match_dup 10) (match_dup 9)]
16315                               UNSPEC_FSCALE_FRACT))
16316               (set (match_dup 12)
16317                    (unspec:XF [(match_dup 10) (match_dup 9)]
16318                               UNSPEC_FSCALE_EXP))])
16319    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16320    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16321    (set (match_operand:DF 0 "register_operand" "")
16322         (float_truncate:DF (match_dup 14)))]
16323   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16324    && flag_unsafe_math_optimizations"
16325 {
16326   rtx temp;
16327   int i;
16328
16329   for (i=2; i<15; i++)
16330     operands[i] = gen_reg_rtx (XFmode);
16331   temp = standard_80387_constant_rtx (5); /* fldl2e */
16332   emit_move_insn (operands[3], temp);
16333   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16334 })
16335
16336 (define_expand "expm1sf2"
16337   [(set (match_dup 2)
16338         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16339    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16340    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16341    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16342    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16343    (parallel [(set (match_dup 8)
16344                    (unspec:XF [(match_dup 7) (match_dup 5)]
16345                               UNSPEC_FSCALE_FRACT))
16346                    (set (match_dup 9)
16347                    (unspec:XF [(match_dup 7) (match_dup 5)]
16348                               UNSPEC_FSCALE_EXP))])
16349    (parallel [(set (match_dup 11)
16350                    (unspec:XF [(match_dup 10) (match_dup 9)]
16351                               UNSPEC_FSCALE_FRACT))
16352               (set (match_dup 12)
16353                    (unspec:XF [(match_dup 10) (match_dup 9)]
16354                               UNSPEC_FSCALE_EXP))])
16355    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16356    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16357    (set (match_operand:SF 0 "register_operand" "")
16358         (float_truncate:SF (match_dup 14)))]
16359   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16360    && flag_unsafe_math_optimizations"
16361 {
16362   rtx temp;
16363   int i;
16364
16365   for (i=2; i<15; i++)
16366     operands[i] = gen_reg_rtx (XFmode);
16367   temp = standard_80387_constant_rtx (5); /* fldl2e */
16368   emit_move_insn (operands[3], temp);
16369   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16370 })
16371
16372 (define_expand "expm1xf2"
16373   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16374                                (match_dup 2)))
16375    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16376    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16377    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16378    (parallel [(set (match_dup 7)
16379                    (unspec:XF [(match_dup 6) (match_dup 4)]
16380                               UNSPEC_FSCALE_FRACT))
16381                    (set (match_dup 8)
16382                    (unspec:XF [(match_dup 6) (match_dup 4)]
16383                               UNSPEC_FSCALE_EXP))])
16384    (parallel [(set (match_dup 10)
16385                    (unspec:XF [(match_dup 9) (match_dup 8)]
16386                               UNSPEC_FSCALE_FRACT))
16387               (set (match_dup 11)
16388                    (unspec:XF [(match_dup 9) (match_dup 8)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16391    (set (match_operand:XF 0 "register_operand" "")
16392         (plus:XF (match_dup 12) (match_dup 7)))]
16393   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16394    && flag_unsafe_math_optimizations"
16395 {
16396   rtx temp;
16397   int i;
16398
16399   for (i=2; i<13; i++)
16400     operands[i] = gen_reg_rtx (XFmode);
16401   temp = standard_80387_constant_rtx (5); /* fldl2e */
16402   emit_move_insn (operands[2], temp);
16403   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16404 })
16405 \f
16406
16407 (define_insn "frndintxf2"
16408   [(set (match_operand:XF 0 "register_operand" "=f")
16409         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16410          UNSPEC_FRNDINT))]
16411   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16412    && flag_unsafe_math_optimizations"
16413   "frndint"
16414   [(set_attr "type" "fpspc")
16415    (set_attr "mode" "XF")])
16416
16417 (define_expand "rintdf2"
16418   [(use (match_operand:DF 0 "register_operand" ""))
16419    (use (match_operand:DF 1 "register_operand" ""))]
16420   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16421    && flag_unsafe_math_optimizations"
16422 {
16423   rtx op0 = gen_reg_rtx (XFmode);
16424   rtx op1 = gen_reg_rtx (XFmode);
16425
16426   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16427   emit_insn (gen_frndintxf2 (op0, op1));
16428
16429   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16430   DONE;
16431 })
16432
16433 (define_expand "rintsf2"
16434   [(use (match_operand:SF 0 "register_operand" ""))
16435    (use (match_operand:SF 1 "register_operand" ""))]
16436   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16437    && flag_unsafe_math_optimizations"
16438 {
16439   rtx op0 = gen_reg_rtx (XFmode);
16440   rtx op1 = gen_reg_rtx (XFmode);
16441
16442   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16443   emit_insn (gen_frndintxf2 (op0, op1));
16444
16445   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16446   DONE;
16447 })
16448
16449 (define_expand "rintxf2"
16450   [(use (match_operand:XF 0 "register_operand" ""))
16451    (use (match_operand:XF 1 "register_operand" ""))]
16452   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16453    && flag_unsafe_math_optimizations"
16454 {
16455   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16456   DONE;
16457 })
16458
16459 (define_insn "frndintxf2_floor"
16460   [(set (match_operand:XF 0 "register_operand" "=f")
16461         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16462          UNSPEC_FRNDINT_FLOOR))
16463    (use (match_operand:HI 2 "memory_operand" "m"))
16464    (use (match_operand:HI 3 "memory_operand" "m"))]
16465   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16466    && flag_unsafe_math_optimizations"
16467   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16468   [(set_attr "type" "frndint")
16469    (set_attr "i387_cw" "floor")
16470    (set_attr "mode" "XF")])
16471
16472 (define_expand "floordf2"
16473   [(use (match_operand:DF 0 "register_operand" ""))
16474    (use (match_operand:DF 1 "register_operand" ""))]
16475   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16476    && flag_unsafe_math_optimizations"
16477 {
16478   rtx op0 = gen_reg_rtx (XFmode);
16479   rtx op1 = gen_reg_rtx (XFmode);
16480   rtx op2 = assign_386_stack_local (HImode, 1);
16481   rtx op3 = assign_386_stack_local (HImode, 2);
16482         
16483   ix86_optimize_mode_switching = 1;
16484
16485   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16486   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16487
16488   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16489   DONE;
16490 })
16491
16492 (define_expand "floorsf2"
16493   [(use (match_operand:SF 0 "register_operand" ""))
16494    (use (match_operand:SF 1 "register_operand" ""))]
16495   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16496    && flag_unsafe_math_optimizations"
16497 {
16498   rtx op0 = gen_reg_rtx (XFmode);
16499   rtx op1 = gen_reg_rtx (XFmode);
16500   rtx op2 = assign_386_stack_local (HImode, 1);
16501   rtx op3 = assign_386_stack_local (HImode, 2);
16502         
16503   ix86_optimize_mode_switching = 1;
16504
16505   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16506   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16507
16508   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16509   DONE;
16510 })
16511
16512 (define_expand "floorxf2"
16513   [(use (match_operand:XF 0 "register_operand" ""))
16514    (use (match_operand:XF 1 "register_operand" ""))]
16515   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16516    && flag_unsafe_math_optimizations"
16517 {
16518   rtx op2 = assign_386_stack_local (HImode, 1);
16519   rtx op3 = assign_386_stack_local (HImode, 2);
16520         
16521   ix86_optimize_mode_switching = 1;
16522
16523   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16524   DONE;
16525 })
16526
16527 (define_insn "frndintxf2_ceil"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16530          UNSPEC_FRNDINT_CEIL))
16531    (use (match_operand:HI 2 "memory_operand" "m"))
16532    (use (match_operand:HI 3 "memory_operand" "m"))]
16533   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16534    && flag_unsafe_math_optimizations"
16535   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16536   [(set_attr "type" "frndint")
16537    (set_attr "i387_cw" "ceil")
16538    (set_attr "mode" "XF")])
16539
16540 (define_expand "ceildf2"
16541   [(use (match_operand:DF 0 "register_operand" ""))
16542    (use (match_operand:DF 1 "register_operand" ""))]
16543   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16544    && flag_unsafe_math_optimizations"
16545 {
16546   rtx op0 = gen_reg_rtx (XFmode);
16547   rtx op1 = gen_reg_rtx (XFmode);
16548   rtx op2 = assign_386_stack_local (HImode, 1);
16549   rtx op3 = assign_386_stack_local (HImode, 2);
16550         
16551   ix86_optimize_mode_switching = 1;
16552
16553   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16554   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16555
16556   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16557   DONE;
16558 })
16559
16560 (define_expand "ceilsf2"
16561   [(use (match_operand:SF 0 "register_operand" ""))
16562    (use (match_operand:SF 1 "register_operand" ""))]
16563   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16564    && flag_unsafe_math_optimizations"
16565 {
16566   rtx op0 = gen_reg_rtx (XFmode);
16567   rtx op1 = gen_reg_rtx (XFmode);
16568   rtx op2 = assign_386_stack_local (HImode, 1);
16569   rtx op3 = assign_386_stack_local (HImode, 2);
16570         
16571   ix86_optimize_mode_switching = 1;
16572
16573   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16574   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16575
16576   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16577   DONE;
16578 })
16579
16580 (define_expand "ceilxf2"
16581   [(use (match_operand:XF 0 "register_operand" ""))
16582    (use (match_operand:XF 1 "register_operand" ""))]
16583   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16584    && flag_unsafe_math_optimizations"
16585 {
16586   rtx op2 = assign_386_stack_local (HImode, 1);
16587   rtx op3 = assign_386_stack_local (HImode, 2);
16588         
16589   ix86_optimize_mode_switching = 1;
16590
16591   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16592   DONE;
16593 })
16594
16595 (define_insn "frndintxf2_trunc"
16596   [(set (match_operand:XF 0 "register_operand" "=f")
16597         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16598          UNSPEC_FRNDINT_TRUNC))
16599    (use (match_operand:HI 2 "memory_operand" "m"))
16600    (use (match_operand:HI 3 "memory_operand" "m"))]
16601   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16602    && flag_unsafe_math_optimizations"
16603   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16604   [(set_attr "type" "frndint")
16605    (set_attr "i387_cw" "trunc")
16606    (set_attr "mode" "XF")])
16607
16608 (define_expand "btruncdf2"
16609   [(use (match_operand:DF 0 "register_operand" ""))
16610    (use (match_operand:DF 1 "register_operand" ""))]
16611   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16612    && flag_unsafe_math_optimizations"
16613 {
16614   rtx op0 = gen_reg_rtx (XFmode);
16615   rtx op1 = gen_reg_rtx (XFmode);
16616   rtx op2 = assign_386_stack_local (HImode, 1);
16617   rtx op3 = assign_386_stack_local (HImode, 2);
16618         
16619   ix86_optimize_mode_switching = 1;
16620
16621   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16622   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16623
16624   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16625   DONE;
16626 })
16627
16628 (define_expand "btruncsf2"
16629   [(use (match_operand:SF 0 "register_operand" ""))
16630    (use (match_operand:SF 1 "register_operand" ""))]
16631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16632    && flag_unsafe_math_optimizations"
16633 {
16634   rtx op0 = gen_reg_rtx (XFmode);
16635   rtx op1 = gen_reg_rtx (XFmode);
16636   rtx op2 = assign_386_stack_local (HImode, 1);
16637   rtx op3 = assign_386_stack_local (HImode, 2);
16638         
16639   ix86_optimize_mode_switching = 1;
16640
16641   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16642   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16643
16644   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16645   DONE;
16646 })
16647
16648 (define_expand "btruncxf2"
16649   [(use (match_operand:XF 0 "register_operand" ""))
16650    (use (match_operand:XF 1 "register_operand" ""))]
16651   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16652    && flag_unsafe_math_optimizations"
16653 {
16654   rtx op2 = assign_386_stack_local (HImode, 1);
16655   rtx op3 = assign_386_stack_local (HImode, 2);
16656         
16657   ix86_optimize_mode_switching = 1;
16658
16659   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16660   DONE;
16661 })
16662
16663 (define_insn "frndintxf2_mask_pm"
16664   [(set (match_operand:XF 0 "register_operand" "=f")
16665         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16666          UNSPEC_FRNDINT_MASK_PM))
16667    (use (match_operand:HI 2 "memory_operand" "m"))
16668    (use (match_operand:HI 3 "memory_operand" "m"))]
16669   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16670    && flag_unsafe_math_optimizations"
16671   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16672   [(set_attr "type" "frndint")
16673    (set_attr "i387_cw" "mask_pm")
16674    (set_attr "mode" "XF")])
16675
16676 (define_expand "nearbyintdf2"
16677   [(use (match_operand:DF 0 "register_operand" ""))
16678    (use (match_operand:DF 1 "register_operand" ""))]
16679   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16680    && flag_unsafe_math_optimizations"
16681 {
16682   rtx op0 = gen_reg_rtx (XFmode);
16683   rtx op1 = gen_reg_rtx (XFmode);
16684   rtx op2 = assign_386_stack_local (HImode, 1);
16685   rtx op3 = assign_386_stack_local (HImode, 2);
16686         
16687   ix86_optimize_mode_switching = 1;
16688
16689   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16690   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16691
16692   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16693   DONE;
16694 })
16695
16696 (define_expand "nearbyintsf2"
16697   [(use (match_operand:SF 0 "register_operand" ""))
16698    (use (match_operand:SF 1 "register_operand" ""))]
16699   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16700    && flag_unsafe_math_optimizations"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704   rtx op2 = assign_386_stack_local (HImode, 1);
16705   rtx op3 = assign_386_stack_local (HImode, 2);
16706         
16707   ix86_optimize_mode_switching = 1;
16708
16709   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16710   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16711
16712   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16713   DONE;
16714 })
16715
16716 (define_expand "nearbyintxf2"
16717   [(use (match_operand:XF 0 "register_operand" ""))
16718    (use (match_operand:XF 1 "register_operand" ""))]
16719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16720    && flag_unsafe_math_optimizations"
16721 {
16722   rtx op2 = assign_386_stack_local (HImode, 1);
16723   rtx op3 = assign_386_stack_local (HImode, 2);
16724         
16725   ix86_optimize_mode_switching = 1;
16726
16727   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16728                                      op2, op3));
16729   DONE;
16730 })
16731
16732 \f
16733 ;; Block operation instructions
16734
16735 (define_insn "cld"
16736  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16737  ""
16738  "cld"
16739   [(set_attr "type" "cld")])
16740
16741 (define_expand "movmemsi"
16742   [(use (match_operand:BLK 0 "memory_operand" ""))
16743    (use (match_operand:BLK 1 "memory_operand" ""))
16744    (use (match_operand:SI 2 "nonmemory_operand" ""))
16745    (use (match_operand:SI 3 "const_int_operand" ""))]
16746   "! optimize_size"
16747 {
16748  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16749    DONE;
16750  else
16751    FAIL;
16752 })
16753
16754 (define_expand "movmemdi"
16755   [(use (match_operand:BLK 0 "memory_operand" ""))
16756    (use (match_operand:BLK 1 "memory_operand" ""))
16757    (use (match_operand:DI 2 "nonmemory_operand" ""))
16758    (use (match_operand:DI 3 "const_int_operand" ""))]
16759   "TARGET_64BIT"
16760 {
16761  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16762    DONE;
16763  else
16764    FAIL;
16765 })
16766
16767 ;; Most CPUs don't like single string operations
16768 ;; Handle this case here to simplify previous expander.
16769
16770 (define_expand "strmov"
16771   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16772    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16773    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16774               (clobber (reg:CC FLAGS_REG))])
16775    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16776               (clobber (reg:CC FLAGS_REG))])]
16777   ""
16778 {
16779   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16780
16781   /* If .md ever supports :P for Pmode, these can be directly
16782      in the pattern above.  */
16783   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16784   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16785
16786   if (TARGET_SINGLE_STRINGOP || optimize_size)
16787     {
16788       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16789                                       operands[2], operands[3],
16790                                       operands[5], operands[6]));
16791       DONE;
16792     }
16793
16794   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16795 })
16796
16797 (define_expand "strmov_singleop"
16798   [(parallel [(set (match_operand 1 "memory_operand" "")
16799                    (match_operand 3 "memory_operand" ""))
16800               (set (match_operand 0 "register_operand" "")
16801                    (match_operand 4 "" ""))
16802               (set (match_operand 2 "register_operand" "")
16803                    (match_operand 5 "" ""))
16804               (use (reg:SI DIRFLAG_REG))])]
16805   "TARGET_SINGLE_STRINGOP || optimize_size"
16806   "")
16807
16808 (define_insn "*strmovdi_rex_1"
16809   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16810         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16811    (set (match_operand:DI 0 "register_operand" "=D")
16812         (plus:DI (match_dup 2)
16813                  (const_int 8)))
16814    (set (match_operand:DI 1 "register_operand" "=S")
16815         (plus:DI (match_dup 3)
16816                  (const_int 8)))
16817    (use (reg:SI DIRFLAG_REG))]
16818   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16819   "movsq"
16820   [(set_attr "type" "str")
16821    (set_attr "mode" "DI")
16822    (set_attr "memory" "both")])
16823
16824 (define_insn "*strmovsi_1"
16825   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16826         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16827    (set (match_operand:SI 0 "register_operand" "=D")
16828         (plus:SI (match_dup 2)
16829                  (const_int 4)))
16830    (set (match_operand:SI 1 "register_operand" "=S")
16831         (plus:SI (match_dup 3)
16832                  (const_int 4)))
16833    (use (reg:SI DIRFLAG_REG))]
16834   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16835   "{movsl|movsd}"
16836   [(set_attr "type" "str")
16837    (set_attr "mode" "SI")
16838    (set_attr "memory" "both")])
16839
16840 (define_insn "*strmovsi_rex_1"
16841   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16842         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16843    (set (match_operand:DI 0 "register_operand" "=D")
16844         (plus:DI (match_dup 2)
16845                  (const_int 4)))
16846    (set (match_operand:DI 1 "register_operand" "=S")
16847         (plus:DI (match_dup 3)
16848                  (const_int 4)))
16849    (use (reg:SI DIRFLAG_REG))]
16850   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16851   "{movsl|movsd}"
16852   [(set_attr "type" "str")
16853    (set_attr "mode" "SI")
16854    (set_attr "memory" "both")])
16855
16856 (define_insn "*strmovhi_1"
16857   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16858         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16859    (set (match_operand:SI 0 "register_operand" "=D")
16860         (plus:SI (match_dup 2)
16861                  (const_int 2)))
16862    (set (match_operand:SI 1 "register_operand" "=S")
16863         (plus:SI (match_dup 3)
16864                  (const_int 2)))
16865    (use (reg:SI DIRFLAG_REG))]
16866   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867   "movsw"
16868   [(set_attr "type" "str")
16869    (set_attr "memory" "both")
16870    (set_attr "mode" "HI")])
16871
16872 (define_insn "*strmovhi_rex_1"
16873   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16874         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16875    (set (match_operand:DI 0 "register_operand" "=D")
16876         (plus:DI (match_dup 2)
16877                  (const_int 2)))
16878    (set (match_operand:DI 1 "register_operand" "=S")
16879         (plus:DI (match_dup 3)
16880                  (const_int 2)))
16881    (use (reg:SI DIRFLAG_REG))]
16882   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16883   "movsw"
16884   [(set_attr "type" "str")
16885    (set_attr "memory" "both")
16886    (set_attr "mode" "HI")])
16887
16888 (define_insn "*strmovqi_1"
16889   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16890         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16891    (set (match_operand:SI 0 "register_operand" "=D")
16892         (plus:SI (match_dup 2)
16893                  (const_int 1)))
16894    (set (match_operand:SI 1 "register_operand" "=S")
16895         (plus:SI (match_dup 3)
16896                  (const_int 1)))
16897    (use (reg:SI DIRFLAG_REG))]
16898   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16899   "movsb"
16900   [(set_attr "type" "str")
16901    (set_attr "memory" "both")
16902    (set_attr "mode" "QI")])
16903
16904 (define_insn "*strmovqi_rex_1"
16905   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16906         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16907    (set (match_operand:DI 0 "register_operand" "=D")
16908         (plus:DI (match_dup 2)
16909                  (const_int 1)))
16910    (set (match_operand:DI 1 "register_operand" "=S")
16911         (plus:DI (match_dup 3)
16912                  (const_int 1)))
16913    (use (reg:SI DIRFLAG_REG))]
16914   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16915   "movsb"
16916   [(set_attr "type" "str")
16917    (set_attr "memory" "both")
16918    (set_attr "mode" "QI")])
16919
16920 (define_expand "rep_mov"
16921   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16922               (set (match_operand 0 "register_operand" "")
16923                    (match_operand 5 "" ""))
16924               (set (match_operand 2 "register_operand" "")
16925                    (match_operand 6 "" ""))
16926               (set (match_operand 1 "memory_operand" "")
16927                    (match_operand 3 "memory_operand" ""))
16928               (use (match_dup 4))
16929               (use (reg:SI DIRFLAG_REG))])]
16930   ""
16931   "")
16932
16933 (define_insn "*rep_movdi_rex64"
16934   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16935    (set (match_operand:DI 0 "register_operand" "=D") 
16936         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16937                             (const_int 3))
16938                  (match_operand:DI 3 "register_operand" "0")))
16939    (set (match_operand:DI 1 "register_operand" "=S") 
16940         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16941                  (match_operand:DI 4 "register_operand" "1")))
16942    (set (mem:BLK (match_dup 3))
16943         (mem:BLK (match_dup 4)))
16944    (use (match_dup 5))
16945    (use (reg:SI DIRFLAG_REG))]
16946   "TARGET_64BIT"
16947   "{rep\;movsq|rep movsq}"
16948   [(set_attr "type" "str")
16949    (set_attr "prefix_rep" "1")
16950    (set_attr "memory" "both")
16951    (set_attr "mode" "DI")])
16952
16953 (define_insn "*rep_movsi"
16954   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16955    (set (match_operand:SI 0 "register_operand" "=D") 
16956         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16957                             (const_int 2))
16958                  (match_operand:SI 3 "register_operand" "0")))
16959    (set (match_operand:SI 1 "register_operand" "=S") 
16960         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16961                  (match_operand:SI 4 "register_operand" "1")))
16962    (set (mem:BLK (match_dup 3))
16963         (mem:BLK (match_dup 4)))
16964    (use (match_dup 5))
16965    (use (reg:SI DIRFLAG_REG))]
16966   "!TARGET_64BIT"
16967   "{rep\;movsl|rep movsd}"
16968   [(set_attr "type" "str")
16969    (set_attr "prefix_rep" "1")
16970    (set_attr "memory" "both")
16971    (set_attr "mode" "SI")])
16972
16973 (define_insn "*rep_movsi_rex64"
16974   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16975    (set (match_operand:DI 0 "register_operand" "=D") 
16976         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16977                             (const_int 2))
16978                  (match_operand:DI 3 "register_operand" "0")))
16979    (set (match_operand:DI 1 "register_operand" "=S") 
16980         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16981                  (match_operand:DI 4 "register_operand" "1")))
16982    (set (mem:BLK (match_dup 3))
16983         (mem:BLK (match_dup 4)))
16984    (use (match_dup 5))
16985    (use (reg:SI DIRFLAG_REG))]
16986   "TARGET_64BIT"
16987   "{rep\;movsl|rep movsd}"
16988   [(set_attr "type" "str")
16989    (set_attr "prefix_rep" "1")
16990    (set_attr "memory" "both")
16991    (set_attr "mode" "SI")])
16992
16993 (define_insn "*rep_movqi"
16994   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16995    (set (match_operand:SI 0 "register_operand" "=D") 
16996         (plus:SI (match_operand:SI 3 "register_operand" "0")
16997                  (match_operand:SI 5 "register_operand" "2")))
16998    (set (match_operand:SI 1 "register_operand" "=S") 
16999         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17000    (set (mem:BLK (match_dup 3))
17001         (mem:BLK (match_dup 4)))
17002    (use (match_dup 5))
17003    (use (reg:SI DIRFLAG_REG))]
17004   "!TARGET_64BIT"
17005   "{rep\;movsb|rep movsb}"
17006   [(set_attr "type" "str")
17007    (set_attr "prefix_rep" "1")
17008    (set_attr "memory" "both")
17009    (set_attr "mode" "SI")])
17010
17011 (define_insn "*rep_movqi_rex64"
17012   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17013    (set (match_operand:DI 0 "register_operand" "=D") 
17014         (plus:DI (match_operand:DI 3 "register_operand" "0")
17015                  (match_operand:DI 5 "register_operand" "2")))
17016    (set (match_operand:DI 1 "register_operand" "=S") 
17017         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17018    (set (mem:BLK (match_dup 3))
17019         (mem:BLK (match_dup 4)))
17020    (use (match_dup 5))
17021    (use (reg:SI DIRFLAG_REG))]
17022   "TARGET_64BIT"
17023   "{rep\;movsb|rep movsb}"
17024   [(set_attr "type" "str")
17025    (set_attr "prefix_rep" "1")
17026    (set_attr "memory" "both")
17027    (set_attr "mode" "SI")])
17028
17029 (define_expand "clrmemsi"
17030    [(use (match_operand:BLK 0 "memory_operand" ""))
17031     (use (match_operand:SI 1 "nonmemory_operand" ""))
17032     (use (match_operand 2 "const_int_operand" ""))]
17033   ""
17034 {
17035  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17036    DONE;
17037  else
17038    FAIL;
17039 })
17040
17041 (define_expand "clrmemdi"
17042    [(use (match_operand:BLK 0 "memory_operand" ""))
17043     (use (match_operand:DI 1 "nonmemory_operand" ""))
17044     (use (match_operand 2 "const_int_operand" ""))]
17045   "TARGET_64BIT"
17046 {
17047  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17048    DONE;
17049  else
17050    FAIL;
17051 })
17052
17053 ;; Most CPUs don't like single string operations
17054 ;; Handle this case here to simplify previous expander.
17055
17056 (define_expand "strset"
17057   [(set (match_operand 1 "memory_operand" "")
17058         (match_operand 2 "register_operand" ""))
17059    (parallel [(set (match_operand 0 "register_operand" "")
17060                    (match_dup 3))
17061               (clobber (reg:CC FLAGS_REG))])]
17062   ""
17063 {
17064   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17065     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17066
17067   /* If .md ever supports :P for Pmode, this can be directly
17068      in the pattern above.  */
17069   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17070                               GEN_INT (GET_MODE_SIZE (GET_MODE
17071                                                       (operands[2]))));
17072   if (TARGET_SINGLE_STRINGOP || optimize_size)
17073     {
17074       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17075                                       operands[3]));
17076       DONE;
17077     }
17078 })
17079
17080 (define_expand "strset_singleop"
17081   [(parallel [(set (match_operand 1 "memory_operand" "")
17082                    (match_operand 2 "register_operand" ""))
17083               (set (match_operand 0 "register_operand" "")
17084                    (match_operand 3 "" ""))
17085               (use (reg:SI DIRFLAG_REG))])]
17086   "TARGET_SINGLE_STRINGOP || optimize_size"
17087   "")
17088
17089 (define_insn "*strsetdi_rex_1"
17090   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17091         (match_operand:DI 2 "register_operand" "a"))
17092    (set (match_operand:DI 0 "register_operand" "=D")
17093         (plus:DI (match_dup 1)
17094                  (const_int 8)))
17095    (use (reg:SI DIRFLAG_REG))]
17096   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17097   "stosq"
17098   [(set_attr "type" "str")
17099    (set_attr "memory" "store")
17100    (set_attr "mode" "DI")])
17101
17102 (define_insn "*strsetsi_1"
17103   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17104         (match_operand:SI 2 "register_operand" "a"))
17105    (set (match_operand:SI 0 "register_operand" "=D")
17106         (plus:SI (match_dup 1)
17107                  (const_int 4)))
17108    (use (reg:SI DIRFLAG_REG))]
17109   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17110   "{stosl|stosd}"
17111   [(set_attr "type" "str")
17112    (set_attr "memory" "store")
17113    (set_attr "mode" "SI")])
17114
17115 (define_insn "*strsetsi_rex_1"
17116   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17117         (match_operand:SI 2 "register_operand" "a"))
17118    (set (match_operand:DI 0 "register_operand" "=D")
17119         (plus:DI (match_dup 1)
17120                  (const_int 4)))
17121    (use (reg:SI DIRFLAG_REG))]
17122   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17123   "{stosl|stosd}"
17124   [(set_attr "type" "str")
17125    (set_attr "memory" "store")
17126    (set_attr "mode" "SI")])
17127
17128 (define_insn "*strsethi_1"
17129   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17130         (match_operand:HI 2 "register_operand" "a"))
17131    (set (match_operand:SI 0 "register_operand" "=D")
17132         (plus:SI (match_dup 1)
17133                  (const_int 2)))
17134    (use (reg:SI DIRFLAG_REG))]
17135   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17136   "stosw"
17137   [(set_attr "type" "str")
17138    (set_attr "memory" "store")
17139    (set_attr "mode" "HI")])
17140
17141 (define_insn "*strsethi_rex_1"
17142   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17143         (match_operand:HI 2 "register_operand" "a"))
17144    (set (match_operand:DI 0 "register_operand" "=D")
17145         (plus:DI (match_dup 1)
17146                  (const_int 2)))
17147    (use (reg:SI DIRFLAG_REG))]
17148   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17149   "stosw"
17150   [(set_attr "type" "str")
17151    (set_attr "memory" "store")
17152    (set_attr "mode" "HI")])
17153
17154 (define_insn "*strsetqi_1"
17155   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17156         (match_operand:QI 2 "register_operand" "a"))
17157    (set (match_operand:SI 0 "register_operand" "=D")
17158         (plus:SI (match_dup 1)
17159                  (const_int 1)))
17160    (use (reg:SI DIRFLAG_REG))]
17161   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17162   "stosb"
17163   [(set_attr "type" "str")
17164    (set_attr "memory" "store")
17165    (set_attr "mode" "QI")])
17166
17167 (define_insn "*strsetqi_rex_1"
17168   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17169         (match_operand:QI 2 "register_operand" "a"))
17170    (set (match_operand:DI 0 "register_operand" "=D")
17171         (plus:DI (match_dup 1)
17172                  (const_int 1)))
17173    (use (reg:SI DIRFLAG_REG))]
17174   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17175   "stosb"
17176   [(set_attr "type" "str")
17177    (set_attr "memory" "store")
17178    (set_attr "mode" "QI")])
17179
17180 (define_expand "rep_stos"
17181   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17182               (set (match_operand 0 "register_operand" "")
17183                    (match_operand 4 "" ""))
17184               (set (match_operand 2 "memory_operand" "") (const_int 0))
17185               (use (match_operand 3 "register_operand" ""))
17186               (use (match_dup 1))
17187               (use (reg:SI DIRFLAG_REG))])]
17188   ""
17189   "")
17190
17191 (define_insn "*rep_stosdi_rex64"
17192   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17193    (set (match_operand:DI 0 "register_operand" "=D") 
17194         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17195                             (const_int 3))
17196                  (match_operand:DI 3 "register_operand" "0")))
17197    (set (mem:BLK (match_dup 3))
17198         (const_int 0))
17199    (use (match_operand:DI 2 "register_operand" "a"))
17200    (use (match_dup 4))
17201    (use (reg:SI DIRFLAG_REG))]
17202   "TARGET_64BIT"
17203   "{rep\;stosq|rep stosq}"
17204   [(set_attr "type" "str")
17205    (set_attr "prefix_rep" "1")
17206    (set_attr "memory" "store")
17207    (set_attr "mode" "DI")])
17208
17209 (define_insn "*rep_stossi"
17210   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17211    (set (match_operand:SI 0 "register_operand" "=D") 
17212         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17213                             (const_int 2))
17214                  (match_operand:SI 3 "register_operand" "0")))
17215    (set (mem:BLK (match_dup 3))
17216         (const_int 0))
17217    (use (match_operand:SI 2 "register_operand" "a"))
17218    (use (match_dup 4))
17219    (use (reg:SI DIRFLAG_REG))]
17220   "!TARGET_64BIT"
17221   "{rep\;stosl|rep stosd}"
17222   [(set_attr "type" "str")
17223    (set_attr "prefix_rep" "1")
17224    (set_attr "memory" "store")
17225    (set_attr "mode" "SI")])
17226
17227 (define_insn "*rep_stossi_rex64"
17228   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17229    (set (match_operand:DI 0 "register_operand" "=D") 
17230         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17231                             (const_int 2))
17232                  (match_operand:DI 3 "register_operand" "0")))
17233    (set (mem:BLK (match_dup 3))
17234         (const_int 0))
17235    (use (match_operand:SI 2 "register_operand" "a"))
17236    (use (match_dup 4))
17237    (use (reg:SI DIRFLAG_REG))]
17238   "TARGET_64BIT"
17239   "{rep\;stosl|rep stosd}"
17240   [(set_attr "type" "str")
17241    (set_attr "prefix_rep" "1")
17242    (set_attr "memory" "store")
17243    (set_attr "mode" "SI")])
17244
17245 (define_insn "*rep_stosqi"
17246   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17247    (set (match_operand:SI 0 "register_operand" "=D") 
17248         (plus:SI (match_operand:SI 3 "register_operand" "0")
17249                  (match_operand:SI 4 "register_operand" "1")))
17250    (set (mem:BLK (match_dup 3))
17251         (const_int 0))
17252    (use (match_operand:QI 2 "register_operand" "a"))
17253    (use (match_dup 4))
17254    (use (reg:SI DIRFLAG_REG))]
17255   "!TARGET_64BIT"
17256   "{rep\;stosb|rep stosb}"
17257   [(set_attr "type" "str")
17258    (set_attr "prefix_rep" "1")
17259    (set_attr "memory" "store")
17260    (set_attr "mode" "QI")])
17261
17262 (define_insn "*rep_stosqi_rex64"
17263   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17264    (set (match_operand:DI 0 "register_operand" "=D") 
17265         (plus:DI (match_operand:DI 3 "register_operand" "0")
17266                  (match_operand:DI 4 "register_operand" "1")))
17267    (set (mem:BLK (match_dup 3))
17268         (const_int 0))
17269    (use (match_operand:QI 2 "register_operand" "a"))
17270    (use (match_dup 4))
17271    (use (reg:SI DIRFLAG_REG))]
17272   "TARGET_64BIT"
17273   "{rep\;stosb|rep stosb}"
17274   [(set_attr "type" "str")
17275    (set_attr "prefix_rep" "1")
17276    (set_attr "memory" "store")
17277    (set_attr "mode" "QI")])
17278
17279 (define_expand "cmpstrsi"
17280   [(set (match_operand:SI 0 "register_operand" "")
17281         (compare:SI (match_operand:BLK 1 "general_operand" "")
17282                     (match_operand:BLK 2 "general_operand" "")))
17283    (use (match_operand 3 "general_operand" ""))
17284    (use (match_operand 4 "immediate_operand" ""))]
17285   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17286 {
17287   rtx addr1, addr2, out, outlow, count, countreg, align;
17288
17289   /* Can't use this if the user has appropriated esi or edi.  */
17290   if (global_regs[4] || global_regs[5])
17291     FAIL;
17292
17293   out = operands[0];
17294   if (GET_CODE (out) != REG)
17295     out = gen_reg_rtx (SImode);
17296
17297   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17298   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17299   if (addr1 != XEXP (operands[1], 0))
17300     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17301   if (addr2 != XEXP (operands[2], 0))
17302     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17303
17304   count = operands[3];
17305   countreg = ix86_zero_extend_to_Pmode (count);
17306
17307   /* %%% Iff we are testing strict equality, we can use known alignment
17308      to good advantage.  This may be possible with combine, particularly
17309      once cc0 is dead.  */
17310   align = operands[4];
17311
17312   emit_insn (gen_cld ());
17313   if (GET_CODE (count) == CONST_INT)
17314     {
17315       if (INTVAL (count) == 0)
17316         {
17317           emit_move_insn (operands[0], const0_rtx);
17318           DONE;
17319         }
17320       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17321                                     operands[1], operands[2]));
17322     }
17323   else
17324     {
17325       if (TARGET_64BIT)
17326         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17327       else
17328         emit_insn (gen_cmpsi_1 (countreg, countreg));
17329       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17330                                  operands[1], operands[2]));
17331     }
17332
17333   outlow = gen_lowpart (QImode, out);
17334   emit_insn (gen_cmpintqi (outlow));
17335   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17336
17337   if (operands[0] != out)
17338     emit_move_insn (operands[0], out);
17339
17340   DONE;
17341 })
17342
17343 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17344
17345 (define_expand "cmpintqi"
17346   [(set (match_dup 1)
17347         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17348    (set (match_dup 2)
17349         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17350    (parallel [(set (match_operand:QI 0 "register_operand" "")
17351                    (minus:QI (match_dup 1)
17352                              (match_dup 2)))
17353               (clobber (reg:CC FLAGS_REG))])]
17354   ""
17355   "operands[1] = gen_reg_rtx (QImode);
17356    operands[2] = gen_reg_rtx (QImode);")
17357
17358 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17359 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17360
17361 (define_expand "cmpstrqi_nz_1"
17362   [(parallel [(set (reg:CC FLAGS_REG)
17363                    (compare:CC (match_operand 4 "memory_operand" "")
17364                                (match_operand 5 "memory_operand" "")))
17365               (use (match_operand 2 "register_operand" ""))
17366               (use (match_operand:SI 3 "immediate_operand" ""))
17367               (use (reg:SI DIRFLAG_REG))
17368               (clobber (match_operand 0 "register_operand" ""))
17369               (clobber (match_operand 1 "register_operand" ""))
17370               (clobber (match_dup 2))])]
17371   ""
17372   "")
17373
17374 (define_insn "*cmpstrqi_nz_1"
17375   [(set (reg:CC FLAGS_REG)
17376         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17377                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17378    (use (match_operand:SI 6 "register_operand" "2"))
17379    (use (match_operand:SI 3 "immediate_operand" "i"))
17380    (use (reg:SI DIRFLAG_REG))
17381    (clobber (match_operand:SI 0 "register_operand" "=S"))
17382    (clobber (match_operand:SI 1 "register_operand" "=D"))
17383    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17384   "!TARGET_64BIT"
17385   "repz{\;| }cmpsb"
17386   [(set_attr "type" "str")
17387    (set_attr "mode" "QI")
17388    (set_attr "prefix_rep" "1")])
17389
17390 (define_insn "*cmpstrqi_nz_rex_1"
17391   [(set (reg:CC FLAGS_REG)
17392         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17393                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17394    (use (match_operand:DI 6 "register_operand" "2"))
17395    (use (match_operand:SI 3 "immediate_operand" "i"))
17396    (use (reg:SI DIRFLAG_REG))
17397    (clobber (match_operand:DI 0 "register_operand" "=S"))
17398    (clobber (match_operand:DI 1 "register_operand" "=D"))
17399    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17400   "TARGET_64BIT"
17401   "repz{\;| }cmpsb"
17402   [(set_attr "type" "str")
17403    (set_attr "mode" "QI")
17404    (set_attr "prefix_rep" "1")])
17405
17406 ;; The same, but the count is not known to not be zero.
17407
17408 (define_expand "cmpstrqi_1"
17409   [(parallel [(set (reg:CC FLAGS_REG)
17410                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17411                                      (const_int 0))
17412                   (compare:CC (match_operand 4 "memory_operand" "")
17413                               (match_operand 5 "memory_operand" ""))
17414                   (const_int 0)))
17415               (use (match_operand:SI 3 "immediate_operand" ""))
17416               (use (reg:CC FLAGS_REG))
17417               (use (reg:SI DIRFLAG_REG))
17418               (clobber (match_operand 0 "register_operand" ""))
17419               (clobber (match_operand 1 "register_operand" ""))
17420               (clobber (match_dup 2))])]
17421   ""
17422   "")
17423
17424 (define_insn "*cmpstrqi_1"
17425   [(set (reg:CC FLAGS_REG)
17426         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17427                              (const_int 0))
17428           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17429                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17430           (const_int 0)))
17431    (use (match_operand:SI 3 "immediate_operand" "i"))
17432    (use (reg:CC FLAGS_REG))
17433    (use (reg:SI DIRFLAG_REG))
17434    (clobber (match_operand:SI 0 "register_operand" "=S"))
17435    (clobber (match_operand:SI 1 "register_operand" "=D"))
17436    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17437   "!TARGET_64BIT"
17438   "repz{\;| }cmpsb"
17439   [(set_attr "type" "str")
17440    (set_attr "mode" "QI")
17441    (set_attr "prefix_rep" "1")])
17442
17443 (define_insn "*cmpstrqi_rex_1"
17444   [(set (reg:CC FLAGS_REG)
17445         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17446                              (const_int 0))
17447           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17448                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17449           (const_int 0)))
17450    (use (match_operand:SI 3 "immediate_operand" "i"))
17451    (use (reg:CC FLAGS_REG))
17452    (use (reg:SI DIRFLAG_REG))
17453    (clobber (match_operand:DI 0 "register_operand" "=S"))
17454    (clobber (match_operand:DI 1 "register_operand" "=D"))
17455    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17456   "TARGET_64BIT"
17457   "repz{\;| }cmpsb"
17458   [(set_attr "type" "str")
17459    (set_attr "mode" "QI")
17460    (set_attr "prefix_rep" "1")])
17461
17462 (define_expand "strlensi"
17463   [(set (match_operand:SI 0 "register_operand" "")
17464         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17465                     (match_operand:QI 2 "immediate_operand" "")
17466                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17467   ""
17468 {
17469  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17470    DONE;
17471  else
17472    FAIL;
17473 })
17474
17475 (define_expand "strlendi"
17476   [(set (match_operand:DI 0 "register_operand" "")
17477         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17478                     (match_operand:QI 2 "immediate_operand" "")
17479                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17480   ""
17481 {
17482  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17483    DONE;
17484  else
17485    FAIL;
17486 })
17487
17488 (define_expand "strlenqi_1"
17489   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17490               (use (reg:SI DIRFLAG_REG))
17491               (clobber (match_operand 1 "register_operand" ""))
17492               (clobber (reg:CC FLAGS_REG))])]
17493   ""
17494   "")
17495
17496 (define_insn "*strlenqi_1"
17497   [(set (match_operand:SI 0 "register_operand" "=&c")
17498         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17499                     (match_operand:QI 2 "register_operand" "a")
17500                     (match_operand:SI 3 "immediate_operand" "i")
17501                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17502    (use (reg:SI DIRFLAG_REG))
17503    (clobber (match_operand:SI 1 "register_operand" "=D"))
17504    (clobber (reg:CC FLAGS_REG))]
17505   "!TARGET_64BIT"
17506   "repnz{\;| }scasb"
17507   [(set_attr "type" "str")
17508    (set_attr "mode" "QI")
17509    (set_attr "prefix_rep" "1")])
17510
17511 (define_insn "*strlenqi_rex_1"
17512   [(set (match_operand:DI 0 "register_operand" "=&c")
17513         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17514                     (match_operand:QI 2 "register_operand" "a")
17515                     (match_operand:DI 3 "immediate_operand" "i")
17516                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17517    (use (reg:SI DIRFLAG_REG))
17518    (clobber (match_operand:DI 1 "register_operand" "=D"))
17519    (clobber (reg:CC FLAGS_REG))]
17520   "TARGET_64BIT"
17521   "repnz{\;| }scasb"
17522   [(set_attr "type" "str")
17523    (set_attr "mode" "QI")
17524    (set_attr "prefix_rep" "1")])
17525
17526 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17527 ;; handled in combine, but it is not currently up to the task.
17528 ;; When used for their truth value, the cmpstr* expanders generate
17529 ;; code like this:
17530 ;;
17531 ;;   repz cmpsb
17532 ;;   seta       %al
17533 ;;   setb       %dl
17534 ;;   cmpb       %al, %dl
17535 ;;   jcc        label
17536 ;;
17537 ;; The intermediate three instructions are unnecessary.
17538
17539 ;; This one handles cmpstr*_nz_1...
17540 (define_peephole2
17541   [(parallel[
17542      (set (reg:CC FLAGS_REG)
17543           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17544                       (mem:BLK (match_operand 5 "register_operand" ""))))
17545      (use (match_operand 6 "register_operand" ""))
17546      (use (match_operand:SI 3 "immediate_operand" ""))
17547      (use (reg:SI DIRFLAG_REG))
17548      (clobber (match_operand 0 "register_operand" ""))
17549      (clobber (match_operand 1 "register_operand" ""))
17550      (clobber (match_operand 2 "register_operand" ""))])
17551    (set (match_operand:QI 7 "register_operand" "")
17552         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17553    (set (match_operand:QI 8 "register_operand" "")
17554         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17555    (set (reg 17)
17556         (compare (match_dup 7) (match_dup 8)))
17557   ]
17558   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17559   [(parallel[
17560      (set (reg:CC FLAGS_REG)
17561           (compare:CC (mem:BLK (match_dup 4))
17562                       (mem:BLK (match_dup 5))))
17563      (use (match_dup 6))
17564      (use (match_dup 3))
17565      (use (reg:SI DIRFLAG_REG))
17566      (clobber (match_dup 0))
17567      (clobber (match_dup 1))
17568      (clobber (match_dup 2))])]
17569   "")
17570
17571 ;; ...and this one handles cmpstr*_1.
17572 (define_peephole2
17573   [(parallel[
17574      (set (reg:CC FLAGS_REG)
17575           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17576                                (const_int 0))
17577             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17578                         (mem:BLK (match_operand 5 "register_operand" "")))
17579             (const_int 0)))
17580      (use (match_operand:SI 3 "immediate_operand" ""))
17581      (use (reg:CC FLAGS_REG))
17582      (use (reg:SI DIRFLAG_REG))
17583      (clobber (match_operand 0 "register_operand" ""))
17584      (clobber (match_operand 1 "register_operand" ""))
17585      (clobber (match_operand 2 "register_operand" ""))])
17586    (set (match_operand:QI 7 "register_operand" "")
17587         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17588    (set (match_operand:QI 8 "register_operand" "")
17589         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17590    (set (reg 17)
17591         (compare (match_dup 7) (match_dup 8)))
17592   ]
17593   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17594   [(parallel[
17595      (set (reg:CC FLAGS_REG)
17596           (if_then_else:CC (ne (match_dup 6)
17597                                (const_int 0))
17598             (compare:CC (mem:BLK (match_dup 4))
17599                         (mem:BLK (match_dup 5)))
17600             (const_int 0)))
17601      (use (match_dup 3))
17602      (use (reg:CC FLAGS_REG))
17603      (use (reg:SI DIRFLAG_REG))
17604      (clobber (match_dup 0))
17605      (clobber (match_dup 1))
17606      (clobber (match_dup 2))])]
17607   "")
17608
17609
17610 \f
17611 ;; Conditional move instructions.
17612
17613 (define_expand "movdicc"
17614   [(set (match_operand:DI 0 "register_operand" "")
17615         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17616                          (match_operand:DI 2 "general_operand" "")
17617                          (match_operand:DI 3 "general_operand" "")))]
17618   "TARGET_64BIT"
17619   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17620
17621 (define_insn "x86_movdicc_0_m1_rex64"
17622   [(set (match_operand:DI 0 "register_operand" "=r")
17623         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17624           (const_int -1)
17625           (const_int 0)))
17626    (clobber (reg:CC FLAGS_REG))]
17627   "TARGET_64BIT"
17628   "sbb{q}\t%0, %0"
17629   ; Since we don't have the proper number of operands for an alu insn,
17630   ; fill in all the blanks.
17631   [(set_attr "type" "alu")
17632    (set_attr "pent_pair" "pu")
17633    (set_attr "memory" "none")
17634    (set_attr "imm_disp" "false")
17635    (set_attr "mode" "DI")
17636    (set_attr "length_immediate" "0")])
17637
17638 (define_insn "movdicc_c_rex64"
17639   [(set (match_operand:DI 0 "register_operand" "=r,r")
17640         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17641                                 [(reg 17) (const_int 0)])
17642                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17643                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17644   "TARGET_64BIT && TARGET_CMOVE
17645    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17646   "@
17647    cmov%O2%C1\t{%2, %0|%0, %2}
17648    cmov%O2%c1\t{%3, %0|%0, %3}"
17649   [(set_attr "type" "icmov")
17650    (set_attr "mode" "DI")])
17651
17652 (define_expand "movsicc"
17653   [(set (match_operand:SI 0 "register_operand" "")
17654         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17655                          (match_operand:SI 2 "general_operand" "")
17656                          (match_operand:SI 3 "general_operand" "")))]
17657   ""
17658   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17659
17660 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17661 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17662 ;; So just document what we're doing explicitly.
17663
17664 (define_insn "x86_movsicc_0_m1"
17665   [(set (match_operand:SI 0 "register_operand" "=r")
17666         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17667           (const_int -1)
17668           (const_int 0)))
17669    (clobber (reg:CC FLAGS_REG))]
17670   ""
17671   "sbb{l}\t%0, %0"
17672   ; Since we don't have the proper number of operands for an alu insn,
17673   ; fill in all the blanks.
17674   [(set_attr "type" "alu")
17675    (set_attr "pent_pair" "pu")
17676    (set_attr "memory" "none")
17677    (set_attr "imm_disp" "false")
17678    (set_attr "mode" "SI")
17679    (set_attr "length_immediate" "0")])
17680
17681 (define_insn "*movsicc_noc"
17682   [(set (match_operand:SI 0 "register_operand" "=r,r")
17683         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17684                                 [(reg 17) (const_int 0)])
17685                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17686                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17687   "TARGET_CMOVE
17688    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17689   "@
17690    cmov%O2%C1\t{%2, %0|%0, %2}
17691    cmov%O2%c1\t{%3, %0|%0, %3}"
17692   [(set_attr "type" "icmov")
17693    (set_attr "mode" "SI")])
17694
17695 (define_expand "movhicc"
17696   [(set (match_operand:HI 0 "register_operand" "")
17697         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17698                          (match_operand:HI 2 "general_operand" "")
17699                          (match_operand:HI 3 "general_operand" "")))]
17700   "TARGET_HIMODE_MATH"
17701   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17702
17703 (define_insn "*movhicc_noc"
17704   [(set (match_operand:HI 0 "register_operand" "=r,r")
17705         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17706                                 [(reg 17) (const_int 0)])
17707                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17708                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17709   "TARGET_CMOVE
17710    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17711   "@
17712    cmov%O2%C1\t{%2, %0|%0, %2}
17713    cmov%O2%c1\t{%3, %0|%0, %3}"
17714   [(set_attr "type" "icmov")
17715    (set_attr "mode" "HI")])
17716
17717 (define_expand "movqicc"
17718   [(set (match_operand:QI 0 "register_operand" "")
17719         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17720                          (match_operand:QI 2 "general_operand" "")
17721                          (match_operand:QI 3 "general_operand" "")))]
17722   "TARGET_QIMODE_MATH"
17723   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17724
17725 (define_insn_and_split "*movqicc_noc"
17726   [(set (match_operand:QI 0 "register_operand" "=r,r")
17727         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17728                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17729                       (match_operand:QI 2 "register_operand" "r,0")
17730                       (match_operand:QI 3 "register_operand" "0,r")))]
17731   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17732   "#"
17733   "&& reload_completed"
17734   [(set (match_dup 0)
17735         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17736                       (match_dup 2)
17737                       (match_dup 3)))]
17738   "operands[0] = gen_lowpart (SImode, operands[0]);
17739    operands[2] = gen_lowpart (SImode, operands[2]);
17740    operands[3] = gen_lowpart (SImode, operands[3]);"
17741   [(set_attr "type" "icmov")
17742    (set_attr "mode" "SI")])
17743
17744 (define_expand "movsfcc"
17745   [(set (match_operand:SF 0 "register_operand" "")
17746         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17747                          (match_operand:SF 2 "register_operand" "")
17748                          (match_operand:SF 3 "register_operand" "")))]
17749   "TARGET_CMOVE"
17750   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17751
17752 (define_insn "*movsfcc_1"
17753   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17754         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17755                                 [(reg 17) (const_int 0)])
17756                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17757                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17758   "TARGET_CMOVE
17759    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17760   "@
17761    fcmov%F1\t{%2, %0|%0, %2}
17762    fcmov%f1\t{%3, %0|%0, %3}
17763    cmov%O2%C1\t{%2, %0|%0, %2}
17764    cmov%O2%c1\t{%3, %0|%0, %3}"
17765   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17766    (set_attr "mode" "SF,SF,SI,SI")])
17767
17768 (define_expand "movdfcc"
17769   [(set (match_operand:DF 0 "register_operand" "")
17770         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17771                          (match_operand:DF 2 "register_operand" "")
17772                          (match_operand:DF 3 "register_operand" "")))]
17773   "TARGET_CMOVE"
17774   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17775
17776 (define_insn "*movdfcc_1"
17777   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17778         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17779                                 [(reg 17) (const_int 0)])
17780                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17781                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17782   "!TARGET_64BIT && TARGET_CMOVE
17783    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17784   "@
17785    fcmov%F1\t{%2, %0|%0, %2}
17786    fcmov%f1\t{%3, %0|%0, %3}
17787    #
17788    #"
17789   [(set_attr "type" "fcmov,fcmov,multi,multi")
17790    (set_attr "mode" "DF")])
17791
17792 (define_insn "*movdfcc_1_rex64"
17793   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17794         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17795                                 [(reg 17) (const_int 0)])
17796                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17797                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17798   "TARGET_64BIT && TARGET_CMOVE
17799    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17800   "@
17801    fcmov%F1\t{%2, %0|%0, %2}
17802    fcmov%f1\t{%3, %0|%0, %3}
17803    cmov%O2%C1\t{%2, %0|%0, %2}
17804    cmov%O2%c1\t{%3, %0|%0, %3}"
17805   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17806    (set_attr "mode" "DF")])
17807
17808 (define_split
17809   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17810         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17811                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17812                       (match_operand:DF 2 "nonimmediate_operand" "")
17813                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17814   "!TARGET_64BIT && reload_completed"
17815   [(set (match_dup 2)
17816         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17817                       (match_dup 5)
17818                       (match_dup 7)))
17819    (set (match_dup 3)
17820         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17821                       (match_dup 6)
17822                       (match_dup 8)))]
17823   "split_di (operands+2, 1, operands+5, operands+6);
17824    split_di (operands+3, 1, operands+7, operands+8);
17825    split_di (operands, 1, operands+2, operands+3);")
17826
17827 (define_expand "movxfcc"
17828   [(set (match_operand:XF 0 "register_operand" "")
17829         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17830                          (match_operand:XF 2 "register_operand" "")
17831                          (match_operand:XF 3 "register_operand" "")))]
17832   "TARGET_CMOVE"
17833   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17834
17835 (define_insn "*movxfcc_1"
17836   [(set (match_operand:XF 0 "register_operand" "=f,f")
17837         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17838                                 [(reg 17) (const_int 0)])
17839                       (match_operand:XF 2 "register_operand" "f,0")
17840                       (match_operand:XF 3 "register_operand" "0,f")))]
17841   "TARGET_CMOVE"
17842   "@
17843    fcmov%F1\t{%2, %0|%0, %2}
17844    fcmov%f1\t{%3, %0|%0, %3}"
17845   [(set_attr "type" "fcmov")
17846    (set_attr "mode" "XF")])
17847
17848 (define_expand "minsf3"
17849   [(parallel [
17850      (set (match_operand:SF 0 "register_operand" "")
17851           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17852                                (match_operand:SF 2 "nonimmediate_operand" ""))
17853                            (match_dup 1)
17854                            (match_dup 2)))
17855      (clobber (reg:CC FLAGS_REG))])]
17856   "TARGET_SSE"
17857   "")
17858
17859 (define_insn "*minsf"
17860   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17861         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17862                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17863                          (match_dup 1)
17864                          (match_dup 2)))
17865    (clobber (reg:CC FLAGS_REG))]
17866   "TARGET_SSE && TARGET_IEEE_FP"
17867   "#")
17868
17869 (define_insn "*minsf_nonieee"
17870   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17871         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17872                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17873                          (match_dup 1)
17874                          (match_dup 2)))
17875    (clobber (reg:CC FLAGS_REG))]
17876   "TARGET_SSE && !TARGET_IEEE_FP
17877    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17878   "#")
17879
17880 (define_split
17881   [(set (match_operand:SF 0 "register_operand" "")
17882         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17883                              (match_operand:SF 2 "nonimmediate_operand" ""))
17884                          (match_operand:SF 3 "register_operand" "")
17885                          (match_operand:SF 4 "nonimmediate_operand" "")))
17886    (clobber (reg:CC FLAGS_REG))]
17887   "SSE_REG_P (operands[0]) && reload_completed
17888    && ((operands_match_p (operands[1], operands[3])
17889         && operands_match_p (operands[2], operands[4]))
17890        || (operands_match_p (operands[1], operands[4])
17891            && operands_match_p (operands[2], operands[3])))"
17892   [(set (match_dup 0)
17893         (if_then_else:SF (lt (match_dup 1)
17894                              (match_dup 2))
17895                          (match_dup 1)
17896                          (match_dup 2)))])
17897
17898 ;; Conditional addition patterns
17899 (define_expand "addqicc"
17900   [(match_operand:QI 0 "register_operand" "")
17901    (match_operand 1 "comparison_operator" "")
17902    (match_operand:QI 2 "register_operand" "")
17903    (match_operand:QI 3 "const_int_operand" "")]
17904   ""
17905   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17906
17907 (define_expand "addhicc"
17908   [(match_operand:HI 0 "register_operand" "")
17909    (match_operand 1 "comparison_operator" "")
17910    (match_operand:HI 2 "register_operand" "")
17911    (match_operand:HI 3 "const_int_operand" "")]
17912   ""
17913   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17914
17915 (define_expand "addsicc"
17916   [(match_operand:SI 0 "register_operand" "")
17917    (match_operand 1 "comparison_operator" "")
17918    (match_operand:SI 2 "register_operand" "")
17919    (match_operand:SI 3 "const_int_operand" "")]
17920   ""
17921   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17922
17923 (define_expand "adddicc"
17924   [(match_operand:DI 0 "register_operand" "")
17925    (match_operand 1 "comparison_operator" "")
17926    (match_operand:DI 2 "register_operand" "")
17927    (match_operand:DI 3 "const_int_operand" "")]
17928   "TARGET_64BIT"
17929   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17930
17931 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17932
17933 (define_split
17934   [(set (match_operand:SF 0 "fp_register_operand" "")
17935         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17936                              (match_operand:SF 2 "register_operand" ""))
17937                          (match_operand:SF 3 "register_operand" "")
17938                          (match_operand:SF 4 "register_operand" "")))
17939    (clobber (reg:CC FLAGS_REG))]
17940   "reload_completed
17941    && ((operands_match_p (operands[1], operands[3])
17942         && operands_match_p (operands[2], operands[4]))
17943        || (operands_match_p (operands[1], operands[4])
17944            && operands_match_p (operands[2], operands[3])))"
17945   [(set (reg:CCFP FLAGS_REG)
17946         (compare:CCFP (match_dup 2)
17947                       (match_dup 1)))
17948    (set (match_dup 0)
17949         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17950                          (match_dup 1)
17951                          (match_dup 2)))])
17952
17953 (define_insn "*minsf_sse"
17954   [(set (match_operand:SF 0 "register_operand" "=x")
17955         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17956                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17957                          (match_dup 1)
17958                          (match_dup 2)))]
17959   "TARGET_SSE && reload_completed"
17960   "minss\t{%2, %0|%0, %2}"
17961   [(set_attr "type" "sse")
17962    (set_attr "mode" "SF")])
17963
17964 (define_expand "mindf3"
17965   [(parallel [
17966      (set (match_operand:DF 0 "register_operand" "")
17967           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17968                                (match_operand:DF 2 "nonimmediate_operand" ""))
17969                            (match_dup 1)
17970                            (match_dup 2)))
17971      (clobber (reg:CC FLAGS_REG))])]
17972   "TARGET_SSE2 && TARGET_SSE_MATH"
17973   "#")
17974
17975 (define_insn "*mindf"
17976   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17977         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17978                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17979                          (match_dup 1)
17980                          (match_dup 2)))
17981    (clobber (reg:CC FLAGS_REG))]
17982   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17983   "#")
17984
17985 (define_insn "*mindf_nonieee"
17986   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17987         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17988                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17989                          (match_dup 1)
17990                          (match_dup 2)))
17991    (clobber (reg:CC FLAGS_REG))]
17992   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17994   "#")
17995
17996 (define_split
17997   [(set (match_operand:DF 0 "register_operand" "")
17998         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17999                              (match_operand:DF 2 "nonimmediate_operand" ""))
18000                          (match_operand:DF 3 "register_operand" "")
18001                          (match_operand:DF 4 "nonimmediate_operand" "")))
18002    (clobber (reg:CC FLAGS_REG))]
18003   "SSE_REG_P (operands[0]) && reload_completed
18004    && ((operands_match_p (operands[1], operands[3])
18005         && operands_match_p (operands[2], operands[4]))
18006        || (operands_match_p (operands[1], operands[4])
18007            && operands_match_p (operands[2], operands[3])))"
18008   [(set (match_dup 0)
18009         (if_then_else:DF (lt (match_dup 1)
18010                              (match_dup 2))
18011                          (match_dup 1)
18012                          (match_dup 2)))])
18013
18014 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18015 (define_split
18016   [(set (match_operand:DF 0 "fp_register_operand" "")
18017         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18018                              (match_operand:DF 2 "register_operand" ""))
18019                          (match_operand:DF 3 "register_operand" "")
18020                          (match_operand:DF 4 "register_operand" "")))
18021    (clobber (reg:CC FLAGS_REG))]
18022   "reload_completed
18023    && ((operands_match_p (operands[1], operands[3])
18024         && operands_match_p (operands[2], operands[4]))
18025        || (operands_match_p (operands[1], operands[4])
18026            && operands_match_p (operands[2], operands[3])))"
18027   [(set (reg:CCFP FLAGS_REG)
18028         (compare:CCFP (match_dup 2)
18029                       (match_dup 1)))
18030    (set (match_dup 0)
18031         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18032                          (match_dup 1)
18033                          (match_dup 2)))])
18034
18035 (define_insn "*mindf_sse"
18036   [(set (match_operand:DF 0 "register_operand" "=Y")
18037         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18038                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18039                          (match_dup 1)
18040                          (match_dup 2)))]
18041   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18042   "minsd\t{%2, %0|%0, %2}"
18043   [(set_attr "type" "sse")
18044    (set_attr "mode" "DF")])
18045
18046 (define_expand "maxsf3"
18047   [(parallel [
18048      (set (match_operand:SF 0 "register_operand" "")
18049           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18050                                (match_operand:SF 2 "nonimmediate_operand" ""))
18051                            (match_dup 1)
18052                            (match_dup 2)))
18053      (clobber (reg:CC FLAGS_REG))])]
18054   "TARGET_SSE"
18055   "#")
18056
18057 (define_insn "*maxsf"
18058   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18059         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18060                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18061                          (match_dup 1)
18062                          (match_dup 2)))
18063    (clobber (reg:CC FLAGS_REG))]
18064   "TARGET_SSE && TARGET_IEEE_FP"
18065   "#")
18066
18067 (define_insn "*maxsf_nonieee"
18068   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18069         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18070                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18071                          (match_dup 1)
18072                          (match_dup 2)))
18073    (clobber (reg:CC FLAGS_REG))]
18074   "TARGET_SSE && !TARGET_IEEE_FP
18075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18076   "#")
18077
18078 (define_split
18079   [(set (match_operand:SF 0 "register_operand" "")
18080         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18081                              (match_operand:SF 2 "nonimmediate_operand" ""))
18082                          (match_operand:SF 3 "register_operand" "")
18083                          (match_operand:SF 4 "nonimmediate_operand" "")))
18084    (clobber (reg:CC FLAGS_REG))]
18085   "SSE_REG_P (operands[0]) && reload_completed
18086    && ((operands_match_p (operands[1], operands[3])
18087         && operands_match_p (operands[2], operands[4]))
18088        || (operands_match_p (operands[1], operands[4])
18089            && operands_match_p (operands[2], operands[3])))"
18090   [(set (match_dup 0)
18091         (if_then_else:SF (gt (match_dup 1)
18092                              (match_dup 2))
18093                          (match_dup 1)
18094                          (match_dup 2)))])
18095
18096 (define_split
18097   [(set (match_operand:SF 0 "fp_register_operand" "")
18098         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18099                              (match_operand:SF 2 "register_operand" ""))
18100                          (match_operand:SF 3 "register_operand" "")
18101                          (match_operand:SF 4 "register_operand" "")))
18102    (clobber (reg:CC FLAGS_REG))]
18103   "reload_completed
18104    && ((operands_match_p (operands[1], operands[3])
18105         && operands_match_p (operands[2], operands[4]))
18106        || (operands_match_p (operands[1], operands[4])
18107            && operands_match_p (operands[2], operands[3])))"
18108   [(set (reg:CCFP FLAGS_REG)
18109         (compare:CCFP (match_dup 1)
18110                       (match_dup 2)))
18111    (set (match_dup 0)
18112         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18113                          (match_dup 1)
18114                          (match_dup 2)))])
18115
18116 (define_insn "*maxsf_sse"
18117   [(set (match_operand:SF 0 "register_operand" "=x")
18118         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18119                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18120                          (match_dup 1)
18121                          (match_dup 2)))]
18122   "TARGET_SSE && reload_completed"
18123   "maxss\t{%2, %0|%0, %2}"
18124   [(set_attr "type" "sse")
18125    (set_attr "mode" "SF")])
18126
18127 (define_expand "maxdf3"
18128   [(parallel [
18129      (set (match_operand:DF 0 "register_operand" "")
18130           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18131                                (match_operand:DF 2 "nonimmediate_operand" ""))
18132                            (match_dup 1)
18133                            (match_dup 2)))
18134      (clobber (reg:CC FLAGS_REG))])]
18135   "TARGET_SSE2 && TARGET_SSE_MATH"
18136   "#")
18137
18138 (define_insn "*maxdf"
18139   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18140         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18141                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18142                          (match_dup 1)
18143                          (match_dup 2)))
18144    (clobber (reg:CC FLAGS_REG))]
18145   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18146   "#")
18147
18148 (define_insn "*maxdf_nonieee"
18149   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18150         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18151                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18152                          (match_dup 1)
18153                          (match_dup 2)))
18154    (clobber (reg:CC FLAGS_REG))]
18155   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18157   "#")
18158
18159 (define_split
18160   [(set (match_operand:DF 0 "register_operand" "")
18161         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18162                              (match_operand:DF 2 "nonimmediate_operand" ""))
18163                          (match_operand:DF 3 "register_operand" "")
18164                          (match_operand:DF 4 "nonimmediate_operand" "")))
18165    (clobber (reg:CC FLAGS_REG))]
18166   "SSE_REG_P (operands[0]) && reload_completed
18167    && ((operands_match_p (operands[1], operands[3])
18168         && operands_match_p (operands[2], operands[4]))
18169        || (operands_match_p (operands[1], operands[4])
18170            && operands_match_p (operands[2], operands[3])))"
18171   [(set (match_dup 0)
18172         (if_then_else:DF (gt (match_dup 1)
18173                              (match_dup 2))
18174                          (match_dup 1)
18175                          (match_dup 2)))])
18176
18177 (define_split
18178   [(set (match_operand:DF 0 "fp_register_operand" "")
18179         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18180                              (match_operand:DF 2 "register_operand" ""))
18181                          (match_operand:DF 3 "register_operand" "")
18182                          (match_operand:DF 4 "register_operand" "")))
18183    (clobber (reg:CC FLAGS_REG))]
18184   "reload_completed
18185    && ((operands_match_p (operands[1], operands[3])
18186         && operands_match_p (operands[2], operands[4]))
18187        || (operands_match_p (operands[1], operands[4])
18188            && operands_match_p (operands[2], operands[3])))"
18189   [(set (reg:CCFP FLAGS_REG)
18190         (compare:CCFP (match_dup 1)
18191                       (match_dup 2)))
18192    (set (match_dup 0)
18193         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18194                          (match_dup 1)
18195                          (match_dup 2)))])
18196
18197 (define_insn "*maxdf_sse"
18198   [(set (match_operand:DF 0 "register_operand" "=Y")
18199         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18200                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18201                          (match_dup 1)
18202                          (match_dup 2)))]
18203   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18204   "maxsd\t{%2, %0|%0, %2}"
18205   [(set_attr "type" "sse")
18206    (set_attr "mode" "DF")])
18207 \f
18208 ;; Misc patterns (?)
18209
18210 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18211 ;; Otherwise there will be nothing to keep
18212 ;; 
18213 ;; [(set (reg ebp) (reg esp))]
18214 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18215 ;;  (clobber (eflags)]
18216 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18217 ;;
18218 ;; in proper program order.
18219 (define_insn "pro_epilogue_adjust_stack_1"
18220   [(set (match_operand:SI 0 "register_operand" "=r,r")
18221         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18222                  (match_operand:SI 2 "immediate_operand" "i,i")))
18223    (clobber (reg:CC FLAGS_REG))
18224    (clobber (mem:BLK (scratch)))]
18225   "!TARGET_64BIT"
18226 {
18227   switch (get_attr_type (insn))
18228     {
18229     case TYPE_IMOV:
18230       return "mov{l}\t{%1, %0|%0, %1}";
18231
18232     case TYPE_ALU:
18233       if (GET_CODE (operands[2]) == CONST_INT
18234           && (INTVAL (operands[2]) == 128
18235               || (INTVAL (operands[2]) < 0
18236                   && INTVAL (operands[2]) != -128)))
18237         {
18238           operands[2] = GEN_INT (-INTVAL (operands[2]));
18239           return "sub{l}\t{%2, %0|%0, %2}";
18240         }
18241       return "add{l}\t{%2, %0|%0, %2}";
18242
18243     case TYPE_LEA:
18244       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18245       return "lea{l}\t{%a2, %0|%0, %a2}";
18246
18247     default:
18248       abort ();
18249     }
18250 }
18251   [(set (attr "type")
18252         (cond [(eq_attr "alternative" "0")
18253                  (const_string "alu")
18254                (match_operand:SI 2 "const0_operand" "")
18255                  (const_string "imov")
18256               ]
18257               (const_string "lea")))
18258    (set_attr "mode" "SI")])
18259
18260 (define_insn "pro_epilogue_adjust_stack_rex64"
18261   [(set (match_operand:DI 0 "register_operand" "=r,r")
18262         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18263                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18264    (clobber (reg:CC FLAGS_REG))
18265    (clobber (mem:BLK (scratch)))]
18266   "TARGET_64BIT"
18267 {
18268   switch (get_attr_type (insn))
18269     {
18270     case TYPE_IMOV:
18271       return "mov{q}\t{%1, %0|%0, %1}";
18272
18273     case TYPE_ALU:
18274       if (GET_CODE (operands[2]) == CONST_INT
18275           /* Avoid overflows.  */
18276           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18277           && (INTVAL (operands[2]) == 128
18278               || (INTVAL (operands[2]) < 0
18279                   && INTVAL (operands[2]) != -128)))
18280         {
18281           operands[2] = GEN_INT (-INTVAL (operands[2]));
18282           return "sub{q}\t{%2, %0|%0, %2}";
18283         }
18284       return "add{q}\t{%2, %0|%0, %2}";
18285
18286     case TYPE_LEA:
18287       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18288       return "lea{q}\t{%a2, %0|%0, %a2}";
18289
18290     default:
18291       abort ();
18292     }
18293 }
18294   [(set (attr "type")
18295         (cond [(eq_attr "alternative" "0")
18296                  (const_string "alu")
18297                (match_operand:DI 2 "const0_operand" "")
18298                  (const_string "imov")
18299               ]
18300               (const_string "lea")))
18301    (set_attr "mode" "DI")])
18302
18303 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18304   [(set (match_operand:DI 0 "register_operand" "=r,r")
18305         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18306                  (match_operand:DI 3 "immediate_operand" "i,i")))
18307    (use (match_operand:DI 2 "register_operand" "r,r"))
18308    (clobber (reg:CC FLAGS_REG))
18309    (clobber (mem:BLK (scratch)))]
18310   "TARGET_64BIT"
18311 {
18312   switch (get_attr_type (insn))
18313     {
18314     case TYPE_ALU:
18315       return "add{q}\t{%2, %0|%0, %2}";
18316
18317     case TYPE_LEA:
18318       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18319       return "lea{q}\t{%a2, %0|%0, %a2}";
18320
18321     default:
18322       abort ();
18323     }
18324 }
18325   [(set_attr "type" "alu,lea")
18326    (set_attr "mode" "DI")])
18327
18328 ;; Placeholder for the conditional moves.  This one is split either to SSE
18329 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18330 ;; fact is that compares supported by the cmp??ss instructions are exactly
18331 ;; swapped of those supported by cmove sequence.
18332 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18333 ;; supported by i387 comparisons and we do need to emit two conditional moves
18334 ;; in tandem.
18335
18336 (define_insn "sse_movsfcc"
18337   [(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")
18338         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18339                         [(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")
18340                          (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")])
18341                       (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")
18342                       (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")))
18343    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18344    (clobber (reg:CC FLAGS_REG))]
18345   "TARGET_SSE
18346    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18347    /* Avoid combine from being smart and converting min/max
18348       instruction patterns into conditional moves.  */
18349    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18350         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18351        || !rtx_equal_p (operands[4], operands[2])
18352        || !rtx_equal_p (operands[5], operands[3]))
18353    && (!TARGET_IEEE_FP
18354        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18355   "#")
18356
18357 (define_insn "sse_movsfcc_eq"
18358   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18359         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18360                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18361                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18362                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18363    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18364    (clobber (reg:CC FLAGS_REG))]
18365   "TARGET_SSE
18366    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18367   "#")
18368
18369 (define_insn "sse_movdfcc"
18370   [(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")
18371         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18372                         [(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")
18373                          (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")])
18374                       (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")
18375                       (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")))
18376    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18377    (clobber (reg:CC FLAGS_REG))]
18378   "TARGET_SSE2
18379    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18380    /* Avoid combine from being smart and converting min/max
18381       instruction patterns into conditional moves.  */
18382    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18383         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18384        || !rtx_equal_p (operands[4], operands[2])
18385        || !rtx_equal_p (operands[5], operands[3]))
18386    && (!TARGET_IEEE_FP
18387        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18388   "#")
18389
18390 (define_insn "sse_movdfcc_eq"
18391   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18392         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18393                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18394                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18395                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18396    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18397    (clobber (reg:CC FLAGS_REG))]
18398   "TARGET_SSE
18399    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18400   "#")
18401
18402 ;; For non-sse moves just expand the usual cmove sequence.
18403 (define_split
18404   [(set (match_operand 0 "register_operand" "")
18405         (if_then_else (match_operator 1 "comparison_operator"
18406                         [(match_operand 4 "nonimmediate_operand" "")
18407                          (match_operand 5 "register_operand" "")])
18408                       (match_operand 2 "nonimmediate_operand" "")
18409                       (match_operand 3 "nonimmediate_operand" "")))
18410    (clobber (match_operand 6 "" ""))
18411    (clobber (reg:CC FLAGS_REG))]
18412   "!SSE_REG_P (operands[0]) && reload_completed
18413    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18414   [(const_int 0)]
18415 {
18416    ix86_compare_op0 = operands[5];
18417    ix86_compare_op1 = operands[4];
18418    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18419                                  VOIDmode, operands[5], operands[4]);
18420    ix86_expand_fp_movcc (operands);
18421    DONE;
18422 })
18423
18424 ;; Split SSE based conditional move into sequence:
18425 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18426 ;; and   op2, op0   -  zero op2 if comparison was false
18427 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18428 ;; or    op2, op0   -  get the nonzero one into the result.
18429 (define_split
18430   [(set (match_operand:SF 0 "register_operand" "")
18431         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18432                         [(match_operand:SF 4 "register_operand" "")
18433                          (match_operand:SF 5 "nonimmediate_operand" "")])
18434                       (match_operand:SF 2 "register_operand" "")
18435                       (match_operand:SF 3 "register_operand" "")))
18436    (clobber (match_operand 6 "" ""))
18437    (clobber (reg:CC FLAGS_REG))]
18438   "SSE_REG_P (operands[0]) && reload_completed"
18439   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18440    (set (match_dup 2) (and:V4SF (match_dup 2)
18441                                 (match_dup 8)))
18442    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18443                                           (match_dup 3)))
18444    (set (match_dup 0) (ior:V4SF (match_dup 6)
18445                                 (match_dup 7)))]
18446 {
18447   /* If op2 == op3, op3 would be clobbered before it is used.  */
18448   if (operands_match_p (operands[2], operands[3]))
18449     {
18450       emit_move_insn (operands[0], operands[2]);
18451       DONE;
18452     }
18453
18454   PUT_MODE (operands[1], GET_MODE (operands[0]));
18455   if (operands_match_p (operands[0], operands[4]))
18456     operands[6] = operands[4], operands[7] = operands[2];
18457   else
18458     operands[6] = operands[2], operands[7] = operands[4];
18459   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18460   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18461   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18462   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18463   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18464   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18465 })
18466
18467 (define_split
18468   [(set (match_operand:DF 0 "register_operand" "")
18469         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18470                         [(match_operand:DF 4 "register_operand" "")
18471                          (match_operand:DF 5 "nonimmediate_operand" "")])
18472                       (match_operand:DF 2 "register_operand" "")
18473                       (match_operand:DF 3 "register_operand" "")))
18474    (clobber (match_operand 6 "" ""))
18475    (clobber (reg:CC FLAGS_REG))]
18476   "SSE_REG_P (operands[0]) && reload_completed"
18477   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18478    (set (match_dup 2) (and:V2DF (match_dup 2)
18479                                 (match_dup 8)))
18480    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18481                                           (match_dup 3)))
18482    (set (match_dup 0) (ior:V2DF (match_dup 6)
18483                                 (match_dup 7)))]
18484 {
18485   if (GET_MODE (operands[2]) == DFmode
18486       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18487     {
18488       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18489       emit_insn (gen_sse2_unpcklpd (op, op, op));
18490       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18491       emit_insn (gen_sse2_unpcklpd (op, op, op));
18492     }
18493
18494   /* If op2 == op3, op3 would be clobbered before it is used.  */
18495   if (operands_match_p (operands[2], operands[3]))
18496     {
18497       emit_move_insn (operands[0], operands[2]);
18498       DONE;
18499     }
18500
18501   PUT_MODE (operands[1], GET_MODE (operands[0]));
18502   if (operands_match_p (operands[0], operands[4]))
18503     operands[6] = operands[4], operands[7] = operands[2];
18504   else
18505     operands[6] = operands[2], operands[7] = operands[4];
18506   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18507   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18508   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18509   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18510   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18511   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18512 })
18513
18514 ;; Special case of conditional move we can handle effectively.
18515 ;; Do not brother with the integer/floating point case, since these are
18516 ;; bot considerably slower, unlike in the generic case.
18517 (define_insn "*sse_movsfcc_const0_1"
18518   [(set (match_operand:SF 0 "register_operand" "=&x")
18519         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18520                         [(match_operand:SF 4 "register_operand" "0")
18521                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18522                       (match_operand:SF 2 "register_operand" "x")
18523                       (match_operand:SF 3 "const0_operand" "X")))]
18524   "TARGET_SSE"
18525   "#")
18526
18527 (define_insn "*sse_movsfcc_const0_2"
18528   [(set (match_operand:SF 0 "register_operand" "=&x")
18529         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18530                         [(match_operand:SF 4 "register_operand" "0")
18531                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18532                       (match_operand:SF 2 "const0_operand" "X")
18533                       (match_operand:SF 3 "register_operand" "x")))]
18534   "TARGET_SSE"
18535   "#")
18536
18537 (define_insn "*sse_movsfcc_const0_3"
18538   [(set (match_operand:SF 0 "register_operand" "=&x")
18539         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18540                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18541                          (match_operand:SF 5 "register_operand" "0")])
18542                       (match_operand:SF 2 "register_operand" "x")
18543                       (match_operand:SF 3 "const0_operand" "X")))]
18544   "TARGET_SSE"
18545   "#")
18546
18547 (define_insn "*sse_movsfcc_const0_4"
18548   [(set (match_operand:SF 0 "register_operand" "=&x")
18549         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18550                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18551                          (match_operand:SF 5 "register_operand" "0")])
18552                       (match_operand:SF 2 "const0_operand" "X")
18553                       (match_operand:SF 3 "register_operand" "x")))]
18554   "TARGET_SSE"
18555   "#")
18556
18557 (define_insn "*sse_movdfcc_const0_1"
18558   [(set (match_operand:DF 0 "register_operand" "=&Y")
18559         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18560                         [(match_operand:DF 4 "register_operand" "0")
18561                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18562                       (match_operand:DF 2 "register_operand" "Y")
18563                       (match_operand:DF 3 "const0_operand" "X")))]
18564   "TARGET_SSE2"
18565   "#")
18566
18567 (define_insn "*sse_movdfcc_const0_2"
18568   [(set (match_operand:DF 0 "register_operand" "=&Y")
18569         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18570                         [(match_operand:DF 4 "register_operand" "0")
18571                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18572                       (match_operand:DF 2 "const0_operand" "X")
18573                       (match_operand:DF 3 "register_operand" "Y")))]
18574   "TARGET_SSE2"
18575   "#")
18576
18577 (define_insn "*sse_movdfcc_const0_3"
18578   [(set (match_operand:DF 0 "register_operand" "=&Y")
18579         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18580                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18581                          (match_operand:DF 5 "register_operand" "0")])
18582                       (match_operand:DF 2 "register_operand" "Y")
18583                       (match_operand:DF 3 "const0_operand" "X")))]
18584   "TARGET_SSE2"
18585   "#")
18586
18587 (define_insn "*sse_movdfcc_const0_4"
18588   [(set (match_operand:DF 0 "register_operand" "=&Y")
18589         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18590                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18591                          (match_operand:DF 5 "register_operand" "0")])
18592                       (match_operand:DF 2 "const0_operand" "X")
18593                       (match_operand:DF 3 "register_operand" "Y")))]
18594   "TARGET_SSE2"
18595   "#")
18596
18597 (define_split
18598   [(set (match_operand:SF 0 "register_operand" "")
18599         (if_then_else (match_operator 1 "comparison_operator"
18600                         [(match_operand:SF 4 "nonimmediate_operand" "")
18601                          (match_operand:SF 5 "nonimmediate_operand" "")])
18602                       (match_operand:SF 2 "nonmemory_operand" "")
18603                       (match_operand:SF 3 "nonmemory_operand" "")))]
18604   "SSE_REG_P (operands[0]) && reload_completed
18605    && (const0_operand (operands[2], GET_MODE (operands[0]))
18606        || const0_operand (operands[3], GET_MODE (operands[0])))"
18607   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18608    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18609 {
18610   PUT_MODE (operands[1], GET_MODE (operands[0]));
18611   if (!sse_comparison_operator (operands[1], VOIDmode)
18612       || !rtx_equal_p (operands[0], operands[4]))
18613     {
18614       rtx tmp = operands[5];
18615       operands[5] = operands[4];
18616       operands[4] = tmp;
18617       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18618     }
18619   if (!rtx_equal_p (operands[0], operands[4]))
18620     abort ();
18621   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18622   if (const0_operand (operands[2], GET_MODE (operands[2])))
18623     {
18624       operands[7] = operands[3];
18625       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18626     }
18627   else
18628     {
18629       operands[7] = operands[2];
18630       operands[6] = operands[8];
18631     }
18632   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18633 })
18634
18635 (define_split
18636   [(set (match_operand:DF 0 "register_operand" "")
18637         (if_then_else (match_operator 1 "comparison_operator"
18638                         [(match_operand:DF 4 "nonimmediate_operand" "")
18639                          (match_operand:DF 5 "nonimmediate_operand" "")])
18640                       (match_operand:DF 2 "nonmemory_operand" "")
18641                       (match_operand:DF 3 "nonmemory_operand" "")))]
18642   "SSE_REG_P (operands[0]) && reload_completed
18643    && (const0_operand (operands[2], GET_MODE (operands[0]))
18644        || const0_operand (operands[3], GET_MODE (operands[0])))"
18645   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18646    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18647 {
18648   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18649       && GET_MODE (operands[2]) == DFmode)
18650     {
18651       if (REG_P (operands[2]))
18652         {
18653           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18654           emit_insn (gen_sse2_unpcklpd (op, op, op));
18655         }
18656       if (REG_P (operands[3]))
18657         {
18658           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18659           emit_insn (gen_sse2_unpcklpd (op, op, op));
18660         }
18661     }
18662   PUT_MODE (operands[1], GET_MODE (operands[0]));
18663   if (!sse_comparison_operator (operands[1], VOIDmode)
18664       || !rtx_equal_p (operands[0], operands[4]))
18665     {
18666       rtx tmp = operands[5];
18667       operands[5] = operands[4];
18668       operands[4] = tmp;
18669       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18670     }
18671   if (!rtx_equal_p (operands[0], operands[4]))
18672     abort ();
18673   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18674   if (const0_operand (operands[2], GET_MODE (operands[2])))
18675     {
18676       operands[7] = operands[3];
18677       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18678     }
18679   else
18680     {
18681       operands[7] = operands[2];
18682       operands[6] = operands[8];
18683     }
18684   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18685 })
18686
18687 (define_expand "allocate_stack_worker"
18688   [(match_operand:SI 0 "register_operand" "")]
18689   "TARGET_STACK_PROBE"
18690 {
18691   if (reload_completed)
18692     {
18693       if (TARGET_64BIT)
18694         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18695       else
18696         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18697     }
18698   else
18699     {
18700       if (TARGET_64BIT)
18701         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18702       else
18703         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18704     }
18705   DONE;
18706 })
18707
18708 (define_insn "allocate_stack_worker_1"
18709   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18710     UNSPECV_STACK_PROBE)
18711    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18712    (clobber (match_scratch:SI 1 "=0"))
18713    (clobber (reg:CC FLAGS_REG))]
18714   "!TARGET_64BIT && TARGET_STACK_PROBE"
18715   "call\t__alloca"
18716   [(set_attr "type" "multi")
18717    (set_attr "length" "5")])
18718
18719 (define_expand "allocate_stack_worker_postreload"
18720   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18721                                     UNSPECV_STACK_PROBE)
18722               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18723               (clobber (match_dup 0))
18724               (clobber (reg:CC FLAGS_REG))])]
18725   ""
18726   "")
18727
18728 (define_insn "allocate_stack_worker_rex64"
18729   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18730     UNSPECV_STACK_PROBE)
18731    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18732    (clobber (match_scratch:DI 1 "=0"))
18733    (clobber (reg:CC FLAGS_REG))]
18734   "TARGET_64BIT && TARGET_STACK_PROBE"
18735   "call\t__alloca"
18736   [(set_attr "type" "multi")
18737    (set_attr "length" "5")])
18738
18739 (define_expand "allocate_stack_worker_rex64_postreload"
18740   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18741                                     UNSPECV_STACK_PROBE)
18742               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18743               (clobber (match_dup 0))
18744               (clobber (reg:CC FLAGS_REG))])]
18745   ""
18746   "")
18747
18748 (define_expand "allocate_stack"
18749   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18750                    (minus:SI (reg:SI SP_REG)
18751                              (match_operand:SI 1 "general_operand" "")))
18752               (clobber (reg:CC FLAGS_REG))])
18753    (parallel [(set (reg:SI SP_REG)
18754                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   "TARGET_STACK_PROBE"
18757 {
18758 #ifdef CHECK_STACK_LIMIT
18759   if (GET_CODE (operands[1]) == CONST_INT
18760       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18761     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18762                            operands[1]));
18763   else 
18764 #endif
18765     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18766                                                             operands[1])));
18767
18768   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18769   DONE;
18770 })
18771
18772 (define_expand "builtin_setjmp_receiver"
18773   [(label_ref (match_operand 0 "" ""))]
18774   "!TARGET_64BIT && flag_pic"
18775 {
18776   emit_insn (gen_set_got (pic_offset_table_rtx));
18777   DONE;
18778 })
18779 \f
18780 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18781
18782 (define_split
18783   [(set (match_operand 0 "register_operand" "")
18784         (match_operator 3 "promotable_binary_operator"
18785            [(match_operand 1 "register_operand" "")
18786             (match_operand 2 "aligned_operand" "")]))
18787    (clobber (reg:CC FLAGS_REG))]
18788   "! TARGET_PARTIAL_REG_STALL && reload_completed
18789    && ((GET_MODE (operands[0]) == HImode 
18790         && ((!optimize_size && !TARGET_FAST_PREFIX)
18791             || GET_CODE (operands[2]) != CONST_INT
18792             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18793        || (GET_MODE (operands[0]) == QImode 
18794            && (TARGET_PROMOTE_QImode || optimize_size)))"
18795   [(parallel [(set (match_dup 0)
18796                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18797               (clobber (reg:CC FLAGS_REG))])]
18798   "operands[0] = gen_lowpart (SImode, operands[0]);
18799    operands[1] = gen_lowpart (SImode, operands[1]);
18800    if (GET_CODE (operands[3]) != ASHIFT)
18801      operands[2] = gen_lowpart (SImode, operands[2]);
18802    PUT_MODE (operands[3], SImode);")
18803
18804 ; Promote the QImode tests, as i386 has encoding of the AND
18805 ; instruction with 32-bit sign-extended immediate and thus the
18806 ; instruction size is unchanged, except in the %eax case for
18807 ; which it is increased by one byte, hence the ! optimize_size.
18808 (define_split
18809   [(set (reg 17)
18810         (compare (and (match_operand 1 "aligned_operand" "")
18811                       (match_operand 2 "const_int_operand" ""))
18812                  (const_int 0)))
18813    (set (match_operand 0 "register_operand" "")
18814         (and (match_dup 1) (match_dup 2)))]
18815   "! TARGET_PARTIAL_REG_STALL && reload_completed
18816    /* Ensure that the operand will remain sign-extended immediate.  */
18817    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18818    && ! optimize_size
18819    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18820        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18821   [(parallel [(set (reg:CCNO FLAGS_REG)
18822                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18823                                  (const_int 0)))
18824               (set (match_dup 0)
18825                    (and:SI (match_dup 1) (match_dup 2)))])]
18826   "operands[2]
18827      = gen_int_mode (INTVAL (operands[2])
18828                      & GET_MODE_MASK (GET_MODE (operands[0])),
18829                      SImode);
18830    operands[0] = gen_lowpart (SImode, operands[0]);
18831    operands[1] = gen_lowpart (SImode, operands[1]);")
18832
18833 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18834 ; the TEST instruction with 32-bit sign-extended immediate and thus
18835 ; the instruction size would at least double, which is not what we
18836 ; want even with ! optimize_size.
18837 (define_split
18838   [(set (reg 17)
18839         (compare (and (match_operand:HI 0 "aligned_operand" "")
18840                       (match_operand:HI 1 "const_int_operand" ""))
18841                  (const_int 0)))]
18842   "! TARGET_PARTIAL_REG_STALL && reload_completed
18843    /* Ensure that the operand will remain sign-extended immediate.  */
18844    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18845    && ! TARGET_FAST_PREFIX
18846    && ! optimize_size"
18847   [(set (reg:CCNO FLAGS_REG)
18848         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18849                       (const_int 0)))]
18850   "operands[1]
18851      = gen_int_mode (INTVAL (operands[1])
18852                      & GET_MODE_MASK (GET_MODE (operands[0])),
18853                      SImode);
18854    operands[0] = gen_lowpart (SImode, operands[0]);")
18855
18856 (define_split
18857   [(set (match_operand 0 "register_operand" "")
18858         (neg (match_operand 1 "register_operand" "")))
18859    (clobber (reg:CC FLAGS_REG))]
18860   "! TARGET_PARTIAL_REG_STALL && reload_completed
18861    && (GET_MODE (operands[0]) == HImode
18862        || (GET_MODE (operands[0]) == QImode 
18863            && (TARGET_PROMOTE_QImode || optimize_size)))"
18864   [(parallel [(set (match_dup 0)
18865                    (neg:SI (match_dup 1)))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   "operands[0] = gen_lowpart (SImode, operands[0]);
18868    operands[1] = gen_lowpart (SImode, operands[1]);")
18869
18870 (define_split
18871   [(set (match_operand 0 "register_operand" "")
18872         (not (match_operand 1 "register_operand" "")))]
18873   "! TARGET_PARTIAL_REG_STALL && reload_completed
18874    && (GET_MODE (operands[0]) == HImode
18875        || (GET_MODE (operands[0]) == QImode 
18876            && (TARGET_PROMOTE_QImode || optimize_size)))"
18877   [(set (match_dup 0)
18878         (not:SI (match_dup 1)))]
18879   "operands[0] = gen_lowpart (SImode, operands[0]);
18880    operands[1] = gen_lowpart (SImode, operands[1]);")
18881
18882 (define_split 
18883   [(set (match_operand 0 "register_operand" "")
18884         (if_then_else (match_operator 1 "comparison_operator" 
18885                                 [(reg 17) (const_int 0)])
18886                       (match_operand 2 "register_operand" "")
18887                       (match_operand 3 "register_operand" "")))]
18888   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18889    && (GET_MODE (operands[0]) == HImode
18890        || (GET_MODE (operands[0]) == QImode 
18891            && (TARGET_PROMOTE_QImode || optimize_size)))"
18892   [(set (match_dup 0)
18893         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18894   "operands[0] = gen_lowpart (SImode, operands[0]);
18895    operands[2] = gen_lowpart (SImode, operands[2]);
18896    operands[3] = gen_lowpart (SImode, operands[3]);")
18897                         
18898 \f
18899 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18900 ;; transform a complex memory operation into two memory to register operations.
18901
18902 ;; Don't push memory operands
18903 (define_peephole2
18904   [(set (match_operand:SI 0 "push_operand" "")
18905         (match_operand:SI 1 "memory_operand" ""))
18906    (match_scratch:SI 2 "r")]
18907   "! optimize_size && ! TARGET_PUSH_MEMORY"
18908   [(set (match_dup 2) (match_dup 1))
18909    (set (match_dup 0) (match_dup 2))]
18910   "")
18911
18912 (define_peephole2
18913   [(set (match_operand:DI 0 "push_operand" "")
18914         (match_operand:DI 1 "memory_operand" ""))
18915    (match_scratch:DI 2 "r")]
18916   "! optimize_size && ! TARGET_PUSH_MEMORY"
18917   [(set (match_dup 2) (match_dup 1))
18918    (set (match_dup 0) (match_dup 2))]
18919   "")
18920
18921 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18922 ;; SImode pushes.
18923 (define_peephole2
18924   [(set (match_operand:SF 0 "push_operand" "")
18925         (match_operand:SF 1 "memory_operand" ""))
18926    (match_scratch:SF 2 "r")]
18927   "! optimize_size && ! TARGET_PUSH_MEMORY"
18928   [(set (match_dup 2) (match_dup 1))
18929    (set (match_dup 0) (match_dup 2))]
18930   "")
18931
18932 (define_peephole2
18933   [(set (match_operand:HI 0 "push_operand" "")
18934         (match_operand:HI 1 "memory_operand" ""))
18935    (match_scratch:HI 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:QI 0 "push_operand" "")
18943         (match_operand:QI 1 "memory_operand" ""))
18944    (match_scratch:QI 2 "q")]
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 ;; Don't move an immediate directly to memory when the instruction
18951 ;; gets too big.
18952 (define_peephole2
18953   [(match_scratch:SI 1 "r")
18954    (set (match_operand:SI 0 "memory_operand" "")
18955         (const_int 0))]
18956   "! optimize_size
18957    && ! TARGET_USE_MOV0
18958    && TARGET_SPLIT_LONG_MOVES
18959    && get_attr_length (insn) >= ix86_cost->large_insn
18960    && peep2_regno_dead_p (0, FLAGS_REG)"
18961   [(parallel [(set (match_dup 1) (const_int 0))
18962               (clobber (reg:CC FLAGS_REG))])
18963    (set (match_dup 0) (match_dup 1))]
18964   "")
18965
18966 (define_peephole2
18967   [(match_scratch:HI 1 "r")
18968    (set (match_operand:HI 0 "memory_operand" "")
18969         (const_int 0))]
18970   "! optimize_size
18971    && ! TARGET_USE_MOV0
18972    && TARGET_SPLIT_LONG_MOVES
18973    && get_attr_length (insn) >= ix86_cost->large_insn
18974    && peep2_regno_dead_p (0, FLAGS_REG)"
18975   [(parallel [(set (match_dup 2) (const_int 0))
18976               (clobber (reg:CC FLAGS_REG))])
18977    (set (match_dup 0) (match_dup 1))]
18978   "operands[2] = gen_lowpart (SImode, operands[1]);")
18979
18980 (define_peephole2
18981   [(match_scratch:QI 1 "q")
18982    (set (match_operand:QI 0 "memory_operand" "")
18983         (const_int 0))]
18984   "! optimize_size
18985    && ! TARGET_USE_MOV0
18986    && TARGET_SPLIT_LONG_MOVES
18987    && get_attr_length (insn) >= ix86_cost->large_insn
18988    && peep2_regno_dead_p (0, FLAGS_REG)"
18989   [(parallel [(set (match_dup 2) (const_int 0))
18990               (clobber (reg:CC FLAGS_REG))])
18991    (set (match_dup 0) (match_dup 1))]
18992   "operands[2] = gen_lowpart (SImode, operands[1]);")
18993
18994 (define_peephole2
18995   [(match_scratch:SI 2 "r")
18996    (set (match_operand:SI 0 "memory_operand" "")
18997         (match_operand:SI 1 "immediate_operand" ""))]
18998   "! optimize_size
18999    && get_attr_length (insn) >= ix86_cost->large_insn
19000    && TARGET_SPLIT_LONG_MOVES"
19001   [(set (match_dup 2) (match_dup 1))
19002    (set (match_dup 0) (match_dup 2))]
19003   "")
19004
19005 (define_peephole2
19006   [(match_scratch:HI 2 "r")
19007    (set (match_operand:HI 0 "memory_operand" "")
19008         (match_operand:HI 1 "immediate_operand" ""))]
19009   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19010   && TARGET_SPLIT_LONG_MOVES"
19011   [(set (match_dup 2) (match_dup 1))
19012    (set (match_dup 0) (match_dup 2))]
19013   "")
19014
19015 (define_peephole2
19016   [(match_scratch:QI 2 "q")
19017    (set (match_operand:QI 0 "memory_operand" "")
19018         (match_operand:QI 1 "immediate_operand" ""))]
19019   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19020   && TARGET_SPLIT_LONG_MOVES"
19021   [(set (match_dup 2) (match_dup 1))
19022    (set (match_dup 0) (match_dup 2))]
19023   "")
19024
19025 ;; Don't compare memory with zero, load and use a test instead.
19026 (define_peephole2
19027   [(set (reg 17)
19028         (compare (match_operand:SI 0 "memory_operand" "")
19029                  (const_int 0)))
19030    (match_scratch:SI 3 "r")]
19031   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19032   [(set (match_dup 3) (match_dup 0))
19033    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19034   "")
19035
19036 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19037 ;; Don't split NOTs with a displacement operand, because resulting XOR
19038 ;; will not be pairable anyway.
19039 ;;
19040 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19041 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19042 ;; so this split helps here as well.
19043 ;;
19044 ;; Note: Can't do this as a regular split because we can't get proper
19045 ;; lifetime information then.
19046
19047 (define_peephole2
19048   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19049         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19050   "!optimize_size
19051    && peep2_regno_dead_p (0, FLAGS_REG)
19052    && ((TARGET_PENTIUM 
19053         && (GET_CODE (operands[0]) != MEM
19054             || !memory_displacement_operand (operands[0], SImode)))
19055        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19056   [(parallel [(set (match_dup 0)
19057                    (xor:SI (match_dup 1) (const_int -1)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "")
19060
19061 (define_peephole2
19062   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19063         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19064   "!optimize_size
19065    && peep2_regno_dead_p (0, FLAGS_REG)
19066    && ((TARGET_PENTIUM 
19067         && (GET_CODE (operands[0]) != MEM
19068             || !memory_displacement_operand (operands[0], HImode)))
19069        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19070   [(parallel [(set (match_dup 0)
19071                    (xor:HI (match_dup 1) (const_int -1)))
19072               (clobber (reg:CC FLAGS_REG))])]
19073   "")
19074
19075 (define_peephole2
19076   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19077         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19078   "!optimize_size
19079    && peep2_regno_dead_p (0, FLAGS_REG)
19080    && ((TARGET_PENTIUM 
19081         && (GET_CODE (operands[0]) != MEM
19082             || !memory_displacement_operand (operands[0], QImode)))
19083        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19084   [(parallel [(set (match_dup 0)
19085                    (xor:QI (match_dup 1) (const_int -1)))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   "")
19088
19089 ;; Non pairable "test imm, reg" instructions can be translated to
19090 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19091 ;; byte opcode instead of two, have a short form for byte operands),
19092 ;; so do it for other CPUs as well.  Given that the value was dead,
19093 ;; this should not create any new dependencies.  Pass on the sub-word
19094 ;; versions if we're concerned about partial register stalls.
19095
19096 (define_peephole2
19097   [(set (reg 17)
19098         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19099                          (match_operand:SI 1 "immediate_operand" ""))
19100                  (const_int 0)))]
19101   "ix86_match_ccmode (insn, CCNOmode)
19102    && (true_regnum (operands[0]) != 0
19103        || (GET_CODE (operands[1]) == CONST_INT
19104            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19105    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19106   [(parallel
19107      [(set (reg:CCNO FLAGS_REG)
19108            (compare:CCNO (and:SI (match_dup 0)
19109                                  (match_dup 1))
19110                          (const_int 0)))
19111       (set (match_dup 0)
19112            (and:SI (match_dup 0) (match_dup 1)))])]
19113   "")
19114
19115 ;; We don't need to handle HImode case, because it will be promoted to SImode
19116 ;; on ! TARGET_PARTIAL_REG_STALL
19117
19118 (define_peephole2
19119   [(set (reg 17)
19120         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19121                          (match_operand:QI 1 "immediate_operand" ""))
19122                  (const_int 0)))]
19123   "! TARGET_PARTIAL_REG_STALL
19124    && ix86_match_ccmode (insn, CCNOmode)
19125    && true_regnum (operands[0]) != 0
19126    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19127   [(parallel
19128      [(set (reg:CCNO FLAGS_REG)
19129            (compare:CCNO (and:QI (match_dup 0)
19130                                  (match_dup 1))
19131                          (const_int 0)))
19132       (set (match_dup 0)
19133            (and:QI (match_dup 0) (match_dup 1)))])]
19134   "")
19135
19136 (define_peephole2
19137   [(set (reg 17)
19138         (compare
19139           (and:SI
19140             (zero_extract:SI
19141               (match_operand 0 "ext_register_operand" "")
19142               (const_int 8)
19143               (const_int 8))
19144             (match_operand 1 "const_int_operand" ""))
19145           (const_int 0)))]
19146   "! TARGET_PARTIAL_REG_STALL
19147    && ix86_match_ccmode (insn, CCNOmode)
19148    && true_regnum (operands[0]) != 0
19149    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19150   [(parallel [(set (reg:CCNO FLAGS_REG)
19151                    (compare:CCNO
19152                        (and:SI
19153                          (zero_extract:SI
19154                          (match_dup 0)
19155                          (const_int 8)
19156                          (const_int 8))
19157                         (match_dup 1))
19158                    (const_int 0)))
19159               (set (zero_extract:SI (match_dup 0)
19160                                     (const_int 8)
19161                                     (const_int 8))
19162                    (and:SI 
19163                      (zero_extract:SI
19164                        (match_dup 0)
19165                        (const_int 8)
19166                        (const_int 8))
19167                      (match_dup 1)))])]
19168   "")
19169
19170 ;; Don't do logical operations with memory inputs.
19171 (define_peephole2
19172   [(match_scratch:SI 2 "r")
19173    (parallel [(set (match_operand:SI 0 "register_operand" "")
19174                    (match_operator:SI 3 "arith_or_logical_operator"
19175                      [(match_dup 0)
19176                       (match_operand:SI 1 "memory_operand" "")]))
19177               (clobber (reg:CC FLAGS_REG))])]
19178   "! optimize_size && ! TARGET_READ_MODIFY"
19179   [(set (match_dup 2) (match_dup 1))
19180    (parallel [(set (match_dup 0)
19181                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19182               (clobber (reg:CC FLAGS_REG))])]
19183   "")
19184
19185 (define_peephole2
19186   [(match_scratch:SI 2 "r")
19187    (parallel [(set (match_operand:SI 0 "register_operand" "")
19188                    (match_operator:SI 3 "arith_or_logical_operator"
19189                      [(match_operand:SI 1 "memory_operand" "")
19190                       (match_dup 0)]))
19191               (clobber (reg:CC FLAGS_REG))])]
19192   "! optimize_size && ! TARGET_READ_MODIFY"
19193   [(set (match_dup 2) (match_dup 1))
19194    (parallel [(set (match_dup 0)
19195                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19196               (clobber (reg:CC FLAGS_REG))])]
19197   "")
19198
19199 ; Don't do logical operations with memory outputs
19200 ;
19201 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19202 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19203 ; the same decoder scheduling characteristics as the original.
19204
19205 (define_peephole2
19206   [(match_scratch:SI 2 "r")
19207    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19208                    (match_operator:SI 3 "arith_or_logical_operator"
19209                      [(match_dup 0)
19210                       (match_operand:SI 1 "nonmemory_operand" "")]))
19211               (clobber (reg:CC FLAGS_REG))])]
19212   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19213   [(set (match_dup 2) (match_dup 0))
19214    (parallel [(set (match_dup 2)
19215                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19216               (clobber (reg:CC FLAGS_REG))])
19217    (set (match_dup 0) (match_dup 2))]
19218   "")
19219
19220 (define_peephole2
19221   [(match_scratch:SI 2 "r")
19222    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19223                    (match_operator:SI 3 "arith_or_logical_operator"
19224                      [(match_operand:SI 1 "nonmemory_operand" "")
19225                       (match_dup 0)]))
19226               (clobber (reg:CC FLAGS_REG))])]
19227   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19228   [(set (match_dup 2) (match_dup 0))
19229    (parallel [(set (match_dup 2)
19230                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19231               (clobber (reg:CC FLAGS_REG))])
19232    (set (match_dup 0) (match_dup 2))]
19233   "")
19234
19235 ;; Attempt to always use XOR for zeroing registers.
19236 (define_peephole2
19237   [(set (match_operand 0 "register_operand" "")
19238         (const_int 0))]
19239   "(GET_MODE (operands[0]) == QImode
19240     || GET_MODE (operands[0]) == HImode
19241     || GET_MODE (operands[0]) == SImode
19242     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19243    && (! TARGET_USE_MOV0 || optimize_size)
19244    && peep2_regno_dead_p (0, FLAGS_REG)"
19245   [(parallel [(set (match_dup 0) (const_int 0))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19248                               operands[0]);")
19249
19250 (define_peephole2
19251   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19252         (const_int 0))]
19253   "(GET_MODE (operands[0]) == QImode
19254     || GET_MODE (operands[0]) == HImode)
19255    && (! TARGET_USE_MOV0 || optimize_size)
19256    && peep2_regno_dead_p (0, FLAGS_REG)"
19257   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19258               (clobber (reg:CC FLAGS_REG))])])
19259
19260 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19261 (define_peephole2
19262   [(set (match_operand 0 "register_operand" "")
19263         (const_int -1))]
19264   "(GET_MODE (operands[0]) == HImode
19265     || GET_MODE (operands[0]) == SImode 
19266     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19267    && (optimize_size || TARGET_PENTIUM)
19268    && peep2_regno_dead_p (0, FLAGS_REG)"
19269   [(parallel [(set (match_dup 0) (const_int -1))
19270               (clobber (reg:CC FLAGS_REG))])]
19271   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19272                               operands[0]);")
19273
19274 ;; Attempt to convert simple leas to adds. These can be created by
19275 ;; move expanders.
19276 (define_peephole2
19277   [(set (match_operand:SI 0 "register_operand" "")
19278         (plus:SI (match_dup 0)
19279                  (match_operand:SI 1 "nonmemory_operand" "")))]
19280   "peep2_regno_dead_p (0, FLAGS_REG)"
19281   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19282               (clobber (reg:CC FLAGS_REG))])]
19283   "")
19284
19285 (define_peephole2
19286   [(set (match_operand:SI 0 "register_operand" "")
19287         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19288                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19289   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19290   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19291               (clobber (reg:CC FLAGS_REG))])]
19292   "operands[2] = gen_lowpart (SImode, operands[2]);")
19293
19294 (define_peephole2
19295   [(set (match_operand:DI 0 "register_operand" "")
19296         (plus:DI (match_dup 0)
19297                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19298   "peep2_regno_dead_p (0, FLAGS_REG)"
19299   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19300               (clobber (reg:CC FLAGS_REG))])]
19301   "")
19302
19303 (define_peephole2
19304   [(set (match_operand:SI 0 "register_operand" "")
19305         (mult:SI (match_dup 0)
19306                  (match_operand:SI 1 "const_int_operand" "")))]
19307   "exact_log2 (INTVAL (operands[1])) >= 0
19308    && peep2_regno_dead_p (0, FLAGS_REG)"
19309   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19312
19313 (define_peephole2
19314   [(set (match_operand:DI 0 "register_operand" "")
19315         (mult:DI (match_dup 0)
19316                  (match_operand:DI 1 "const_int_operand" "")))]
19317   "exact_log2 (INTVAL (operands[1])) >= 0
19318    && peep2_regno_dead_p (0, FLAGS_REG)"
19319   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19322
19323 (define_peephole2
19324   [(set (match_operand:SI 0 "register_operand" "")
19325         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19326                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19327   "exact_log2 (INTVAL (operands[2])) >= 0
19328    && REGNO (operands[0]) == REGNO (operands[1])
19329    && peep2_regno_dead_p (0, FLAGS_REG)"
19330   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19333
19334 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19335 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19336 ;; many CPUs it is also faster, since special hardware to avoid esp
19337 ;; dependencies is present.
19338
19339 ;; While some of these conversions may be done using splitters, we use peepholes
19340 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19341
19342 ;; Convert prologue esp subtractions to push.
19343 ;; We need register to push.  In order to keep verify_flow_info happy we have
19344 ;; two choices
19345 ;; - use scratch and clobber it in order to avoid dependencies
19346 ;; - use already live register
19347 ;; We can't use the second way right now, since there is no reliable way how to
19348 ;; verify that given register is live.  First choice will also most likely in
19349 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19350 ;; call clobbered registers are dead.  We may want to use base pointer as an
19351 ;; alternative when no register is available later.
19352
19353 (define_peephole2
19354   [(match_scratch:SI 0 "r")
19355    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19356               (clobber (reg:CC FLAGS_REG))
19357               (clobber (mem:BLK (scratch)))])]
19358   "optimize_size || !TARGET_SUB_ESP_4"
19359   [(clobber (match_dup 0))
19360    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19361               (clobber (mem:BLK (scratch)))])])
19362
19363 (define_peephole2
19364   [(match_scratch:SI 0 "r")
19365    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19366               (clobber (reg:CC FLAGS_REG))
19367               (clobber (mem:BLK (scratch)))])]
19368   "optimize_size || !TARGET_SUB_ESP_8"
19369   [(clobber (match_dup 0))
19370    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19371    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19372               (clobber (mem:BLK (scratch)))])])
19373
19374 ;; Convert esp subtractions to push.
19375 (define_peephole2
19376   [(match_scratch:SI 0 "r")
19377    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19378               (clobber (reg:CC FLAGS_REG))])]
19379   "optimize_size || !TARGET_SUB_ESP_4"
19380   [(clobber (match_dup 0))
19381    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19382
19383 (define_peephole2
19384   [(match_scratch:SI 0 "r")
19385    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19386               (clobber (reg:CC FLAGS_REG))])]
19387   "optimize_size || !TARGET_SUB_ESP_8"
19388   [(clobber (match_dup 0))
19389    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19390    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19391
19392 ;; Convert epilogue deallocator to pop.
19393 (define_peephole2
19394   [(match_scratch:SI 0 "r")
19395    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19396               (clobber (reg:CC FLAGS_REG))
19397               (clobber (mem:BLK (scratch)))])]
19398   "optimize_size || !TARGET_ADD_ESP_4"
19399   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19401               (clobber (mem:BLK (scratch)))])]
19402   "")
19403
19404 ;; Two pops case is tricky, since pop causes dependency on destination register.
19405 ;; We use two registers if available.
19406 (define_peephole2
19407   [(match_scratch:SI 0 "r")
19408    (match_scratch:SI 1 "r")
19409    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19410               (clobber (reg:CC FLAGS_REG))
19411               (clobber (mem:BLK (scratch)))])]
19412   "optimize_size || !TARGET_ADD_ESP_8"
19413   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19414               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19415               (clobber (mem:BLK (scratch)))])
19416    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19417               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19418   "")
19419
19420 (define_peephole2
19421   [(match_scratch:SI 0 "r")
19422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19423               (clobber (reg:CC FLAGS_REG))
19424               (clobber (mem:BLK (scratch)))])]
19425   "optimize_size"
19426   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19427               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19428               (clobber (mem:BLK (scratch)))])
19429    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19430               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19431   "")
19432
19433 ;; Convert esp additions to pop.
19434 (define_peephole2
19435   [(match_scratch:SI 0 "r")
19436    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19437               (clobber (reg:CC FLAGS_REG))])]
19438   ""
19439   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19440               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19441   "")
19442
19443 ;; Two pops case is tricky, since pop causes dependency on destination register.
19444 ;; We use two registers if available.
19445 (define_peephole2
19446   [(match_scratch:SI 0 "r")
19447    (match_scratch:SI 1 "r")
19448    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19449               (clobber (reg:CC FLAGS_REG))])]
19450   ""
19451   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19453    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19455   "")
19456
19457 (define_peephole2
19458   [(match_scratch:SI 0 "r")
19459    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460               (clobber (reg:CC FLAGS_REG))])]
19461   "optimize_size"
19462   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19463               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19464    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19465               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19466   "")
19467 \f
19468 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19469 ;; required and register dies.
19470 (define_peephole2
19471   [(set (reg 17)
19472         (compare (match_operand:SI 0 "register_operand" "")
19473                  (match_operand:SI 1 "incdec_operand" "")))]
19474   "ix86_match_ccmode (insn, CCGCmode)
19475    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19476   [(parallel [(set (reg:CCGC FLAGS_REG)
19477                    (compare:CCGC (match_dup 0)
19478                                  (match_dup 1)))
19479               (clobber (match_dup 0))])]
19480   "")
19481
19482 (define_peephole2
19483   [(set (reg 17)
19484         (compare (match_operand:HI 0 "register_operand" "")
19485                  (match_operand:HI 1 "incdec_operand" "")))]
19486   "ix86_match_ccmode (insn, CCGCmode)
19487    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19488   [(parallel [(set (reg:CCGC FLAGS_REG)
19489                    (compare:CCGC (match_dup 0)
19490                                  (match_dup 1)))
19491               (clobber (match_dup 0))])]
19492   "")
19493
19494 (define_peephole2
19495   [(set (reg 17)
19496         (compare (match_operand:QI 0 "register_operand" "")
19497                  (match_operand:QI 1 "incdec_operand" "")))]
19498   "ix86_match_ccmode (insn, CCGCmode)
19499    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19500   [(parallel [(set (reg:CCGC FLAGS_REG)
19501                    (compare:CCGC (match_dup 0)
19502                                  (match_dup 1)))
19503               (clobber (match_dup 0))])]
19504   "")
19505
19506 ;; Convert compares with 128 to shorter add -128
19507 (define_peephole2
19508   [(set (reg 17)
19509         (compare (match_operand:SI 0 "register_operand" "")
19510                  (const_int 128)))]
19511   "ix86_match_ccmode (insn, CCGCmode)
19512    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19513   [(parallel [(set (reg:CCGC FLAGS_REG)
19514                    (compare:CCGC (match_dup 0)
19515                                  (const_int 128)))
19516               (clobber (match_dup 0))])]
19517   "")
19518
19519 (define_peephole2
19520   [(set (reg 17)
19521         (compare (match_operand:HI 0 "register_operand" "")
19522                  (const_int 128)))]
19523   "ix86_match_ccmode (insn, CCGCmode)
19524    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19525   [(parallel [(set (reg:CCGC FLAGS_REG)
19526                    (compare:CCGC (match_dup 0)
19527                                  (const_int 128)))
19528               (clobber (match_dup 0))])]
19529   "")
19530 \f
19531 (define_peephole2
19532   [(match_scratch:DI 0 "r")
19533    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19534               (clobber (reg:CC FLAGS_REG))
19535               (clobber (mem:BLK (scratch)))])]
19536   "optimize_size || !TARGET_SUB_ESP_4"
19537   [(clobber (match_dup 0))
19538    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19539               (clobber (mem:BLK (scratch)))])])
19540
19541 (define_peephole2
19542   [(match_scratch:DI 0 "r")
19543    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19544               (clobber (reg:CC FLAGS_REG))
19545               (clobber (mem:BLK (scratch)))])]
19546   "optimize_size || !TARGET_SUB_ESP_8"
19547   [(clobber (match_dup 0))
19548    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19549    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19550               (clobber (mem:BLK (scratch)))])])
19551
19552 ;; Convert esp subtractions to push.
19553 (define_peephole2
19554   [(match_scratch:DI 0 "r")
19555    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19556               (clobber (reg:CC FLAGS_REG))])]
19557   "optimize_size || !TARGET_SUB_ESP_4"
19558   [(clobber (match_dup 0))
19559    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19560
19561 (define_peephole2
19562   [(match_scratch:DI 0 "r")
19563    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19564               (clobber (reg:CC FLAGS_REG))])]
19565   "optimize_size || !TARGET_SUB_ESP_8"
19566   [(clobber (match_dup 0))
19567    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19568    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19569
19570 ;; Convert epilogue deallocator to pop.
19571 (define_peephole2
19572   [(match_scratch:DI 0 "r")
19573    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19574               (clobber (reg:CC FLAGS_REG))
19575               (clobber (mem:BLK (scratch)))])]
19576   "optimize_size || !TARGET_ADD_ESP_4"
19577   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19578               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19579               (clobber (mem:BLK (scratch)))])]
19580   "")
19581
19582 ;; Two pops case is tricky, since pop causes dependency on destination register.
19583 ;; We use two registers if available.
19584 (define_peephole2
19585   [(match_scratch:DI 0 "r")
19586    (match_scratch:DI 1 "r")
19587    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19588               (clobber (reg:CC FLAGS_REG))
19589               (clobber (mem:BLK (scratch)))])]
19590   "optimize_size || !TARGET_ADD_ESP_8"
19591   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19592               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19593               (clobber (mem:BLK (scratch)))])
19594    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19595               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19596   "")
19597
19598 (define_peephole2
19599   [(match_scratch:DI 0 "r")
19600    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19601               (clobber (reg:CC FLAGS_REG))
19602               (clobber (mem:BLK (scratch)))])]
19603   "optimize_size"
19604   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19605               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19606               (clobber (mem:BLK (scratch)))])
19607    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19608               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19609   "")
19610
19611 ;; Convert esp additions to pop.
19612 (define_peephole2
19613   [(match_scratch:DI 0 "r")
19614    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19615               (clobber (reg:CC FLAGS_REG))])]
19616   ""
19617   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19618               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19619   "")
19620
19621 ;; Two pops case is tricky, since pop causes dependency on destination register.
19622 ;; We use two registers if available.
19623 (define_peephole2
19624   [(match_scratch:DI 0 "r")
19625    (match_scratch:DI 1 "r")
19626    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19627               (clobber (reg:CC FLAGS_REG))])]
19628   ""
19629   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19630               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19631    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19633   "")
19634
19635 (define_peephole2
19636   [(match_scratch:DI 0 "r")
19637    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "optimize_size"
19640   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19641               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19642    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19643               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19644   "")
19645 \f
19646 ;; Convert imul by three, five and nine into lea
19647 (define_peephole2
19648   [(parallel
19649     [(set (match_operand:SI 0 "register_operand" "")
19650           (mult:SI (match_operand:SI 1 "register_operand" "")
19651                    (match_operand:SI 2 "const_int_operand" "")))
19652      (clobber (reg:CC FLAGS_REG))])]
19653   "INTVAL (operands[2]) == 3
19654    || INTVAL (operands[2]) == 5
19655    || INTVAL (operands[2]) == 9"
19656   [(set (match_dup 0)
19657         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19658                  (match_dup 1)))]
19659   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19660
19661 (define_peephole2
19662   [(parallel
19663     [(set (match_operand:SI 0 "register_operand" "")
19664           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19665                    (match_operand:SI 2 "const_int_operand" "")))
19666      (clobber (reg:CC FLAGS_REG))])]
19667   "!optimize_size 
19668    && (INTVAL (operands[2]) == 3
19669        || INTVAL (operands[2]) == 5
19670        || INTVAL (operands[2]) == 9)"
19671   [(set (match_dup 0) (match_dup 1))
19672    (set (match_dup 0)
19673         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19674                  (match_dup 0)))]
19675   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19676
19677 (define_peephole2
19678   [(parallel
19679     [(set (match_operand:DI 0 "register_operand" "")
19680           (mult:DI (match_operand:DI 1 "register_operand" "")
19681                    (match_operand:DI 2 "const_int_operand" "")))
19682      (clobber (reg:CC FLAGS_REG))])]
19683   "TARGET_64BIT
19684    && (INTVAL (operands[2]) == 3
19685        || INTVAL (operands[2]) == 5
19686        || INTVAL (operands[2]) == 9)"
19687   [(set (match_dup 0)
19688         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19689                  (match_dup 1)))]
19690   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19691
19692 (define_peephole2
19693   [(parallel
19694     [(set (match_operand:DI 0 "register_operand" "")
19695           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19696                    (match_operand:DI 2 "const_int_operand" "")))
19697      (clobber (reg:CC FLAGS_REG))])]
19698   "TARGET_64BIT
19699    && !optimize_size 
19700    && (INTVAL (operands[2]) == 3
19701        || INTVAL (operands[2]) == 5
19702        || INTVAL (operands[2]) == 9)"
19703   [(set (match_dup 0) (match_dup 1))
19704    (set (match_dup 0)
19705         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19706                  (match_dup 0)))]
19707   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19708
19709 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19710 ;; imul $32bit_imm, reg, reg is direct decoded.
19711 (define_peephole2
19712   [(match_scratch:DI 3 "r")
19713    (parallel [(set (match_operand:DI 0 "register_operand" "")
19714                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19715                             (match_operand:DI 2 "immediate_operand" "")))
19716               (clobber (reg:CC FLAGS_REG))])]
19717   "TARGET_K8 && !optimize_size
19718    && (GET_CODE (operands[2]) != CONST_INT
19719        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19720   [(set (match_dup 3) (match_dup 1))
19721    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19722               (clobber (reg:CC FLAGS_REG))])]
19723 "")
19724
19725 (define_peephole2
19726   [(match_scratch:SI 3 "r")
19727    (parallel [(set (match_operand:SI 0 "register_operand" "")
19728                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19729                             (match_operand:SI 2 "immediate_operand" "")))
19730               (clobber (reg:CC FLAGS_REG))])]
19731   "TARGET_K8 && !optimize_size
19732    && (GET_CODE (operands[2]) != CONST_INT
19733        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19734   [(set (match_dup 3) (match_dup 1))
19735    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19736               (clobber (reg:CC FLAGS_REG))])]
19737 "")
19738
19739 (define_peephole2
19740   [(match_scratch:SI 3 "r")
19741    (parallel [(set (match_operand:DI 0 "register_operand" "")
19742                    (zero_extend:DI
19743                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19744                               (match_operand:SI 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) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19751               (clobber (reg:CC FLAGS_REG))])]
19752 "")
19753
19754 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19755 ;; Convert it into imul reg, reg
19756 ;; It would be better to force assembler to encode instruction using long
19757 ;; immediate, but there is apparently no way to do so.
19758 (define_peephole2
19759   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19760                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19761                             (match_operand:DI 2 "const_int_operand" "")))
19762               (clobber (reg:CC FLAGS_REG))])
19763    (match_scratch:DI 3 "r")]
19764   "TARGET_K8 && !optimize_size
19765    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19766   [(set (match_dup 3) (match_dup 2))
19767    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19768               (clobber (reg:CC FLAGS_REG))])]
19769 {
19770   if (!rtx_equal_p (operands[0], operands[1]))
19771     emit_move_insn (operands[0], operands[1]);
19772 })
19773
19774 (define_peephole2
19775   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19776                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19777                             (match_operand:SI 2 "const_int_operand" "")))
19778               (clobber (reg:CC FLAGS_REG))])
19779    (match_scratch:SI 3 "r")]
19780   "TARGET_K8 && !optimize_size
19781    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19782   [(set (match_dup 3) (match_dup 2))
19783    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19784               (clobber (reg:CC FLAGS_REG))])]
19785 {
19786   if (!rtx_equal_p (operands[0], operands[1]))
19787     emit_move_insn (operands[0], operands[1]);
19788 })
19789
19790 (define_peephole2
19791   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19792                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19793                             (match_operand:HI 2 "immediate_operand" "")))
19794               (clobber (reg:CC FLAGS_REG))])
19795    (match_scratch:HI 3 "r")]
19796   "TARGET_K8 && !optimize_size"
19797   [(set (match_dup 3) (match_dup 2))
19798    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19799               (clobber (reg:CC FLAGS_REG))])]
19800 {
19801   if (!rtx_equal_p (operands[0], operands[1]))
19802     emit_move_insn (operands[0], operands[1]);
19803 })
19804 \f
19805 ;; Call-value patterns last so that the wildcard operand does not
19806 ;; disrupt insn-recog's switch tables.
19807
19808 (define_insn "*call_value_pop_0"
19809   [(set (match_operand 0 "" "")
19810         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19811               (match_operand:SI 2 "" "")))
19812    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19813                             (match_operand:SI 3 "immediate_operand" "")))]
19814   "!TARGET_64BIT"
19815 {
19816   if (SIBLING_CALL_P (insn))
19817     return "jmp\t%P1";
19818   else
19819     return "call\t%P1";
19820 }
19821   [(set_attr "type" "callv")])
19822
19823 (define_insn "*call_value_pop_1"
19824   [(set (match_operand 0 "" "")
19825         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19826               (match_operand:SI 2 "" "")))
19827    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19828                             (match_operand:SI 3 "immediate_operand" "i")))]
19829   "!TARGET_64BIT"
19830 {
19831   if (constant_call_address_operand (operands[1], Pmode))
19832     {
19833       if (SIBLING_CALL_P (insn))
19834         return "jmp\t%P1";
19835       else
19836         return "call\t%P1";
19837     }
19838   if (SIBLING_CALL_P (insn))
19839     return "jmp\t%A1";
19840   else
19841     return "call\t%A1";
19842 }
19843   [(set_attr "type" "callv")])
19844
19845 (define_insn "*call_value_0"
19846   [(set (match_operand 0 "" "")
19847         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19848               (match_operand:SI 2 "" "")))]
19849   "!TARGET_64BIT"
19850 {
19851   if (SIBLING_CALL_P (insn))
19852     return "jmp\t%P1";
19853   else
19854     return "call\t%P1";
19855 }
19856   [(set_attr "type" "callv")])
19857
19858 (define_insn "*call_value_0_rex64"
19859   [(set (match_operand 0 "" "")
19860         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19861               (match_operand:DI 2 "const_int_operand" "")))]
19862   "TARGET_64BIT"
19863 {
19864   if (SIBLING_CALL_P (insn))
19865     return "jmp\t%P1";
19866   else
19867     return "call\t%P1";
19868 }
19869   [(set_attr "type" "callv")])
19870
19871 (define_insn "*call_value_1"
19872   [(set (match_operand 0 "" "")
19873         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19874               (match_operand:SI 2 "" "")))]
19875   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19876 {
19877   if (constant_call_address_operand (operands[1], Pmode))
19878     return "call\t%P1";
19879   return "call\t%*%1";
19880 }
19881   [(set_attr "type" "callv")])
19882
19883 (define_insn "*sibcall_value_1"
19884   [(set (match_operand 0 "" "")
19885         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19886               (match_operand:SI 2 "" "")))]
19887   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19888 {
19889   if (constant_call_address_operand (operands[1], Pmode))
19890     return "jmp\t%P1";
19891   return "jmp\t%*%1";
19892 }
19893   [(set_attr "type" "callv")])
19894
19895 (define_insn "*call_value_1_rex64"
19896   [(set (match_operand 0 "" "")
19897         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19898               (match_operand:DI 2 "" "")))]
19899   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19900 {
19901   if (constant_call_address_operand (operands[1], Pmode))
19902     return "call\t%P1";
19903   return "call\t%A1";
19904 }
19905   [(set_attr "type" "callv")])
19906
19907 (define_insn "*sibcall_value_1_rex64"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910               (match_operand:DI 2 "" "")))]
19911   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19912   "jmp\t%P1"
19913   [(set_attr "type" "callv")])
19914
19915 (define_insn "*sibcall_value_1_rex64_v"
19916   [(set (match_operand 0 "" "")
19917         (call (mem:QI (reg:DI 40))
19918               (match_operand:DI 1 "" "")))]
19919   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19920   "jmp\t*%%r11"
19921   [(set_attr "type" "callv")])
19922 \f
19923 (define_insn "trap"
19924   [(trap_if (const_int 1) (const_int 5))]
19925   ""
19926   "int\t$5")
19927
19928 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19929 ;;; for the sake of bounds checking.  By emitting bounds checks as
19930 ;;; conditional traps rather than as conditional jumps around
19931 ;;; unconditional traps we avoid introducing spurious basic-block
19932 ;;; boundaries and facilitate elimination of redundant checks.  In
19933 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19934 ;;; interrupt 5.
19935 ;;; 
19936 ;;; FIXME: Static branch prediction rules for ix86 are such that
19937 ;;; forward conditional branches predict as untaken.  As implemented
19938 ;;; below, pseudo conditional traps violate that rule.  We should use
19939 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19940 ;;; section loaded at the end of the text segment and branch forward
19941 ;;; there on bounds-failure, and then jump back immediately (in case
19942 ;;; the system chooses to ignore bounds violations, or to report
19943 ;;; violations and continue execution).
19944
19945 (define_expand "conditional_trap"
19946   [(trap_if (match_operator 0 "comparison_operator"
19947              [(match_dup 2) (const_int 0)])
19948             (match_operand 1 "const_int_operand" ""))]
19949   ""
19950 {
19951   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19952                               ix86_expand_compare (GET_CODE (operands[0]),
19953                                                    NULL, NULL),
19954                               operands[1]));
19955   DONE;
19956 })
19957
19958 (define_insn "*conditional_trap_1"
19959   [(trap_if (match_operator 0 "comparison_operator"
19960              [(reg 17) (const_int 0)])
19961             (match_operand 1 "const_int_operand" ""))]
19962   ""
19963 {
19964   operands[2] = gen_label_rtx ();
19965   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19966   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19967                              CODE_LABEL_NUMBER (operands[2]));
19968   RET;
19969 })
19970
19971         ;; Pentium III SIMD instructions.
19972
19973 ;; Moves for SSE/MMX regs.
19974
19975 (define_insn "movv4sf_internal"
19976   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19977         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19978   "TARGET_SSE"
19979   "@
19980     xorps\t%0, %0
19981     movaps\t{%1, %0|%0, %1}
19982     movaps\t{%1, %0|%0, %1}"
19983   [(set_attr "type" "ssemov")
19984    (set_attr "mode" "V4SF")])
19985
19986 (define_split
19987   [(set (match_operand:V4SF 0 "register_operand" "")
19988         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19989   "TARGET_SSE"
19990   [(set (match_dup 0)
19991         (vec_merge:V4SF
19992          (vec_duplicate:V4SF (match_dup 1))
19993          (match_dup 2)
19994          (const_int 1)))]
19995 {
19996   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19997   operands[2] = CONST0_RTX (V4SFmode);
19998 })
19999
20000 (define_insn "movv4si_internal"
20001   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20002         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20003   "TARGET_SSE"
20004 {
20005   switch (which_alternative)
20006     {
20007     case 0:
20008       if (get_attr_mode (insn) == MODE_V4SF)
20009         return "xorps\t%0, %0";
20010       else
20011         return "pxor\t%0, %0";
20012     case 1:
20013     case 2:
20014       if (get_attr_mode (insn) == MODE_V4SF)
20015         return "movaps\t{%1, %0|%0, %1}";
20016       else
20017         return "movdqa\t{%1, %0|%0, %1}";
20018     default:
20019       abort ();
20020     }
20021 }
20022   [(set_attr "type" "ssemov")
20023    (set (attr "mode")
20024         (cond [(eq_attr "alternative" "0,1")
20025                  (if_then_else
20026                    (ne (symbol_ref "optimize_size")
20027                        (const_int 0))
20028                    (const_string "V4SF")
20029                    (const_string "TI"))
20030                (eq_attr "alternative" "2")
20031                  (if_then_else
20032                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20033                             (const_int 0))
20034                         (ne (symbol_ref "optimize_size")
20035                             (const_int 0)))
20036                    (const_string "V4SF")
20037                    (const_string "TI"))]
20038                (const_string "TI")))])
20039
20040 (define_insn "movv2di_internal"
20041   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20042         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20043   "TARGET_SSE"
20044 {
20045   switch (which_alternative)
20046     {
20047     case 0:
20048       if (get_attr_mode (insn) == MODE_V4SF)
20049         return "xorps\t%0, %0";
20050       else
20051         return "pxor\t%0, %0";
20052     case 1:
20053     case 2:
20054       if (get_attr_mode (insn) == MODE_V4SF)
20055         return "movaps\t{%1, %0|%0, %1}";
20056       else
20057         return "movdqa\t{%1, %0|%0, %1}";
20058     default:
20059       abort ();
20060     }
20061 }
20062   [(set_attr "type" "ssemov")
20063    (set (attr "mode")
20064         (cond [(eq_attr "alternative" "0,1")
20065                  (if_then_else
20066                    (ne (symbol_ref "optimize_size")
20067                        (const_int 0))
20068                    (const_string "V4SF")
20069                    (const_string "TI"))
20070                (eq_attr "alternative" "2")
20071                  (if_then_else
20072                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20073                             (const_int 0))
20074                         (ne (symbol_ref "optimize_size")
20075                             (const_int 0)))
20076                    (const_string "V4SF")
20077                    (const_string "TI"))]
20078                (const_string "TI")))])
20079
20080 (define_split
20081   [(set (match_operand:V2DF 0 "register_operand" "")
20082         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20083   "TARGET_SSE2"
20084   [(set (match_dup 0)
20085         (vec_merge:V2DF
20086          (vec_duplicate:V2DF (match_dup 1))
20087          (match_dup 2)
20088          (const_int 1)))]
20089 {
20090   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20091   operands[2] = CONST0_RTX (V2DFmode);
20092 })
20093
20094 (define_insn "movv8qi_internal"
20095   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20096         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20097   "TARGET_MMX
20098    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20099   "@
20100     pxor\t%0, %0
20101     movq\t{%1, %0|%0, %1}
20102     movq\t{%1, %0|%0, %1}
20103     movdq2q\t{%1, %0|%0, %1}
20104     movq2dq\t{%1, %0|%0, %1}
20105     movq\t{%1, %0|%0, %1}
20106     movq\t{%1, %0|%0, %1}"
20107   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20108    (set_attr "mode" "DI")])
20109
20110 (define_insn "movv4hi_internal"
20111   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20112         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20113   "TARGET_MMX
20114    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20115   "@
20116     pxor\t%0, %0
20117     movq\t{%1, %0|%0, %1}
20118     movq\t{%1, %0|%0, %1}
20119     movdq2q\t{%1, %0|%0, %1}
20120     movq2dq\t{%1, %0|%0, %1}
20121     movq\t{%1, %0|%0, %1}
20122     movq\t{%1, %0|%0, %1}"
20123   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20124    (set_attr "mode" "DI")])
20125
20126 (define_insn "*movv2si_internal"
20127   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20128         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20129   "TARGET_MMX
20130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20131   "@
20132     pxor\t%0, %0
20133     movq\t{%1, %0|%0, %1}
20134     movq\t{%1, %0|%0, %1}
20135     movdq2q\t{%1, %0|%0, %1}
20136     movq2dq\t{%1, %0|%0, %1}
20137     movq\t{%1, %0|%0, %1}
20138     movq\t{%1, %0|%0, %1}"
20139   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20140    (set_attr "mode" "DI")])
20141
20142 (define_insn "movv2sf_internal"
20143   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20144         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20145   "TARGET_3DNOW
20146    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20147   "@
20148     pxor\t%0, %0
20149     movq\t{%1, %0|%0, %1}
20150     movq\t{%1, %0|%0, %1}
20151     movdq2q\t{%1, %0|%0, %1}
20152     movq2dq\t{%1, %0|%0, %1}
20153     movlps\t{%1, %0|%0, %1}
20154     movlps\t{%1, %0|%0, %1}"
20155   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20156    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20157
20158 (define_expand "movti"
20159   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20160         (match_operand:TI 1 "nonimmediate_operand" ""))]
20161   "TARGET_SSE || TARGET_64BIT"
20162 {
20163   if (TARGET_64BIT)
20164     ix86_expand_move (TImode, operands);
20165   else
20166     ix86_expand_vector_move (TImode, operands);
20167   DONE;
20168 })
20169
20170 (define_expand "movtf"
20171   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20172         (match_operand:TF 1 "nonimmediate_operand" ""))]
20173   "TARGET_64BIT"
20174 {
20175   if (TARGET_64BIT)
20176     ix86_expand_move (TFmode, operands);
20177   else
20178     ix86_expand_vector_move (TFmode, operands);
20179   DONE;
20180 })
20181
20182 (define_insn "movv2df_internal"
20183   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20184         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20185   "TARGET_SSE2
20186    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20187 {
20188   switch (which_alternative)
20189     {
20190     case 0:
20191       if (get_attr_mode (insn) == MODE_V4SF)
20192         return "xorps\t%0, %0";
20193       else
20194         return "xorpd\t%0, %0";
20195     case 1:
20196     case 2:
20197       if (get_attr_mode (insn) == MODE_V4SF)
20198         return "movaps\t{%1, %0|%0, %1}";
20199       else
20200         return "movapd\t{%1, %0|%0, %1}";
20201     default:
20202       abort ();
20203     }
20204 }
20205   [(set_attr "type" "ssemov")
20206    (set (attr "mode")
20207         (cond [(eq_attr "alternative" "0,1")
20208                  (if_then_else
20209                    (ne (symbol_ref "optimize_size")
20210                        (const_int 0))
20211                    (const_string "V4SF")
20212                    (const_string "V2DF"))
20213                (eq_attr "alternative" "2")
20214                  (if_then_else
20215                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20216                             (const_int 0))
20217                         (ne (symbol_ref "optimize_size")
20218                             (const_int 0)))
20219                    (const_string "V4SF")
20220                    (const_string "V2DF"))]
20221                (const_string "V2DF")))])
20222
20223 (define_insn "movv8hi_internal"
20224   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20225         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20226   "TARGET_SSE2
20227    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20228 {
20229   switch (which_alternative)
20230     {
20231     case 0:
20232       if (get_attr_mode (insn) == MODE_V4SF)
20233         return "xorps\t%0, %0";
20234       else
20235         return "pxor\t%0, %0";
20236     case 1:
20237     case 2:
20238       if (get_attr_mode (insn) == MODE_V4SF)
20239         return "movaps\t{%1, %0|%0, %1}";
20240       else
20241         return "movdqa\t{%1, %0|%0, %1}";
20242     default:
20243       abort ();
20244     }
20245 }
20246   [(set_attr "type" "ssemov")
20247    (set (attr "mode")
20248         (cond [(eq_attr "alternative" "0,1")
20249                  (if_then_else
20250                    (ne (symbol_ref "optimize_size")
20251                        (const_int 0))
20252                    (const_string "V4SF")
20253                    (const_string "TI"))
20254                (eq_attr "alternative" "2")
20255                  (if_then_else
20256                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20257                             (const_int 0))
20258                         (ne (symbol_ref "optimize_size")
20259                             (const_int 0)))
20260                    (const_string "V4SF")
20261                    (const_string "TI"))]
20262                (const_string "TI")))])
20263
20264 (define_insn "movv16qi_internal"
20265   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20266         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20267   "TARGET_SSE2
20268    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20269 {
20270   switch (which_alternative)
20271     {
20272     case 0:
20273       if (get_attr_mode (insn) == MODE_V4SF)
20274         return "xorps\t%0, %0";
20275       else
20276         return "pxor\t%0, %0";
20277     case 1:
20278     case 2:
20279       if (get_attr_mode (insn) == MODE_V4SF)
20280         return "movaps\t{%1, %0|%0, %1}";
20281       else
20282         return "movdqa\t{%1, %0|%0, %1}";
20283     default:
20284       abort ();
20285     }
20286 }
20287   [(set_attr "type" "ssemov")
20288    (set (attr "mode")
20289         (cond [(eq_attr "alternative" "0,1")
20290                  (if_then_else
20291                    (ne (symbol_ref "optimize_size")
20292                        (const_int 0))
20293                    (const_string "V4SF")
20294                    (const_string "TI"))
20295                (eq_attr "alternative" "2")
20296                  (if_then_else
20297                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20298                             (const_int 0))
20299                         (ne (symbol_ref "optimize_size")
20300                             (const_int 0)))
20301                    (const_string "V4SF")
20302                    (const_string "TI"))]
20303                (const_string "TI")))])
20304
20305 (define_expand "movv2df"
20306   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20307         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20308   "TARGET_SSE2"
20309 {
20310   ix86_expand_vector_move (V2DFmode, operands);
20311   DONE;
20312 })
20313
20314 (define_expand "movv8hi"
20315   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20316         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20317   "TARGET_SSE2"
20318 {
20319   ix86_expand_vector_move (V8HImode, operands);
20320   DONE;
20321 })
20322
20323 (define_expand "movv16qi"
20324   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20325         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20326   "TARGET_SSE2"
20327 {
20328   ix86_expand_vector_move (V16QImode, operands);
20329   DONE;
20330 })
20331
20332 (define_expand "movv4sf"
20333   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20334         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20335   "TARGET_SSE"
20336 {
20337   ix86_expand_vector_move (V4SFmode, operands);
20338   DONE;
20339 })
20340
20341 (define_expand "movv4si"
20342   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20343         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20344   "TARGET_SSE"
20345 {
20346   ix86_expand_vector_move (V4SImode, operands);
20347   DONE;
20348 })
20349
20350 (define_expand "movv2di"
20351   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20352         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20353   "TARGET_SSE"
20354 {
20355   ix86_expand_vector_move (V2DImode, operands);
20356   DONE;
20357 })
20358
20359 (define_expand "movv2si"
20360   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20361         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20362   "TARGET_MMX"
20363 {
20364   ix86_expand_vector_move (V2SImode, operands);
20365   DONE;
20366 })
20367
20368 (define_expand "movv4hi"
20369   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20370         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20371   "TARGET_MMX"
20372 {
20373   ix86_expand_vector_move (V4HImode, operands);
20374   DONE;
20375 })
20376
20377 (define_expand "movv8qi"
20378   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20379         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20380   "TARGET_MMX"
20381 {
20382   ix86_expand_vector_move (V8QImode, operands);
20383   DONE;
20384 })
20385
20386 (define_expand "movv2sf"
20387   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20388         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20389    "TARGET_3DNOW"
20390 {
20391   ix86_expand_vector_move (V2SFmode, operands);
20392   DONE;
20393 })
20394
20395 (define_insn "*pushti"
20396   [(set (match_operand:TI 0 "push_operand" "=<")
20397         (match_operand:TI 1 "register_operand" "x"))]
20398   "TARGET_SSE"
20399   "#")
20400
20401 (define_insn "*pushv2df"
20402   [(set (match_operand:V2DF 0 "push_operand" "=<")
20403         (match_operand:V2DF 1 "register_operand" "x"))]
20404   "TARGET_SSE"
20405   "#")
20406
20407 (define_insn "*pushv2di"
20408   [(set (match_operand:V2DI 0 "push_operand" "=<")
20409         (match_operand:V2DI 1 "register_operand" "x"))]
20410   "TARGET_SSE2"
20411   "#")
20412
20413 (define_insn "*pushv8hi"
20414   [(set (match_operand:V8HI 0 "push_operand" "=<")
20415         (match_operand:V8HI 1 "register_operand" "x"))]
20416   "TARGET_SSE2"
20417   "#")
20418
20419 (define_insn "*pushv16qi"
20420   [(set (match_operand:V16QI 0 "push_operand" "=<")
20421         (match_operand:V16QI 1 "register_operand" "x"))]
20422   "TARGET_SSE2"
20423   "#")
20424
20425 (define_insn "*pushv4sf"
20426   [(set (match_operand:V4SF 0 "push_operand" "=<")
20427         (match_operand:V4SF 1 "register_operand" "x"))]
20428   "TARGET_SSE"
20429   "#")
20430
20431 (define_insn "*pushv4si"
20432   [(set (match_operand:V4SI 0 "push_operand" "=<")
20433         (match_operand:V4SI 1 "register_operand" "x"))]
20434   "TARGET_SSE2"
20435   "#")
20436
20437 (define_insn "*pushv2si"
20438   [(set (match_operand:V2SI 0 "push_operand" "=<")
20439         (match_operand:V2SI 1 "register_operand" "y"))]
20440   "TARGET_MMX"
20441   "#")
20442
20443 (define_insn "*pushv4hi"
20444   [(set (match_operand:V4HI 0 "push_operand" "=<")
20445         (match_operand:V4HI 1 "register_operand" "y"))]
20446   "TARGET_MMX"
20447   "#")
20448
20449 (define_insn "*pushv8qi"
20450   [(set (match_operand:V8QI 0 "push_operand" "=<")
20451         (match_operand:V8QI 1 "register_operand" "y"))]
20452   "TARGET_MMX"
20453   "#")
20454
20455 (define_insn "*pushv2sf"
20456   [(set (match_operand:V2SF 0 "push_operand" "=<")
20457         (match_operand:V2SF 1 "register_operand" "y"))]
20458   "TARGET_3DNOW"
20459   "#")
20460
20461 (define_split
20462   [(set (match_operand 0 "push_operand" "")
20463         (match_operand 1 "register_operand" ""))]
20464   "!TARGET_64BIT && reload_completed
20465    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20467    (set (match_dup 2) (match_dup 1))]
20468   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20469                                  stack_pointer_rtx);
20470    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20471
20472 (define_split
20473   [(set (match_operand 0 "push_operand" "")
20474         (match_operand 1 "register_operand" ""))]
20475   "TARGET_64BIT && reload_completed
20476    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20477   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20478    (set (match_dup 2) (match_dup 1))]
20479   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20480                                  stack_pointer_rtx);
20481    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20482
20483
20484 (define_insn "movti_internal"
20485   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20486         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20487   "TARGET_SSE && !TARGET_64BIT
20488    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20489 {
20490   switch (which_alternative)
20491     {
20492     case 0:
20493       if (get_attr_mode (insn) == MODE_V4SF)
20494         return "xorps\t%0, %0";
20495       else
20496         return "pxor\t%0, %0";
20497     case 1:
20498     case 2:
20499       if (get_attr_mode (insn) == MODE_V4SF)
20500         return "movaps\t{%1, %0|%0, %1}";
20501       else
20502         return "movdqa\t{%1, %0|%0, %1}";
20503     default:
20504       abort ();
20505     }
20506 }
20507   [(set_attr "type" "ssemov,ssemov,ssemov")
20508    (set (attr "mode")
20509         (cond [(eq_attr "alternative" "0,1")
20510                  (if_then_else
20511                    (ne (symbol_ref "optimize_size")
20512                        (const_int 0))
20513                    (const_string "V4SF")
20514                    (const_string "TI"))
20515                (eq_attr "alternative" "2")
20516                  (if_then_else
20517                    (ne (symbol_ref "optimize_size")
20518                        (const_int 0))
20519                    (const_string "V4SF")
20520                    (const_string "TI"))]
20521                (const_string "TI")))])
20522
20523 (define_insn "*movti_rex64"
20524   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20525         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20526   "TARGET_64BIT
20527    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20528 {
20529   switch (which_alternative)
20530     {
20531     case 0:
20532     case 1:
20533       return "#";
20534     case 2:
20535       if (get_attr_mode (insn) == MODE_V4SF)
20536         return "xorps\t%0, %0";
20537       else
20538         return "pxor\t%0, %0";
20539     case 3:
20540     case 4:
20541       if (get_attr_mode (insn) == MODE_V4SF)
20542         return "movaps\t{%1, %0|%0, %1}";
20543       else
20544         return "movdqa\t{%1, %0|%0, %1}";
20545     default:
20546       abort ();
20547     }
20548 }
20549   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20550    (set (attr "mode")
20551         (cond [(eq_attr "alternative" "2,3")
20552                  (if_then_else
20553                    (ne (symbol_ref "optimize_size")
20554                        (const_int 0))
20555                    (const_string "V4SF")
20556                    (const_string "TI"))
20557                (eq_attr "alternative" "4")
20558                  (if_then_else
20559                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20560                             (const_int 0))
20561                         (ne (symbol_ref "optimize_size")
20562                             (const_int 0)))
20563                    (const_string "V4SF")
20564                    (const_string "TI"))]
20565                (const_string "DI")))])
20566
20567 (define_insn "*movtf_rex64"
20568   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20569         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20570   "TARGET_64BIT
20571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20572 {
20573   switch (which_alternative)
20574     {
20575     case 0:
20576     case 1:
20577       return "#";
20578     case 2:
20579       if (get_attr_mode (insn) == MODE_V4SF)
20580         return "xorps\t%0, %0";
20581       else
20582         return "pxor\t%0, %0";
20583     case 3:
20584     case 4:
20585       if (get_attr_mode (insn) == MODE_V4SF)
20586         return "movaps\t{%1, %0|%0, %1}";
20587       else
20588         return "movdqa\t{%1, %0|%0, %1}";
20589     default:
20590       abort ();
20591     }
20592 }
20593   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20594    (set (attr "mode")
20595         (cond [(eq_attr "alternative" "2,3")
20596                  (if_then_else
20597                    (ne (symbol_ref "optimize_size")
20598                        (const_int 0))
20599                    (const_string "V4SF")
20600                    (const_string "TI"))
20601                (eq_attr "alternative" "4")
20602                  (if_then_else
20603                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20604                             (const_int 0))
20605                         (ne (symbol_ref "optimize_size")
20606                             (const_int 0)))
20607                    (const_string "V4SF")
20608                    (const_string "TI"))]
20609                (const_string "DI")))])
20610
20611 (define_split
20612   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20613         (match_operand:TI 1 "general_operand" ""))]
20614   "reload_completed && !SSE_REG_P (operands[0])
20615    && !SSE_REG_P (operands[1])"
20616   [(const_int 0)]
20617   "ix86_split_long_move (operands); DONE;")
20618
20619 (define_split
20620   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20621         (match_operand:TF 1 "general_operand" ""))]
20622   "reload_completed && !SSE_REG_P (operands[0])
20623    && !SSE_REG_P (operands[1])"
20624   [(const_int 0)]
20625   "ix86_split_long_move (operands); DONE;")
20626
20627 ;; These two patterns are useful for specifying exactly whether to use
20628 ;; movaps or movups
20629 (define_expand "sse_movaps"
20630   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20631         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20632                      UNSPEC_MOVA))]
20633   "TARGET_SSE"
20634 {
20635   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20636     {
20637       rtx tmp = gen_reg_rtx (V4SFmode);
20638       emit_insn (gen_sse_movaps (tmp, operands[1]));
20639       emit_move_insn (operands[0], tmp);
20640       DONE;
20641     }
20642 })
20643
20644 (define_insn "*sse_movaps_1"
20645   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20646         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20647                      UNSPEC_MOVA))]
20648   "TARGET_SSE
20649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20650   "movaps\t{%1, %0|%0, %1}"
20651   [(set_attr "type" "ssemov,ssemov")
20652    (set_attr "mode" "V4SF")])
20653
20654 (define_expand "sse_movups"
20655   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20656         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20657                      UNSPEC_MOVU))]
20658   "TARGET_SSE"
20659 {
20660   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20661     {
20662       rtx tmp = gen_reg_rtx (V4SFmode);
20663       emit_insn (gen_sse_movups (tmp, operands[1]));
20664       emit_move_insn (operands[0], tmp);
20665       DONE;
20666     }
20667 })
20668
20669 (define_insn "*sse_movups_1"
20670   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20671         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20672                      UNSPEC_MOVU))]
20673   "TARGET_SSE
20674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20675   "movups\t{%1, %0|%0, %1}"
20676   [(set_attr "type" "ssecvt,ssecvt")
20677    (set_attr "mode" "V4SF")])
20678
20679 ;; SSE Strange Moves.
20680
20681 (define_insn "sse_movmskps"
20682   [(set (match_operand:SI 0 "register_operand" "=r")
20683         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20684                    UNSPEC_MOVMSK))]
20685   "TARGET_SSE"
20686   "movmskps\t{%1, %0|%0, %1}"
20687   [(set_attr "type" "ssecvt")
20688    (set_attr "mode" "V4SF")])
20689
20690 (define_insn "mmx_pmovmskb"
20691   [(set (match_operand:SI 0 "register_operand" "=r")
20692         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20693                    UNSPEC_MOVMSK))]
20694   "TARGET_SSE || TARGET_3DNOW_A"
20695   "pmovmskb\t{%1, %0|%0, %1}"
20696   [(set_attr "type" "ssecvt")
20697    (set_attr "mode" "V4SF")])
20698
20699
20700 (define_insn "mmx_maskmovq"
20701   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20702         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20703                       (match_operand:V8QI 2 "register_operand" "y")]
20704                      UNSPEC_MASKMOV))]
20705   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20706   ;; @@@ check ordering of operands in intel/nonintel syntax
20707   "maskmovq\t{%2, %1|%1, %2}"
20708   [(set_attr "type" "mmxcvt")
20709    (set_attr "mode" "DI")])
20710
20711 (define_insn "mmx_maskmovq_rex"
20712   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20713         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20714                       (match_operand:V8QI 2 "register_operand" "y")]
20715                      UNSPEC_MASKMOV))]
20716   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20717   ;; @@@ check ordering of operands in intel/nonintel syntax
20718   "maskmovq\t{%2, %1|%1, %2}"
20719   [(set_attr "type" "mmxcvt")
20720    (set_attr "mode" "DI")])
20721
20722 (define_insn "sse_movntv4sf"
20723   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20724         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20725                      UNSPEC_MOVNT))]
20726   "TARGET_SSE"
20727   "movntps\t{%1, %0|%0, %1}"
20728   [(set_attr "type" "ssemov")
20729    (set_attr "mode" "V4SF")])
20730
20731 (define_insn "sse_movntdi"
20732   [(set (match_operand:DI 0 "memory_operand" "=m")
20733         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20734                    UNSPEC_MOVNT))]
20735   "TARGET_SSE || TARGET_3DNOW_A"
20736   "movntq\t{%1, %0|%0, %1}"
20737   [(set_attr "type" "mmxmov")
20738    (set_attr "mode" "DI")])
20739
20740 (define_insn "sse_movhlps"
20741   [(set (match_operand:V4SF 0 "register_operand" "=x")
20742         (vec_merge:V4SF
20743          (match_operand:V4SF 1 "register_operand" "0")
20744          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20745                           (parallel [(const_int 2)
20746                                      (const_int 3)
20747                                      (const_int 0)
20748                                      (const_int 1)]))
20749          (const_int 3)))]
20750   "TARGET_SSE"
20751   "movhlps\t{%2, %0|%0, %2}"
20752   [(set_attr "type" "ssecvt")
20753    (set_attr "mode" "V4SF")])
20754
20755 (define_insn "sse_movlhps"
20756   [(set (match_operand:V4SF 0 "register_operand" "=x")
20757         (vec_merge:V4SF
20758          (match_operand:V4SF 1 "register_operand" "0")
20759          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20760                           (parallel [(const_int 2)
20761                                      (const_int 3)
20762                                      (const_int 0)
20763                                      (const_int 1)]))
20764          (const_int 12)))]
20765   "TARGET_SSE"
20766   "movlhps\t{%2, %0|%0, %2}"
20767   [(set_attr "type" "ssecvt")
20768    (set_attr "mode" "V4SF")])
20769
20770 (define_insn "sse_movhps"
20771   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20772         (vec_merge:V4SF
20773          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20774          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20775          (const_int 12)))]
20776   "TARGET_SSE
20777    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20778   "movhps\t{%2, %0|%0, %2}"
20779   [(set_attr "type" "ssecvt")
20780    (set_attr "mode" "V4SF")])
20781
20782 (define_insn "sse_movlps"
20783   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20784         (vec_merge:V4SF
20785          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20786          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20787          (const_int 3)))]
20788   "TARGET_SSE
20789    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20790   "movlps\t{%2, %0|%0, %2}"
20791   [(set_attr "type" "ssecvt")
20792    (set_attr "mode" "V4SF")])
20793
20794 (define_expand "sse_loadss"
20795   [(match_operand:V4SF 0 "register_operand" "")
20796    (match_operand:SF 1 "memory_operand" "")]
20797   "TARGET_SSE"
20798 {
20799   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20800                                CONST0_RTX (V4SFmode)));
20801   DONE;
20802 })
20803
20804 (define_insn "sse_loadss_1"
20805   [(set (match_operand:V4SF 0 "register_operand" "=x")
20806         (vec_merge:V4SF
20807          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20808          (match_operand:V4SF 2 "const0_operand" "X")
20809          (const_int 1)))]
20810   "TARGET_SSE"
20811   "movss\t{%1, %0|%0, %1}"
20812   [(set_attr "type" "ssemov")
20813    (set_attr "mode" "SF")])
20814
20815 (define_insn "sse_movss"
20816   [(set (match_operand:V4SF 0 "register_operand" "=x")
20817         (vec_merge:V4SF
20818          (match_operand:V4SF 1 "register_operand" "0")
20819          (match_operand:V4SF 2 "register_operand" "x")
20820          (const_int 1)))]
20821   "TARGET_SSE"
20822   "movss\t{%2, %0|%0, %2}"
20823   [(set_attr "type" "ssemov")
20824    (set_attr "mode" "SF")])
20825
20826 (define_insn "sse_storess"
20827   [(set (match_operand:SF 0 "memory_operand" "=m")
20828         (vec_select:SF
20829          (match_operand:V4SF 1 "register_operand" "x")
20830          (parallel [(const_int 0)])))]
20831   "TARGET_SSE"
20832   "movss\t{%1, %0|%0, %1}"
20833   [(set_attr "type" "ssemov")
20834    (set_attr "mode" "SF")])
20835
20836 (define_insn "sse_shufps"
20837   [(set (match_operand:V4SF 0 "register_operand" "=x")
20838         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20839                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20840                       (match_operand:SI 3 "immediate_operand" "i")]
20841                      UNSPEC_SHUFFLE))]
20842   "TARGET_SSE"
20843   ;; @@@ check operand order for intel/nonintel syntax
20844   "shufps\t{%3, %2, %0|%0, %2, %3}"
20845   [(set_attr "type" "ssecvt")
20846    (set_attr "mode" "V4SF")])
20847
20848
20849 ;; SSE arithmetic
20850
20851 (define_insn "addv4sf3"
20852   [(set (match_operand:V4SF 0 "register_operand" "=x")
20853         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20854                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20855   "TARGET_SSE"
20856   "addps\t{%2, %0|%0, %2}"
20857   [(set_attr "type" "sseadd")
20858    (set_attr "mode" "V4SF")])
20859
20860 (define_insn "vmaddv4sf3"
20861   [(set (match_operand:V4SF 0 "register_operand" "=x")
20862         (vec_merge:V4SF
20863          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20864                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20865          (match_dup 1)
20866          (const_int 1)))]
20867   "TARGET_SSE"
20868   "addss\t{%2, %0|%0, %2}"
20869   [(set_attr "type" "sseadd")
20870    (set_attr "mode" "SF")])
20871
20872 (define_insn "subv4sf3"
20873   [(set (match_operand:V4SF 0 "register_operand" "=x")
20874         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20875                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20876   "TARGET_SSE"
20877   "subps\t{%2, %0|%0, %2}"
20878   [(set_attr "type" "sseadd")
20879    (set_attr "mode" "V4SF")])
20880
20881 (define_insn "vmsubv4sf3"
20882   [(set (match_operand:V4SF 0 "register_operand" "=x")
20883         (vec_merge:V4SF
20884          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20885                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20886          (match_dup 1)
20887          (const_int 1)))]
20888   "TARGET_SSE"
20889   "subss\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "sseadd")
20891    (set_attr "mode" "SF")])
20892
20893 ;; ??? Should probably be done by generic code instead.
20894 (define_expand "negv4sf2"
20895   [(set (match_operand:V4SF 0 "register_operand" "")
20896         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20897                   (match_dup 2)))]
20898   "TARGET_SSE"
20899 {
20900   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20901   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20902   operands[2] = force_reg (V4SFmode, vm0);
20903 })
20904
20905 (define_insn "mulv4sf3"
20906   [(set (match_operand:V4SF 0 "register_operand" "=x")
20907         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20908                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20909   "TARGET_SSE"
20910   "mulps\t{%2, %0|%0, %2}"
20911   [(set_attr "type" "ssemul")
20912    (set_attr "mode" "V4SF")])
20913
20914 (define_insn "vmmulv4sf3"
20915   [(set (match_operand:V4SF 0 "register_operand" "=x")
20916         (vec_merge:V4SF
20917          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20918                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20919          (match_dup 1)
20920          (const_int 1)))]
20921   "TARGET_SSE"
20922   "mulss\t{%2, %0|%0, %2}"
20923   [(set_attr "type" "ssemul")
20924    (set_attr "mode" "SF")])
20925
20926 (define_insn "divv4sf3"
20927   [(set (match_operand:V4SF 0 "register_operand" "=x")
20928         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20929                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20930   "TARGET_SSE"
20931   "divps\t{%2, %0|%0, %2}"
20932   [(set_attr "type" "ssediv")
20933    (set_attr "mode" "V4SF")])
20934
20935 (define_insn "vmdivv4sf3"
20936   [(set (match_operand:V4SF 0 "register_operand" "=x")
20937         (vec_merge:V4SF
20938          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20939                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20940          (match_dup 1)
20941          (const_int 1)))]
20942   "TARGET_SSE"
20943   "divss\t{%2, %0|%0, %2}"
20944   [(set_attr "type" "ssediv")
20945    (set_attr "mode" "SF")])
20946
20947
20948 ;; SSE square root/reciprocal
20949
20950 (define_insn "rcpv4sf2"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (unspec:V4SF
20953          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20954   "TARGET_SSE"
20955   "rcpps\t{%1, %0|%0, %1}"
20956   [(set_attr "type" "sse")
20957    (set_attr "mode" "V4SF")])
20958
20959 (define_insn "vmrcpv4sf2"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (vec_merge:V4SF
20962          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20963                       UNSPEC_RCP)
20964          (match_operand:V4SF 2 "register_operand" "0")
20965          (const_int 1)))]
20966   "TARGET_SSE"
20967   "rcpss\t{%1, %0|%0, %1}"
20968   [(set_attr "type" "sse")
20969    (set_attr "mode" "SF")])
20970
20971 (define_insn "rsqrtv4sf2"
20972   [(set (match_operand:V4SF 0 "register_operand" "=x")
20973         (unspec:V4SF
20974          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20975   "TARGET_SSE"
20976   "rsqrtps\t{%1, %0|%0, %1}"
20977   [(set_attr "type" "sse")
20978    (set_attr "mode" "V4SF")])
20979
20980 (define_insn "vmrsqrtv4sf2"
20981   [(set (match_operand:V4SF 0 "register_operand" "=x")
20982         (vec_merge:V4SF
20983          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20984                       UNSPEC_RSQRT)
20985          (match_operand:V4SF 2 "register_operand" "0")
20986          (const_int 1)))]
20987   "TARGET_SSE"
20988   "rsqrtss\t{%1, %0|%0, %1}"
20989   [(set_attr "type" "sse")
20990    (set_attr "mode" "SF")])
20991
20992 (define_insn "sqrtv4sf2"
20993   [(set (match_operand:V4SF 0 "register_operand" "=x")
20994         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20995   "TARGET_SSE"
20996   "sqrtps\t{%1, %0|%0, %1}"
20997   [(set_attr "type" "sse")
20998    (set_attr "mode" "V4SF")])
20999
21000 (define_insn "vmsqrtv4sf2"
21001   [(set (match_operand:V4SF 0 "register_operand" "=x")
21002         (vec_merge:V4SF
21003          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21004          (match_operand:V4SF 2 "register_operand" "0")
21005          (const_int 1)))]
21006   "TARGET_SSE"
21007   "sqrtss\t{%1, %0|%0, %1}"
21008   [(set_attr "type" "sse")
21009    (set_attr "mode" "SF")])
21010
21011 ;; SSE logical operations.
21012
21013 ;; SSE defines logical operations on floating point values.  This brings
21014 ;; interesting challenge to RTL representation where logicals are only valid
21015 ;; on integral types.  We deal with this by representing the floating point
21016 ;; logical as logical on arguments casted to TImode as this is what hardware
21017 ;; really does.  Unfortunately hardware requires the type information to be
21018 ;; present and thus we must avoid subregs from being simplified and eliminated
21019 ;; in later compilation phases.
21020 ;;
21021 ;; We have following variants from each instruction:
21022 ;; sse_andsf3 - the operation taking V4SF vector operands
21023 ;;              and doing TImode cast on them
21024 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21025 ;;                      TImode, since backend insist on eliminating casts
21026 ;;                      on memory operands
21027 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21028 ;;                   We cannot accept memory operand here as instruction reads
21029 ;;                   whole scalar.  This is generated only post reload by GCC
21030 ;;                   scalar float operations that expands to logicals (fabs)
21031 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21032 ;;                   memory operand.  Eventually combine can be able
21033 ;;                   to synthesize these using splitter.
21034 ;; sse2_anddf3, *sse2_anddf3_memory
21035 ;;              
21036 ;; 
21037 ;; These are not called andti3 etc. because we really really don't want
21038 ;; the compiler to widen DImode ands to TImode ands and then try to move
21039 ;; into DImode subregs of SSE registers, and them together, and move out
21040 ;; of DImode subregs again!
21041 ;; SSE1 single precision floating point logical operation
21042 (define_expand "sse_andv4sf3"
21043   [(set (match_operand:V4SF 0 "register_operand" "")
21044         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21045                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21046   "TARGET_SSE"
21047   "")
21048
21049 (define_insn "*sse_andv4sf3"
21050   [(set (match_operand:V4SF 0 "register_operand" "=x")
21051         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21052                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21053   "TARGET_SSE
21054    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21055   "andps\t{%2, %0|%0, %2}"
21056   [(set_attr "type" "sselog")
21057    (set_attr "mode" "V4SF")])
21058
21059 (define_expand "sse_nandv4sf3"
21060   [(set (match_operand:V4SF 0 "register_operand" "")
21061         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21062                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21063   "TARGET_SSE"
21064   "")
21065
21066 (define_insn "*sse_nandv4sf3"
21067   [(set (match_operand:V4SF 0 "register_operand" "=x")
21068         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21069                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21070   "TARGET_SSE"
21071   "andnps\t{%2, %0|%0, %2}"
21072   [(set_attr "type" "sselog")
21073    (set_attr "mode" "V4SF")])
21074
21075 (define_expand "sse_iorv4sf3"
21076   [(set (match_operand:V4SF 0 "register_operand" "")
21077         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21078                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21079   "TARGET_SSE"
21080   "")
21081
21082 (define_insn "*sse_iorv4sf3"
21083   [(set (match_operand:V4SF 0 "register_operand" "=x")
21084         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21085                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21086   "TARGET_SSE
21087    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21088   "orps\t{%2, %0|%0, %2}"
21089   [(set_attr "type" "sselog")
21090    (set_attr "mode" "V4SF")])
21091
21092 (define_expand "sse_xorv4sf3"
21093   [(set (match_operand:V4SF 0 "register_operand" "")
21094         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21095                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21096   "TARGET_SSE"
21097   "")
21098
21099 (define_insn "*sse_xorv4sf3"
21100   [(set (match_operand:V4SF 0 "register_operand" "=x")
21101         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21102                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21103   "TARGET_SSE
21104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21105   "xorps\t{%2, %0|%0, %2}"
21106   [(set_attr "type" "sselog")
21107    (set_attr "mode" "V4SF")])
21108
21109 ;; SSE2 double precision floating point logical operation
21110
21111 (define_expand "sse2_andv2df3"
21112   [(set (match_operand:V2DF 0 "register_operand" "")
21113         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21114                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21115   "TARGET_SSE2"
21116   "")
21117
21118 (define_insn "*sse2_andv2df3"
21119   [(set (match_operand:V2DF 0 "register_operand" "=x")
21120         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21121                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21122   "TARGET_SSE2
21123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21124   "andpd\t{%2, %0|%0, %2}"
21125   [(set_attr "type" "sselog")
21126    (set_attr "mode" "V2DF")])
21127
21128 (define_expand "sse2_nandv2df3"
21129   [(set (match_operand:V2DF 0 "register_operand" "")
21130         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21131                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21132   "TARGET_SSE2"
21133   "")
21134
21135 (define_insn "*sse2_nandv2df3"
21136   [(set (match_operand:V2DF 0 "register_operand" "=x")
21137         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21138                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21139   "TARGET_SSE2"
21140   "andnpd\t{%2, %0|%0, %2}"
21141   [(set_attr "type" "sselog")
21142    (set_attr "mode" "V2DF")])
21143
21144 (define_expand "sse2_iorv2df3"
21145   [(set (match_operand:V2DF 0 "register_operand" "")
21146         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21147                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21148   "TARGET_SSE2"
21149   "")
21150
21151 (define_insn "*sse2_iorv2df3"
21152   [(set (match_operand:V2DF 0 "register_operand" "=x")
21153         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21154                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21155   "TARGET_SSE2
21156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21157   "orpd\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "sselog")
21159    (set_attr "mode" "V2DF")])
21160
21161 (define_expand "sse2_xorv2df3"
21162   [(set (match_operand:V2DF 0 "register_operand" "")
21163         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21164                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21165   "TARGET_SSE2"
21166   "")
21167
21168 (define_insn "*sse2_xorv2df3"
21169   [(set (match_operand:V2DF 0 "register_operand" "=x")
21170         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21171                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21172   "TARGET_SSE2
21173    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21174   "xorpd\t{%2, %0|%0, %2}"
21175   [(set_attr "type" "sselog")
21176    (set_attr "mode" "V2DF")])
21177
21178 ;; SSE2 integral logicals.  These patterns must always come after floating
21179 ;; point ones since we don't want compiler to use integer opcodes on floating
21180 ;; point SSE values to avoid matching of subregs in the match_operand.
21181 (define_insn "*sse2_andti3"
21182   [(set (match_operand:TI 0 "register_operand" "=x")
21183         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21184                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21185   "TARGET_SSE2
21186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21187   "pand\t{%2, %0|%0, %2}"
21188   [(set_attr "type" "sselog")
21189    (set_attr "mode" "TI")])
21190
21191 (define_insn "sse2_andv2di3"
21192   [(set (match_operand:V2DI 0 "register_operand" "=x")
21193         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21194                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21195   "TARGET_SSE2
21196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21197   "pand\t{%2, %0|%0, %2}"
21198   [(set_attr "type" "sselog")
21199    (set_attr "mode" "TI")])
21200
21201 (define_insn "*sse2_nandti3"
21202   [(set (match_operand:TI 0 "register_operand" "=x")
21203         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21204                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21205   "TARGET_SSE2"
21206   "pandn\t{%2, %0|%0, %2}"
21207   [(set_attr "type" "sselog")
21208    (set_attr "mode" "TI")])
21209
21210 (define_insn "sse2_nandv2di3"
21211   [(set (match_operand:V2DI 0 "register_operand" "=x")
21212         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21213                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21214   "TARGET_SSE2
21215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21216   "pandn\t{%2, %0|%0, %2}"
21217   [(set_attr "type" "sselog")
21218    (set_attr "mode" "TI")])
21219
21220 (define_insn "*sse2_iorti3"
21221   [(set (match_operand:TI 0 "register_operand" "=x")
21222         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21223                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21224   "TARGET_SSE2
21225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21226   "por\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "sselog")
21228    (set_attr "mode" "TI")])
21229
21230 (define_insn "sse2_iorv2di3"
21231   [(set (match_operand:V2DI 0 "register_operand" "=x")
21232         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21233                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21234   "TARGET_SSE2
21235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21236   "por\t{%2, %0|%0, %2}"
21237   [(set_attr "type" "sselog")
21238    (set_attr "mode" "TI")])
21239
21240 (define_insn "*sse2_xorti3"
21241   [(set (match_operand:TI 0 "register_operand" "=x")
21242         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21243                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21244   "TARGET_SSE2
21245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21246   "pxor\t{%2, %0|%0, %2}"
21247   [(set_attr "type" "sselog")
21248    (set_attr "mode" "TI")])
21249
21250 (define_insn "sse2_xorv2di3"
21251   [(set (match_operand:V2DI 0 "register_operand" "=x")
21252         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21253                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21254   "TARGET_SSE2
21255    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21256   "pxor\t{%2, %0|%0, %2}"
21257   [(set_attr "type" "sselog")
21258    (set_attr "mode" "TI")])
21259
21260 ;; Use xor, but don't show input operands so they aren't live before
21261 ;; this insn.
21262 (define_insn "sse_clrv4sf"
21263   [(set (match_operand:V4SF 0 "register_operand" "=x")
21264         (match_operand:V4SF 1 "const0_operand" "X"))]
21265   "TARGET_SSE"
21266 {
21267   if (get_attr_mode (insn) == MODE_TI)
21268     return "pxor\t{%0, %0|%0, %0}";
21269   else
21270     return "xorps\t{%0, %0|%0, %0}";
21271 }
21272   [(set_attr "type" "sselog")
21273    (set_attr "memory" "none")
21274    (set (attr "mode")
21275         (if_then_else
21276            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21277                          (const_int 0))
21278                      (ne (symbol_ref "TARGET_SSE2")
21279                          (const_int 0)))
21280                 (eq (symbol_ref "optimize_size")
21281                     (const_int 0)))
21282          (const_string "TI")
21283          (const_string "V4SF")))])
21284
21285 ;; Use xor, but don't show input operands so they aren't live before
21286 ;; this insn.
21287 (define_insn "sse_clrv2df"
21288   [(set (match_operand:V2DF 0 "register_operand" "=x")
21289         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21290   "TARGET_SSE2"
21291   "xorpd\t{%0, %0|%0, %0}"
21292   [(set_attr "type" "sselog")
21293    (set_attr "memory" "none")
21294    (set_attr "mode" "V4SF")])
21295
21296 ;; SSE mask-generating compares
21297
21298 (define_insn "maskcmpv4sf3"
21299   [(set (match_operand:V4SI 0 "register_operand" "=x")
21300         (match_operator:V4SI 3 "sse_comparison_operator"
21301                 [(match_operand:V4SF 1 "register_operand" "0")
21302                  (match_operand:V4SF 2 "register_operand" "x")]))]
21303   "TARGET_SSE"
21304   "cmp%D3ps\t{%2, %0|%0, %2}"
21305   [(set_attr "type" "ssecmp")
21306    (set_attr "mode" "V4SF")])
21307
21308 (define_insn "maskncmpv4sf3"
21309   [(set (match_operand:V4SI 0 "register_operand" "=x")
21310         (not:V4SI
21311          (match_operator:V4SI 3 "sse_comparison_operator"
21312                 [(match_operand:V4SF 1 "register_operand" "0")
21313                  (match_operand:V4SF 2 "register_operand" "x")])))]
21314   "TARGET_SSE"
21315 {
21316   if (GET_CODE (operands[3]) == UNORDERED)
21317     return "cmpordps\t{%2, %0|%0, %2}";
21318   else
21319     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21320 }
21321   [(set_attr "type" "ssecmp")
21322    (set_attr "mode" "V4SF")])
21323
21324 (define_insn "vmmaskcmpv4sf3"
21325   [(set (match_operand:V4SI 0 "register_operand" "=x")
21326         (vec_merge:V4SI
21327          (match_operator:V4SI 3 "sse_comparison_operator"
21328                 [(match_operand:V4SF 1 "register_operand" "0")
21329                  (match_operand:V4SF 2 "register_operand" "x")])
21330          (subreg:V4SI (match_dup 1) 0)
21331          (const_int 1)))]
21332   "TARGET_SSE"
21333   "cmp%D3ss\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "ssecmp")
21335    (set_attr "mode" "SF")])
21336
21337 (define_insn "vmmaskncmpv4sf3"
21338   [(set (match_operand:V4SI 0 "register_operand" "=x")
21339         (vec_merge:V4SI
21340          (not:V4SI
21341           (match_operator:V4SI 3 "sse_comparison_operator"
21342                 [(match_operand:V4SF 1 "register_operand" "0")
21343                  (match_operand:V4SF 2 "register_operand" "x")]))
21344          (subreg:V4SI (match_dup 1) 0)
21345          (const_int 1)))]
21346   "TARGET_SSE"
21347 {
21348   if (GET_CODE (operands[3]) == UNORDERED)
21349     return "cmpordss\t{%2, %0|%0, %2}";
21350   else
21351     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21352 }
21353   [(set_attr "type" "ssecmp")
21354    (set_attr "mode" "SF")])
21355
21356 (define_insn "sse_comi"
21357   [(set (reg:CCFP FLAGS_REG)
21358         (compare:CCFP (vec_select:SF
21359                        (match_operand:V4SF 0 "register_operand" "x")
21360                        (parallel [(const_int 0)]))
21361                       (vec_select:SF
21362                        (match_operand:V4SF 1 "register_operand" "x")
21363                        (parallel [(const_int 0)]))))]
21364   "TARGET_SSE"
21365   "comiss\t{%1, %0|%0, %1}"
21366   [(set_attr "type" "ssecomi")
21367    (set_attr "mode" "SF")])
21368
21369 (define_insn "sse_ucomi"
21370   [(set (reg:CCFPU FLAGS_REG)
21371         (compare:CCFPU (vec_select:SF
21372                         (match_operand:V4SF 0 "register_operand" "x")
21373                         (parallel [(const_int 0)]))
21374                        (vec_select:SF
21375                         (match_operand:V4SF 1 "register_operand" "x")
21376                         (parallel [(const_int 0)]))))]
21377   "TARGET_SSE"
21378   "ucomiss\t{%1, %0|%0, %1}"
21379   [(set_attr "type" "ssecomi")
21380    (set_attr "mode" "SF")])
21381
21382
21383 ;; SSE unpack
21384
21385 (define_insn "sse_unpckhps"
21386   [(set (match_operand:V4SF 0 "register_operand" "=x")
21387         (vec_merge:V4SF
21388          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21389                           (parallel [(const_int 2)
21390                                      (const_int 0)
21391                                      (const_int 3)
21392                                      (const_int 1)]))
21393          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21394                           (parallel [(const_int 0)
21395                                      (const_int 2)
21396                                      (const_int 1)
21397                                      (const_int 3)]))
21398          (const_int 5)))]
21399   "TARGET_SSE"
21400   "unpckhps\t{%2, %0|%0, %2}"
21401   [(set_attr "type" "ssecvt")
21402    (set_attr "mode" "V4SF")])
21403
21404 (define_insn "sse_unpcklps"
21405   [(set (match_operand:V4SF 0 "register_operand" "=x")
21406         (vec_merge:V4SF
21407          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21408                           (parallel [(const_int 0)
21409                                      (const_int 2)
21410                                      (const_int 1)
21411                                      (const_int 3)]))
21412          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21413                           (parallel [(const_int 2)
21414                                      (const_int 0)
21415                                      (const_int 3)
21416                                      (const_int 1)]))
21417          (const_int 5)))]
21418   "TARGET_SSE"
21419   "unpcklps\t{%2, %0|%0, %2}"
21420   [(set_attr "type" "ssecvt")
21421    (set_attr "mode" "V4SF")])
21422
21423
21424 ;; SSE min/max
21425
21426 (define_insn "smaxv4sf3"
21427   [(set (match_operand:V4SF 0 "register_operand" "=x")
21428         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21429                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21430   "TARGET_SSE"
21431   "maxps\t{%2, %0|%0, %2}"
21432   [(set_attr "type" "sse")
21433    (set_attr "mode" "V4SF")])
21434
21435 (define_insn "vmsmaxv4sf3"
21436   [(set (match_operand:V4SF 0 "register_operand" "=x")
21437         (vec_merge:V4SF
21438          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21439                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21440          (match_dup 1)
21441          (const_int 1)))]
21442   "TARGET_SSE"
21443   "maxss\t{%2, %0|%0, %2}"
21444   [(set_attr "type" "sse")
21445    (set_attr "mode" "SF")])
21446
21447 (define_insn "sminv4sf3"
21448   [(set (match_operand:V4SF 0 "register_operand" "=x")
21449         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21450                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21451   "TARGET_SSE"
21452   "minps\t{%2, %0|%0, %2}"
21453   [(set_attr "type" "sse")
21454    (set_attr "mode" "V4SF")])
21455
21456 (define_insn "vmsminv4sf3"
21457   [(set (match_operand:V4SF 0 "register_operand" "=x")
21458         (vec_merge:V4SF
21459          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21460                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21461          (match_dup 1)
21462          (const_int 1)))]
21463   "TARGET_SSE"
21464   "minss\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "sse")
21466    (set_attr "mode" "SF")])
21467
21468 ;; SSE <-> integer/MMX conversions
21469
21470 (define_insn "cvtpi2ps"
21471   [(set (match_operand:V4SF 0 "register_operand" "=x")
21472         (vec_merge:V4SF
21473          (match_operand:V4SF 1 "register_operand" "0")
21474          (vec_duplicate:V4SF
21475           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21476          (const_int 12)))]
21477   "TARGET_SSE"
21478   "cvtpi2ps\t{%2, %0|%0, %2}"
21479   [(set_attr "type" "ssecvt")
21480    (set_attr "mode" "V4SF")])
21481
21482 (define_insn "cvtps2pi"
21483   [(set (match_operand:V2SI 0 "register_operand" "=y")
21484         (vec_select:V2SI
21485          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21486          (parallel [(const_int 0) (const_int 1)])))]
21487   "TARGET_SSE"
21488   "cvtps2pi\t{%1, %0|%0, %1}"
21489   [(set_attr "type" "ssecvt")
21490    (set_attr "mode" "V4SF")])
21491
21492 (define_insn "cvttps2pi"
21493   [(set (match_operand:V2SI 0 "register_operand" "=y")
21494         (vec_select:V2SI
21495          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21496                       UNSPEC_FIX)
21497          (parallel [(const_int 0) (const_int 1)])))]
21498   "TARGET_SSE"
21499   "cvttps2pi\t{%1, %0|%0, %1}"
21500   [(set_attr "type" "ssecvt")
21501    (set_attr "mode" "SF")])
21502
21503 (define_insn "cvtsi2ss"
21504   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21505         (vec_merge:V4SF
21506          (match_operand:V4SF 1 "register_operand" "0,0")
21507          (vec_duplicate:V4SF
21508           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21509          (const_int 14)))]
21510   "TARGET_SSE"
21511   "cvtsi2ss\t{%2, %0|%0, %2}"
21512   [(set_attr "type" "sseicvt")
21513    (set_attr "athlon_decode" "vector,double")
21514    (set_attr "mode" "SF")])
21515
21516 (define_insn "cvtsi2ssq"
21517   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21518         (vec_merge:V4SF
21519          (match_operand:V4SF 1 "register_operand" "0,0")
21520          (vec_duplicate:V4SF
21521           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21522          (const_int 14)))]
21523   "TARGET_SSE && TARGET_64BIT"
21524   "cvtsi2ssq\t{%2, %0|%0, %2}"
21525   [(set_attr "type" "sseicvt")
21526    (set_attr "athlon_decode" "vector,double")
21527    (set_attr "mode" "SF")])
21528
21529 (define_insn "cvtss2si"
21530   [(set (match_operand:SI 0 "register_operand" "=r,r")
21531         (vec_select:SI
21532          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21533          (parallel [(const_int 0)])))]
21534   "TARGET_SSE"
21535   "cvtss2si\t{%1, %0|%0, %1}"
21536   [(set_attr "type" "sseicvt")
21537    (set_attr "athlon_decode" "double,vector")
21538    (set_attr "mode" "SI")])
21539
21540 (define_insn "cvtss2siq"
21541   [(set (match_operand:DI 0 "register_operand" "=r,r")
21542         (vec_select:DI
21543          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21544          (parallel [(const_int 0)])))]
21545   "TARGET_SSE"
21546   "cvtss2siq\t{%1, %0|%0, %1}"
21547   [(set_attr "type" "sseicvt")
21548    (set_attr "athlon_decode" "double,vector")
21549    (set_attr "mode" "DI")])
21550
21551 (define_insn "cvttss2si"
21552   [(set (match_operand:SI 0 "register_operand" "=r,r")
21553         (vec_select:SI
21554          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21555                       UNSPEC_FIX)
21556          (parallel [(const_int 0)])))]
21557   "TARGET_SSE"
21558   "cvttss2si\t{%1, %0|%0, %1}"
21559   [(set_attr "type" "sseicvt")
21560    (set_attr "mode" "SF")
21561    (set_attr "athlon_decode" "double,vector")])
21562
21563 (define_insn "cvttss2siq"
21564   [(set (match_operand:DI 0 "register_operand" "=r,r")
21565         (vec_select:DI
21566          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21567                       UNSPEC_FIX)
21568          (parallel [(const_int 0)])))]
21569   "TARGET_SSE && TARGET_64BIT"
21570   "cvttss2siq\t{%1, %0|%0, %1}"
21571   [(set_attr "type" "sseicvt")
21572    (set_attr "mode" "SF")
21573    (set_attr "athlon_decode" "double,vector")])
21574
21575
21576 ;; MMX insns
21577
21578 ;; MMX arithmetic
21579
21580 (define_insn "addv8qi3"
21581   [(set (match_operand:V8QI 0 "register_operand" "=y")
21582         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21583                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21584   "TARGET_MMX"
21585   "paddb\t{%2, %0|%0, %2}"
21586   [(set_attr "type" "mmxadd")
21587    (set_attr "mode" "DI")])
21588
21589 (define_insn "addv4hi3"
21590   [(set (match_operand:V4HI 0 "register_operand" "=y")
21591         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21592                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21593   "TARGET_MMX"
21594   "paddw\t{%2, %0|%0, %2}"
21595   [(set_attr "type" "mmxadd")
21596    (set_attr "mode" "DI")])
21597
21598 (define_insn "addv2si3"
21599   [(set (match_operand:V2SI 0 "register_operand" "=y")
21600         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21601                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21602   "TARGET_MMX"
21603   "paddd\t{%2, %0|%0, %2}"
21604   [(set_attr "type" "mmxadd")
21605    (set_attr "mode" "DI")])
21606
21607 (define_insn "mmx_adddi3"
21608   [(set (match_operand:DI 0 "register_operand" "=y")
21609         (unspec:DI
21610          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21611                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21612          UNSPEC_NOP))]
21613   "TARGET_MMX"
21614   "paddq\t{%2, %0|%0, %2}"
21615   [(set_attr "type" "mmxadd")
21616    (set_attr "mode" "DI")])
21617
21618 (define_insn "ssaddv8qi3"
21619   [(set (match_operand:V8QI 0 "register_operand" "=y")
21620         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21621                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21622   "TARGET_MMX"
21623   "paddsb\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxadd")
21625    (set_attr "mode" "DI")])
21626
21627 (define_insn "ssaddv4hi3"
21628   [(set (match_operand:V4HI 0 "register_operand" "=y")
21629         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21630                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21631   "TARGET_MMX"
21632   "paddsw\t{%2, %0|%0, %2}"
21633   [(set_attr "type" "mmxadd")
21634    (set_attr "mode" "DI")])
21635
21636 (define_insn "usaddv8qi3"
21637   [(set (match_operand:V8QI 0 "register_operand" "=y")
21638         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21639                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21640   "TARGET_MMX"
21641   "paddusb\t{%2, %0|%0, %2}"
21642   [(set_attr "type" "mmxadd")
21643    (set_attr "mode" "DI")])
21644
21645 (define_insn "usaddv4hi3"
21646   [(set (match_operand:V4HI 0 "register_operand" "=y")
21647         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21648                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21649   "TARGET_MMX"
21650   "paddusw\t{%2, %0|%0, %2}"
21651   [(set_attr "type" "mmxadd")
21652    (set_attr "mode" "DI")])
21653
21654 (define_insn "subv8qi3"
21655   [(set (match_operand:V8QI 0 "register_operand" "=y")
21656         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21657                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21658   "TARGET_MMX"
21659   "psubb\t{%2, %0|%0, %2}"
21660   [(set_attr "type" "mmxadd")
21661    (set_attr "mode" "DI")])
21662
21663 (define_insn "subv4hi3"
21664   [(set (match_operand:V4HI 0 "register_operand" "=y")
21665         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21666                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21667   "TARGET_MMX"
21668   "psubw\t{%2, %0|%0, %2}"
21669   [(set_attr "type" "mmxadd")
21670    (set_attr "mode" "DI")])
21671
21672 (define_insn "subv2si3"
21673   [(set (match_operand:V2SI 0 "register_operand" "=y")
21674         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21675                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21676   "TARGET_MMX"
21677   "psubd\t{%2, %0|%0, %2}"
21678   [(set_attr "type" "mmxadd")
21679    (set_attr "mode" "DI")])
21680
21681 (define_insn "mmx_subdi3"
21682   [(set (match_operand:DI 0 "register_operand" "=y")
21683         (unspec:DI
21684          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21685                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21686          UNSPEC_NOP))]
21687   "TARGET_MMX"
21688   "psubq\t{%2, %0|%0, %2}"
21689   [(set_attr "type" "mmxadd")
21690    (set_attr "mode" "DI")])
21691
21692 (define_insn "sssubv8qi3"
21693   [(set (match_operand:V8QI 0 "register_operand" "=y")
21694         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21695                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21696   "TARGET_MMX"
21697   "psubsb\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxadd")
21699    (set_attr "mode" "DI")])
21700
21701 (define_insn "sssubv4hi3"
21702   [(set (match_operand:V4HI 0 "register_operand" "=y")
21703         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21704                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21705   "TARGET_MMX"
21706   "psubsw\t{%2, %0|%0, %2}"
21707   [(set_attr "type" "mmxadd")
21708    (set_attr "mode" "DI")])
21709
21710 (define_insn "ussubv8qi3"
21711   [(set (match_operand:V8QI 0 "register_operand" "=y")
21712         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21713                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21714   "TARGET_MMX"
21715   "psubusb\t{%2, %0|%0, %2}"
21716   [(set_attr "type" "mmxadd")
21717    (set_attr "mode" "DI")])
21718
21719 (define_insn "ussubv4hi3"
21720   [(set (match_operand:V4HI 0 "register_operand" "=y")
21721         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21722                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21723   "TARGET_MMX"
21724   "psubusw\t{%2, %0|%0, %2}"
21725   [(set_attr "type" "mmxadd")
21726    (set_attr "mode" "DI")])
21727
21728 (define_insn "mulv4hi3"
21729   [(set (match_operand:V4HI 0 "register_operand" "=y")
21730         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21731                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21732   "TARGET_MMX"
21733   "pmullw\t{%2, %0|%0, %2}"
21734   [(set_attr "type" "mmxmul")
21735    (set_attr "mode" "DI")])
21736
21737 (define_insn "smulv4hi3_highpart"
21738   [(set (match_operand:V4HI 0 "register_operand" "=y")
21739         (truncate:V4HI
21740          (lshiftrt:V4SI
21741           (mult:V4SI (sign_extend:V4SI
21742                       (match_operand:V4HI 1 "register_operand" "0"))
21743                      (sign_extend:V4SI
21744                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21745           (const_int 16))))]
21746   "TARGET_MMX"
21747   "pmulhw\t{%2, %0|%0, %2}"
21748   [(set_attr "type" "mmxmul")
21749    (set_attr "mode" "DI")])
21750
21751 (define_insn "umulv4hi3_highpart"
21752   [(set (match_operand:V4HI 0 "register_operand" "=y")
21753         (truncate:V4HI
21754          (lshiftrt:V4SI
21755           (mult:V4SI (zero_extend:V4SI
21756                       (match_operand:V4HI 1 "register_operand" "0"))
21757                      (zero_extend:V4SI
21758                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21759           (const_int 16))))]
21760   "TARGET_SSE || TARGET_3DNOW_A"
21761   "pmulhuw\t{%2, %0|%0, %2}"
21762   [(set_attr "type" "mmxmul")
21763    (set_attr "mode" "DI")])
21764
21765 (define_insn "mmx_pmaddwd"
21766   [(set (match_operand:V2SI 0 "register_operand" "=y")
21767         (plus:V2SI
21768          (mult:V2SI
21769           (sign_extend:V2SI
21770            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21771                             (parallel [(const_int 0) (const_int 2)])))
21772           (sign_extend:V2SI
21773            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21774                             (parallel [(const_int 0) (const_int 2)]))))
21775          (mult:V2SI
21776           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21777                                              (parallel [(const_int 1)
21778                                                         (const_int 3)])))
21779           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21780                                              (parallel [(const_int 1)
21781                                                         (const_int 3)]))))))]
21782   "TARGET_MMX"
21783   "pmaddwd\t{%2, %0|%0, %2}"
21784   [(set_attr "type" "mmxmul")
21785    (set_attr "mode" "DI")])
21786
21787
21788 ;; MMX logical operations
21789 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21790 ;; normal code that also wants to use the FPU from getting broken.
21791 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21792 (define_insn "mmx_iordi3"
21793   [(set (match_operand:DI 0 "register_operand" "=y")
21794         (unspec:DI
21795          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21796                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21797          UNSPEC_NOP))]
21798   "TARGET_MMX"
21799   "por\t{%2, %0|%0, %2}"
21800   [(set_attr "type" "mmxadd")
21801    (set_attr "mode" "DI")])
21802
21803 (define_insn "mmx_xordi3"
21804   [(set (match_operand:DI 0 "register_operand" "=y")
21805         (unspec:DI
21806          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21807                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21808          UNSPEC_NOP))]
21809   "TARGET_MMX"
21810   "pxor\t{%2, %0|%0, %2}"
21811   [(set_attr "type" "mmxadd")
21812    (set_attr "mode" "DI")
21813    (set_attr "memory" "none")])
21814
21815 ;; Same as pxor, but don't show input operands so that we don't think
21816 ;; they are live.
21817 (define_insn "mmx_clrdi"
21818   [(set (match_operand:DI 0 "register_operand" "=y")
21819         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21820   "TARGET_MMX"
21821   "pxor\t{%0, %0|%0, %0}"
21822   [(set_attr "type" "mmxadd")
21823    (set_attr "mode" "DI")
21824    (set_attr "memory" "none")])
21825
21826 (define_insn "mmx_anddi3"
21827   [(set (match_operand:DI 0 "register_operand" "=y")
21828         (unspec:DI
21829          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21830                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21831          UNSPEC_NOP))]
21832   "TARGET_MMX"
21833   "pand\t{%2, %0|%0, %2}"
21834   [(set_attr "type" "mmxadd")
21835    (set_attr "mode" "DI")])
21836
21837 (define_insn "mmx_nanddi3"
21838   [(set (match_operand:DI 0 "register_operand" "=y")
21839         (unspec:DI
21840          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21841                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21842          UNSPEC_NOP))]
21843   "TARGET_MMX"
21844   "pandn\t{%2, %0|%0, %2}"
21845   [(set_attr "type" "mmxadd")
21846    (set_attr "mode" "DI")])
21847
21848
21849 ;; MMX unsigned averages/sum of absolute differences
21850
21851 (define_insn "mmx_uavgv8qi3"
21852   [(set (match_operand:V8QI 0 "register_operand" "=y")
21853         (ashiftrt:V8QI
21854          (plus:V8QI (plus:V8QI
21855                      (match_operand:V8QI 1 "register_operand" "0")
21856                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21857                     (const_vector:V8QI [(const_int 1)
21858                                         (const_int 1)
21859                                         (const_int 1)
21860                                         (const_int 1)
21861                                         (const_int 1)
21862                                         (const_int 1)
21863                                         (const_int 1)
21864                                         (const_int 1)]))
21865          (const_int 1)))]
21866   "TARGET_SSE || TARGET_3DNOW_A"
21867   "pavgb\t{%2, %0|%0, %2}"
21868   [(set_attr "type" "mmxshft")
21869    (set_attr "mode" "DI")])
21870
21871 (define_insn "mmx_uavgv4hi3"
21872   [(set (match_operand:V4HI 0 "register_operand" "=y")
21873         (ashiftrt:V4HI
21874          (plus:V4HI (plus:V4HI
21875                      (match_operand:V4HI 1 "register_operand" "0")
21876                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21877                     (const_vector:V4HI [(const_int 1)
21878                                         (const_int 1)
21879                                         (const_int 1)
21880                                         (const_int 1)]))
21881          (const_int 1)))]
21882   "TARGET_SSE || TARGET_3DNOW_A"
21883   "pavgw\t{%2, %0|%0, %2}"
21884   [(set_attr "type" "mmxshft")
21885    (set_attr "mode" "DI")])
21886
21887 (define_insn "mmx_psadbw"
21888   [(set (match_operand:DI 0 "register_operand" "=y")
21889         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21890                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21891                    UNSPEC_PSADBW))]
21892   "TARGET_SSE || TARGET_3DNOW_A"
21893   "psadbw\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "mmxshft")
21895    (set_attr "mode" "DI")])
21896
21897
21898 ;; MMX insert/extract/shuffle
21899
21900 (define_insn "mmx_pinsrw"
21901   [(set (match_operand:V4HI 0 "register_operand" "=y")
21902         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21903                         (vec_duplicate:V4HI
21904                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21905                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21906   "TARGET_SSE || TARGET_3DNOW_A"
21907   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21908   [(set_attr "type" "mmxcvt")
21909    (set_attr "mode" "DI")])
21910
21911 (define_insn "mmx_pextrw"
21912   [(set (match_operand:SI 0 "register_operand" "=r")
21913         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21914                                        (parallel
21915                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21916   "TARGET_SSE || TARGET_3DNOW_A"
21917   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21918   [(set_attr "type" "mmxcvt")
21919    (set_attr "mode" "DI")])
21920
21921 (define_insn "mmx_pshufw"
21922   [(set (match_operand:V4HI 0 "register_operand" "=y")
21923         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21924                       (match_operand:SI 2 "immediate_operand" "i")]
21925                      UNSPEC_SHUFFLE))]
21926   "TARGET_SSE || TARGET_3DNOW_A"
21927   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21928   [(set_attr "type" "mmxcvt")
21929    (set_attr "mode" "DI")])
21930
21931
21932 ;; MMX mask-generating comparisons
21933
21934 (define_insn "eqv8qi3"
21935   [(set (match_operand:V8QI 0 "register_operand" "=y")
21936         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21937                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21938   "TARGET_MMX"
21939   "pcmpeqb\t{%2, %0|%0, %2}"
21940   [(set_attr "type" "mmxcmp")
21941    (set_attr "mode" "DI")])
21942
21943 (define_insn "eqv4hi3"
21944   [(set (match_operand:V4HI 0 "register_operand" "=y")
21945         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21946                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21947   "TARGET_MMX"
21948   "pcmpeqw\t{%2, %0|%0, %2}"
21949   [(set_attr "type" "mmxcmp")
21950    (set_attr "mode" "DI")])
21951
21952 (define_insn "eqv2si3"
21953   [(set (match_operand:V2SI 0 "register_operand" "=y")
21954         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21955                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21956   "TARGET_MMX"
21957   "pcmpeqd\t{%2, %0|%0, %2}"
21958   [(set_attr "type" "mmxcmp")
21959    (set_attr "mode" "DI")])
21960
21961 (define_insn "gtv8qi3"
21962   [(set (match_operand:V8QI 0 "register_operand" "=y")
21963         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21964                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21965   "TARGET_MMX"
21966   "pcmpgtb\t{%2, %0|%0, %2}"
21967   [(set_attr "type" "mmxcmp")
21968    (set_attr "mode" "DI")])
21969
21970 (define_insn "gtv4hi3"
21971   [(set (match_operand:V4HI 0 "register_operand" "=y")
21972         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21973                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21974   "TARGET_MMX"
21975   "pcmpgtw\t{%2, %0|%0, %2}"
21976   [(set_attr "type" "mmxcmp")
21977    (set_attr "mode" "DI")])
21978
21979 (define_insn "gtv2si3"
21980   [(set (match_operand:V2SI 0 "register_operand" "=y")
21981         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21982                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21983   "TARGET_MMX"
21984   "pcmpgtd\t{%2, %0|%0, %2}"
21985   [(set_attr "type" "mmxcmp")
21986    (set_attr "mode" "DI")])
21987
21988
21989 ;; MMX max/min insns
21990
21991 (define_insn "umaxv8qi3"
21992   [(set (match_operand:V8QI 0 "register_operand" "=y")
21993         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21994                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21995   "TARGET_SSE || TARGET_3DNOW_A"
21996   "pmaxub\t{%2, %0|%0, %2}"
21997   [(set_attr "type" "mmxadd")
21998    (set_attr "mode" "DI")])
21999
22000 (define_insn "smaxv4hi3"
22001   [(set (match_operand:V4HI 0 "register_operand" "=y")
22002         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22003                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22004   "TARGET_SSE || TARGET_3DNOW_A"
22005   "pmaxsw\t{%2, %0|%0, %2}"
22006   [(set_attr "type" "mmxadd")
22007    (set_attr "mode" "DI")])
22008
22009 (define_insn "uminv8qi3"
22010   [(set (match_operand:V8QI 0 "register_operand" "=y")
22011         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22012                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22013   "TARGET_SSE || TARGET_3DNOW_A"
22014   "pminub\t{%2, %0|%0, %2}"
22015   [(set_attr "type" "mmxadd")
22016    (set_attr "mode" "DI")])
22017
22018 (define_insn "sminv4hi3"
22019   [(set (match_operand:V4HI 0 "register_operand" "=y")
22020         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22021                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22022   "TARGET_SSE || TARGET_3DNOW_A"
22023   "pminsw\t{%2, %0|%0, %2}"
22024   [(set_attr "type" "mmxadd")
22025    (set_attr "mode" "DI")])
22026
22027
22028 ;; MMX shifts
22029
22030 (define_insn "ashrv4hi3"
22031   [(set (match_operand:V4HI 0 "register_operand" "=y")
22032         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22033                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22034   "TARGET_MMX"
22035   "psraw\t{%2, %0|%0, %2}"
22036   [(set_attr "type" "mmxshft")
22037    (set_attr "mode" "DI")])
22038
22039 (define_insn "ashrv2si3"
22040   [(set (match_operand:V2SI 0 "register_operand" "=y")
22041         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22042                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22043   "TARGET_MMX"
22044   "psrad\t{%2, %0|%0, %2}"
22045   [(set_attr "type" "mmxshft")
22046    (set_attr "mode" "DI")])
22047
22048 (define_insn "lshrv4hi3"
22049   [(set (match_operand:V4HI 0 "register_operand" "=y")
22050         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22051                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22052   "TARGET_MMX"
22053   "psrlw\t{%2, %0|%0, %2}"
22054   [(set_attr "type" "mmxshft")
22055    (set_attr "mode" "DI")])
22056
22057 (define_insn "lshrv2si3"
22058   [(set (match_operand:V2SI 0 "register_operand" "=y")
22059         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22060                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22061   "TARGET_MMX"
22062   "psrld\t{%2, %0|%0, %2}"
22063   [(set_attr "type" "mmxshft")
22064    (set_attr "mode" "DI")])
22065
22066 ;; See logical MMX insns.
22067 (define_insn "mmx_lshrdi3"
22068   [(set (match_operand:DI 0 "register_operand" "=y")
22069         (unspec:DI
22070           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22071                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22072           UNSPEC_NOP))]
22073   "TARGET_MMX"
22074   "psrlq\t{%2, %0|%0, %2}"
22075   [(set_attr "type" "mmxshft")
22076    (set_attr "mode" "DI")])
22077
22078 (define_insn "ashlv4hi3"
22079   [(set (match_operand:V4HI 0 "register_operand" "=y")
22080         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22081                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22082   "TARGET_MMX"
22083   "psllw\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxshft")
22085    (set_attr "mode" "DI")])
22086
22087 (define_insn "ashlv2si3"
22088   [(set (match_operand:V2SI 0 "register_operand" "=y")
22089         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22090                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22091   "TARGET_MMX"
22092   "pslld\t{%2, %0|%0, %2}"
22093   [(set_attr "type" "mmxshft")
22094    (set_attr "mode" "DI")])
22095
22096 ;; See logical MMX insns.
22097 (define_insn "mmx_ashldi3"
22098   [(set (match_operand:DI 0 "register_operand" "=y")
22099         (unspec:DI
22100          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22101                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22102          UNSPEC_NOP))]
22103   "TARGET_MMX"
22104   "psllq\t{%2, %0|%0, %2}"
22105   [(set_attr "type" "mmxshft")
22106    (set_attr "mode" "DI")])
22107
22108
22109 ;; MMX pack/unpack insns.
22110
22111 (define_insn "mmx_packsswb"
22112   [(set (match_operand:V8QI 0 "register_operand" "=y")
22113         (vec_concat:V8QI
22114          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22115          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22116   "TARGET_MMX"
22117   "packsswb\t{%2, %0|%0, %2}"
22118   [(set_attr "type" "mmxshft")
22119    (set_attr "mode" "DI")])
22120
22121 (define_insn "mmx_packssdw"
22122   [(set (match_operand:V4HI 0 "register_operand" "=y")
22123         (vec_concat:V4HI
22124          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22125          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22126   "TARGET_MMX"
22127   "packssdw\t{%2, %0|%0, %2}"
22128   [(set_attr "type" "mmxshft")
22129    (set_attr "mode" "DI")])
22130
22131 (define_insn "mmx_packuswb"
22132   [(set (match_operand:V8QI 0 "register_operand" "=y")
22133         (vec_concat:V8QI
22134          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22135          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22136   "TARGET_MMX"
22137   "packuswb\t{%2, %0|%0, %2}"
22138   [(set_attr "type" "mmxshft")
22139    (set_attr "mode" "DI")])
22140
22141 (define_insn "mmx_punpckhbw"
22142   [(set (match_operand:V8QI 0 "register_operand" "=y")
22143         (vec_merge:V8QI
22144          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22145                           (parallel [(const_int 4)
22146                                      (const_int 0)
22147                                      (const_int 5)
22148                                      (const_int 1)
22149                                      (const_int 6)
22150                                      (const_int 2)
22151                                      (const_int 7)
22152                                      (const_int 3)]))
22153          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22154                           (parallel [(const_int 0)
22155                                      (const_int 4)
22156                                      (const_int 1)
22157                                      (const_int 5)
22158                                      (const_int 2)
22159                                      (const_int 6)
22160                                      (const_int 3)
22161                                      (const_int 7)]))
22162          (const_int 85)))]
22163   "TARGET_MMX"
22164   "punpckhbw\t{%2, %0|%0, %2}"
22165   [(set_attr "type" "mmxcvt")
22166    (set_attr "mode" "DI")])
22167
22168 (define_insn "mmx_punpckhwd"
22169   [(set (match_operand:V4HI 0 "register_operand" "=y")
22170         (vec_merge:V4HI
22171          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22172                           (parallel [(const_int 0)
22173                                      (const_int 2)
22174                                      (const_int 1)
22175                                      (const_int 3)]))
22176          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22177                           (parallel [(const_int 2)
22178                                      (const_int 0)
22179                                      (const_int 3)
22180                                      (const_int 1)]))
22181          (const_int 5)))]
22182   "TARGET_MMX"
22183   "punpckhwd\t{%2, %0|%0, %2}"
22184   [(set_attr "type" "mmxcvt")
22185    (set_attr "mode" "DI")])
22186
22187 (define_insn "mmx_punpckhdq"
22188   [(set (match_operand:V2SI 0 "register_operand" "=y")
22189         (vec_merge:V2SI
22190          (match_operand:V2SI 1 "register_operand" "0")
22191          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22192                           (parallel [(const_int 1)
22193                                      (const_int 0)]))
22194          (const_int 1)))]
22195   "TARGET_MMX"
22196   "punpckhdq\t{%2, %0|%0, %2}"
22197   [(set_attr "type" "mmxcvt")
22198    (set_attr "mode" "DI")])
22199
22200 (define_insn "mmx_punpcklbw"
22201   [(set (match_operand:V8QI 0 "register_operand" "=y")
22202         (vec_merge:V8QI
22203          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22204                           (parallel [(const_int 0)
22205                                      (const_int 4)
22206                                      (const_int 1)
22207                                      (const_int 5)
22208                                      (const_int 2)
22209                                      (const_int 6)
22210                                      (const_int 3)
22211                                      (const_int 7)]))
22212          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22213                           (parallel [(const_int 4)
22214                                      (const_int 0)
22215                                      (const_int 5)
22216                                      (const_int 1)
22217                                      (const_int 6)
22218                                      (const_int 2)
22219                                      (const_int 7)
22220                                      (const_int 3)]))
22221          (const_int 85)))]
22222   "TARGET_MMX"
22223   "punpcklbw\t{%2, %0|%0, %2}"
22224   [(set_attr "type" "mmxcvt")
22225    (set_attr "mode" "DI")])
22226
22227 (define_insn "mmx_punpcklwd"
22228   [(set (match_operand:V4HI 0 "register_operand" "=y")
22229         (vec_merge:V4HI
22230          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22231                           (parallel [(const_int 2)
22232                                      (const_int 0)
22233                                      (const_int 3)
22234                                      (const_int 1)]))
22235          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22236                           (parallel [(const_int 0)
22237                                      (const_int 2)
22238                                      (const_int 1)
22239                                      (const_int 3)]))
22240          (const_int 5)))]
22241   "TARGET_MMX"
22242   "punpcklwd\t{%2, %0|%0, %2}"
22243   [(set_attr "type" "mmxcvt")
22244    (set_attr "mode" "DI")])
22245
22246 (define_insn "mmx_punpckldq"
22247   [(set (match_operand:V2SI 0 "register_operand" "=y")
22248         (vec_merge:V2SI
22249          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22250                            (parallel [(const_int 1)
22251                                       (const_int 0)]))
22252          (match_operand:V2SI 2 "register_operand" "y")
22253          (const_int 1)))]
22254   "TARGET_MMX"
22255   "punpckldq\t{%2, %0|%0, %2}"
22256   [(set_attr "type" "mmxcvt")
22257    (set_attr "mode" "DI")])
22258
22259
22260 ;; Miscellaneous stuff
22261
22262 (define_insn "emms"
22263   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22264    (clobber (reg:XF 8))
22265    (clobber (reg:XF 9))
22266    (clobber (reg:XF 10))
22267    (clobber (reg:XF 11))
22268    (clobber (reg:XF 12))
22269    (clobber (reg:XF 13))
22270    (clobber (reg:XF 14))
22271    (clobber (reg:XF 15))
22272    (clobber (reg:DI 29))
22273    (clobber (reg:DI 30))
22274    (clobber (reg:DI 31))
22275    (clobber (reg:DI 32))
22276    (clobber (reg:DI 33))
22277    (clobber (reg:DI 34))
22278    (clobber (reg:DI 35))
22279    (clobber (reg:DI 36))]
22280   "TARGET_MMX"
22281   "emms"
22282   [(set_attr "type" "mmx")
22283    (set_attr "memory" "unknown")])
22284
22285 (define_insn "ldmxcsr"
22286   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22287                     UNSPECV_LDMXCSR)]
22288   "TARGET_SSE"
22289   "ldmxcsr\t%0"
22290   [(set_attr "type" "sse")
22291    (set_attr "memory" "load")])
22292
22293 (define_insn "stmxcsr"
22294   [(set (match_operand:SI 0 "memory_operand" "=m")
22295         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22296   "TARGET_SSE"
22297   "stmxcsr\t%0"
22298   [(set_attr "type" "sse")
22299    (set_attr "memory" "store")])
22300
22301 (define_expand "sfence"
22302   [(set (match_dup 0)
22303         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22304   "TARGET_SSE || TARGET_3DNOW_A"
22305 {
22306   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22307   MEM_VOLATILE_P (operands[0]) = 1;
22308 })
22309
22310 (define_insn "*sfence_insn"
22311   [(set (match_operand:BLK 0 "" "")
22312         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22313   "TARGET_SSE || TARGET_3DNOW_A"
22314   "sfence"
22315   [(set_attr "type" "sse")
22316    (set_attr "memory" "unknown")])
22317
22318 (define_expand "sse_prologue_save"
22319   [(parallel [(set (match_operand:BLK 0 "" "")
22320                    (unspec:BLK [(reg:DI 21)
22321                                 (reg:DI 22)
22322                                 (reg:DI 23)
22323                                 (reg:DI 24)
22324                                 (reg:DI 25)
22325                                 (reg:DI 26)
22326                                 (reg:DI 27)
22327                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22328               (use (match_operand:DI 1 "register_operand" ""))
22329               (use (match_operand:DI 2 "immediate_operand" ""))
22330               (use (label_ref:DI (match_operand 3 "" "")))])]
22331   "TARGET_64BIT"
22332   "")
22333
22334 (define_insn "*sse_prologue_save_insn"
22335   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22336                           (match_operand:DI 4 "const_int_operand" "n")))
22337         (unspec:BLK [(reg:DI 21)
22338                      (reg:DI 22)
22339                      (reg:DI 23)
22340                      (reg:DI 24)
22341                      (reg:DI 25)
22342                      (reg:DI 26)
22343                      (reg:DI 27)
22344                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22345    (use (match_operand:DI 1 "register_operand" "r"))
22346    (use (match_operand:DI 2 "const_int_operand" "i"))
22347    (use (label_ref:DI (match_operand 3 "" "X")))]
22348   "TARGET_64BIT
22349    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22350    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22351   "*
22352 {
22353   int i;
22354   operands[0] = gen_rtx_MEM (Pmode,
22355                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22356   output_asm_insn (\"jmp\\t%A1\", operands);
22357   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22358     {
22359       operands[4] = adjust_address (operands[0], DImode, i*16);
22360       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22361       PUT_MODE (operands[4], TImode);
22362       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22363         output_asm_insn (\"rex\", operands);
22364       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22365     }
22366   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22367                              CODE_LABEL_NUMBER (operands[3]));
22368   RET;
22369 }
22370   "
22371   [(set_attr "type" "other")
22372    (set_attr "length_immediate" "0")
22373    (set_attr "length_address" "0")
22374    (set_attr "length" "135")
22375    (set_attr "memory" "store")
22376    (set_attr "modrm" "0")
22377    (set_attr "mode" "DI")])
22378
22379 ;; 3Dnow! instructions
22380
22381 (define_insn "addv2sf3"
22382   [(set (match_operand:V2SF 0 "register_operand" "=y")
22383         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22384                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22385   "TARGET_3DNOW"
22386   "pfadd\\t{%2, %0|%0, %2}"
22387   [(set_attr "type" "mmxadd")
22388    (set_attr "mode" "V2SF")])
22389
22390 (define_insn "subv2sf3"
22391   [(set (match_operand:V2SF 0 "register_operand" "=y")
22392         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22393                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22394   "TARGET_3DNOW"
22395   "pfsub\\t{%2, %0|%0, %2}"
22396   [(set_attr "type" "mmxadd")
22397    (set_attr "mode" "V2SF")])
22398
22399 (define_insn "subrv2sf3"
22400   [(set (match_operand:V2SF 0 "register_operand" "=y")
22401         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22402                     (match_operand:V2SF 1 "register_operand" "0")))]
22403   "TARGET_3DNOW"
22404   "pfsubr\\t{%2, %0|%0, %2}"
22405   [(set_attr "type" "mmxadd")
22406    (set_attr "mode" "V2SF")])
22407
22408 (define_insn "gtv2sf3"
22409   [(set (match_operand:V2SI 0 "register_operand" "=y")
22410         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22411                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22412  "TARGET_3DNOW"
22413   "pfcmpgt\\t{%2, %0|%0, %2}"
22414   [(set_attr "type" "mmxcmp")
22415    (set_attr "mode" "V2SF")])
22416
22417 (define_insn "gev2sf3"
22418   [(set (match_operand:V2SI 0 "register_operand" "=y")
22419         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22420                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22421   "TARGET_3DNOW"
22422   "pfcmpge\\t{%2, %0|%0, %2}"
22423   [(set_attr "type" "mmxcmp")
22424    (set_attr "mode" "V2SF")])
22425
22426 (define_insn "eqv2sf3"
22427   [(set (match_operand:V2SI 0 "register_operand" "=y")
22428         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22429                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22430   "TARGET_3DNOW"
22431   "pfcmpeq\\t{%2, %0|%0, %2}"
22432   [(set_attr "type" "mmxcmp")
22433    (set_attr "mode" "V2SF")])
22434
22435 (define_insn "pfmaxv2sf3"
22436   [(set (match_operand:V2SF 0 "register_operand" "=y")
22437         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22438                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22439   "TARGET_3DNOW"
22440   "pfmax\\t{%2, %0|%0, %2}"
22441   [(set_attr "type" "mmxadd")
22442    (set_attr "mode" "V2SF")])
22443
22444 (define_insn "pfminv2sf3"
22445   [(set (match_operand:V2SF 0 "register_operand" "=y")
22446         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22447                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22448   "TARGET_3DNOW"
22449   "pfmin\\t{%2, %0|%0, %2}"
22450   [(set_attr "type" "mmxadd")
22451    (set_attr "mode" "V2SF")])
22452
22453 (define_insn "mulv2sf3"
22454   [(set (match_operand:V2SF 0 "register_operand" "=y")
22455         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22456                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22457   "TARGET_3DNOW"
22458   "pfmul\\t{%2, %0|%0, %2}"
22459   [(set_attr "type" "mmxmul")
22460    (set_attr "mode" "V2SF")])
22461
22462 (define_insn "femms"
22463   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22464    (clobber (reg:XF 8))
22465    (clobber (reg:XF 9))
22466    (clobber (reg:XF 10))
22467    (clobber (reg:XF 11))
22468    (clobber (reg:XF 12))
22469    (clobber (reg:XF 13))
22470    (clobber (reg:XF 14))
22471    (clobber (reg:XF 15))
22472    (clobber (reg:DI 29))
22473    (clobber (reg:DI 30))
22474    (clobber (reg:DI 31))
22475    (clobber (reg:DI 32))
22476    (clobber (reg:DI 33))
22477    (clobber (reg:DI 34))
22478    (clobber (reg:DI 35))
22479    (clobber (reg:DI 36))]
22480   "TARGET_3DNOW"
22481   "femms"
22482   [(set_attr "type" "mmx")
22483    (set_attr "memory" "none")]) 
22484
22485 (define_insn "pf2id"
22486   [(set (match_operand:V2SI 0 "register_operand" "=y")
22487         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22488   "TARGET_3DNOW"
22489   "pf2id\\t{%1, %0|%0, %1}"
22490   [(set_attr "type" "mmxcvt")
22491    (set_attr "mode" "V2SF")])
22492
22493 (define_insn "pf2iw"
22494   [(set (match_operand:V2SI 0 "register_operand" "=y")
22495         (sign_extend:V2SI
22496            (ss_truncate:V2HI
22497               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22498   "TARGET_3DNOW_A"
22499   "pf2iw\\t{%1, %0|%0, %1}"
22500   [(set_attr "type" "mmxcvt")
22501    (set_attr "mode" "V2SF")])
22502
22503 (define_insn "pfacc"
22504   [(set (match_operand:V2SF 0 "register_operand" "=y")
22505         (vec_concat:V2SF
22506            (plus:SF
22507               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22508                              (parallel [(const_int  0)]))
22509               (vec_select:SF (match_dup 1)
22510                              (parallel [(const_int 1)])))
22511            (plus:SF
22512               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22513                              (parallel [(const_int  0)]))
22514               (vec_select:SF (match_dup 2)
22515                              (parallel [(const_int 1)])))))]
22516   "TARGET_3DNOW"
22517   "pfacc\\t{%2, %0|%0, %2}"
22518   [(set_attr "type" "mmxadd")
22519    (set_attr "mode" "V2SF")])
22520
22521 (define_insn "pfnacc"
22522   [(set (match_operand:V2SF 0 "register_operand" "=y")
22523         (vec_concat:V2SF
22524            (minus:SF
22525               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22526                              (parallel [(const_int 0)]))
22527               (vec_select:SF (match_dup 1)
22528                              (parallel [(const_int 1)])))
22529            (minus:SF
22530               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22531                              (parallel [(const_int  0)]))
22532               (vec_select:SF (match_dup 2)
22533                              (parallel [(const_int 1)])))))]
22534   "TARGET_3DNOW_A"
22535   "pfnacc\\t{%2, %0|%0, %2}"
22536   [(set_attr "type" "mmxadd")
22537    (set_attr "mode" "V2SF")])
22538
22539 (define_insn "pfpnacc"
22540   [(set (match_operand:V2SF 0 "register_operand" "=y")
22541         (vec_concat:V2SF
22542            (minus:SF
22543               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22544                              (parallel [(const_int 0)]))
22545               (vec_select:SF (match_dup 1)
22546                              (parallel [(const_int 1)])))
22547            (plus:SF
22548               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22549                              (parallel [(const_int 0)]))
22550               (vec_select:SF (match_dup 2)
22551                              (parallel [(const_int 1)])))))]
22552   "TARGET_3DNOW_A"
22553   "pfpnacc\\t{%2, %0|%0, %2}"
22554   [(set_attr "type" "mmxadd")
22555    (set_attr "mode" "V2SF")])
22556
22557 (define_insn "pi2fw"
22558   [(set (match_operand:V2SF 0 "register_operand" "=y")
22559         (float:V2SF
22560            (vec_concat:V2SI
22561               (sign_extend:SI
22562                  (truncate:HI
22563                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22564                                    (parallel [(const_int 0)]))))
22565               (sign_extend:SI
22566                  (truncate:HI
22567                     (vec_select:SI (match_dup 1)
22568                                    (parallel [(const_int  1)])))))))]
22569   "TARGET_3DNOW_A"
22570   "pi2fw\\t{%1, %0|%0, %1}"
22571   [(set_attr "type" "mmxcvt")
22572    (set_attr "mode" "V2SF")])
22573
22574 (define_insn "floatv2si2"
22575   [(set (match_operand:V2SF 0 "register_operand" "=y")
22576         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22577   "TARGET_3DNOW"
22578   "pi2fd\\t{%1, %0|%0, %1}"
22579   [(set_attr "type" "mmxcvt")
22580    (set_attr "mode" "V2SF")])
22581
22582 ;; This insn is identical to pavgb in operation, but the opcode is
22583 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22584
22585 (define_insn "pavgusb"
22586  [(set (match_operand:V8QI 0 "register_operand" "=y")
22587        (unspec:V8QI
22588           [(match_operand:V8QI 1 "register_operand" "0")
22589            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22590           UNSPEC_PAVGUSB))]
22591   "TARGET_3DNOW"
22592   "pavgusb\\t{%2, %0|%0, %2}"
22593   [(set_attr "type" "mmxshft")
22594    (set_attr "mode" "TI")])
22595
22596 ;; 3DNow reciprocal and sqrt
22597  
22598 (define_insn "pfrcpv2sf2"
22599   [(set (match_operand:V2SF 0 "register_operand" "=y")
22600         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22601         UNSPEC_PFRCP))]
22602   "TARGET_3DNOW"
22603   "pfrcp\\t{%1, %0|%0, %1}"
22604   [(set_attr "type" "mmx")
22605    (set_attr "mode" "TI")])
22606
22607 (define_insn "pfrcpit1v2sf3"
22608   [(set (match_operand:V2SF 0 "register_operand" "=y")
22609         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22610                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22611                      UNSPEC_PFRCPIT1))]
22612   "TARGET_3DNOW"
22613   "pfrcpit1\\t{%2, %0|%0, %2}"
22614   [(set_attr "type" "mmx")
22615    (set_attr "mode" "TI")])
22616
22617 (define_insn "pfrcpit2v2sf3"
22618   [(set (match_operand:V2SF 0 "register_operand" "=y")
22619         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22620                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22621                      UNSPEC_PFRCPIT2))]
22622   "TARGET_3DNOW"
22623   "pfrcpit2\\t{%2, %0|%0, %2}"
22624   [(set_attr "type" "mmx")
22625    (set_attr "mode" "TI")])
22626
22627 (define_insn "pfrsqrtv2sf2"
22628   [(set (match_operand:V2SF 0 "register_operand" "=y")
22629         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22630                      UNSPEC_PFRSQRT))]
22631   "TARGET_3DNOW"
22632   "pfrsqrt\\t{%1, %0|%0, %1}"
22633   [(set_attr "type" "mmx")
22634    (set_attr "mode" "TI")])
22635                 
22636 (define_insn "pfrsqit1v2sf3"
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_PFRSQIT1))]
22641   "TARGET_3DNOW"
22642   "pfrsqit1\\t{%2, %0|%0, %2}"
22643   [(set_attr "type" "mmx")
22644    (set_attr "mode" "TI")])
22645
22646 (define_insn "pmulhrwv4hi3"
22647   [(set (match_operand:V4HI 0 "register_operand" "=y")
22648         (truncate:V4HI
22649            (lshiftrt:V4SI
22650               (plus:V4SI
22651                  (mult:V4SI
22652                     (sign_extend:V4SI
22653                        (match_operand:V4HI 1 "register_operand" "0"))
22654                     (sign_extend:V4SI
22655                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22656                  (const_vector:V4SI [(const_int 32768)
22657                                      (const_int 32768)
22658                                      (const_int 32768)
22659                                      (const_int 32768)]))
22660               (const_int 16))))]
22661   "TARGET_3DNOW"
22662   "pmulhrw\\t{%2, %0|%0, %2}"
22663   [(set_attr "type" "mmxmul")
22664    (set_attr "mode" "TI")])
22665
22666 (define_insn "pswapdv2si2"
22667   [(set (match_operand:V2SI 0 "register_operand" "=y")
22668         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22669                          (parallel [(const_int 1) (const_int 0)])))]
22670   "TARGET_3DNOW_A"
22671   "pswapd\\t{%1, %0|%0, %1}"
22672   [(set_attr "type" "mmxcvt")
22673    (set_attr "mode" "TI")])
22674
22675 (define_insn "pswapdv2sf2"
22676   [(set (match_operand:V2SF 0 "register_operand" "=y")
22677         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22678                          (parallel [(const_int 1) (const_int 0)])))]
22679   "TARGET_3DNOW_A"
22680   "pswapd\\t{%1, %0|%0, %1}"
22681   [(set_attr "type" "mmxcvt")
22682    (set_attr "mode" "TI")])
22683
22684 (define_expand "prefetch"
22685   [(prefetch (match_operand 0 "address_operand" "")
22686              (match_operand:SI 1 "const_int_operand" "")
22687              (match_operand:SI 2 "const_int_operand" ""))]
22688   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22689 {
22690   int rw = INTVAL (operands[1]);
22691   int locality = INTVAL (operands[2]);
22692
22693   if (rw != 0 && rw != 1)
22694     abort ();
22695   if (locality < 0 || locality > 3)
22696     abort ();
22697   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22698     abort ();
22699
22700   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22701      suported by SSE counterpart or the SSE prefetch is not available
22702      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22703      of locality.  */
22704   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22705     operands[2] = GEN_INT (3);
22706   else
22707     operands[1] = const0_rtx;
22708 })
22709
22710 (define_insn "*prefetch_sse"
22711   [(prefetch (match_operand:SI 0 "address_operand" "p")
22712              (const_int 0)
22713              (match_operand:SI 1 "const_int_operand" ""))]
22714   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22715 {
22716   static const char * const patterns[4] = {
22717    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22718   };
22719
22720   int locality = INTVAL (operands[1]);
22721   if (locality < 0 || locality > 3)
22722     abort ();
22723
22724   return patterns[locality];  
22725 }
22726   [(set_attr "type" "sse")
22727    (set_attr "memory" "none")])
22728
22729 (define_insn "*prefetch_sse_rex"
22730   [(prefetch (match_operand:DI 0 "address_operand" "p")
22731              (const_int 0)
22732              (match_operand:SI 1 "const_int_operand" ""))]
22733   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22734 {
22735   static const char * const patterns[4] = {
22736    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22737   };
22738
22739   int locality = INTVAL (operands[1]);
22740   if (locality < 0 || locality > 3)
22741     abort ();
22742
22743   return patterns[locality];  
22744 }
22745   [(set_attr "type" "sse")
22746    (set_attr "memory" "none")])
22747
22748 (define_insn "*prefetch_3dnow"
22749   [(prefetch (match_operand:SI 0 "address_operand" "p")
22750              (match_operand:SI 1 "const_int_operand" "n")
22751              (const_int 3))]
22752   "TARGET_3DNOW && !TARGET_64BIT"
22753 {
22754   if (INTVAL (operands[1]) == 0)
22755     return "prefetch\t%a0";
22756   else
22757     return "prefetchw\t%a0";
22758 }
22759   [(set_attr "type" "mmx")
22760    (set_attr "memory" "none")])
22761
22762 (define_insn "*prefetch_3dnow_rex"
22763   [(prefetch (match_operand:DI 0 "address_operand" "p")
22764              (match_operand:SI 1 "const_int_operand" "n")
22765              (const_int 3))]
22766   "TARGET_3DNOW && TARGET_64BIT"
22767 {
22768   if (INTVAL (operands[1]) == 0)
22769     return "prefetch\t%a0";
22770   else
22771     return "prefetchw\t%a0";
22772 }
22773   [(set_attr "type" "mmx")
22774    (set_attr "memory" "none")])
22775
22776 ;; SSE2 support
22777
22778 (define_insn "addv2df3"
22779   [(set (match_operand:V2DF 0 "register_operand" "=x")
22780         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22781                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22782   "TARGET_SSE2"
22783   "addpd\t{%2, %0|%0, %2}"
22784   [(set_attr "type" "sseadd")
22785    (set_attr "mode" "V2DF")])
22786
22787 (define_insn "vmaddv2df3"
22788   [(set (match_operand:V2DF 0 "register_operand" "=x")
22789         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22790                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22791                         (match_dup 1)
22792                         (const_int 1)))]
22793   "TARGET_SSE2"
22794   "addsd\t{%2, %0|%0, %2}"
22795   [(set_attr "type" "sseadd")
22796    (set_attr "mode" "DF")])
22797
22798 (define_insn "subv2df3"
22799   [(set (match_operand:V2DF 0 "register_operand" "=x")
22800         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22801                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22802   "TARGET_SSE2"
22803   "subpd\t{%2, %0|%0, %2}"
22804   [(set_attr "type" "sseadd")
22805    (set_attr "mode" "V2DF")])
22806
22807 (define_insn "vmsubv2df3"
22808   [(set (match_operand:V2DF 0 "register_operand" "=x")
22809         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22810                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22811                         (match_dup 1)
22812                         (const_int 1)))]
22813   "TARGET_SSE2"
22814   "subsd\t{%2, %0|%0, %2}"
22815   [(set_attr "type" "sseadd")
22816    (set_attr "mode" "DF")])
22817
22818 (define_insn "mulv2df3"
22819   [(set (match_operand:V2DF 0 "register_operand" "=x")
22820         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22821                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22822   "TARGET_SSE2"
22823   "mulpd\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "ssemul")
22825    (set_attr "mode" "V2DF")])
22826
22827 (define_insn "vmmulv2df3"
22828   [(set (match_operand:V2DF 0 "register_operand" "=x")
22829         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22830                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22831                         (match_dup 1)
22832                         (const_int 1)))]
22833   "TARGET_SSE2"
22834   "mulsd\t{%2, %0|%0, %2}"
22835   [(set_attr "type" "ssemul")
22836    (set_attr "mode" "DF")])
22837
22838 (define_insn "divv2df3"
22839   [(set (match_operand:V2DF 0 "register_operand" "=x")
22840         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22841                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22842   "TARGET_SSE2"
22843   "divpd\t{%2, %0|%0, %2}"
22844   [(set_attr "type" "ssediv")
22845    (set_attr "mode" "V2DF")])
22846
22847 (define_insn "vmdivv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22851                         (match_dup 1)
22852                         (const_int 1)))]
22853   "TARGET_SSE2"
22854   "divsd\t{%2, %0|%0, %2}"
22855   [(set_attr "type" "ssediv")
22856    (set_attr "mode" "DF")])
22857
22858 ;; SSE min/max
22859
22860 (define_insn "smaxv2df3"
22861   [(set (match_operand:V2DF 0 "register_operand" "=x")
22862         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22863                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22864   "TARGET_SSE2"
22865   "maxpd\t{%2, %0|%0, %2}"
22866   [(set_attr "type" "sseadd")
22867    (set_attr "mode" "V2DF")])
22868
22869 (define_insn "vmsmaxv2df3"
22870   [(set (match_operand:V2DF 0 "register_operand" "=x")
22871         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22872                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22873                         (match_dup 1)
22874                         (const_int 1)))]
22875   "TARGET_SSE2"
22876   "maxsd\t{%2, %0|%0, %2}"
22877   [(set_attr "type" "sseadd")
22878    (set_attr "mode" "DF")])
22879
22880 (define_insn "sminv2df3"
22881   [(set (match_operand:V2DF 0 "register_operand" "=x")
22882         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22883                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22884   "TARGET_SSE2"
22885   "minpd\t{%2, %0|%0, %2}"
22886   [(set_attr "type" "sseadd")
22887    (set_attr "mode" "V2DF")])
22888
22889 (define_insn "vmsminv2df3"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x")
22891         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22892                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22893                         (match_dup 1)
22894                         (const_int 1)))]
22895   "TARGET_SSE2"
22896   "minsd\t{%2, %0|%0, %2}"
22897   [(set_attr "type" "sseadd")
22898    (set_attr "mode" "DF")])
22899 ;; SSE2 square root.  There doesn't appear to be an extension for the
22900 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22901
22902 (define_insn "sqrtv2df2"
22903   [(set (match_operand:V2DF 0 "register_operand" "=x")
22904         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22905   "TARGET_SSE2"
22906   "sqrtpd\t{%1, %0|%0, %1}"
22907   [(set_attr "type" "sse")
22908    (set_attr "mode" "V2DF")])
22909
22910 (define_insn "vmsqrtv2df2"
22911   [(set (match_operand:V2DF 0 "register_operand" "=x")
22912         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22913                         (match_operand:V2DF 2 "register_operand" "0")
22914                         (const_int 1)))]
22915   "TARGET_SSE2"
22916   "sqrtsd\t{%1, %0|%0, %1}"
22917   [(set_attr "type" "sse")
22918    (set_attr "mode" "SF")])
22919
22920 ;; SSE mask-generating compares
22921
22922 (define_insn "maskcmpv2df3"
22923   [(set (match_operand:V2DI 0 "register_operand" "=x")
22924         (match_operator:V2DI 3 "sse_comparison_operator"
22925                              [(match_operand:V2DF 1 "register_operand" "0")
22926                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22927   "TARGET_SSE2"
22928   "cmp%D3pd\t{%2, %0|%0, %2}"
22929   [(set_attr "type" "ssecmp")
22930    (set_attr "mode" "V2DF")])
22931
22932 (define_insn "maskncmpv2df3"
22933   [(set (match_operand:V2DI 0 "register_operand" "=x")
22934         (not:V2DI
22935          (match_operator:V2DI 3 "sse_comparison_operator"
22936                               [(match_operand:V2DF 1 "register_operand" "0")
22937                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22938   "TARGET_SSE2"
22939 {
22940   if (GET_CODE (operands[3]) == UNORDERED)
22941     return "cmpordps\t{%2, %0|%0, %2}";
22942   else
22943     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22944 }
22945   [(set_attr "type" "ssecmp")
22946    (set_attr "mode" "V2DF")])
22947
22948 (define_insn "vmmaskcmpv2df3"
22949   [(set (match_operand:V2DI 0 "register_operand" "=x")
22950         (vec_merge:V2DI
22951          (match_operator:V2DI 3 "sse_comparison_operator"
22952                               [(match_operand:V2DF 1 "register_operand" "0")
22953                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22954          (subreg:V2DI (match_dup 1) 0)
22955          (const_int 1)))]
22956   "TARGET_SSE2"
22957   "cmp%D3sd\t{%2, %0|%0, %2}"
22958   [(set_attr "type" "ssecmp")
22959    (set_attr "mode" "DF")])
22960
22961 (define_insn "vmmaskncmpv2df3"
22962   [(set (match_operand:V2DI 0 "register_operand" "=x")
22963         (vec_merge:V2DI
22964          (not:V2DI
22965           (match_operator:V2DI 3 "sse_comparison_operator"
22966                                [(match_operand:V2DF 1 "register_operand" "0")
22967                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22968          (subreg:V2DI (match_dup 1) 0)
22969          (const_int 1)))]
22970   "TARGET_SSE2"
22971 {
22972   if (GET_CODE (operands[3]) == UNORDERED)
22973     return "cmpordsd\t{%2, %0|%0, %2}";
22974   else
22975     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22976 }
22977   [(set_attr "type" "ssecmp")
22978    (set_attr "mode" "DF")])
22979
22980 (define_insn "sse2_comi"
22981   [(set (reg:CCFP FLAGS_REG)
22982         (compare:CCFP (vec_select:DF
22983                        (match_operand:V2DF 0 "register_operand" "x")
22984                        (parallel [(const_int 0)]))
22985                       (vec_select:DF
22986                        (match_operand:V2DF 1 "register_operand" "x")
22987                        (parallel [(const_int 0)]))))]
22988   "TARGET_SSE2"
22989   "comisd\t{%1, %0|%0, %1}"
22990   [(set_attr "type" "ssecomi")
22991    (set_attr "mode" "DF")])
22992
22993 (define_insn "sse2_ucomi"
22994   [(set (reg:CCFPU FLAGS_REG)
22995         (compare:CCFPU (vec_select:DF
22996                          (match_operand:V2DF 0 "register_operand" "x")
22997                          (parallel [(const_int 0)]))
22998                         (vec_select:DF
22999                          (match_operand:V2DF 1 "register_operand" "x")
23000                          (parallel [(const_int 0)]))))]
23001   "TARGET_SSE2"
23002   "ucomisd\t{%1, %0|%0, %1}"
23003   [(set_attr "type" "ssecomi")
23004    (set_attr "mode" "DF")])
23005
23006 ;; SSE Strange Moves.
23007
23008 (define_insn "sse2_movmskpd"
23009   [(set (match_operand:SI 0 "register_operand" "=r")
23010         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23011                    UNSPEC_MOVMSK))]
23012   "TARGET_SSE2"
23013   "movmskpd\t{%1, %0|%0, %1}"
23014   [(set_attr "type" "ssecvt")
23015    (set_attr "mode" "V2DF")])
23016
23017 (define_insn "sse2_pmovmskb"
23018   [(set (match_operand:SI 0 "register_operand" "=r")
23019         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23020                    UNSPEC_MOVMSK))]
23021   "TARGET_SSE2"
23022   "pmovmskb\t{%1, %0|%0, %1}"
23023   [(set_attr "type" "ssecvt")
23024    (set_attr "mode" "V2DF")])
23025
23026 (define_insn "sse2_maskmovdqu"
23027   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23028         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23029                        (match_operand:V16QI 2 "register_operand" "x")]
23030                       UNSPEC_MASKMOV))]
23031   "TARGET_SSE2"
23032   ;; @@@ check ordering of operands in intel/nonintel syntax
23033   "maskmovdqu\t{%2, %1|%1, %2}"
23034   [(set_attr "type" "ssecvt")
23035    (set_attr "mode" "TI")])
23036
23037 (define_insn "sse2_maskmovdqu_rex64"
23038   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23039         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23040                        (match_operand:V16QI 2 "register_operand" "x")]
23041                       UNSPEC_MASKMOV))]
23042   "TARGET_SSE2"
23043   ;; @@@ check ordering of operands in intel/nonintel syntax
23044   "maskmovdqu\t{%2, %1|%1, %2}"
23045   [(set_attr "type" "ssecvt")
23046    (set_attr "mode" "TI")])
23047
23048 (define_insn "sse2_movntv2df"
23049   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23050         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23051                      UNSPEC_MOVNT))]
23052   "TARGET_SSE2"
23053   "movntpd\t{%1, %0|%0, %1}"
23054   [(set_attr "type" "ssecvt")
23055    (set_attr "mode" "V2DF")])
23056
23057 (define_insn "sse2_movntv2di"
23058   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23059         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23060                      UNSPEC_MOVNT))]
23061   "TARGET_SSE2"
23062   "movntdq\t{%1, %0|%0, %1}"
23063   [(set_attr "type" "ssecvt")
23064    (set_attr "mode" "TI")])
23065
23066 (define_insn "sse2_movntsi"
23067   [(set (match_operand:SI 0 "memory_operand" "=m")
23068         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23069                    UNSPEC_MOVNT))]
23070   "TARGET_SSE2"
23071   "movnti\t{%1, %0|%0, %1}"
23072   [(set_attr "type" "ssecvt")
23073    (set_attr "mode" "V2DF")])
23074
23075 ;; SSE <-> integer/MMX conversions
23076
23077 ;; Conversions between SI and SF
23078
23079 (define_insn "cvtdq2ps"
23080   [(set (match_operand:V4SF 0 "register_operand" "=x")
23081         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23082   "TARGET_SSE2"
23083   "cvtdq2ps\t{%1, %0|%0, %1}"
23084   [(set_attr "type" "ssecvt")
23085    (set_attr "mode" "V2DF")])
23086
23087 (define_insn "cvtps2dq"
23088   [(set (match_operand:V4SI 0 "register_operand" "=x")
23089         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23090   "TARGET_SSE2"
23091   "cvtps2dq\t{%1, %0|%0, %1}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "TI")])
23094
23095 (define_insn "cvttps2dq"
23096   [(set (match_operand:V4SI 0 "register_operand" "=x")
23097         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23098                      UNSPEC_FIX))]
23099   "TARGET_SSE2"
23100   "cvttps2dq\t{%1, %0|%0, %1}"
23101   [(set_attr "type" "ssecvt")
23102    (set_attr "mode" "TI")])
23103
23104 ;; Conversions between SI and DF
23105
23106 (define_insn "cvtdq2pd"
23107   [(set (match_operand:V2DF 0 "register_operand" "=x")
23108         (float:V2DF (vec_select:V2SI
23109                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23110                      (parallel
23111                       [(const_int 0)
23112                        (const_int 1)]))))]
23113   "TARGET_SSE2"
23114   "cvtdq2pd\t{%1, %0|%0, %1}"
23115   [(set_attr "type" "ssecvt")
23116    (set_attr "mode" "V2DF")])
23117
23118 (define_insn "cvtpd2dq"
23119   [(set (match_operand:V4SI 0 "register_operand" "=x")
23120         (vec_concat:V4SI
23121          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23122          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23123   "TARGET_SSE2"
23124   "cvtpd2dq\t{%1, %0|%0, %1}"
23125   [(set_attr "type" "ssecvt")
23126    (set_attr "mode" "TI")])
23127
23128 (define_insn "cvttpd2dq"
23129   [(set (match_operand:V4SI 0 "register_operand" "=x")
23130         (vec_concat:V4SI
23131          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23132                       UNSPEC_FIX)
23133          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23134   "TARGET_SSE2"
23135   "cvttpd2dq\t{%1, %0|%0, %1}"
23136   [(set_attr "type" "ssecvt")
23137    (set_attr "mode" "TI")])
23138
23139 (define_insn "cvtpd2pi"
23140   [(set (match_operand:V2SI 0 "register_operand" "=y")
23141         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23142   "TARGET_SSE2"
23143   "cvtpd2pi\t{%1, %0|%0, %1}"
23144   [(set_attr "type" "ssecvt")
23145    (set_attr "mode" "TI")])
23146
23147 (define_insn "cvttpd2pi"
23148   [(set (match_operand:V2SI 0 "register_operand" "=y")
23149         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23150                      UNSPEC_FIX))]
23151   "TARGET_SSE2"
23152   "cvttpd2pi\t{%1, %0|%0, %1}"
23153   [(set_attr "type" "ssecvt")
23154    (set_attr "mode" "TI")])
23155
23156 (define_insn "cvtpi2pd"
23157   [(set (match_operand:V2DF 0 "register_operand" "=x")
23158         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23159   "TARGET_SSE2"
23160   "cvtpi2pd\t{%1, %0|%0, %1}"
23161   [(set_attr "type" "ssecvt")
23162    (set_attr "mode" "TI")])
23163
23164 ;; Conversions between SI and DF
23165
23166 (define_insn "cvtsd2si"
23167   [(set (match_operand:SI 0 "register_operand" "=r,r")
23168         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23169                                (parallel [(const_int 0)]))))]
23170   "TARGET_SSE2"
23171   "cvtsd2si\t{%1, %0|%0, %1}"
23172   [(set_attr "type" "sseicvt")
23173    (set_attr "athlon_decode" "double,vector")
23174    (set_attr "mode" "SI")])
23175
23176 (define_insn "cvtsd2siq"
23177   [(set (match_operand:DI 0 "register_operand" "=r,r")
23178         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23179                                (parallel [(const_int 0)]))))]
23180   "TARGET_SSE2 && TARGET_64BIT"
23181   "cvtsd2siq\t{%1, %0|%0, %1}"
23182   [(set_attr "type" "sseicvt")
23183    (set_attr "athlon_decode" "double,vector")
23184    (set_attr "mode" "DI")])
23185
23186 (define_insn "cvttsd2si"
23187   [(set (match_operand:SI 0 "register_operand" "=r,r")
23188         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23189                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23190   "TARGET_SSE2"
23191   "cvttsd2si\t{%1, %0|%0, %1}"
23192   [(set_attr "type" "sseicvt")
23193    (set_attr "mode" "SI")
23194    (set_attr "athlon_decode" "double,vector")])
23195
23196 (define_insn "cvttsd2siq"
23197   [(set (match_operand:DI 0 "register_operand" "=r,r")
23198         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23199                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23200   "TARGET_SSE2 && TARGET_64BIT"
23201   "cvttsd2siq\t{%1, %0|%0, %1}"
23202   [(set_attr "type" "sseicvt")
23203    (set_attr "mode" "DI")
23204    (set_attr "athlon_decode" "double,vector")])
23205
23206 (define_insn "cvtsi2sd"
23207   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23208         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23209                         (vec_duplicate:V2DF
23210                           (float:DF
23211                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23212                         (const_int 2)))]
23213   "TARGET_SSE2"
23214   "cvtsi2sd\t{%2, %0|%0, %2}"
23215   [(set_attr "type" "sseicvt")
23216    (set_attr "mode" "DF")
23217    (set_attr "athlon_decode" "double,direct")])
23218
23219 (define_insn "cvtsi2sdq"
23220   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23221         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23222                         (vec_duplicate:V2DF
23223                           (float:DF
23224                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23225                         (const_int 2)))]
23226   "TARGET_SSE2 && TARGET_64BIT"
23227   "cvtsi2sdq\t{%2, %0|%0, %2}"
23228   [(set_attr "type" "sseicvt")
23229    (set_attr "mode" "DF")
23230    (set_attr "athlon_decode" "double,direct")])
23231
23232 ;; Conversions between SF and DF
23233
23234 (define_insn "cvtsd2ss"
23235   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23236         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23237                         (vec_duplicate:V4SF
23238                           (float_truncate:V2SF
23239                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23240                         (const_int 14)))]
23241   "TARGET_SSE2"
23242   "cvtsd2ss\t{%2, %0|%0, %2}"
23243   [(set_attr "type" "ssecvt")
23244    (set_attr "athlon_decode" "vector,double")
23245    (set_attr "mode" "SF")])
23246
23247 (define_insn "cvtss2sd"
23248   [(set (match_operand:V2DF 0 "register_operand" "=x")
23249         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23250                         (float_extend:V2DF
23251                           (vec_select:V2SF
23252                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23253                             (parallel [(const_int 0)
23254                                        (const_int 1)])))
23255                         (const_int 2)))]
23256   "TARGET_SSE2"
23257   "cvtss2sd\t{%2, %0|%0, %2}"
23258   [(set_attr "type" "ssecvt")
23259    (set_attr "mode" "DF")])
23260
23261 (define_insn "cvtpd2ps"
23262   [(set (match_operand:V4SF 0 "register_operand" "=x")
23263         (subreg:V4SF
23264           (vec_concat:V4SI
23265             (subreg:V2SI (float_truncate:V2SF
23266                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23267             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23268   "TARGET_SSE2"
23269   "cvtpd2ps\t{%1, %0|%0, %1}"
23270   [(set_attr "type" "ssecvt")
23271    (set_attr "mode" "V4SF")])
23272
23273 (define_insn "cvtps2pd"
23274   [(set (match_operand:V2DF 0 "register_operand" "=x")
23275         (float_extend:V2DF
23276           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23277                            (parallel [(const_int 0)
23278                                       (const_int 1)]))))]
23279   "TARGET_SSE2"
23280   "cvtps2pd\t{%1, %0|%0, %1}"
23281   [(set_attr "type" "ssecvt")
23282    (set_attr "mode" "V2DF")])
23283
23284 ;; SSE2 variants of MMX insns
23285
23286 ;; MMX arithmetic
23287
23288 (define_insn "addv16qi3"
23289   [(set (match_operand:V16QI 0 "register_operand" "=x")
23290         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23291                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23292   "TARGET_SSE2"
23293   "paddb\t{%2, %0|%0, %2}"
23294   [(set_attr "type" "sseiadd")
23295    (set_attr "mode" "TI")])
23296
23297 (define_insn "addv8hi3"
23298   [(set (match_operand:V8HI 0 "register_operand" "=x")
23299         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23300                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23301   "TARGET_SSE2"
23302   "paddw\t{%2, %0|%0, %2}"
23303   [(set_attr "type" "sseiadd")
23304    (set_attr "mode" "TI")])
23305
23306 (define_insn "addv4si3"
23307   [(set (match_operand:V4SI 0 "register_operand" "=x")
23308         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23309                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23310   "TARGET_SSE2"
23311   "paddd\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "sseiadd")
23313    (set_attr "mode" "TI")])
23314
23315 (define_insn "addv2di3"
23316   [(set (match_operand:V2DI 0 "register_operand" "=x")
23317         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23318                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23319   "TARGET_SSE2"
23320   "paddq\t{%2, %0|%0, %2}"
23321   [(set_attr "type" "sseiadd")
23322    (set_attr "mode" "TI")])
23323
23324 (define_insn "ssaddv16qi3"
23325   [(set (match_operand:V16QI 0 "register_operand" "=x")
23326         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23327                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23328   "TARGET_SSE2"
23329   "paddsb\t{%2, %0|%0, %2}"
23330   [(set_attr "type" "sseiadd")
23331    (set_attr "mode" "TI")])
23332
23333 (define_insn "ssaddv8hi3"
23334   [(set (match_operand:V8HI 0 "register_operand" "=x")
23335         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23336                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23337   "TARGET_SSE2"
23338   "paddsw\t{%2, %0|%0, %2}"
23339   [(set_attr "type" "sseiadd")
23340    (set_attr "mode" "TI")])
23341
23342 (define_insn "usaddv16qi3"
23343   [(set (match_operand:V16QI 0 "register_operand" "=x")
23344         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23345                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23346   "TARGET_SSE2"
23347   "paddusb\t{%2, %0|%0, %2}"
23348   [(set_attr "type" "sseiadd")
23349    (set_attr "mode" "TI")])
23350
23351 (define_insn "usaddv8hi3"
23352   [(set (match_operand:V8HI 0 "register_operand" "=x")
23353         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23354                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23355   "TARGET_SSE2"
23356   "paddusw\t{%2, %0|%0, %2}"
23357   [(set_attr "type" "sseiadd")
23358    (set_attr "mode" "TI")])
23359
23360 (define_insn "subv16qi3"
23361   [(set (match_operand:V16QI 0 "register_operand" "=x")
23362         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23363                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23364   "TARGET_SSE2"
23365   "psubb\t{%2, %0|%0, %2}"
23366   [(set_attr "type" "sseiadd")
23367    (set_attr "mode" "TI")])
23368
23369 (define_insn "subv8hi3"
23370   [(set (match_operand:V8HI 0 "register_operand" "=x")
23371         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23372                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23373   "TARGET_SSE2"
23374   "psubw\t{%2, %0|%0, %2}"
23375   [(set_attr "type" "sseiadd")
23376    (set_attr "mode" "TI")])
23377
23378 (define_insn "subv4si3"
23379   [(set (match_operand:V4SI 0 "register_operand" "=x")
23380         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23381                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23382   "TARGET_SSE2"
23383   "psubd\t{%2, %0|%0, %2}"
23384   [(set_attr "type" "sseiadd")
23385    (set_attr "mode" "TI")])
23386
23387 (define_insn "subv2di3"
23388   [(set (match_operand:V2DI 0 "register_operand" "=x")
23389         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23390                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23391   "TARGET_SSE2"
23392   "psubq\t{%2, %0|%0, %2}"
23393   [(set_attr "type" "sseiadd")
23394    (set_attr "mode" "TI")])
23395
23396 (define_insn "sssubv16qi3"
23397   [(set (match_operand:V16QI 0 "register_operand" "=x")
23398         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23399                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23400   "TARGET_SSE2"
23401   "psubsb\t{%2, %0|%0, %2}"
23402   [(set_attr "type" "sseiadd")
23403    (set_attr "mode" "TI")])
23404
23405 (define_insn "sssubv8hi3"
23406   [(set (match_operand:V8HI 0 "register_operand" "=x")
23407         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23408                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23409   "TARGET_SSE2"
23410   "psubsw\t{%2, %0|%0, %2}"
23411   [(set_attr "type" "sseiadd")
23412    (set_attr "mode" "TI")])
23413
23414 (define_insn "ussubv16qi3"
23415   [(set (match_operand:V16QI 0 "register_operand" "=x")
23416         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23417                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23418   "TARGET_SSE2"
23419   "psubusb\t{%2, %0|%0, %2}"
23420   [(set_attr "type" "sseiadd")
23421    (set_attr "mode" "TI")])
23422
23423 (define_insn "ussubv8hi3"
23424   [(set (match_operand:V8HI 0 "register_operand" "=x")
23425         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23426                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23427   "TARGET_SSE2"
23428   "psubusw\t{%2, %0|%0, %2}"
23429   [(set_attr "type" "sseiadd")
23430    (set_attr "mode" "TI")])
23431
23432 (define_insn "mulv8hi3"
23433   [(set (match_operand:V8HI 0 "register_operand" "=x")
23434         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23435                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23436   "TARGET_SSE2"
23437   "pmullw\t{%2, %0|%0, %2}"
23438   [(set_attr "type" "sseimul")
23439    (set_attr "mode" "TI")])
23440
23441 (define_insn "smulv8hi3_highpart"
23442   [(set (match_operand:V8HI 0 "register_operand" "=x")
23443         (truncate:V8HI
23444          (lshiftrt:V8SI
23445           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23446                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23447           (const_int 16))))]
23448   "TARGET_SSE2"
23449   "pmulhw\t{%2, %0|%0, %2}"
23450   [(set_attr "type" "sseimul")
23451    (set_attr "mode" "TI")])
23452
23453 (define_insn "umulv8hi3_highpart"
23454   [(set (match_operand:V8HI 0 "register_operand" "=x")
23455         (truncate:V8HI
23456          (lshiftrt:V8SI
23457           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23458                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23459           (const_int 16))))]
23460   "TARGET_SSE2"
23461   "pmulhuw\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseimul")
23463    (set_attr "mode" "TI")])
23464
23465 (define_insn "sse2_umulsidi3"
23466   [(set (match_operand:DI 0 "register_operand" "=y")
23467         (mult:DI (zero_extend:DI (vec_select:SI
23468                                   (match_operand:V2SI 1 "register_operand" "0")
23469                                   (parallel [(const_int 0)])))
23470                  (zero_extend:DI (vec_select:SI
23471                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23472                                   (parallel [(const_int 0)])))))]
23473   "TARGET_SSE2"
23474   "pmuludq\t{%2, %0|%0, %2}"
23475   [(set_attr "type" "mmxmul")
23476    (set_attr "mode" "DI")])
23477
23478 (define_insn "sse2_umulv2siv2di3"
23479   [(set (match_operand:V2DI 0 "register_operand" "=x")
23480         (mult:V2DI (zero_extend:V2DI
23481                      (vec_select:V2SI
23482                        (match_operand:V4SI 1 "register_operand" "0")
23483                        (parallel [(const_int 0) (const_int 2)])))
23484                    (zero_extend:V2DI
23485                      (vec_select:V2SI
23486                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23487                        (parallel [(const_int 0) (const_int 2)])))))]
23488   "TARGET_SSE2"
23489   "pmuludq\t{%2, %0|%0, %2}"
23490   [(set_attr "type" "sseimul")
23491    (set_attr "mode" "TI")])
23492
23493 (define_insn "sse2_pmaddwd"
23494   [(set (match_operand:V4SI 0 "register_operand" "=x")
23495         (plus:V4SI
23496          (mult:V4SI
23497           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23498                                              (parallel [(const_int 0)
23499                                                         (const_int 2)
23500                                                         (const_int 4)
23501                                                         (const_int 6)])))
23502           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23503                                              (parallel [(const_int 0)
23504                                                         (const_int 2)
23505                                                         (const_int 4)
23506                                                         (const_int 6)]))))
23507          (mult:V4SI
23508           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23509                                              (parallel [(const_int 1)
23510                                                         (const_int 3)
23511                                                         (const_int 5)
23512                                                         (const_int 7)])))
23513           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23514                                              (parallel [(const_int 1)
23515                                                         (const_int 3)
23516                                                         (const_int 5)
23517                                                         (const_int 7)]))))))]
23518   "TARGET_SSE2"
23519   "pmaddwd\t{%2, %0|%0, %2}"
23520   [(set_attr "type" "sseiadd")
23521    (set_attr "mode" "TI")])
23522
23523 ;; Same as pxor, but don't show input operands so that we don't think
23524 ;; they are live.
23525 (define_insn "sse2_clrti"
23526   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23527   "TARGET_SSE2"
23528 {
23529   if (get_attr_mode (insn) == MODE_TI)
23530     return "pxor\t%0, %0";
23531   else
23532     return "xorps\t%0, %0";
23533 }
23534   [(set_attr "type" "ssemov")
23535    (set_attr "memory" "none")
23536    (set (attr "mode")
23537               (if_then_else
23538                 (ne (symbol_ref "optimize_size")
23539                     (const_int 0))
23540                 (const_string "V4SF")
23541                 (const_string "TI")))])
23542
23543 ;; MMX unsigned averages/sum of absolute differences
23544
23545 (define_insn "sse2_uavgv16qi3"
23546   [(set (match_operand:V16QI 0 "register_operand" "=x")
23547         (ashiftrt:V16QI
23548          (plus:V16QI (plus:V16QI
23549                      (match_operand:V16QI 1 "register_operand" "0")
23550                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23551                      (const_vector:V16QI [(const_int 1) (const_int 1)
23552                                           (const_int 1) (const_int 1)
23553                                           (const_int 1) (const_int 1)
23554                                           (const_int 1) (const_int 1)
23555                                           (const_int 1) (const_int 1)
23556                                           (const_int 1) (const_int 1)
23557                                           (const_int 1) (const_int 1)
23558                                           (const_int 1) (const_int 1)]))
23559          (const_int 1)))]
23560   "TARGET_SSE2"
23561   "pavgb\t{%2, %0|%0, %2}"
23562   [(set_attr "type" "sseiadd")
23563    (set_attr "mode" "TI")])
23564
23565 (define_insn "sse2_uavgv8hi3"
23566   [(set (match_operand:V8HI 0 "register_operand" "=x")
23567         (ashiftrt:V8HI
23568          (plus:V8HI (plus:V8HI
23569                      (match_operand:V8HI 1 "register_operand" "0")
23570                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23571                     (const_vector:V8HI [(const_int 1) (const_int 1)
23572                                         (const_int 1) (const_int 1)
23573                                         (const_int 1) (const_int 1)
23574                                         (const_int 1) (const_int 1)]))
23575          (const_int 1)))]
23576   "TARGET_SSE2"
23577   "pavgw\t{%2, %0|%0, %2}"
23578   [(set_attr "type" "sseiadd")
23579    (set_attr "mode" "TI")])
23580
23581 ;; @@@ this isn't the right representation.
23582 (define_insn "sse2_psadbw"
23583   [(set (match_operand:V2DI 0 "register_operand" "=x")
23584         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23585                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23586                      UNSPEC_PSADBW))]
23587   "TARGET_SSE2"
23588   "psadbw\t{%2, %0|%0, %2}"
23589   [(set_attr "type" "sseiadd")
23590    (set_attr "mode" "TI")])
23591
23592
23593 ;; MMX insert/extract/shuffle
23594
23595 (define_insn "sse2_pinsrw"
23596   [(set (match_operand:V8HI 0 "register_operand" "=x")
23597         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23598                         (vec_duplicate:V8HI
23599                          (truncate:HI
23600                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23601                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23602   "TARGET_SSE2"
23603   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23604   [(set_attr "type" "ssecvt")
23605    (set_attr "mode" "TI")])
23606
23607 (define_insn "sse2_pextrw"
23608   [(set (match_operand:SI 0 "register_operand" "=r")
23609         (zero_extend:SI
23610           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23611                          (parallel
23612                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23613   "TARGET_SSE2"
23614   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23615   [(set_attr "type" "ssecvt")
23616    (set_attr "mode" "TI")])
23617
23618 (define_insn "sse2_pshufd"
23619   [(set (match_operand:V4SI 0 "register_operand" "=x")
23620         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23621                       (match_operand:SI 2 "immediate_operand" "i")]
23622                      UNSPEC_SHUFFLE))]
23623   "TARGET_SSE2"
23624   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23625   [(set_attr "type" "ssecvt")
23626    (set_attr "mode" "TI")])
23627
23628 (define_insn "sse2_pshuflw"
23629   [(set (match_operand:V8HI 0 "register_operand" "=x")
23630         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23631                       (match_operand:SI 2 "immediate_operand" "i")]
23632                      UNSPEC_PSHUFLW))]
23633   "TARGET_SSE2"
23634   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23635   [(set_attr "type" "ssecvt")
23636    (set_attr "mode" "TI")])
23637
23638 (define_insn "sse2_pshufhw"
23639   [(set (match_operand:V8HI 0 "register_operand" "=x")
23640         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23641                       (match_operand:SI 2 "immediate_operand" "i")]
23642                      UNSPEC_PSHUFHW))]
23643   "TARGET_SSE2"
23644   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23645   [(set_attr "type" "ssecvt")
23646    (set_attr "mode" "TI")])
23647
23648 ;; MMX mask-generating comparisons
23649
23650 (define_insn "eqv16qi3"
23651   [(set (match_operand:V16QI 0 "register_operand" "=x")
23652         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23653                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23654   "TARGET_SSE2"
23655   "pcmpeqb\t{%2, %0|%0, %2}"
23656   [(set_attr "type" "ssecmp")
23657    (set_attr "mode" "TI")])
23658
23659 (define_insn "eqv8hi3"
23660   [(set (match_operand:V8HI 0 "register_operand" "=x")
23661         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23662                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23663   "TARGET_SSE2"
23664   "pcmpeqw\t{%2, %0|%0, %2}"
23665   [(set_attr "type" "ssecmp")
23666    (set_attr "mode" "TI")])
23667
23668 (define_insn "eqv4si3"
23669   [(set (match_operand:V4SI 0 "register_operand" "=x")
23670         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23671                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23672   "TARGET_SSE2"
23673   "pcmpeqd\t{%2, %0|%0, %2}"
23674   [(set_attr "type" "ssecmp")
23675    (set_attr "mode" "TI")])
23676
23677 (define_insn "gtv16qi3"
23678   [(set (match_operand:V16QI 0 "register_operand" "=x")
23679         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23680                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23681   "TARGET_SSE2"
23682   "pcmpgtb\t{%2, %0|%0, %2}"
23683   [(set_attr "type" "ssecmp")
23684    (set_attr "mode" "TI")])
23685
23686 (define_insn "gtv8hi3"
23687   [(set (match_operand:V8HI 0 "register_operand" "=x")
23688         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23689                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23690   "TARGET_SSE2"
23691   "pcmpgtw\t{%2, %0|%0, %2}"
23692   [(set_attr "type" "ssecmp")
23693    (set_attr "mode" "TI")])
23694
23695 (define_insn "gtv4si3"
23696   [(set (match_operand:V4SI 0 "register_operand" "=x")
23697         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23698                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23699   "TARGET_SSE2"
23700   "pcmpgtd\t{%2, %0|%0, %2}"
23701   [(set_attr "type" "ssecmp")
23702    (set_attr "mode" "TI")])
23703
23704
23705 ;; MMX max/min insns
23706
23707 (define_insn "umaxv16qi3"
23708   [(set (match_operand:V16QI 0 "register_operand" "=x")
23709         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23710                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23711   "TARGET_SSE2"
23712   "pmaxub\t{%2, %0|%0, %2}"
23713   [(set_attr "type" "sseiadd")
23714    (set_attr "mode" "TI")])
23715
23716 (define_insn "smaxv8hi3"
23717   [(set (match_operand:V8HI 0 "register_operand" "=x")
23718         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23719                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23720   "TARGET_SSE2"
23721   "pmaxsw\t{%2, %0|%0, %2}"
23722   [(set_attr "type" "sseiadd")
23723    (set_attr "mode" "TI")])
23724
23725 (define_insn "uminv16qi3"
23726   [(set (match_operand:V16QI 0 "register_operand" "=x")
23727         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23728                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23729   "TARGET_SSE2"
23730   "pminub\t{%2, %0|%0, %2}"
23731   [(set_attr "type" "sseiadd")
23732    (set_attr "mode" "TI")])
23733
23734 (define_insn "sminv8hi3"
23735   [(set (match_operand:V8HI 0 "register_operand" "=x")
23736         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23737                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23738   "TARGET_SSE2"
23739   "pminsw\t{%2, %0|%0, %2}"
23740   [(set_attr "type" "sseiadd")
23741    (set_attr "mode" "TI")])
23742
23743
23744 ;; MMX shifts
23745
23746 (define_insn "ashrv8hi3"
23747   [(set (match_operand:V8HI 0 "register_operand" "=x")
23748         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23749                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23750   "TARGET_SSE2"
23751   "psraw\t{%2, %0|%0, %2}"
23752   [(set_attr "type" "sseishft")
23753    (set_attr "mode" "TI")])
23754
23755 (define_insn "ashrv4si3"
23756   [(set (match_operand:V4SI 0 "register_operand" "=x")
23757         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23758                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23759   "TARGET_SSE2"
23760   "psrad\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "sseishft")
23762    (set_attr "mode" "TI")])
23763
23764 (define_insn "lshrv8hi3"
23765   [(set (match_operand:V8HI 0 "register_operand" "=x")
23766         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23767                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23768   "TARGET_SSE2"
23769   "psrlw\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "sseishft")
23771    (set_attr "mode" "TI")])
23772
23773 (define_insn "lshrv4si3"
23774   [(set (match_operand:V4SI 0 "register_operand" "=x")
23775         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23776                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23777   "TARGET_SSE2"
23778   "psrld\t{%2, %0|%0, %2}"
23779   [(set_attr "type" "sseishft")
23780    (set_attr "mode" "TI")])
23781
23782 (define_insn "lshrv2di3"
23783   [(set (match_operand:V2DI 0 "register_operand" "=x")
23784         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23785                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23786   "TARGET_SSE2"
23787   "psrlq\t{%2, %0|%0, %2}"
23788   [(set_attr "type" "sseishft")
23789    (set_attr "mode" "TI")])
23790
23791 (define_insn "ashlv8hi3"
23792   [(set (match_operand:V8HI 0 "register_operand" "=x")
23793         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23794                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23795   "TARGET_SSE2"
23796   "psllw\t{%2, %0|%0, %2}"
23797   [(set_attr "type" "sseishft")
23798    (set_attr "mode" "TI")])
23799
23800 (define_insn "ashlv4si3"
23801   [(set (match_operand:V4SI 0 "register_operand" "=x")
23802         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23803                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23804   "TARGET_SSE2"
23805   "pslld\t{%2, %0|%0, %2}"
23806   [(set_attr "type" "sseishft")
23807    (set_attr "mode" "TI")])
23808
23809 (define_insn "ashlv2di3"
23810   [(set (match_operand:V2DI 0 "register_operand" "=x")
23811         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23812                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23813   "TARGET_SSE2"
23814   "psllq\t{%2, %0|%0, %2}"
23815   [(set_attr "type" "sseishft")
23816    (set_attr "mode" "TI")])
23817
23818 (define_insn "ashrv8hi3_ti"
23819   [(set (match_operand:V8HI 0 "register_operand" "=x")
23820         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23821                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23822   "TARGET_SSE2"
23823   "psraw\t{%2, %0|%0, %2}"
23824   [(set_attr "type" "sseishft")
23825    (set_attr "mode" "TI")])
23826
23827 (define_insn "ashrv4si3_ti"
23828   [(set (match_operand:V4SI 0 "register_operand" "=x")
23829         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23830                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23831   "TARGET_SSE2"
23832   "psrad\t{%2, %0|%0, %2}"
23833   [(set_attr "type" "sseishft")
23834    (set_attr "mode" "TI")])
23835
23836 (define_insn "lshrv8hi3_ti"
23837   [(set (match_operand:V8HI 0 "register_operand" "=x")
23838         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23839                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23840   "TARGET_SSE2"
23841   "psrlw\t{%2, %0|%0, %2}"
23842   [(set_attr "type" "sseishft")
23843    (set_attr "mode" "TI")])
23844
23845 (define_insn "lshrv4si3_ti"
23846   [(set (match_operand:V4SI 0 "register_operand" "=x")
23847         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23848                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23849   "TARGET_SSE2"
23850   "psrld\t{%2, %0|%0, %2}"
23851   [(set_attr "type" "sseishft")
23852    (set_attr "mode" "TI")])
23853
23854 (define_insn "lshrv2di3_ti"
23855   [(set (match_operand:V2DI 0 "register_operand" "=x")
23856         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23857                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23858   "TARGET_SSE2"
23859   "psrlq\t{%2, %0|%0, %2}"
23860   [(set_attr "type" "sseishft")
23861    (set_attr "mode" "TI")])
23862
23863 (define_insn "ashlv8hi3_ti"
23864   [(set (match_operand:V8HI 0 "register_operand" "=x")
23865         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23866                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23867   "TARGET_SSE2"
23868   "psllw\t{%2, %0|%0, %2}"
23869   [(set_attr "type" "sseishft")
23870    (set_attr "mode" "TI")])
23871
23872 (define_insn "ashlv4si3_ti"
23873   [(set (match_operand:V4SI 0 "register_operand" "=x")
23874         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23875                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23876   "TARGET_SSE2"
23877   "pslld\t{%2, %0|%0, %2}"
23878   [(set_attr "type" "sseishft")
23879    (set_attr "mode" "TI")])
23880
23881 (define_insn "ashlv2di3_ti"
23882   [(set (match_operand:V2DI 0 "register_operand" "=x")
23883         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23884                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23885   "TARGET_SSE2"
23886   "psllq\t{%2, %0|%0, %2}"
23887   [(set_attr "type" "sseishft")
23888    (set_attr "mode" "TI")])
23889
23890 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23891 ;; we wouldn't need here it since we never generate TImode arithmetic.
23892
23893 ;; There has to be some kind of prize for the weirdest new instruction...
23894 (define_insn "sse2_ashlti3"
23895   [(set (match_operand:TI 0 "register_operand" "=x")
23896         (unspec:TI
23897          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23898                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23899                                (const_int 8)))] UNSPEC_NOP))]
23900   "TARGET_SSE2"
23901   "pslldq\t{%2, %0|%0, %2}"
23902   [(set_attr "type" "sseishft")
23903    (set_attr "mode" "TI")])
23904
23905 (define_insn "sse2_lshrti3"
23906   [(set (match_operand:TI 0 "register_operand" "=x")
23907         (unspec:TI
23908          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23909                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23910                                 (const_int 8)))] UNSPEC_NOP))]
23911   "TARGET_SSE2"
23912   "psrldq\t{%2, %0|%0, %2}"
23913   [(set_attr "type" "sseishft")
23914    (set_attr "mode" "TI")])
23915
23916 ;; SSE unpack
23917
23918 (define_insn "sse2_unpckhpd"
23919   [(set (match_operand:V2DF 0 "register_operand" "=x")
23920         (vec_concat:V2DF
23921          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23922                         (parallel [(const_int 1)]))
23923          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23924                         (parallel [(const_int 1)]))))]
23925   "TARGET_SSE2"
23926   "unpckhpd\t{%2, %0|%0, %2}"
23927   [(set_attr "type" "ssecvt")
23928    (set_attr "mode" "V2DF")])
23929
23930 (define_insn "sse2_unpcklpd"
23931   [(set (match_operand:V2DF 0 "register_operand" "=x")
23932         (vec_concat:V2DF
23933          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23934                         (parallel [(const_int 0)]))
23935          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23936                         (parallel [(const_int 0)]))))]
23937   "TARGET_SSE2"
23938   "unpcklpd\t{%2, %0|%0, %2}"
23939   [(set_attr "type" "ssecvt")
23940    (set_attr "mode" "V2DF")])
23941
23942 ;; MMX pack/unpack insns.
23943
23944 (define_insn "sse2_packsswb"
23945   [(set (match_operand:V16QI 0 "register_operand" "=x")
23946         (vec_concat:V16QI
23947          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23948          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23949   "TARGET_SSE2"
23950   "packsswb\t{%2, %0|%0, %2}"
23951   [(set_attr "type" "ssecvt")
23952    (set_attr "mode" "TI")])
23953
23954 (define_insn "sse2_packssdw"
23955   [(set (match_operand:V8HI 0 "register_operand" "=x")
23956         (vec_concat:V8HI
23957          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23958          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23959   "TARGET_SSE2"
23960   "packssdw\t{%2, %0|%0, %2}"
23961   [(set_attr "type" "ssecvt")
23962    (set_attr "mode" "TI")])
23963
23964 (define_insn "sse2_packuswb"
23965   [(set (match_operand:V16QI 0 "register_operand" "=x")
23966         (vec_concat:V16QI
23967          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23968          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23969   "TARGET_SSE2"
23970   "packuswb\t{%2, %0|%0, %2}"
23971   [(set_attr "type" "ssecvt")
23972    (set_attr "mode" "TI")])
23973
23974 (define_insn "sse2_punpckhbw"
23975   [(set (match_operand:V16QI 0 "register_operand" "=x")
23976         (vec_merge:V16QI
23977          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23978                            (parallel [(const_int 8) (const_int 0)
23979                                       (const_int 9) (const_int 1)
23980                                       (const_int 10) (const_int 2)
23981                                       (const_int 11) (const_int 3)
23982                                       (const_int 12) (const_int 4)
23983                                       (const_int 13) (const_int 5)
23984                                       (const_int 14) (const_int 6)
23985                                       (const_int 15) (const_int 7)]))
23986          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23987                            (parallel [(const_int 0) (const_int 8)
23988                                       (const_int 1) (const_int 9)
23989                                       (const_int 2) (const_int 10)
23990                                       (const_int 3) (const_int 11)
23991                                       (const_int 4) (const_int 12)
23992                                       (const_int 5) (const_int 13)
23993                                       (const_int 6) (const_int 14)
23994                                       (const_int 7) (const_int 15)]))
23995          (const_int 21845)))]
23996   "TARGET_SSE2"
23997   "punpckhbw\t{%2, %0|%0, %2}"
23998   [(set_attr "type" "ssecvt")
23999    (set_attr "mode" "TI")])
24000
24001 (define_insn "sse2_punpckhwd"
24002   [(set (match_operand:V8HI 0 "register_operand" "=x")
24003         (vec_merge:V8HI
24004          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24005                           (parallel [(const_int 4) (const_int 0)
24006                                      (const_int 5) (const_int 1)
24007                                      (const_int 6) (const_int 2)
24008                                      (const_int 7) (const_int 3)]))
24009          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24010                           (parallel [(const_int 0) (const_int 4)
24011                                      (const_int 1) (const_int 5)
24012                                      (const_int 2) (const_int 6)
24013                                      (const_int 3) (const_int 7)]))
24014          (const_int 85)))]
24015   "TARGET_SSE2"
24016   "punpckhwd\t{%2, %0|%0, %2}"
24017   [(set_attr "type" "ssecvt")
24018    (set_attr "mode" "TI")])
24019
24020 (define_insn "sse2_punpckhdq"
24021   [(set (match_operand:V4SI 0 "register_operand" "=x")
24022         (vec_merge:V4SI
24023          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24024                           (parallel [(const_int 2) (const_int 0)
24025                                      (const_int 3) (const_int 1)]))
24026          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24027                           (parallel [(const_int 0) (const_int 2)
24028                                      (const_int 1) (const_int 3)]))
24029          (const_int 5)))]
24030   "TARGET_SSE2"
24031   "punpckhdq\t{%2, %0|%0, %2}"
24032   [(set_attr "type" "ssecvt")
24033    (set_attr "mode" "TI")])
24034
24035 (define_insn "sse2_punpcklbw"
24036   [(set (match_operand:V16QI 0 "register_operand" "=x")
24037         (vec_merge:V16QI
24038          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24039                            (parallel [(const_int 0) (const_int 8)
24040                                       (const_int 1) (const_int 9)
24041                                       (const_int 2) (const_int 10)
24042                                       (const_int 3) (const_int 11)
24043                                       (const_int 4) (const_int 12)
24044                                       (const_int 5) (const_int 13)
24045                                       (const_int 6) (const_int 14)
24046                                       (const_int 7) (const_int 15)]))
24047          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24048                            (parallel [(const_int 8) (const_int 0)
24049                                       (const_int 9) (const_int 1)
24050                                       (const_int 10) (const_int 2)
24051                                       (const_int 11) (const_int 3)
24052                                       (const_int 12) (const_int 4)
24053                                       (const_int 13) (const_int 5)
24054                                       (const_int 14) (const_int 6)
24055                                       (const_int 15) (const_int 7)]))
24056          (const_int 21845)))]
24057   "TARGET_SSE2"
24058   "punpcklbw\t{%2, %0|%0, %2}"
24059   [(set_attr "type" "ssecvt")
24060    (set_attr "mode" "TI")])
24061
24062 (define_insn "sse2_punpcklwd"
24063   [(set (match_operand:V8HI 0 "register_operand" "=x")
24064         (vec_merge:V8HI
24065          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24066                           (parallel [(const_int 0) (const_int 4)
24067                                      (const_int 1) (const_int 5)
24068                                      (const_int 2) (const_int 6)
24069                                      (const_int 3) (const_int 7)]))
24070          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24071                           (parallel [(const_int 4) (const_int 0)
24072                                      (const_int 5) (const_int 1)
24073                                      (const_int 6) (const_int 2)
24074                                      (const_int 7) (const_int 3)]))
24075          (const_int 85)))]
24076   "TARGET_SSE2"
24077   "punpcklwd\t{%2, %0|%0, %2}"
24078   [(set_attr "type" "ssecvt")
24079    (set_attr "mode" "TI")])
24080
24081 (define_insn "sse2_punpckldq"
24082   [(set (match_operand:V4SI 0 "register_operand" "=x")
24083         (vec_merge:V4SI
24084          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24085                           (parallel [(const_int 0) (const_int 2)
24086                                      (const_int 1) (const_int 3)]))
24087          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24088                           (parallel [(const_int 2) (const_int 0)
24089                                      (const_int 3) (const_int 1)]))
24090          (const_int 5)))]
24091   "TARGET_SSE2"
24092   "punpckldq\t{%2, %0|%0, %2}"
24093   [(set_attr "type" "ssecvt")
24094    (set_attr "mode" "TI")])
24095
24096 (define_insn "sse2_punpcklqdq"
24097   [(set (match_operand:V2DI 0 "register_operand" "=x")
24098         (vec_merge:V2DI
24099          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24100                           (parallel [(const_int 1)
24101                                      (const_int 0)]))
24102          (match_operand:V2DI 1 "register_operand" "0")
24103          (const_int 1)))]
24104   "TARGET_SSE2"
24105   "punpcklqdq\t{%2, %0|%0, %2}"
24106   [(set_attr "type" "ssecvt")
24107    (set_attr "mode" "TI")])
24108
24109 (define_insn "sse2_punpckhqdq"
24110   [(set (match_operand:V2DI 0 "register_operand" "=x")
24111         (vec_merge:V2DI
24112          (match_operand:V2DI 1 "register_operand" "0")
24113          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24114                           (parallel [(const_int 1)
24115                                      (const_int 0)]))
24116          (const_int 1)))]
24117   "TARGET_SSE2"
24118   "punpckhqdq\t{%2, %0|%0, %2}"
24119   [(set_attr "type" "ssecvt")
24120    (set_attr "mode" "TI")])
24121
24122 ;; SSE2 moves
24123
24124 (define_insn "sse2_movapd"
24125   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24126         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24127                      UNSPEC_MOVA))]
24128   "TARGET_SSE2
24129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24130   "movapd\t{%1, %0|%0, %1}"
24131   [(set_attr "type" "ssemov")
24132    (set_attr "mode" "V2DF")])
24133
24134 (define_insn "sse2_movupd"
24135   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24136         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24137                      UNSPEC_MOVU))]
24138   "TARGET_SSE2
24139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24140   "movupd\t{%1, %0|%0, %1}"
24141   [(set_attr "type" "ssecvt")
24142    (set_attr "mode" "V2DF")])
24143
24144 (define_insn "sse2_movdqa"
24145   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24146         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24147                        UNSPEC_MOVA))]
24148   "TARGET_SSE2
24149    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24150   "movdqa\t{%1, %0|%0, %1}"
24151   [(set_attr "type" "ssemov")
24152    (set_attr "mode" "TI")])
24153
24154 (define_insn "sse2_movdqu"
24155   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24156         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24157                        UNSPEC_MOVU))]
24158   "TARGET_SSE2
24159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24160   "movdqu\t{%1, %0|%0, %1}"
24161   [(set_attr "type" "ssecvt")
24162    (set_attr "mode" "TI")])
24163
24164 (define_insn "sse2_movdq2q"
24165   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24166         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24167                        (parallel [(const_int 0)])))]
24168   "TARGET_SSE2 && !TARGET_64BIT"
24169   "@
24170    movq\t{%1, %0|%0, %1}
24171    movdq2q\t{%1, %0|%0, %1}"
24172   [(set_attr "type" "ssecvt")
24173    (set_attr "mode" "TI")])
24174
24175 (define_insn "sse2_movdq2q_rex64"
24176   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24177         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24178                        (parallel [(const_int 0)])))]
24179   "TARGET_SSE2 && TARGET_64BIT"
24180   "@
24181    movq\t{%1, %0|%0, %1}
24182    movdq2q\t{%1, %0|%0, %1}
24183    movd\t{%1, %0|%0, %1}"
24184   [(set_attr "type" "ssecvt")
24185    (set_attr "mode" "TI")])
24186
24187 (define_insn "sse2_movq2dq"
24188   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24189         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24190                          (const_int 0)))]
24191   "TARGET_SSE2 && !TARGET_64BIT"
24192   "@
24193    movq\t{%1, %0|%0, %1}
24194    movq2dq\t{%1, %0|%0, %1}"
24195   [(set_attr "type" "ssecvt,ssemov")
24196    (set_attr "mode" "TI")])
24197
24198 (define_insn "sse2_movq2dq_rex64"
24199   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24200         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24201                          (const_int 0)))]
24202   "TARGET_SSE2 && TARGET_64BIT"
24203   "@
24204    movq\t{%1, %0|%0, %1}
24205    movq2dq\t{%1, %0|%0, %1}
24206    movd\t{%1, %0|%0, %1}"
24207   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24208    (set_attr "mode" "TI")])
24209
24210 (define_insn "sse2_movq"
24211   [(set (match_operand:V2DI 0 "register_operand" "=x")
24212         (vec_concat:V2DI (vec_select:DI
24213                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24214                           (parallel [(const_int 0)]))
24215                          (const_int 0)))]
24216   "TARGET_SSE2"
24217   "movq\t{%1, %0|%0, %1}"
24218   [(set_attr "type" "ssemov")
24219    (set_attr "mode" "TI")])
24220
24221 (define_insn "sse2_loadd"
24222   [(set (match_operand:V4SI 0 "register_operand" "=x")
24223         (vec_merge:V4SI
24224          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24225          (const_vector:V4SI [(const_int 0)
24226                              (const_int 0)
24227                              (const_int 0)
24228                              (const_int 0)])
24229          (const_int 1)))]
24230   "TARGET_SSE2"
24231   "movd\t{%1, %0|%0, %1}"
24232   [(set_attr "type" "ssemov")
24233    (set_attr "mode" "TI")])
24234
24235 (define_insn "sse2_stored"
24236   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24237         (vec_select:SI
24238          (match_operand:V4SI 1 "register_operand" "x")
24239          (parallel [(const_int 0)])))]
24240   "TARGET_SSE2"
24241   "movd\t{%1, %0|%0, %1}"
24242   [(set_attr "type" "ssemov")
24243    (set_attr "mode" "TI")])
24244
24245 (define_insn "sse2_movhpd"
24246   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24247         (vec_merge:V2DF
24248          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24249          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24250          (const_int 2)))]
24251   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24252   "movhpd\t{%2, %0|%0, %2}"
24253   [(set_attr "type" "ssecvt")
24254    (set_attr "mode" "V2DF")])
24255
24256 (define_expand "sse2_loadsd"
24257   [(match_operand:V2DF 0 "register_operand" "")
24258    (match_operand:DF 1 "memory_operand" "")]
24259   "TARGET_SSE2"
24260 {
24261   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24262                                 CONST0_RTX (V2DFmode)));
24263   DONE;
24264 })
24265
24266 (define_insn "sse2_loadsd_1"
24267   [(set (match_operand:V2DF 0 "register_operand" "=x")
24268         (vec_merge:V2DF
24269          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24270          (match_operand:V2DF 2 "const0_operand" "X")
24271          (const_int 1)))]
24272   "TARGET_SSE2"
24273   "movsd\t{%1, %0|%0, %1}"
24274   [(set_attr "type" "ssecvt")
24275    (set_attr "mode" "DF")])
24276
24277 (define_insn "sse2_movsd"
24278   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24279         (vec_merge:V2DF
24280          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24281          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24282          (const_int 1)))]
24283   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24284   "@movsd\t{%2, %0|%0, %2}
24285     movlpd\t{%2, %0|%0, %2}
24286     movlpd\t{%2, %0|%0, %2}"
24287   [(set_attr "type" "ssecvt")
24288    (set_attr "mode" "DF,V2DF,V2DF")])
24289
24290 (define_insn "sse2_storesd"
24291   [(set (match_operand:DF 0 "memory_operand" "=m")
24292         (vec_select:DF
24293          (match_operand:V2DF 1 "register_operand" "x")
24294          (parallel [(const_int 0)])))]
24295   "TARGET_SSE2"
24296   "movsd\t{%1, %0|%0, %1}"
24297   [(set_attr "type" "ssecvt")
24298    (set_attr "mode" "DF")])
24299
24300 (define_insn "sse2_shufpd"
24301   [(set (match_operand:V2DF 0 "register_operand" "=x")
24302         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24303                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24304                       (match_operand:SI 3 "immediate_operand" "i")]
24305                      UNSPEC_SHUFFLE))]
24306   "TARGET_SSE2"
24307   ;; @@@ check operand order for intel/nonintel syntax
24308   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24309   [(set_attr "type" "ssecvt")
24310    (set_attr "mode" "V2DF")])
24311
24312 (define_insn "sse2_clflush"
24313   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24314                     UNSPECV_CLFLUSH)]
24315   "TARGET_SSE2"
24316   "clflush\t%a0"
24317   [(set_attr "type" "sse")
24318    (set_attr "memory" "unknown")])
24319
24320 (define_expand "sse2_mfence"
24321   [(set (match_dup 0)
24322         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24323   "TARGET_SSE2"
24324 {
24325   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24326   MEM_VOLATILE_P (operands[0]) = 1;
24327 })
24328
24329 (define_insn "*mfence_insn"
24330   [(set (match_operand:BLK 0 "" "")
24331         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24332   "TARGET_SSE2"
24333   "mfence"
24334   [(set_attr "type" "sse")
24335    (set_attr "memory" "unknown")])
24336
24337 (define_expand "sse2_lfence"
24338   [(set (match_dup 0)
24339         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24340   "TARGET_SSE2"
24341 {
24342   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24343   MEM_VOLATILE_P (operands[0]) = 1;
24344 })
24345
24346 (define_insn "*lfence_insn"
24347   [(set (match_operand:BLK 0 "" "")
24348         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24349   "TARGET_SSE2"
24350   "lfence"
24351   [(set_attr "type" "sse")
24352    (set_attr "memory" "unknown")])
24353
24354 ;; SSE3
24355
24356 (define_insn "mwait"
24357   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24358                      (match_operand:SI 1 "register_operand" "c")]
24359                     UNSPECV_MWAIT)]
24360   "TARGET_SSE3"
24361   "mwait\t%0, %1"
24362   [(set_attr "length" "3")])
24363
24364 (define_insn "monitor"
24365   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24366                      (match_operand:SI 1 "register_operand" "c")
24367                      (match_operand:SI 2 "register_operand" "d")]
24368                     UNSPECV_MONITOR)]
24369   "TARGET_SSE3"
24370   "monitor\t%0, %1, %2"
24371   [(set_attr "length" "3")])
24372
24373 ;; SSE3 arithmetic
24374
24375 (define_insn "addsubv4sf3"
24376   [(set (match_operand:V4SF 0 "register_operand" "=x")
24377         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24378                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24379                      UNSPEC_ADDSUB))]
24380   "TARGET_SSE3"
24381   "addsubps\t{%2, %0|%0, %2}"
24382   [(set_attr "type" "sseadd")
24383    (set_attr "mode" "V4SF")])
24384
24385 (define_insn "addsubv2df3"
24386   [(set (match_operand:V2DF 0 "register_operand" "=x")
24387         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24388                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24389                      UNSPEC_ADDSUB))]
24390   "TARGET_SSE3"
24391   "addsubpd\t{%2, %0|%0, %2}"
24392   [(set_attr "type" "sseadd")
24393    (set_attr "mode" "V2DF")])
24394
24395 (define_insn "haddv4sf3"
24396   [(set (match_operand:V4SF 0 "register_operand" "=x")
24397         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24398                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24399                      UNSPEC_HADD))]
24400   "TARGET_SSE3"
24401   "haddps\t{%2, %0|%0, %2}"
24402   [(set_attr "type" "sseadd")
24403    (set_attr "mode" "V4SF")])
24404
24405 (define_insn "haddv2df3"
24406   [(set (match_operand:V2DF 0 "register_operand" "=x")
24407         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24408                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24409                      UNSPEC_HADD))]
24410   "TARGET_SSE3"
24411   "haddpd\t{%2, %0|%0, %2}"
24412   [(set_attr "type" "sseadd")
24413    (set_attr "mode" "V2DF")])
24414
24415 (define_insn "hsubv4sf3"
24416   [(set (match_operand:V4SF 0 "register_operand" "=x")
24417         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24418                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24419                      UNSPEC_HSUB))]
24420   "TARGET_SSE3"
24421   "hsubps\t{%2, %0|%0, %2}"
24422   [(set_attr "type" "sseadd")
24423    (set_attr "mode" "V4SF")])
24424
24425 (define_insn "hsubv2df3"
24426   [(set (match_operand:V2DF 0 "register_operand" "=x")
24427         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24428                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24429                      UNSPEC_HSUB))]
24430   "TARGET_SSE3"
24431   "hsubpd\t{%2, %0|%0, %2}"
24432   [(set_attr "type" "sseadd")
24433    (set_attr "mode" "V2DF")])
24434
24435 (define_insn "movshdup"
24436   [(set (match_operand:V4SF 0 "register_operand" "=x")
24437         (unspec:V4SF
24438          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24439   "TARGET_SSE3"
24440   "movshdup\t{%1, %0|%0, %1}"
24441   [(set_attr "type" "sse")
24442    (set_attr "mode" "V4SF")])
24443
24444 (define_insn "movsldup"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF
24447          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24448   "TARGET_SSE3"
24449   "movsldup\t{%1, %0|%0, %1}"
24450   [(set_attr "type" "sse")
24451    (set_attr "mode" "V4SF")])
24452
24453 (define_insn "lddqu"
24454   [(set (match_operand:V16QI 0 "register_operand" "=x")
24455         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24456                        UNSPEC_LDQQU))]
24457   "TARGET_SSE3"
24458   "lddqu\t{%1, %0|%0, %1}"
24459   [(set_attr "type" "ssecvt")
24460    (set_attr "mode" "TI")])
24461
24462 (define_insn "loadddup"
24463   [(set (match_operand:V2DF 0 "register_operand" "=x")
24464         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24465   "TARGET_SSE3"
24466   "movddup\t{%1, %0|%0, %1}"
24467   [(set_attr "type" "ssecvt")
24468    (set_attr "mode" "DF")])
24469
24470 (define_insn "movddup"
24471   [(set (match_operand:V2DF 0 "register_operand" "=x")
24472         (vec_duplicate:V2DF
24473          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24474                         (parallel [(const_int 0)]))))]
24475   "TARGET_SSE3"
24476   "movddup\t{%1, %0|%0, %1}"
24477   [(set_attr "type" "ssecvt")
24478    (set_attr "mode" "DF")])