OSDN Git Service

* config/i386/i386.c (ix86_expand_vector_move): Tidy.
[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,V1DF"
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 FLAGS_REG)
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 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1138
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1143
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1146
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1152 }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1179
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1184
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1187
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1,2")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1,2")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
1903         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
1904   "!TARGET_64BIT
1905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1906   "@
1907    #
1908    #
1909    movq\t{%1, %0|%0, %1}
1910    movq\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}"
1914   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1915    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1916
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "general_operand" ""))]
1920   "!TARGET_64BIT && reload_completed
1921    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1922   [(const_int 0)]
1923   "ix86_split_long_move (operands); DONE;")
1924
1925 ;; %%% This multiword shite has got to go.
1926 (define_split
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1928         (match_operand:DI 1 "general_operand" ""))]
1929   "!TARGET_64BIT && reload_completed
1930    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1931    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1934
1935 (define_insn "*movdi_1_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1938         (match_operand:DI 1 "general_operand"
1939                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1940   "TARGET_64BIT
1941    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1943 {
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 11)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1975 }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "11,12")
1982               (const_string "ssecvt")
1983             (eq_attr "alternative" "4")
1984               (const_string "multi")
1985             (and (ne (symbol_ref "flag_pic") (const_int 0))
1986                  (match_operand:DI 1 "symbolic_operand" ""))
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1991    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1992    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1993
1994 (define_insn "*movdi_1_rex64_nointerunit"
1995   [(set (match_operand:DI 0 "nonimmediate_operand"
1996                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1997         (match_operand:DI 1 "general_operand"
1998                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_di (operands, 2, operands + 2, operands + 4);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2102    && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 3))
2105    (set (match_dup 4) (match_dup 5))]
2106   "split_di (operands, 2, operands + 2, operands + 4);")
2107
2108 (define_insn "*swapdi_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "+r")
2110         (match_operand:DI 1 "register_operand" "+r"))
2111    (set (match_dup 1)
2112         (match_dup 0))]
2113   "TARGET_64BIT"
2114   "xchg{q}\t%1, %0"
2115   [(set_attr "type" "imov")
2116    (set_attr "mode" "DI")
2117    (set_attr "pent_pair" "np")
2118    (set_attr "athlon_decode" "vector")])
2119
2120 (define_expand "movsf"
2121   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2122         (match_operand:SF 1 "general_operand" ""))]
2123   ""
2124   "ix86_expand_move (SFmode, operands); DONE;")
2125
2126 (define_insn "*pushsf"
2127   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2128         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2129   "!TARGET_64BIT"
2130 {
2131   switch (which_alternative)
2132     {
2133     case 1:
2134       return "push{l}\t%1";
2135
2136     default:
2137       /* This insn should be already split before reg-stack.  */
2138       abort ();
2139     }
2140 }
2141   [(set_attr "type" "multi,push,multi")
2142    (set_attr "mode" "SF,SI,SF")])
2143
2144 (define_insn "*pushsf_rex64"
2145   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2146         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2147   "TARGET_64BIT"
2148 {
2149   switch (which_alternative)
2150     {
2151     case 1:
2152       return "push{q}\t%q1";
2153
2154     default:
2155       /* This insn should be already split before reg-stack.  */
2156       abort ();
2157     }
2158 }
2159   [(set_attr "type" "multi,push,multi")
2160    (set_attr "mode" "SF,DI,SF")])
2161
2162 (define_split
2163   [(set (match_operand:SF 0 "push_operand" "")
2164         (match_operand:SF 1 "memory_operand" ""))]
2165   "reload_completed
2166    && GET_CODE (operands[1]) == MEM
2167    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2168    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2169   [(set (match_dup 0)
2170         (match_dup 1))]
2171   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2172
2173
2174 ;; %%% Kill this when call knows how to work this out.
2175 (define_split
2176   [(set (match_operand:SF 0 "push_operand" "")
2177         (match_operand:SF 1 "any_fp_register_operand" ""))]
2178   "!TARGET_64BIT"
2179   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2180    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2181
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "any_fp_register_operand" ""))]
2185   "TARGET_64BIT"
2186   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2187    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2188
2189 (define_insn "*movsf_1"
2190   [(set (match_operand:SF 0 "nonimmediate_operand"
2191           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2192         (match_operand:SF 1 "general_operand"
2193           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2200 {
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       return output_387_reg_move (insn, operands);
2205
2206     case 1:
2207       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2208         return "fstp%z0\t%y0";
2209       else
2210         return "fst%z0\t%y0";
2211
2212     case 2:
2213       return standard_80387_constant_opcode (operands[1]);
2214
2215     case 3:
2216     case 4:
2217       return "mov{l}\t{%1, %0|%0, %1}";
2218     case 5:
2219       if (get_attr_mode (insn) == MODE_TI)
2220         return "pxor\t%0, %0";
2221       else
2222         return "xorps\t%0, %0";
2223     case 6:
2224       if (get_attr_mode (insn) == MODE_V4SF)
2225         return "movaps\t{%1, %0|%0, %1}";
2226       else
2227         return "movss\t{%1, %0|%0, %1}";
2228     case 7:
2229     case 8:
2230       return "movss\t{%1, %0|%0, %1}";
2231
2232     case 9:
2233     case 10:
2234       return "movd\t{%1, %0|%0, %1}";
2235
2236     case 11:
2237       return "movq\t{%1, %0|%0, %1}";
2238
2239     default:
2240       abort();
2241     }
2242 }
2243   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "3,4,9,10")
2246                  (const_string "SI")
2247                (eq_attr "alternative" "5")
2248                  (if_then_else
2249                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2250                                  (const_int 0))
2251                              (ne (symbol_ref "TARGET_SSE2")
2252                                  (const_int 0)))
2253                         (eq (symbol_ref "optimize_size")
2254                             (const_int 0)))
2255                    (const_string "TI")
2256                    (const_string "V4SF"))
2257                /* For architectures resolving dependencies on
2258                   whole SSE registers use APS move to break dependency
2259                   chains, otherwise use short move to avoid extra work. 
2260
2261                   Do the same for architectures resolving dependencies on
2262                   the parts.  While in DF mode it is better to always handle
2263                   just register parts, the SF mode is different due to lack
2264                   of instructions to load just part of the register.  It is
2265                   better to maintain the whole registers in single format
2266                   to avoid problems on using packed logical operations.  */
2267                (eq_attr "alternative" "6")
2268                  (if_then_else
2269                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2270                             (const_int 0))
2271                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2272                             (const_int 0)))
2273                    (const_string "V4SF")
2274                    (const_string "SF"))
2275                (eq_attr "alternative" "11")
2276                  (const_string "DI")]
2277                (const_string "SF")))])
2278
2279 (define_insn "*movsf_1_nointerunit"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       abort();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   abort ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "!TARGET_64BIT && reload_completed"
2422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424   "")
2425
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "any_fp_register_operand" ""))]
2429   "TARGET_64BIT && reload_completed"
2430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2431    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432   "")
2433
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "general_operand" ""))]
2437   "reload_completed"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446   [(set (match_operand:DF 0 "nonimmediate_operand"
2447                                 "=f#x,m  ,f#x,*r  ,o  ,x#f,x#f,x#f  ,m")
2448         (match_operand:DF 1 "general_operand"
2449                                 "fm#x,f#x,G  ,*roF,F*r,C  ,x#f,xHm#f,x#f"))]
2450   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2451    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2452    && (reload_in_progress || reload_completed
2453        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2454        || GET_CODE (operands[1]) != CONST_DOUBLE
2455        || memory_operand (operands[0], DFmode))" 
2456 {
2457   switch (which_alternative)
2458     {
2459     case 0:
2460       return output_387_reg_move (insn, operands);
2461
2462     case 1:
2463       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2464         return "fstp%z0\t%y0";
2465       else
2466         return "fst%z0\t%y0";
2467
2468     case 2:
2469       return standard_80387_constant_opcode (operands[1]);
2470
2471     case 3:
2472     case 4:
2473       return "#";
2474     case 5:
2475       switch (get_attr_mode (insn))
2476         {
2477         case MODE_V4SF:
2478           return "xorps\t%0, %0";
2479         case MODE_V2DF:
2480           return "xorpd\t%0, %0";
2481         case MODE_TI:
2482           return "pxor\t%0, %0";
2483         default:
2484           abort ();
2485         }
2486     case 6:
2487     case 7:
2488     case 8:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "movaps\t{%1, %0|%0, %1}";
2493         case MODE_V2DF:
2494           return "movapd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "movdqa\t{%1, %0|%0, %1}";
2497         case MODE_DI:
2498           return "movq\t{%1, %0|%0, %1}";
2499         case MODE_DF:
2500           return "movsd\t{%1, %0|%0, %1}";
2501         case MODE_V1DF:
2502           return "movlpd\t{%1, %0|%0, %1}";
2503         default:
2504           abort ();
2505         }
2506
2507     default:
2508       abort();
2509     }
2510 }
2511   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512    (set (attr "mode")
2513         (cond [(eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (if_then_else
2520                             (ne (symbol_ref "optimize_size") (const_int 0))
2521                             (const_string "V4SF")
2522                             (const_string "TI"))
2523                        ]
2524                    (const_string "DI"))
2525
2526                /* xorps is one byte shorter.  */
2527                (eq_attr "alternative" "5")
2528                  (cond [(ne (symbol_ref "optimize_size")
2529                             (const_int 0))
2530                           (const_string "V4SF")
2531                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532                             (const_int 0))
2533                           (const_string "TI")
2534                        ]
2535                        (const_string "V2DF"))
2536
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2540
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                    [(ne (symbol_ref "optimize_size")
2545                         (const_int 0))
2546                       (const_string "V4SF")
2547                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                         (const_int 0))
2549                       (const_string "V2DF")
2550                    ]
2551                    (const_string "DF"))
2552                /* For architectures resolving dependencies on register
2553                   parts we may avoid extra work to zero out upper part
2554                   of register.  */
2555                (eq_attr "alternative" "7")
2556                  (if_then_else
2557                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2558                        (const_int 0))
2559                    (const_string "V1DF")
2560                    (const_string "DF"))
2561               ]
2562               (const_string "DF")))])
2563
2564 (define_insn "*movdf_integer"
2565   [(set (match_operand:DF 0 "nonimmediate_operand"
2566                         "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf,Y#rf,Y#rf ,m")
2567         (match_operand:DF 1 "general_operand"
2568                         "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C   ,Y#rf,Ym#rf,Y#rf"))]
2569   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2570    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2571    && (reload_in_progress || reload_completed
2572        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2573        || GET_CODE (operands[1]) != CONST_DOUBLE
2574        || memory_operand (operands[0], DFmode))" 
2575 {
2576   switch (which_alternative)
2577     {
2578     case 0:
2579       return output_387_reg_move (insn, operands);
2580
2581     case 1:
2582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         return "fstp%z0\t%y0";
2584       else
2585         return "fst%z0\t%y0";
2586
2587     case 2:
2588       return standard_80387_constant_opcode (operands[1]);
2589
2590     case 3:
2591     case 4:
2592       return "#";
2593
2594     case 5:
2595       switch (get_attr_mode (insn))
2596         {
2597         case MODE_V4SF:
2598           return "xorps\t%0, %0";
2599         case MODE_V2DF:
2600           return "xorpd\t%0, %0";
2601         case MODE_TI:
2602           return "pxor\t%0, %0";
2603         default:
2604           abort ();
2605         }
2606     case 6:
2607     case 7:
2608     case 8:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "movaps\t{%1, %0|%0, %1}";
2613         case MODE_V2DF:
2614           return "movapd\t{%1, %0|%0, %1}";
2615         case MODE_TI:
2616           return "movdqa\t{%1, %0|%0, %1}";
2617         case MODE_DI:
2618           return "movq\t{%1, %0|%0, %1}";
2619         case MODE_DF:
2620           return "movsd\t{%1, %0|%0, %1}";
2621         case MODE_V1DF:
2622           return "movlpd\t{%1, %0|%0, %1}";
2623         default:
2624           abort ();
2625         }
2626
2627     default:
2628       abort();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2635
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (if_then_else
2640                             (ne (symbol_ref "optimize_size") (const_int 0))
2641                             (const_string "V4SF")
2642                             (const_string "TI"))
2643                        ]
2644                    (const_string "DI"))
2645
2646                /* xorps is one byte shorter.  */
2647                (eq_attr "alternative" "5")
2648                  (cond [(ne (symbol_ref "optimize_size")
2649                             (const_int 0))
2650                           (const_string "V4SF")
2651                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652                             (const_int 0))
2653                           (const_string "TI")
2654                        ]
2655                        (const_string "V2DF"))
2656
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.
2660
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                    [(ne (symbol_ref "optimize_size")
2665                         (const_int 0))
2666                       (const_string "V4SF")
2667                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                         (const_int 0))
2669                       (const_string "V2DF")
2670                    ]
2671                    (const_string "DF"))
2672                /* For architectures resolving dependencies on register
2673                   parts we may avoid extra work to zero out upper part
2674                   of register.  */
2675                (eq_attr "alternative" "7")
2676                  (if_then_else
2677                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678                        (const_int 0))
2679                    (const_string "V1DF")
2680                    (const_string "DF"))
2681               ]
2682               (const_string "DF")))])
2683
2684 (define_split
2685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed
2688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689    && ! (ANY_FP_REG_P (operands[0]) || 
2690          (GET_CODE (operands[0]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692    && ! (ANY_FP_REG_P (operands[1]) || 
2693          (GET_CODE (operands[1]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695   [(const_int 0)]
2696   "ix86_split_long_move (operands); DONE;")
2697
2698 (define_insn "*swapdf"
2699   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700         (match_operand:DF 1 "fp_register_operand" "+f"))
2701    (set (match_dup 1)
2702         (match_dup 0))]
2703   "reload_completed || TARGET_80387"
2704 {
2705   if (STACK_TOP_P (operands[0]))
2706     return "fxch\t%1";
2707   else
2708     return "fxch\t%0";
2709 }
2710   [(set_attr "type" "fxch")
2711    (set_attr "mode" "DF")])
2712
2713 (define_expand "movxf"
2714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715         (match_operand:XF 1 "general_operand" ""))]
2716   ""
2717   "ix86_expand_move (XFmode, operands); DONE;")
2718
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2721 ;; Pushing using integer instructions is longer except for constants
2722 ;; and direct memory references.
2723 ;; (assuming that any given constant is pushed only once, but this ought to be
2724 ;;  handled elsewhere).
2725
2726 (define_insn "*pushxf_nointeger"
2727   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729   "optimize_size"
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   abort ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   abort ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     }
2803   abort();
2804 }
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2807
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2810         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2816 {
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2821
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2829
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2832
2833     case 3: case 4:
2834       return "#";
2835     }
2836   abort();
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2864    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2865   [(set (match_dup 0) (match_dup 1))]
2866 {
2867   rtx c = get_pool_constant (XEXP (operands[1], 0));
2868   rtx r = operands[0];
2869
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2872
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2885
2886   operands[1] = c;
2887 })
2888
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2895 {
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2900 }
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2903 \f
2904 ;; Zero extension instructions
2905
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2909   ""
2910 {
2911   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2912     {
2913       operands[1] = force_reg (HImode, operands[1]);
2914       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2915       DONE;
2916     }
2917 })
2918
2919 (define_insn "zero_extendhisi2_and"
2920   [(set (match_operand:SI 0 "register_operand" "=r")
2921      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2922    (clobber (reg:CC FLAGS_REG))]
2923   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2924   "#"
2925   [(set_attr "type" "alu1")
2926    (set_attr "mode" "SI")])
2927
2928 (define_split
2929   [(set (match_operand:SI 0 "register_operand" "")
2930         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2931    (clobber (reg:CC FLAGS_REG))]
2932   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2933   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2934               (clobber (reg:CC FLAGS_REG))])]
2935   "")
2936
2937 (define_insn "*zero_extendhisi2_movzwl"
2938   [(set (match_operand:SI 0 "register_operand" "=r")
2939      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2941   "movz{wl|x}\t{%1, %0|%0, %1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2944
2945 (define_expand "zero_extendqihi2"
2946   [(parallel
2947     [(set (match_operand:HI 0 "register_operand" "")
2948        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2949      (clobber (reg:CC FLAGS_REG))])]
2950   ""
2951   "")
2952
2953 (define_insn "*zero_extendqihi2_and"
2954   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2955      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2956    (clobber (reg:CC FLAGS_REG))]
2957   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2958   "#"
2959   [(set_attr "type" "alu1")
2960    (set_attr "mode" "HI")])
2961
2962 (define_insn "*zero_extendqihi2_movzbw_and"
2963   [(set (match_operand:HI 0 "register_operand" "=r,r")
2964      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2965    (clobber (reg:CC FLAGS_REG))]
2966   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2967   "#"
2968   [(set_attr "type" "imovx,alu1")
2969    (set_attr "mode" "HI")])
2970
2971 (define_insn "*zero_extendqihi2_movzbw"
2972   [(set (match_operand:HI 0 "register_operand" "=r")
2973      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2974   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2975   "movz{bw|x}\t{%1, %0|%0, %1}"
2976   [(set_attr "type" "imovx")
2977    (set_attr "mode" "HI")])
2978
2979 ;; For the movzbw case strip only the clobber
2980 (define_split
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "reload_completed 
2985    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2986    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2989
2990 ;; When source and destination does not overlap, clear destination
2991 ;; first and then do the movb
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && ANY_QI_REG_P (operands[0])
2998    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2999    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3000   [(set (match_dup 0) (const_int 0))
3001    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3002   "operands[2] = gen_lowpart (QImode, operands[0]);")
3003
3004 ;; Rest is handled by single and.
3005 (define_split
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && true_regnum (operands[0]) == true_regnum (operands[1])"
3011   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3012               (clobber (reg:CC FLAGS_REG))])]
3013   "")
3014
3015 (define_expand "zero_extendqisi2"
3016   [(parallel
3017     [(set (match_operand:SI 0 "register_operand" "")
3018        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3022
3023 (define_insn "*zero_extendqisi2_and"
3024   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "SI")])
3031
3032 (define_insn "*zero_extendqisi2_movzbw_and"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "SI")])
3040
3041 (define_insn "*zero_extendqisi2_movzbw"
3042   [(set (match_operand:SI 0 "register_operand" "=r")
3043      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %0|%0, %1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbl case strip only the clobber
3050 (define_split
3051   [(set (match_operand:SI 0 "register_operand" "")
3052         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_dup 0)
3058         (zero_extend:SI (match_dup 1)))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:SI 0 "register_operand" "")
3064         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 ;; %%% Kill me once multi-word ops are sane.
3087 (define_expand "zero_extendsidi2"
3088   [(set (match_operand:DI 0 "register_operand" "=r")
3089      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3090   ""
3091   "if (!TARGET_64BIT)
3092      {
3093        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3094        DONE;
3095      }
3096   ")
3097
3098 (define_insn "zero_extendsidi2_32"
3099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3100         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3101    (clobber (reg:CC FLAGS_REG))]
3102   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3103   "@
3104    #
3105    #
3106    #
3107    movd\t{%1, %0|%0, %1}
3108    movd\t{%1, %0|%0, %1}"
3109   [(set_attr "mode" "SI,SI,SI,DI,TI")
3110    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3111
3112 (define_insn "*zero_extendsidi2_32_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3114         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3117   "@
3118    #
3119    #
3120    #
3121    movd\t{%1, %0|%0, %1}
3122    movd\t{%1, %0|%0, %1}"
3123   [(set_attr "mode" "SI,SI,SI,DI,TI")
3124    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3125
3126 (define_insn "zero_extendsidi2_rex64"
3127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3129   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3130   "@
3131    mov\t{%k1, %k0|%k0, %k1}
3132    #
3133    movd\t{%1, %0|%0, %1}
3134    movd\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3136    (set_attr "mode" "SI,DI,DI,TI")])
3137
3138 (define_insn "*zero_extendsidi2_rex64_1"
3139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3141   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3142   "@
3143    mov\t{%k1, %k0|%k0, %k1}
3144    #
3145    movd\t{%1, %0|%0, %1}
3146    movd\t{%1, %0|%0, %1}"
3147   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3148    (set_attr "mode" "SI,DI,SI,SI")])
3149
3150 (define_split
3151   [(set (match_operand:DI 0 "memory_operand" "")
3152      (zero_extend:DI (match_dup 0)))]
3153   "TARGET_64BIT"
3154   [(set (match_dup 4) (const_int 0))]
3155   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3156
3157 (define_split 
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT && reload_completed
3162    && true_regnum (operands[0]) == true_regnum (operands[1])"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165
3166 (define_split 
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3172   [(set (match_dup 3) (match_dup 1))
3173    (set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_insn "zero_extendhidi2"
3177   [(set (match_operand:DI 0 "register_operand" "=r,r")
3178      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3179   "TARGET_64BIT"
3180   "@
3181    movz{wl|x}\t{%1, %k0|%k0, %1}
3182    movz{wq|x}\t{%1, %0|%0, %1}"
3183   [(set_attr "type" "imovx")
3184    (set_attr "mode" "SI,DI")])
3185
3186 (define_insn "zero_extendqidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{bl|x}\t{%1, %k0|%k0, %1}
3192    movz{bq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3195 \f
3196 ;; Sign extension instructions
3197
3198 (define_expand "extendsidi2"
3199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3200                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3201               (clobber (reg:CC FLAGS_REG))
3202               (clobber (match_scratch:SI 2 ""))])]
3203   ""
3204 {
3205   if (TARGET_64BIT)
3206     {
3207       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3208       DONE;
3209     }
3210 })
3211
3212 (define_insn "*extendsidi2_1"
3213   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3214         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3215    (clobber (reg:CC FLAGS_REG))
3216    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3217   "!TARGET_64BIT"
3218   "#")
3219
3220 (define_insn "extendsidi2_rex64"
3221   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3222         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3223   "TARGET_64BIT"
3224   "@
3225    {cltq|cdqe}
3226    movs{lq|x}\t{%1,%0|%0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")
3229    (set_attr "prefix_0f" "0")
3230    (set_attr "modrm" "0,1")])
3231
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3235   "TARGET_64BIT"
3236   "movs{wq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")])
3239
3240 (define_insn "extendqidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "TARGET_64BIT"
3244   "movs{bq|x}\t{%1,%0|%0, %1}"
3245    [(set_attr "type" "imovx")
3246     (set_attr "mode" "DI")])
3247
3248 ;; Extend to memory case when source register does die.
3249 (define_split 
3250   [(set (match_operand:DI 0 "memory_operand" "")
3251         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))
3253    (clobber (match_operand:SI 2 "register_operand" ""))]
3254   "(reload_completed
3255     && dead_or_set_p (insn, operands[1])
3256     && !reg_mentioned_p (operands[1], operands[0]))"
3257   [(set (match_dup 3) (match_dup 1))
3258    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3259               (clobber (reg:CC FLAGS_REG))])
3260    (set (match_dup 4) (match_dup 1))]
3261   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3262
3263 ;; Extend to memory case when source register does not die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "reload_completed"
3270   [(const_int 0)]
3271 {
3272   split_di (&operands[0], 1, &operands[3], &operands[4]);
3273
3274   emit_move_insn (operands[3], operands[1]);
3275
3276   /* Generate a cltd if possible and doing so it profitable.  */
3277   if (true_regnum (operands[1]) == 0
3278       && true_regnum (operands[2]) == 1
3279       && (optimize_size || TARGET_USE_CLTD))
3280     {
3281       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3282     }
3283   else
3284     {
3285       emit_move_insn (operands[2], operands[1]);
3286       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3287     }
3288   emit_move_insn (operands[4], operands[2]);
3289   DONE;
3290 })
3291
3292 ;; Extend to register case.  Optimize case where source and destination
3293 ;; registers match and cases where we can use cltd.
3294 (define_split 
3295   [(set (match_operand:DI 0 "register_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_scratch:SI 2 ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3305     emit_move_insn (operands[3], operands[1]);
3306
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[3]) == 0
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3312       DONE;
3313     }
3314
3315   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[4], operands[1]);
3317
3318   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3319   DONE;
3320 })
3321
3322 (define_insn "extendhisi2"
3323   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3324         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3325   ""
3326 {
3327   switch (get_attr_prefix_0f (insn))
3328     {
3329     case 0:
3330       return "{cwtl|cwde}";
3331     default:
3332       return "movs{wl|x}\t{%1,%0|%0, %1}";
3333     }
3334 }
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")
3337    (set (attr "prefix_0f")
3338      ;; movsx is short decodable while cwtl is vector decoded.
3339      (if_then_else (and (eq_attr "cpu" "!k6")
3340                         (eq_attr "alternative" "0"))
3341         (const_string "0")
3342         (const_string "1")))
3343    (set (attr "modrm")
3344      (if_then_else (eq_attr "prefix_0f" "0")
3345         (const_string "0")
3346         (const_string "1")))])
3347
3348 (define_insn "*extendhisi2_zext"
3349   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3350         (zero_extend:DI
3351           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3352   "TARGET_64BIT"
3353 {
3354   switch (get_attr_prefix_0f (insn))
3355     {
3356     case 0:
3357       return "{cwtl|cwde}";
3358     default:
3359       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3360     }
3361 }
3362   [(set_attr "type" "imovx")
3363    (set_attr "mode" "SI")
3364    (set (attr "prefix_0f")
3365      ;; movsx is short decodable while cwtl is vector decoded.
3366      (if_then_else (and (eq_attr "cpu" "!k6")
3367                         (eq_attr "alternative" "0"))
3368         (const_string "0")
3369         (const_string "1")))
3370    (set (attr "modrm")
3371      (if_then_else (eq_attr "prefix_0f" "0")
3372         (const_string "0")
3373         (const_string "1")))])
3374
3375 (define_insn "extendqihi2"
3376   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3378   ""
3379 {
3380   switch (get_attr_prefix_0f (insn))
3381     {
3382     case 0:
3383       return "{cbtw|cbw}";
3384     default:
3385       return "movs{bw|x}\t{%1,%0|%0, %1}";
3386     }
3387 }
3388   [(set_attr "type" "imovx")
3389    (set_attr "mode" "HI")
3390    (set (attr "prefix_0f")
3391      ;; movsx is short decodable while cwtl is vector decoded.
3392      (if_then_else (and (eq_attr "cpu" "!k6")
3393                         (eq_attr "alternative" "0"))
3394         (const_string "0")
3395         (const_string "1")))
3396    (set (attr "modrm")
3397      (if_then_else (eq_attr "prefix_0f" "0")
3398         (const_string "0")
3399         (const_string "1")))])
3400
3401 (define_insn "extendqisi2"
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3404   ""
3405   "movs{bl|x}\t{%1,%0|%0, %1}"
3406    [(set_attr "type" "imovx")
3407     (set_attr "mode" "SI")])
3408
3409 (define_insn "*extendqisi2_zext"
3410   [(set (match_operand:DI 0 "register_operand" "=r")
3411         (zero_extend:DI
3412           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3413   "TARGET_64BIT"
3414   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3417 \f
3418 ;; Conversions between float and double.
3419
3420 ;; These are all no-ops in the model used for the 80387.  So just
3421 ;; emit moves.
3422
3423 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3424 (define_insn "*dummy_extendsfdf2"
3425   [(set (match_operand:DF 0 "push_operand" "=<")
3426         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3427   "0"
3428   "#")
3429
3430 (define_split
3431   [(set (match_operand:DF 0 "push_operand" "")
3432         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3433   "!TARGET_64BIT"
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3435    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "TARGET_64BIT"
3441   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_insn "*dummy_extendsfxf2"
3445   [(set (match_operand:XF 0 "push_operand" "=<")
3446         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3447   "0"
3448   "#")
3449
3450 (define_split
3451   [(set (match_operand:XF 0 "push_operand" "")
3452         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3453   ""
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3455    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3456   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3463    (set (mem:DF (reg:DI 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:DF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:SI 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   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_expand "extendsfdf2"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3484         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3485   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3486 {
3487   /* ??? Needed for compress_float_constant since all fp constants
3488      are LEGITIMATE_CONSTANT_P.  */
3489   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3490     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3491   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3492     operands[1] = force_reg (SFmode, operands[1]);
3493 })
3494
3495 (define_insn "*extendsfdf2_mixed"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3497         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3499    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3500 {
3501   switch (which_alternative)
3502     {
3503     case 0:
3504       return output_387_reg_move (insn, operands);
3505
3506     case 1:
3507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3508         return "fstp%z0\t%y0";
3509       else
3510         return "fst%z0\t%y0";
3511
3512     case 2:
3513       return "cvtss2sd\t{%1, %0|%0, %1}";
3514
3515     default:
3516       abort ();
3517     }
3518 }
3519   [(set_attr "type" "fmov,fmov,ssecvt")
3520    (set_attr "mode" "SF,XF,DF")])
3521
3522 (define_insn "*extendsfdf2_sse"
3523   [(set (match_operand:DF 0 "register_operand" "=Y")
3524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3525   "TARGET_SSE2 && TARGET_SSE_MATH
3526    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3527   "cvtss2sd\t{%1, %0|%0, %1}"
3528   [(set_attr "type" "ssecvt")
3529    (set_attr "mode" "DF")])
3530
3531 (define_insn "*extendsfdf2_i387"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 {
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3541
3542     case 1:
3543       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0";
3545       else
3546         return "fst%z0\t%y0";
3547
3548     default:
3549       abort ();
3550     }
3551 }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extendsfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3558   "TARGET_80387"
3559 {
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (SFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extendsfxf2_i387"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3571   "TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       return output_387_reg_move (insn, operands);
3578
3579     case 1:
3580       /* There is no non-popping store to memory for XFmode.  So if
3581          we need one, follow the store with a load.  */
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586
3587     default:
3588       abort ();
3589     }
3590 }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3593
3594 (define_expand "extenddfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3597   "TARGET_80387"
3598 {
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (DFmode, operands[1]);
3605 })
3606
3607 (define_insn "*extenddfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3612 {
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3617
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0";
3625
3626     default:
3627       abort ();
3628     }
3629 }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "DF,XF")])
3632
3633 ;; %%% This seems bad bad news.
3634 ;; This cannot output into an f-reg because there is no way to be sure
3635 ;; of truncating in that case.  Otherwise this is just like a simple move
3636 ;; insn.  So we pretend we can output to a reg in order to get better
3637 ;; register preferencing, but we really use a stack slot.
3638
3639 ;; Conversion from DFmode to SFmode.
3640
3641 (define_expand "truncdfsf2"
3642   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3643         (float_truncate:SF
3644           (match_operand:DF 1 "nonimmediate_operand" "")))]
3645   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3646 {
3647   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3648     operands[1] = force_reg (DFmode, operands[1]);
3649
3650   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3651     ;
3652   else if (flag_unsafe_math_optimizations)
3653     ;
3654   else
3655     {
3656       rtx temp = assign_386_stack_local (SFmode, 0);
3657       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3658       DONE;
3659     }
3660 })
3661
3662 (define_expand "truncdfsf2_with_temp"
3663   [(parallel [(set (match_operand:SF 0 "" "")
3664                    (float_truncate:SF (match_operand:DF 1 "" "")))
3665               (clobber (match_operand:SF 2 "" ""))])]
3666   "")
3667
3668 (define_insn "*truncdfsf_fast_mixed"
3669   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3670         (float_truncate:SF
3671           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3672   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3673 {
3674   switch (which_alternative)
3675     {
3676     case 0:
3677       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678         return "fstp%z0\t%y0";
3679       else
3680         return "fst%z0\t%y0";
3681     case 1:
3682       return output_387_reg_move (insn, operands);
3683     case 2:
3684       return "cvtsd2ss\t{%1, %0|%0, %1}";
3685     default:
3686       abort ();
3687     }
3688 }
3689   [(set_attr "type" "fmov,fmov,ssecvt")
3690    (set_attr "mode" "SF")])
3691
3692 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3693 ;; because nothing we do here is unsafe.
3694 (define_insn "*truncdfsf_fast_sse"
3695   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3696         (float_truncate:SF
3697           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3698   "TARGET_SSE2 && TARGET_SSE_MATH"
3699   "cvtsd2ss\t{%1, %0|%0, %1}"
3700   [(set_attr "type" "ssecvt")
3701    (set_attr "mode" "SF")])
3702
3703 (define_insn "*truncdfsf_fast_i387"
3704   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3707   "TARGET_80387 && flag_unsafe_math_optimizations"
3708   "* return output_387_reg_move (insn, operands);"
3709   [(set_attr "type" "fmov")
3710    (set_attr "mode" "SF")])
3711
3712 (define_insn "*truncdfsf_mixed"
3713   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3714         (float_truncate:SF
3715           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3716    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3717   "TARGET_MIX_SSE_I387"
3718 {
3719   switch (which_alternative)
3720     {
3721     case 0:
3722       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723         return "fstp%z0\t%y0";
3724       else
3725         return "fst%z0\t%y0";
3726     case 1:
3727       return "#";
3728     case 2:
3729       return "cvtsd2ss\t{%1, %0|%0, %1}";
3730     default:
3731       abort ();
3732     }
3733 }
3734   [(set_attr "type" "fmov,multi,ssecvt")
3735    (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_i387"
3738   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3741    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3742   "TARGET_80387"
3743 {
3744   switch (which_alternative)
3745     {
3746     case 0:
3747       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748         return "fstp%z0\t%y0";
3749       else
3750         return "fst%z0\t%y0";
3751     case 1:
3752       return "#";
3753     default:
3754       abort ();
3755     }
3756 }
3757   [(set_attr "type" "fmov,multi")
3758    (set_attr "mode" "SF")])
3759
3760 (define_split
3761   [(set (match_operand:SF 0 "register_operand" "")
3762         (float_truncate:SF
3763          (match_operand:DF 1 "fp_register_operand" "")))
3764    (clobber (match_operand 2 "" ""))]
3765   "reload_completed"
3766   [(set (match_dup 2) (match_dup 1))
3767    (set (match_dup 0) (match_dup 2))]
3768 {
3769   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3770 })
3771
3772 ;; Conversion from XFmode to SFmode.
3773
3774 (define_expand "truncxfsf2"
3775   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3776                    (float_truncate:SF
3777                     (match_operand:XF 1 "register_operand" "")))
3778               (clobber (match_dup 2))])]
3779   "TARGET_80387"
3780 {
3781   if (flag_unsafe_math_optimizations)
3782     {
3783       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3784       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3785       if (reg != operands[0])
3786         emit_move_insn (operands[0], reg);
3787       DONE;
3788     }
3789   else
3790     operands[2] = assign_386_stack_local (SFmode, 0);
3791 })
3792
3793 (define_insn "*truncxfsf2_mixed"
3794   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3795         (float_truncate:SF
3796          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3797    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3798   "TARGET_MIX_SSE_I387"
3799 {
3800   switch (which_alternative)
3801     {
3802     case 0:
3803       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3804         return "fstp%z0\t%y0";
3805       else
3806         return "fst%z0\t%y0";
3807     default:
3808       abort();
3809     }
3810 }
3811   [(set_attr "type" "fmov,multi,multi,multi")
3812    (set_attr "mode" "SF")])
3813
3814 (define_insn "truncxfsf2_i387_noop"
3815   [(set (match_operand:SF 0 "register_operand" "=f")
3816         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3817   "TARGET_80387 && flag_unsafe_math_optimizations"
3818 {
3819   return output_387_reg_move (insn, operands);
3820 }
3821   [(set_attr "type" "fmov")
3822    (set_attr "mode" "SF")])
3823
3824 (define_insn "*truncxfsf2_i387"
3825   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3826         (float_truncate:SF
3827          (match_operand:XF 1 "register_operand" "f,f,f")))
3828    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3829   "TARGET_80387"
3830 {
3831   switch (which_alternative)
3832     {
3833     case 0:
3834       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835         return "fstp%z0\t%y0";
3836       else
3837         return "fst%z0\t%y0";
3838     default:
3839       abort ();
3840     }
3841 }
3842   [(set_attr "type" "fmov,multi,multi")
3843    (set_attr "mode" "SF")])
3844
3845 (define_insn "*truncxfsf2_i387_1"
3846   [(set (match_operand:SF 0 "memory_operand" "=m")
3847         (float_truncate:SF
3848          (match_operand:XF 1 "register_operand" "f")))]
3849   "TARGET_80387"
3850 {
3851   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3852     return "fstp%z0\t%y0";
3853   else
3854     return "fst%z0\t%y0";
3855 }
3856   [(set_attr "type" "fmov")
3857    (set_attr "mode" "SF")])
3858
3859 (define_split
3860   [(set (match_operand:SF 0 "register_operand" "")
3861         (float_truncate:SF
3862          (match_operand:XF 1 "register_operand" "")))
3863    (clobber (match_operand:SF 2 "memory_operand" ""))]
3864   "TARGET_80387 && reload_completed"
3865   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3866    (set (match_dup 0) (match_dup 2))]
3867   "")
3868
3869 (define_split
3870   [(set (match_operand:SF 0 "memory_operand" "")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "")))
3873    (clobber (match_operand:SF 2 "memory_operand" ""))]
3874   "TARGET_80387"
3875   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3876   "")
3877
3878 ;; Conversion from XFmode to DFmode.
3879
3880 (define_expand "truncxfdf2"
3881   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3882                    (float_truncate:DF
3883                     (match_operand:XF 1 "register_operand" "")))
3884               (clobber (match_dup 2))])]
3885   "TARGET_80387"
3886 {
3887   if (flag_unsafe_math_optimizations)
3888     {
3889       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3890       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3891       if (reg != operands[0])
3892         emit_move_insn (operands[0], reg);
3893       DONE;
3894     }
3895   else
3896     operands[2] = assign_386_stack_local (DFmode, 0);
3897 })
3898
3899 (define_insn "*truncxfdf2_mixed"
3900   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3901         (float_truncate:DF
3902          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3903    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3904   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3905 {
3906   switch (which_alternative)
3907     {
3908     case 0:
3909       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910         return "fstp%z0\t%y0";
3911       else
3912         return "fst%z0\t%y0";
3913     default:
3914       abort();
3915     }
3916   abort ();
3917 }
3918   [(set_attr "type" "fmov,multi,multi,multi")
3919    (set_attr "mode" "DF")])
3920
3921 (define_insn "truncxfdf2_i387_noop"
3922   [(set (match_operand:DF 0 "register_operand" "=f")
3923         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3924   "TARGET_80387 && flag_unsafe_math_optimizations"
3925 {
3926   return output_387_reg_move (insn, operands);
3927 }
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "DF")])
3930
3931 (define_insn "*truncxfdf2_i387"
3932   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3933         (float_truncate:DF
3934          (match_operand:XF 1 "register_operand" "f,f,f")))
3935    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3936   "TARGET_80387"
3937 {
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     default:
3946       abort ();
3947     }
3948 }
3949   [(set_attr "type" "fmov,multi,multi")
3950    (set_attr "mode" "DF")])
3951
3952 (define_insn "*truncxfdf2_i387_1"
3953   [(set (match_operand:DF 0 "memory_operand" "=m")
3954         (float_truncate:DF
3955           (match_operand:XF 1 "register_operand" "f")))]
3956   "TARGET_80387"
3957 {
3958   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3959     return "fstp%z0\t%y0";
3960   else
3961     return "fst%z0\t%y0";
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_split
3967   [(set (match_operand:DF 0 "register_operand" "")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "")))
3970    (clobber (match_operand:DF 2 "memory_operand" ""))]
3971   "TARGET_80387 && reload_completed"
3972   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3973    (set (match_dup 0) (match_dup 2))]
3974   "")
3975
3976 (define_split
3977   [(set (match_operand:DF 0 "memory_operand" "")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "")))
3980    (clobber (match_operand:DF 2 "memory_operand" ""))]
3981   "TARGET_80387"
3982   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3983   "")
3984 \f
3985 ;; %%% Break up all these bad boys.
3986
3987 ;; Signed conversion to DImode.
3988
3989 (define_expand "fix_truncxfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387"
3994   "")
3995
3996 (define_expand "fix_truncdfdi2"
3997   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3999               (clobber (reg:CC FLAGS_REG))])]
4000   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4001 {
4002   if (TARGET_64BIT && TARGET_SSE2)
4003    {
4004      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4005      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4006      if (out != operands[0])
4007         emit_move_insn (operands[0], out);
4008      DONE;
4009    }
4010 })
4011
4012 (define_expand "fix_truncsfdi2"
4013   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4014                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4015               (clobber (reg:CC FLAGS_REG))])] 
4016   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4017 {
4018   if (TARGET_SSE && TARGET_64BIT)
4019    {
4020      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4021      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4022      if (out != operands[0])
4023         emit_move_insn (operands[0], out);
4024      DONE;
4025    }
4026 })
4027
4028 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4029 ;; of the machinery.
4030 (define_insn_and_split "*fix_truncdi_1"
4031   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4032         (fix:DI (match_operand 1 "register_operand" "f,f")))
4033    (clobber (reg:CC FLAGS_REG))]
4034   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4035    && !reload_completed && !reload_in_progress
4036    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4037   "#"
4038   "&& 1"
4039   [(const_int 0)]
4040 {
4041   ix86_optimize_mode_switching = 1;
4042   operands[2] = assign_386_stack_local (HImode, 1);
4043   operands[3] = assign_386_stack_local (HImode, 2);
4044   if (memory_operand (operands[0], VOIDmode))
4045     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4046                                        operands[2], operands[3]));
4047   else
4048     {
4049       operands[4] = assign_386_stack_local (DImode, 0);
4050       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4051                                            operands[2], operands[3],
4052                                            operands[4]));
4053     }
4054   DONE;
4055 }
4056   [(set_attr "type" "fistp")
4057    (set_attr "i387_cw" "trunc")
4058    (set_attr "mode" "DI")])
4059
4060 (define_insn "fix_truncdi_nomemory"
4061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4062         (fix:DI (match_operand 1 "register_operand" "f,f")))
4063    (use (match_operand:HI 2 "memory_operand" "m,m"))
4064    (use (match_operand:HI 3 "memory_operand" "m,m"))
4065    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4066    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4067   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4069   "#"
4070   [(set_attr "type" "fistp")
4071    (set_attr "i387_cw" "trunc")
4072    (set_attr "mode" "DI")])
4073
4074 (define_insn "fix_truncdi_memory"
4075   [(set (match_operand:DI 0 "memory_operand" "=m")
4076         (fix:DI (match_operand 1 "register_operand" "f")))
4077    (use (match_operand:HI 2 "memory_operand" "m"))
4078    (use (match_operand:HI 3 "memory_operand" "m"))
4079    (clobber (match_scratch:DF 4 "=&1f"))]
4080   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082   "* return output_fix_trunc (insn, operands);"
4083   [(set_attr "type" "fistp")
4084    (set_attr "i387_cw" "trunc")
4085    (set_attr "mode" "DI")])
4086
4087 (define_split 
4088   [(set (match_operand:DI 0 "register_operand" "")
4089         (fix:DI (match_operand 1 "register_operand" "")))
4090    (use (match_operand:HI 2 "memory_operand" ""))
4091    (use (match_operand:HI 3 "memory_operand" ""))
4092    (clobber (match_operand:DI 4 "memory_operand" ""))
4093    (clobber (match_scratch 5 ""))]
4094   "reload_completed"
4095   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4096               (use (match_dup 2))
4097               (use (match_dup 3))
4098               (clobber (match_dup 5))])
4099    (set (match_dup 0) (match_dup 4))]
4100   "")
4101
4102 (define_split 
4103   [(set (match_operand:DI 0 "memory_operand" "")
4104         (fix:DI (match_operand 1 "register_operand" "")))
4105    (use (match_operand:HI 2 "memory_operand" ""))
4106    (use (match_operand:HI 3 "memory_operand" ""))
4107    (clobber (match_operand:DI 4 "memory_operand" ""))
4108    (clobber (match_scratch 5 ""))]
4109   "reload_completed"
4110   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4111               (use (match_dup 2))
4112               (use (match_dup 3))
4113               (clobber (match_dup 5))])]
4114   "")
4115
4116 ;; When SSE available, it is always faster to use it!
4117 (define_insn "fix_truncsfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4120   "TARGET_64BIT && TARGET_SSE"
4121   "cvttss2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "SF")
4124    (set_attr "athlon_decode" "double,vector")])
4125
4126 ;; Avoid vector decoded form of the instruction.
4127 (define_peephole2
4128   [(match_scratch:SF 2 "x")
4129    (set (match_operand:DI 0 "register_operand" "")
4130         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4131   "TARGET_K8 && !optimize_size"
4132   [(set (match_dup 2) (match_dup 1))
4133    (set (match_dup 0) (fix:DI (match_dup 2)))]
4134   "")
4135
4136 (define_insn "fix_truncdfdi_sse"
4137   [(set (match_operand:DI 0 "register_operand" "=r,r")
4138         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4139   "TARGET_64BIT && TARGET_SSE2"
4140   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4141   [(set_attr "type" "sseicvt,sseicvt")
4142    (set_attr "mode" "DF")
4143    (set_attr "athlon_decode" "double,vector")])
4144
4145 ;; Avoid vector decoded form of the instruction.
4146 (define_peephole2
4147   [(match_scratch:DF 2 "Y")
4148    (set (match_operand:DI 0 "register_operand" "")
4149         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4150   "TARGET_K8 && !optimize_size"
4151   [(set (match_dup 2) (match_dup 1))
4152    (set (match_dup 0) (fix:DI (match_dup 2)))]
4153   "")
4154
4155 ;; Signed conversion to SImode.
4156
4157 (define_expand "fix_truncxfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387"
4162   "")
4163
4164 (define_expand "fix_truncdfsi2"
4165   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4166                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4167               (clobber (reg:CC FLAGS_REG))])]
4168   "TARGET_80387 || TARGET_SSE2"
4169 {
4170   if (TARGET_SSE2)
4171    {
4172      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4173      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4174      if (out != operands[0])
4175         emit_move_insn (operands[0], out);
4176      DONE;
4177    }
4178 })
4179
4180 (define_expand "fix_truncsfsi2"
4181   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4182                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4183               (clobber (reg:CC FLAGS_REG))])] 
4184   "TARGET_80387 || TARGET_SSE"
4185 {
4186   if (TARGET_SSE)
4187    {
4188      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4189      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4190      if (out != operands[0])
4191         emit_move_insn (operands[0], out);
4192      DONE;
4193    }
4194 })
4195
4196 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4197 ;; of the machinery.
4198 (define_insn_and_split "*fix_truncsi_1"
4199   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4200         (fix:SI (match_operand 1 "register_operand" "f,f")))
4201    (clobber (reg:CC FLAGS_REG))]
4202   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4203    && !reload_completed && !reload_in_progress
4204    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4205   "#"
4206   "&& 1"
4207   [(const_int 0)]
4208 {
4209   ix86_optimize_mode_switching = 1;
4210   operands[2] = assign_386_stack_local (HImode, 1);
4211   operands[3] = assign_386_stack_local (HImode, 2);
4212   if (memory_operand (operands[0], VOIDmode))
4213     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4214                                        operands[2], operands[3]));
4215   else
4216     {
4217       operands[4] = assign_386_stack_local (SImode, 0);
4218       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4219                                            operands[2], operands[3],
4220                                            operands[4]));
4221     }
4222   DONE;
4223 }
4224   [(set_attr "type" "fistp")
4225    (set_attr "i387_cw" "trunc")
4226    (set_attr "mode" "SI")])
4227
4228 (define_insn "fix_truncsi_nomemory"
4229   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4230         (fix:SI (match_operand 1 "register_operand" "f,f")))
4231    (use (match_operand:HI 2 "memory_operand" "m,m"))
4232    (use (match_operand:HI 3 "memory_operand" "m,m"))
4233    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4234   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4235    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4236   "#"
4237   [(set_attr "type" "fistp")
4238    (set_attr "i387_cw" "trunc")
4239    (set_attr "mode" "SI")])
4240
4241 (define_insn "fix_truncsi_memory"
4242   [(set (match_operand:SI 0 "memory_operand" "=m")
4243         (fix:SI (match_operand 1 "register_operand" "f")))
4244    (use (match_operand:HI 2 "memory_operand" "m"))
4245    (use (match_operand:HI 3 "memory_operand" "m"))]
4246   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4247    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4248   "* return output_fix_trunc (insn, operands);"
4249   [(set_attr "type" "fistp")
4250    (set_attr "i387_cw" "trunc")
4251    (set_attr "mode" "SI")])
4252
4253 ;; When SSE available, it is always faster to use it!
4254 (define_insn "fix_truncsfsi_sse"
4255   [(set (match_operand:SI 0 "register_operand" "=r,r")
4256         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4257   "TARGET_SSE"
4258   "cvttss2si\t{%1, %0|%0, %1}"
4259   [(set_attr "type" "sseicvt")
4260    (set_attr "mode" "DF")
4261    (set_attr "athlon_decode" "double,vector")])
4262
4263 ;; Avoid vector decoded form of the instruction.
4264 (define_peephole2
4265   [(match_scratch:SF 2 "x")
4266    (set (match_operand:SI 0 "register_operand" "")
4267         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4268   "TARGET_K8 && !optimize_size"
4269   [(set (match_dup 2) (match_dup 1))
4270    (set (match_dup 0) (fix:SI (match_dup 2)))]
4271   "")
4272
4273 (define_insn "fix_truncdfsi_sse"
4274   [(set (match_operand:SI 0 "register_operand" "=r,r")
4275         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4276   "TARGET_SSE2"
4277   "cvttsd2si\t{%1, %0|%0, %1}"
4278   [(set_attr "type" "sseicvt")
4279    (set_attr "mode" "DF")
4280    (set_attr "athlon_decode" "double,vector")])
4281
4282 ;; Avoid vector decoded form of the instruction.
4283 (define_peephole2
4284   [(match_scratch:DF 2 "Y")
4285    (set (match_operand:SI 0 "register_operand" "")
4286         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4287   "TARGET_K8 && !optimize_size"
4288   [(set (match_dup 2) (match_dup 1))
4289    (set (match_dup 0) (fix:SI (match_dup 2)))]
4290   "")
4291
4292 (define_split 
4293   [(set (match_operand:SI 0 "register_operand" "")
4294         (fix:SI (match_operand 1 "register_operand" "")))
4295    (use (match_operand:HI 2 "memory_operand" ""))
4296    (use (match_operand:HI 3 "memory_operand" ""))
4297    (clobber (match_operand:SI 4 "memory_operand" ""))]
4298   "reload_completed"
4299   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4300               (use (match_dup 2))
4301               (use (match_dup 3))])
4302    (set (match_dup 0) (match_dup 4))]
4303   "")
4304
4305 (define_split 
4306   [(set (match_operand:SI 0 "memory_operand" "")
4307         (fix:SI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:SI 4 "memory_operand" ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])]
4315   "")
4316
4317 ;; Signed conversion to HImode.
4318
4319 (define_expand "fix_truncxfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])] 
4323   "TARGET_80387"
4324   "")
4325
4326 (define_expand "fix_truncdfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4329               (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE2"
4331   "")
4332
4333 (define_expand "fix_truncsfhi2"
4334   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4336                (clobber (reg:CC FLAGS_REG))])]
4337   "TARGET_80387 && !TARGET_SSE"
4338   "")
4339
4340 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4341 ;; of the machinery.
4342 (define_insn_and_split "*fix_trunchi_1"
4343   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4344         (fix:HI (match_operand 1 "register_operand" "f,f")))
4345    (clobber (reg:CC FLAGS_REG))]
4346   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4347    && !reload_completed && !reload_in_progress
4348    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4349   "#"
4350   "&& 1"
4351   [(const_int 0)]
4352 {
4353   ix86_optimize_mode_switching = 1;
4354   operands[2] = assign_386_stack_local (HImode, 1);
4355   operands[3] = assign_386_stack_local (HImode, 2);
4356   if (memory_operand (operands[0], VOIDmode))
4357     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4358                                        operands[2], operands[3]));
4359   else
4360     {
4361       operands[4] = assign_386_stack_local (HImode, 0);
4362       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4363                                            operands[2], operands[3],
4364                                            operands[4]));
4365     }
4366   DONE;
4367 }
4368   [(set_attr "type" "fistp")
4369    (set_attr "i387_cw" "trunc")
4370    (set_attr "mode" "HI")])
4371
4372 (define_insn "fix_trunchi_nomemory"
4373   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4374         (fix:HI (match_operand 1 "register_operand" "f,f")))
4375    (use (match_operand:HI 2 "memory_operand" "m,m"))
4376    (use (match_operand:HI 3 "memory_operand" "m,m"))
4377    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4378   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   [(set_attr "type" "fistp")
4382    (set_attr "i387_cw" "trunc")
4383    (set_attr "mode" "HI")])
4384
4385 (define_insn "fix_trunchi_memory"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (fix:HI (match_operand 1 "register_operand" "f")))
4388    (use (match_operand:HI 2 "memory_operand" "m"))
4389    (use (match_operand:HI 3 "memory_operand" "m"))]
4390   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4391    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4392   "* return output_fix_trunc (insn, operands);"
4393   [(set_attr "type" "fistp")
4394    (set_attr "i387_cw" "trunc")
4395    (set_attr "mode" "HI")])
4396
4397 (define_split 
4398   [(set (match_operand:HI 0 "memory_operand" "")
4399         (fix:HI (match_operand 1 "register_operand" "")))
4400    (use (match_operand:HI 2 "memory_operand" ""))
4401    (use (match_operand:HI 3 "memory_operand" ""))
4402    (clobber (match_operand:HI 4 "memory_operand" ""))]
4403   "reload_completed"
4404   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4405               (use (match_dup 2))
4406               (use (match_dup 3))])]
4407   "")
4408
4409 (define_split 
4410   [(set (match_operand:HI 0 "register_operand" "")
4411         (fix:HI (match_operand 1 "register_operand" "")))
4412    (use (match_operand:HI 2 "memory_operand" ""))
4413    (use (match_operand:HI 3 "memory_operand" ""))
4414    (clobber (match_operand:HI 4 "memory_operand" ""))]
4415   "reload_completed"
4416   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4417               (use (match_dup 2))
4418               (use (match_dup 3))
4419               (clobber (match_dup 4))])
4420    (set (match_dup 0) (match_dup 4))]
4421   "")
4422
4423 (define_insn "x86_fnstcw_1"
4424   [(set (match_operand:HI 0 "memory_operand" "=m")
4425         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4426   "TARGET_80387"
4427   "fnstcw\t%0"
4428   [(set_attr "length" "2")
4429    (set_attr "mode" "HI")
4430    (set_attr "unit" "i387")])
4431
4432 (define_insn "x86_fldcw_1"
4433   [(set (reg:HI FPSR_REG)
4434         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4435   "TARGET_80387"
4436   "fldcw\t%0"
4437   [(set_attr "length" "2")
4438    (set_attr "mode" "HI")
4439    (set_attr "unit" "i387")
4440    (set_attr "athlon_decode" "vector")])
4441 \f
4442 ;; Conversion between fixed point and floating point.
4443
4444 ;; Even though we only accept memory inputs, the backend _really_
4445 ;; wants to be able to do this between registers.
4446
4447 (define_expand "floathisf2"
4448   [(set (match_operand:SF 0 "register_operand" "")
4449         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4450   "TARGET_80387 || TARGET_SSE_MATH"
4451 {
4452   if (TARGET_SSE_MATH)
4453     {
4454       emit_insn (gen_floatsisf2 (operands[0],
4455                                  convert_to_mode (SImode, operands[1], 0)));
4456       DONE;
4457     }
4458 })
4459
4460 (define_insn "*floathisf2_i387"
4461   [(set (match_operand:SF 0 "register_operand" "=f,f")
4462         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4463   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4464   "@
4465    fild%z1\t%1
4466    #"
4467   [(set_attr "type" "fmov,multi")
4468    (set_attr "mode" "SF")
4469    (set_attr "fp_int_src" "true")])
4470
4471 (define_expand "floatsisf2"
4472   [(set (match_operand:SF 0 "register_operand" "")
4473         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4474   "TARGET_80387 || TARGET_SSE_MATH"
4475   "")
4476
4477 (define_insn "*floatsisf2_mixed"
4478   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4479         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4480   "TARGET_MIX_SSE_I387"
4481   "@
4482    fild%z1\t%1
4483    #
4484    cvtsi2ss\t{%1, %0|%0, %1}
4485    cvtsi2ss\t{%1, %0|%0, %1}"
4486   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4487    (set_attr "mode" "SF")
4488    (set_attr "athlon_decode" "*,*,vector,double")
4489    (set_attr "fp_int_src" "true")])
4490
4491 (define_insn "*floatsisf2_sse"
4492   [(set (match_operand:SF 0 "register_operand" "=x,x")
4493         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4494   "TARGET_SSE_MATH"
4495   "cvtsi2ss\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "athlon_decode" "vector,double")
4499    (set_attr "fp_int_src" "true")])
4500
4501 (define_insn "*floatsisf2_i387"
4502   [(set (match_operand:SF 0 "register_operand" "=f,f")
4503         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4504   "TARGET_80387"
4505   "@
4506    fild%z1\t%1
4507    #"
4508   [(set_attr "type" "fmov,multi")
4509    (set_attr "mode" "SF")
4510    (set_attr "fp_int_src" "true")])
4511
4512 (define_expand "floatdisf2"
4513   [(set (match_operand:SF 0 "register_operand" "")
4514         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4515   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4516   "")
4517
4518 (define_insn "*floatdisf2_mixed"
4519   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4520         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4521   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4522   "@
4523    fild%z1\t%1
4524    #
4525    cvtsi2ss{q}\t{%1, %0|%0, %1}
4526    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4527   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4528    (set_attr "mode" "SF")
4529    (set_attr "athlon_decode" "*,*,vector,double")
4530    (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatdisf2_sse"
4533   [(set (match_operand:SF 0 "register_operand" "=x,x")
4534         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4535   "TARGET_64BIT && TARGET_SSE_MATH"
4536   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "athlon_decode" "vector,double")
4540    (set_attr "fp_int_src" "true")])
4541
4542 (define_insn "*floatdisf2_i387"
4543   [(set (match_operand:SF 0 "register_operand" "=f,f")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4545   "TARGET_80387"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "SF")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557 {
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4564 })
4565
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_expand "floatsidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4582
4583 (define_insn "*floatsidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd\t{%1, %0|%0, %1}
4591    cvtsi2sd\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "athlon_decode" "*,*,double,direct")
4595    (set_attr "fp_int_src" "true")])
4596
4597 (define_insn "*floatsidf2_sse"
4598   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4600   "TARGET_SSE2 && TARGET_SSE_MATH"
4601   "cvtsi2sd\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "athlon_decode" "double,direct")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_insn "*floatsidf2_i387"
4608   [(set (match_operand:DF 0 "register_operand" "=f,f")
4609         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4610   "TARGET_80387"
4611   "@
4612    fild%z1\t%1
4613    #"
4614   [(set_attr "type" "fmov,multi")
4615    (set_attr "mode" "DF")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_expand "floatdidf2"
4619   [(set (match_operand:DF 0 "register_operand" "")
4620         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4622   "")
4623
4624 (define_insn "*floatdidf2_mixed"
4625   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4626         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4628   "@
4629    fild%z1\t%1
4630    #
4631    cvtsi2sd{q}\t{%1, %0|%0, %1}
4632    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634    (set_attr "mode" "DF")
4635    (set_attr "athlon_decode" "*,*,double,direct")
4636    (set_attr "fp_int_src" "true")])
4637
4638 (define_insn "*floatdidf2_sse"
4639   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4641   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4642   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4643   [(set_attr "type" "sseicvt")
4644    (set_attr "mode" "DF")
4645    (set_attr "athlon_decode" "double,direct")
4646    (set_attr "fp_int_src" "true")])
4647
4648 (define_insn "*floatdidf2_i387"
4649   [(set (match_operand:DF 0 "register_operand" "=f,f")
4650         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4651   "TARGET_80387"
4652   "@
4653    fild%z1\t%1
4654    #"
4655   [(set_attr "type" "fmov,multi")
4656    (set_attr "mode" "DF")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floathixf2"
4660   [(set (match_operand:XF 0 "register_operand" "=f,f")
4661         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "XF")
4668    (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "floatsixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "floatdixf2"
4682   [(set (match_operand:XF 0 "register_operand" "=f,f")
4683         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "XF")
4690    (set_attr "fp_int_src" "true")])
4691
4692 ;; %%% Kill these when reload knows how to do it.
4693 (define_split
4694   [(set (match_operand 0 "fp_register_operand" "")
4695         (float (match_operand 1 "register_operand" "")))]
4696   "reload_completed
4697    && TARGET_80387
4698    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4699   [(const_int 0)]
4700 {
4701   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4702   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4703   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4704   ix86_free_from_memory (GET_MODE (operands[1]));
4705   DONE;
4706 })
4707
4708 (define_expand "floatunssisf2"
4709   [(use (match_operand:SF 0 "register_operand" ""))
4710    (use (match_operand:SI 1 "register_operand" ""))]
4711   "!TARGET_64BIT && TARGET_SSE_MATH"
4712   "x86_emit_floatuns (operands); DONE;")
4713
4714 (define_expand "floatunsdisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:DI 1 "register_operand" ""))]
4717   "TARGET_64BIT && TARGET_SSE_MATH"
4718   "x86_emit_floatuns (operands); DONE;")
4719
4720 (define_expand "floatunsdidf2"
4721   [(use (match_operand:DF 0 "register_operand" ""))
4722    (use (match_operand:DI 1 "register_operand" ""))]
4723   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4724   "x86_emit_floatuns (operands); DONE;")
4725 \f
4726 ;; SSE extract/set expanders
4727
4728 (define_expand "vec_setv2df"
4729   [(match_operand:V2DF 0 "register_operand" "")
4730    (match_operand:DF 1 "register_operand" "")
4731    (match_operand 2 "const_int_operand" "")]
4732   "TARGET_SSE2"
4733 {
4734   switch (INTVAL (operands[2]))
4735     {
4736     case 0:
4737       emit_insn (gen_sse2_loadlpd (operands[0], operands[0], operands[1]));
4738       break;
4739     case 1:
4740       emit_insn (gen_sse2_loadhpd (operands[0], operands[0], operands[1]));
4741       break;
4742     default:
4743       abort ();
4744     }
4745   DONE;
4746 })
4747
4748 (define_expand "vec_extractv2df"
4749   [(match_operand:DF 0 "register_operand" "")
4750    (match_operand:V2DF 1 "register_operand" "")
4751    (match_operand 2 "const_int_operand" "")]
4752   "TARGET_SSE2"
4753 {
4754   switch (INTVAL (operands[2]))
4755     {
4756     case 0:
4757       emit_insn (gen_sse2_storelpd (operands[0], operands[1]));
4758       break;
4759     case 1:
4760       emit_insn (gen_sse2_storehpd (operands[0], operands[1]));
4761       break;
4762     default:
4763       abort ();
4764     }
4765   DONE;
4766 })
4767
4768 (define_expand "vec_initv2df"
4769   [(match_operand:V2DF 0 "register_operand" "")
4770    (match_operand 1 "" "")]
4771   "TARGET_SSE2"
4772 {
4773   ix86_expand_vector_init (operands[0], operands[1]);
4774   DONE;
4775 })
4776
4777 (define_expand "vec_setv4sf"
4778   [(match_operand:V4SF 0 "register_operand" "")
4779    (match_operand:SF 1 "register_operand" "")
4780    (match_operand 2 "const_int_operand" "")]
4781   "TARGET_SSE"
4782 {
4783   switch (INTVAL (operands[2]))
4784     {
4785     case 0:
4786       emit_insn (gen_sse_movss (operands[0], operands[0],
4787                                 simplify_gen_subreg (V4SFmode, operands[1],
4788                                                      SFmode, 0)));
4789       break;
4790     case 1:
4791       {
4792         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4793         rtx tmp = gen_reg_rtx (V4SFmode);
4794  
4795         emit_move_insn (tmp, operands[0]);
4796         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4797         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4798         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4799                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4800       }
4801       break;
4802     case 2:
4803       {
4804         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4805         rtx tmp = gen_reg_rtx (V4SFmode);
4806
4807         emit_move_insn (tmp, operands[0]);
4808         emit_insn (gen_sse_movss (tmp, tmp, op1));
4809         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4810                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4811       }
4812       break;
4813     case 3:
4814       {
4815         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4816         rtx tmp = gen_reg_rtx (V4SFmode);
4817
4818         emit_move_insn (tmp, operands[0]);
4819         emit_insn (gen_sse_movss (tmp, tmp, op1));
4820         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4821                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4822       }
4823       break;
4824     default:
4825       abort ();
4826     }
4827   DONE;
4828 })
4829
4830 (define_expand "vec_extractv4sf"
4831   [(match_operand:SF 0 "register_operand" "")
4832    (match_operand:V4SF 1 "register_operand" "")
4833    (match_operand 2 "const_int_operand" "")]
4834   "TARGET_SSE"
4835 {
4836   switch (INTVAL (operands[2]))
4837     {
4838     case 0:
4839       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4840       break;
4841     case 1:
4842       {
4843         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4844         rtx tmp = gen_reg_rtx (V4SFmode);
4845  
4846         emit_move_insn (tmp, operands[1]);
4847         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4848                                    const1_rtx));
4849       }
4850       break;
4851     case 2:
4852       {
4853         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4854         rtx tmp = gen_reg_rtx (V4SFmode);
4855  
4856         emit_move_insn (tmp, operands[1]);
4857         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4858       }
4859       break;
4860     case 3:
4861       {
4862         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4863         rtx tmp = gen_reg_rtx (V4SFmode);
4864  
4865         emit_move_insn (tmp, operands[1]);
4866         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4867                                    GEN_INT (3)));
4868       }
4869       break;
4870     default:
4871       abort ();
4872     }
4873   DONE;
4874 })
4875
4876 (define_expand "vec_initv4sf"
4877   [(match_operand:V4SF 0 "register_operand" "")
4878    (match_operand 1 "" "")]
4879   "TARGET_SSE"
4880 {
4881   ix86_expand_vector_init (operands[0], operands[1]);
4882   DONE;
4883 })
4884 \f
4885 ;; Add instructions
4886
4887 ;; %%% splits for addsidi3
4888 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4889 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4890 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4891
4892 (define_expand "adddi3"
4893   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4894         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4895                  (match_operand:DI 2 "x86_64_general_operand" "")))
4896    (clobber (reg:CC FLAGS_REG))]
4897   ""
4898   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4899
4900 (define_insn "*adddi3_1"
4901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4902         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4903                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4904    (clobber (reg:CC FLAGS_REG))]
4905   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4906   "#")
4907
4908 (define_split
4909   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4910         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4911                  (match_operand:DI 2 "general_operand" "")))
4912    (clobber (reg:CC FLAGS_REG))]
4913   "!TARGET_64BIT && reload_completed"
4914   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4915                                           UNSPEC_ADD_CARRY))
4916               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4917    (parallel [(set (match_dup 3)
4918                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4919                                      (match_dup 4))
4920                             (match_dup 5)))
4921               (clobber (reg:CC FLAGS_REG))])]
4922   "split_di (operands+0, 1, operands+0, operands+3);
4923    split_di (operands+1, 1, operands+1, operands+4);
4924    split_di (operands+2, 1, operands+2, operands+5);")
4925
4926 (define_insn "adddi3_carry_rex64"
4927   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4928           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4929                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4930                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4931    (clobber (reg:CC FLAGS_REG))]
4932   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4933   "adc{q}\t{%2, %0|%0, %2}"
4934   [(set_attr "type" "alu")
4935    (set_attr "pent_pair" "pu")
4936    (set_attr "mode" "DI")])
4937
4938 (define_insn "*adddi3_cc_rex64"
4939   [(set (reg:CC FLAGS_REG)
4940         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4941                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4942                    UNSPEC_ADD_CARRY))
4943    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4944         (plus:DI (match_dup 1) (match_dup 2)))]
4945   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4946   "add{q}\t{%2, %0|%0, %2}"
4947   [(set_attr "type" "alu")
4948    (set_attr "mode" "DI")])
4949
4950 (define_insn "addqi3_carry"
4951   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4952           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4953                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4954                    (match_operand:QI 2 "general_operand" "qi,qm")))
4955    (clobber (reg:CC FLAGS_REG))]
4956   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4957   "adc{b}\t{%2, %0|%0, %2}"
4958   [(set_attr "type" "alu")
4959    (set_attr "pent_pair" "pu")
4960    (set_attr "mode" "QI")])
4961
4962 (define_insn "addhi3_carry"
4963   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4964           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4965                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4966                    (match_operand:HI 2 "general_operand" "ri,rm")))
4967    (clobber (reg:CC FLAGS_REG))]
4968   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4969   "adc{w}\t{%2, %0|%0, %2}"
4970   [(set_attr "type" "alu")
4971    (set_attr "pent_pair" "pu")
4972    (set_attr "mode" "HI")])
4973
4974 (define_insn "addsi3_carry"
4975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4976           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4977                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4978                    (match_operand:SI 2 "general_operand" "ri,rm")))
4979    (clobber (reg:CC FLAGS_REG))]
4980   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4981   "adc{l}\t{%2, %0|%0, %2}"
4982   [(set_attr "type" "alu")
4983    (set_attr "pent_pair" "pu")
4984    (set_attr "mode" "SI")])
4985
4986 (define_insn "*addsi3_carry_zext"
4987   [(set (match_operand:DI 0 "register_operand" "=r")
4988           (zero_extend:DI 
4989             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4990                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4991                      (match_operand:SI 2 "general_operand" "rim"))))
4992    (clobber (reg:CC FLAGS_REG))]
4993   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4994   "adc{l}\t{%2, %k0|%k0, %2}"
4995   [(set_attr "type" "alu")
4996    (set_attr "pent_pair" "pu")
4997    (set_attr "mode" "SI")])
4998
4999 (define_insn "*addsi3_cc"
5000   [(set (reg:CC FLAGS_REG)
5001         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5002                     (match_operand:SI 2 "general_operand" "ri,rm")]
5003                    UNSPEC_ADD_CARRY))
5004    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5005         (plus:SI (match_dup 1) (match_dup 2)))]
5006   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5007   "add{l}\t{%2, %0|%0, %2}"
5008   [(set_attr "type" "alu")
5009    (set_attr "mode" "SI")])
5010
5011 (define_insn "addqi3_cc"
5012   [(set (reg:CC FLAGS_REG)
5013         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5014                     (match_operand:QI 2 "general_operand" "qi,qm")]
5015                    UNSPEC_ADD_CARRY))
5016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5017         (plus:QI (match_dup 1) (match_dup 2)))]
5018   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5019   "add{b}\t{%2, %0|%0, %2}"
5020   [(set_attr "type" "alu")
5021    (set_attr "mode" "QI")])
5022
5023 (define_expand "addsi3"
5024   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5025                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5026                             (match_operand:SI 2 "general_operand" "")))
5027               (clobber (reg:CC FLAGS_REG))])]
5028   ""
5029   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5030
5031 (define_insn "*lea_1"
5032   [(set (match_operand:SI 0 "register_operand" "=r")
5033         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5034   "!TARGET_64BIT"
5035   "lea{l}\t{%a1, %0|%0, %a1}"
5036   [(set_attr "type" "lea")
5037    (set_attr "mode" "SI")])
5038
5039 (define_insn "*lea_1_rex64"
5040   [(set (match_operand:SI 0 "register_operand" "=r")
5041         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5042   "TARGET_64BIT"
5043   "lea{l}\t{%a1, %0|%0, %a1}"
5044   [(set_attr "type" "lea")
5045    (set_attr "mode" "SI")])
5046
5047 (define_insn "*lea_1_zext"
5048   [(set (match_operand:DI 0 "register_operand" "=r")
5049         (zero_extend:DI
5050          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5051   "TARGET_64BIT"
5052   "lea{l}\t{%a1, %k0|%k0, %a1}"
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn "*lea_2_rex64"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5059   "TARGET_64BIT"
5060   "lea{q}\t{%a1, %0|%0, %a1}"
5061   [(set_attr "type" "lea")
5062    (set_attr "mode" "DI")])
5063
5064 ;; The lea patterns for non-Pmodes needs to be matched by several
5065 ;; insns converted to real lea by splitters.
5066
5067 (define_insn_and_split "*lea_general_1"
5068   [(set (match_operand 0 "register_operand" "=r")
5069         (plus (plus (match_operand 1 "index_register_operand" "l")
5070                     (match_operand 2 "register_operand" "r"))
5071               (match_operand 3 "immediate_operand" "i")))]
5072   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5073     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5074    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5075    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5076    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5077    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5078        || GET_MODE (operands[3]) == VOIDmode)"
5079   "#"
5080   "&& reload_completed"
5081   [(const_int 0)]
5082 {
5083   rtx pat;
5084   operands[0] = gen_lowpart (SImode, operands[0]);
5085   operands[1] = gen_lowpart (Pmode, operands[1]);
5086   operands[2] = gen_lowpart (Pmode, operands[2]);
5087   operands[3] = gen_lowpart (Pmode, operands[3]);
5088   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5089                       operands[3]);
5090   if (Pmode != SImode)
5091     pat = gen_rtx_SUBREG (SImode, pat, 0);
5092   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5093   DONE;
5094 }
5095   [(set_attr "type" "lea")
5096    (set_attr "mode" "SI")])
5097
5098 (define_insn_and_split "*lea_general_1_zext"
5099   [(set (match_operand:DI 0 "register_operand" "=r")
5100         (zero_extend:DI
5101           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5102                             (match_operand:SI 2 "register_operand" "r"))
5103                    (match_operand:SI 3 "immediate_operand" "i"))))]
5104   "TARGET_64BIT"
5105   "#"
5106   "&& reload_completed"
5107   [(set (match_dup 0)
5108         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5109                                                      (match_dup 2))
5110                                             (match_dup 3)) 0)))]
5111 {
5112   operands[1] = gen_lowpart (Pmode, operands[1]);
5113   operands[2] = gen_lowpart (Pmode, operands[2]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5115 }
5116   [(set_attr "type" "lea")
5117    (set_attr "mode" "SI")])
5118
5119 (define_insn_and_split "*lea_general_2"
5120   [(set (match_operand 0 "register_operand" "=r")
5121         (plus (mult (match_operand 1 "index_register_operand" "l")
5122                     (match_operand 2 "const248_operand" "i"))
5123               (match_operand 3 "nonmemory_operand" "ri")))]
5124   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5125     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5126    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5127    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5128    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5129        || GET_MODE (operands[3]) == VOIDmode)"
5130   "#"
5131   "&& reload_completed"
5132   [(const_int 0)]
5133 {
5134   rtx pat;
5135   operands[0] = gen_lowpart (SImode, operands[0]);
5136   operands[1] = gen_lowpart (Pmode, operands[1]);
5137   operands[3] = gen_lowpart (Pmode, operands[3]);
5138   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5139                       operands[3]);
5140   if (Pmode != SImode)
5141     pat = gen_rtx_SUBREG (SImode, pat, 0);
5142   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5143   DONE;
5144 }
5145   [(set_attr "type" "lea")
5146    (set_attr "mode" "SI")])
5147
5148 (define_insn_and_split "*lea_general_2_zext"
5149   [(set (match_operand:DI 0 "register_operand" "=r")
5150         (zero_extend:DI
5151           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5152                             (match_operand:SI 2 "const248_operand" "n"))
5153                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5154   "TARGET_64BIT"
5155   "#"
5156   "&& reload_completed"
5157   [(set (match_dup 0)
5158         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5159                                                      (match_dup 2))
5160                                             (match_dup 3)) 0)))]
5161 {
5162   operands[1] = gen_lowpart (Pmode, operands[1]);
5163   operands[3] = gen_lowpart (Pmode, operands[3]);
5164 }
5165   [(set_attr "type" "lea")
5166    (set_attr "mode" "SI")])
5167
5168 (define_insn_and_split "*lea_general_3"
5169   [(set (match_operand 0 "register_operand" "=r")
5170         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5171                           (match_operand 2 "const248_operand" "i"))
5172                     (match_operand 3 "register_operand" "r"))
5173               (match_operand 4 "immediate_operand" "i")))]
5174   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5175     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5176    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5177    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5178    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5179   "#"
5180   "&& reload_completed"
5181   [(const_int 0)]
5182 {
5183   rtx pat;
5184   operands[0] = gen_lowpart (SImode, operands[0]);
5185   operands[1] = gen_lowpart (Pmode, operands[1]);
5186   operands[3] = gen_lowpart (Pmode, operands[3]);
5187   operands[4] = gen_lowpart (Pmode, operands[4]);
5188   pat = gen_rtx_PLUS (Pmode,
5189                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5190                                                          operands[2]),
5191                                     operands[3]),
5192                       operands[4]);
5193   if (Pmode != SImode)
5194     pat = gen_rtx_SUBREG (SImode, pat, 0);
5195   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5196   DONE;
5197 }
5198   [(set_attr "type" "lea")
5199    (set_attr "mode" "SI")])
5200
5201 (define_insn_and_split "*lea_general_3_zext"
5202   [(set (match_operand:DI 0 "register_operand" "=r")
5203         (zero_extend:DI
5204           (plus:SI (plus:SI (mult:SI
5205                               (match_operand:SI 1 "index_register_operand" "l")
5206                               (match_operand:SI 2 "const248_operand" "n"))
5207                             (match_operand:SI 3 "register_operand" "r"))
5208                    (match_operand:SI 4 "immediate_operand" "i"))))]
5209   "TARGET_64BIT"
5210   "#"
5211   "&& reload_completed"
5212   [(set (match_dup 0)
5213         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5214                                                               (match_dup 2))
5215                                                      (match_dup 3))
5216                                             (match_dup 4)) 0)))]
5217 {
5218   operands[1] = gen_lowpart (Pmode, operands[1]);
5219   operands[3] = gen_lowpart (Pmode, operands[3]);
5220   operands[4] = gen_lowpart (Pmode, operands[4]);
5221 }
5222   [(set_attr "type" "lea")
5223    (set_attr "mode" "SI")])
5224
5225 (define_insn "*adddi_1_rex64"
5226   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5227         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5228                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5229    (clobber (reg:CC FLAGS_REG))]
5230   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5231 {
5232   switch (get_attr_type (insn))
5233     {
5234     case TYPE_LEA:
5235       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5236       return "lea{q}\t{%a2, %0|%0, %a2}";
5237
5238     case TYPE_INCDEC:
5239       if (! rtx_equal_p (operands[0], operands[1]))
5240         abort ();
5241       if (operands[2] == const1_rtx)
5242         return "inc{q}\t%0";
5243       else if (operands[2] == constm1_rtx)
5244         return "dec{q}\t%0";
5245       else
5246         abort ();
5247
5248     default:
5249       if (! rtx_equal_p (operands[0], operands[1]))
5250         abort ();
5251
5252       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5253          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5254       if (GET_CODE (operands[2]) == CONST_INT
5255           /* Avoid overflows.  */
5256           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5257           && (INTVAL (operands[2]) == 128
5258               || (INTVAL (operands[2]) < 0
5259                   && INTVAL (operands[2]) != -128)))
5260         {
5261           operands[2] = GEN_INT (-INTVAL (operands[2]));
5262           return "sub{q}\t{%2, %0|%0, %2}";
5263         }
5264       return "add{q}\t{%2, %0|%0, %2}";
5265     }
5266 }
5267   [(set (attr "type")
5268      (cond [(eq_attr "alternative" "2")
5269               (const_string "lea")
5270             ; Current assemblers are broken and do not allow @GOTOFF in
5271             ; ought but a memory context.
5272             (match_operand:DI 2 "pic_symbolic_operand" "")
5273               (const_string "lea")
5274             (match_operand:DI 2 "incdec_operand" "")
5275               (const_string "incdec")
5276            ]
5277            (const_string "alu")))
5278    (set_attr "mode" "DI")])
5279
5280 ;; Convert lea to the lea pattern to avoid flags dependency.
5281 (define_split
5282   [(set (match_operand:DI 0 "register_operand" "")
5283         (plus:DI (match_operand:DI 1 "register_operand" "")
5284                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5285    (clobber (reg:CC FLAGS_REG))]
5286   "TARGET_64BIT && reload_completed
5287    && true_regnum (operands[0]) != true_regnum (operands[1])"
5288   [(set (match_dup 0)
5289         (plus:DI (match_dup 1)
5290                  (match_dup 2)))]
5291   "")
5292
5293 (define_insn "*adddi_2_rex64"
5294   [(set (reg FLAGS_REG)
5295         (compare
5296           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5297                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5298           (const_int 0)))                       
5299    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5300         (plus:DI (match_dup 1) (match_dup 2)))]
5301   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5302    && ix86_binary_operator_ok (PLUS, DImode, operands)
5303    /* Current assemblers are broken and do not allow @GOTOFF in
5304       ought but a memory context.  */
5305    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 {
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_INCDEC:
5310       if (! rtx_equal_p (operands[0], operands[1]))
5311         abort ();
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else if (operands[2] == constm1_rtx)
5315         return "dec{q}\t%0";
5316       else
5317         abort ();
5318
5319     default:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
5322       /* ???? We ought to handle there the 32bit case too
5323          - do we need new constraint?  */
5324       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5326       if (GET_CODE (operands[2]) == CONST_INT
5327           /* Avoid overflows.  */
5328           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5329           && (INTVAL (operands[2]) == 128
5330               || (INTVAL (operands[2]) < 0
5331                   && INTVAL (operands[2]) != -128)))
5332         {
5333           operands[2] = GEN_INT (-INTVAL (operands[2]));
5334           return "sub{q}\t{%2, %0|%0, %2}";
5335         }
5336       return "add{q}\t{%2, %0|%0, %2}";
5337     }
5338 }
5339   [(set (attr "type")
5340      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5341         (const_string "incdec")
5342         (const_string "alu")))
5343    (set_attr "mode" "DI")])
5344
5345 (define_insn "*adddi_3_rex64"
5346   [(set (reg FLAGS_REG)
5347         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5348                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5349    (clobber (match_scratch:DI 0 "=r"))]
5350   "TARGET_64BIT
5351    && ix86_match_ccmode (insn, CCZmode)
5352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5353    /* Current assemblers are broken and do not allow @GOTOFF in
5354       ought but a memory context.  */
5355    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5356 {
5357   switch (get_attr_type (insn))
5358     {
5359     case TYPE_INCDEC:
5360       if (! rtx_equal_p (operands[0], operands[1]))
5361         abort ();
5362       if (operands[2] == const1_rtx)
5363         return "inc{q}\t%0";
5364       else if (operands[2] == constm1_rtx)
5365         return "dec{q}\t%0";
5366       else
5367         abort ();
5368
5369     default:
5370       if (! rtx_equal_p (operands[0], operands[1]))
5371         abort ();
5372       /* ???? We ought to handle there the 32bit case too
5373          - do we need new constraint?  */
5374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5376       if (GET_CODE (operands[2]) == CONST_INT
5377           /* Avoid overflows.  */
5378           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379           && (INTVAL (operands[2]) == 128
5380               || (INTVAL (operands[2]) < 0
5381                   && INTVAL (operands[2]) != -128)))
5382         {
5383           operands[2] = GEN_INT (-INTVAL (operands[2]));
5384           return "sub{q}\t{%2, %0|%0, %2}";
5385         }
5386       return "add{q}\t{%2, %0|%0, %2}";
5387     }
5388 }
5389   [(set (attr "type")
5390      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391         (const_string "incdec")
5392         (const_string "alu")))
5393    (set_attr "mode" "DI")])
5394
5395 ; For comparisons against 1, -1 and 128, we may generate better code
5396 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5397 ; is matched then.  We can't accept general immediate, because for
5398 ; case of overflows,  the result is messed up.
5399 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5400 ; when negated.
5401 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5402 ; only for comparisons not depending on it.
5403 (define_insn "*adddi_4_rex64"
5404   [(set (reg FLAGS_REG)
5405         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5406                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5407    (clobber (match_scratch:DI 0 "=rm"))]
5408   "TARGET_64BIT
5409    &&  ix86_match_ccmode (insn, CCGCmode)"
5410 {
5411   switch (get_attr_type (insn))
5412     {
5413     case TYPE_INCDEC:
5414       if (operands[2] == constm1_rtx)
5415         return "inc{q}\t%0";
5416       else if (operands[2] == const1_rtx)
5417         return "dec{q}\t%0";
5418       else
5419         abort();
5420
5421     default:
5422       if (! rtx_equal_p (operands[0], operands[1]))
5423         abort ();
5424       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5425          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5426       if ((INTVAL (operands[2]) == -128
5427            || (INTVAL (operands[2]) > 0
5428                && INTVAL (operands[2]) != 128))
5429           /* Avoid overflows.  */
5430           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5431         return "sub{q}\t{%2, %0|%0, %2}";
5432       operands[2] = GEN_INT (-INTVAL (operands[2]));
5433       return "add{q}\t{%2, %0|%0, %2}";
5434     }
5435 }
5436   [(set (attr "type")
5437      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5438         (const_string "incdec")
5439         (const_string "alu")))
5440    (set_attr "mode" "DI")])
5441
5442 (define_insn "*adddi_5_rex64"
5443   [(set (reg FLAGS_REG)
5444         (compare
5445           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5446                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447           (const_int 0)))                       
5448    (clobber (match_scratch:DI 0 "=r"))]
5449   "TARGET_64BIT
5450    && ix86_match_ccmode (insn, CCGOCmode)
5451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5452    /* Current assemblers are broken and do not allow @GOTOFF in
5453       ought but a memory context.  */
5454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5455 {
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       if (! rtx_equal_p (operands[0], operands[1]))
5460         abort ();
5461       if (operands[2] == const1_rtx)
5462         return "inc{q}\t%0";
5463       else if (operands[2] == constm1_rtx)
5464         return "dec{q}\t%0";
5465       else
5466         abort();
5467
5468     default:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5472          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5473       if (GET_CODE (operands[2]) == CONST_INT
5474           /* Avoid overflows.  */
5475           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5476           && (INTVAL (operands[2]) == 128
5477               || (INTVAL (operands[2]) < 0
5478                   && INTVAL (operands[2]) != -128)))
5479         {
5480           operands[2] = GEN_INT (-INTVAL (operands[2]));
5481           return "sub{q}\t{%2, %0|%0, %2}";
5482         }
5483       return "add{q}\t{%2, %0|%0, %2}";
5484     }
5485 }
5486   [(set (attr "type")
5487      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5488         (const_string "incdec")
5489         (const_string "alu")))
5490    (set_attr "mode" "DI")])
5491
5492
5493 (define_insn "*addsi_1"
5494   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5495         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5496                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5497    (clobber (reg:CC FLAGS_REG))]
5498   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5499 {
5500   switch (get_attr_type (insn))
5501     {
5502     case TYPE_LEA:
5503       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5504       return "lea{l}\t{%a2, %0|%0, %a2}";
5505
5506     case TYPE_INCDEC:
5507       if (! rtx_equal_p (operands[0], operands[1]))
5508         abort ();
5509       if (operands[2] == const1_rtx)
5510         return "inc{l}\t%0";
5511       else if (operands[2] == constm1_rtx)
5512         return "dec{l}\t%0";
5513       else
5514         abort();
5515
5516     default:
5517       if (! rtx_equal_p (operands[0], operands[1]))
5518         abort ();
5519
5520       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5521          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5522       if (GET_CODE (operands[2]) == CONST_INT
5523           && (INTVAL (operands[2]) == 128
5524               || (INTVAL (operands[2]) < 0
5525                   && INTVAL (operands[2]) != -128)))
5526         {
5527           operands[2] = GEN_INT (-INTVAL (operands[2]));
5528           return "sub{l}\t{%2, %0|%0, %2}";
5529         }
5530       return "add{l}\t{%2, %0|%0, %2}";
5531     }
5532 }
5533   [(set (attr "type")
5534      (cond [(eq_attr "alternative" "2")
5535               (const_string "lea")
5536             ; Current assemblers are broken and do not allow @GOTOFF in
5537             ; ought but a memory context.
5538             (match_operand:SI 2 "pic_symbolic_operand" "")
5539               (const_string "lea")
5540             (match_operand:SI 2 "incdec_operand" "")
5541               (const_string "incdec")
5542            ]
5543            (const_string "alu")))
5544    (set_attr "mode" "SI")])
5545
5546 ;; Convert lea to the lea pattern to avoid flags dependency.
5547 (define_split
5548   [(set (match_operand 0 "register_operand" "")
5549         (plus (match_operand 1 "register_operand" "")
5550               (match_operand 2 "nonmemory_operand" "")))
5551    (clobber (reg:CC FLAGS_REG))]
5552   "reload_completed
5553    && true_regnum (operands[0]) != true_regnum (operands[1])"
5554   [(const_int 0)]
5555 {
5556   rtx pat;
5557   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5558      may confuse gen_lowpart.  */
5559   if (GET_MODE (operands[0]) != Pmode)
5560     {
5561       operands[1] = gen_lowpart (Pmode, operands[1]);
5562       operands[2] = gen_lowpart (Pmode, operands[2]);
5563     }
5564   operands[0] = gen_lowpart (SImode, operands[0]);
5565   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5566   if (Pmode != SImode)
5567     pat = gen_rtx_SUBREG (SImode, pat, 0);
5568   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5569   DONE;
5570 })
5571
5572 ;; It may seem that nonimmediate operand is proper one for operand 1.
5573 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5574 ;; we take care in ix86_binary_operator_ok to not allow two memory
5575 ;; operands so proper swapping will be done in reload.  This allow
5576 ;; patterns constructed from addsi_1 to match.
5577 (define_insn "addsi_1_zext"
5578   [(set (match_operand:DI 0 "register_operand" "=r,r")
5579         (zero_extend:DI
5580           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5581                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5582    (clobber (reg:CC FLAGS_REG))]
5583   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5584 {
5585   switch (get_attr_type (insn))
5586     {
5587     case TYPE_LEA:
5588       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5589       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5590
5591     case TYPE_INCDEC:
5592       if (operands[2] == const1_rtx)
5593         return "inc{l}\t%k0";
5594       else if (operands[2] == constm1_rtx)
5595         return "dec{l}\t%k0";
5596       else
5597         abort();
5598
5599     default:
5600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602       if (GET_CODE (operands[2]) == CONST_INT
5603           && (INTVAL (operands[2]) == 128
5604               || (INTVAL (operands[2]) < 0
5605                   && INTVAL (operands[2]) != -128)))
5606         {
5607           operands[2] = GEN_INT (-INTVAL (operands[2]));
5608           return "sub{l}\t{%2, %k0|%k0, %2}";
5609         }
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5612 }
5613   [(set (attr "type")
5614      (cond [(eq_attr "alternative" "1")
5615               (const_string "lea")
5616             ; Current assemblers are broken and do not allow @GOTOFF in
5617             ; ought but a memory context.
5618             (match_operand:SI 2 "pic_symbolic_operand" "")
5619               (const_string "lea")
5620             (match_operand:SI 2 "incdec_operand" "")
5621               (const_string "incdec")
5622            ]
5623            (const_string "alu")))
5624    (set_attr "mode" "SI")])
5625
5626 ;; Convert lea to the lea pattern to avoid flags dependency.
5627 (define_split
5628   [(set (match_operand:DI 0 "register_operand" "")
5629         (zero_extend:DI
5630           (plus:SI (match_operand:SI 1 "register_operand" "")
5631                    (match_operand:SI 2 "nonmemory_operand" ""))))
5632    (clobber (reg:CC FLAGS_REG))]
5633   "TARGET_64BIT && reload_completed
5634    && true_regnum (operands[0]) != true_regnum (operands[1])"
5635   [(set (match_dup 0)
5636         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5637 {
5638   operands[1] = gen_lowpart (Pmode, operands[1]);
5639   operands[2] = gen_lowpart (Pmode, operands[2]);
5640 })
5641
5642 (define_insn "*addsi_2"
5643   [(set (reg FLAGS_REG)
5644         (compare
5645           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5646                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5647           (const_int 0)))                       
5648    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5649         (plus:SI (match_dup 1) (match_dup 2)))]
5650   "ix86_match_ccmode (insn, CCGOCmode)
5651    && ix86_binary_operator_ok (PLUS, SImode, operands)
5652    /* Current assemblers are broken and do not allow @GOTOFF in
5653       ought but a memory context.  */
5654    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5655 {
5656   switch (get_attr_type (insn))
5657     {
5658     case TYPE_INCDEC:
5659       if (! rtx_equal_p (operands[0], operands[1]))
5660         abort ();
5661       if (operands[2] == const1_rtx)
5662         return "inc{l}\t%0";
5663       else if (operands[2] == constm1_rtx)
5664         return "dec{l}\t%0";
5665       else
5666         abort();
5667
5668     default:
5669       if (! rtx_equal_p (operands[0], operands[1]))
5670         abort ();
5671       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5673       if (GET_CODE (operands[2]) == CONST_INT
5674           && (INTVAL (operands[2]) == 128
5675               || (INTVAL (operands[2]) < 0
5676                   && INTVAL (operands[2]) != -128)))
5677         {
5678           operands[2] = GEN_INT (-INTVAL (operands[2]));
5679           return "sub{l}\t{%2, %0|%0, %2}";
5680         }
5681       return "add{l}\t{%2, %0|%0, %2}";
5682     }
5683 }
5684   [(set (attr "type")
5685      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5686         (const_string "incdec")
5687         (const_string "alu")))
5688    (set_attr "mode" "SI")])
5689
5690 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5691 (define_insn "*addsi_2_zext"
5692   [(set (reg FLAGS_REG)
5693         (compare
5694           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5695                    (match_operand:SI 2 "general_operand" "rmni"))
5696           (const_int 0)))                       
5697    (set (match_operand:DI 0 "register_operand" "=r")
5698         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5699   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5700    && ix86_binary_operator_ok (PLUS, SImode, operands)
5701    /* Current assemblers are broken and do not allow @GOTOFF in
5702       ought but a memory context.  */
5703    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5704 {
5705   switch (get_attr_type (insn))
5706     {
5707     case TYPE_INCDEC:
5708       if (operands[2] == const1_rtx)
5709         return "inc{l}\t%k0";
5710       else if (operands[2] == constm1_rtx)
5711         return "dec{l}\t%k0";
5712       else
5713         abort();
5714
5715     default:
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (GET_CODE (operands[2]) == CONST_INT
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %k0|%k0, %2}";
5725         }
5726       return "add{l}\t{%2, %k0|%k0, %2}";
5727     }
5728 }
5729   [(set (attr "type")
5730      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731         (const_string "incdec")
5732         (const_string "alu")))
5733    (set_attr "mode" "SI")])
5734
5735 (define_insn "*addsi_3"
5736   [(set (reg FLAGS_REG)
5737         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5738                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5739    (clobber (match_scratch:SI 0 "=r"))]
5740   "ix86_match_ccmode (insn, CCZmode)
5741    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5742    /* Current assemblers are broken and do not allow @GOTOFF in
5743       ought but a memory context.  */
5744    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5745 {
5746   switch (get_attr_type (insn))
5747     {
5748     case TYPE_INCDEC:
5749       if (! rtx_equal_p (operands[0], operands[1]))
5750         abort ();
5751       if (operands[2] == const1_rtx)
5752         return "inc{l}\t%0";
5753       else if (operands[2] == constm1_rtx)
5754         return "dec{l}\t%0";
5755       else
5756         abort();
5757
5758     default:
5759       if (! rtx_equal_p (operands[0], operands[1]))
5760         abort ();
5761       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5762          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5763       if (GET_CODE (operands[2]) == CONST_INT
5764           && (INTVAL (operands[2]) == 128
5765               || (INTVAL (operands[2]) < 0
5766                   && INTVAL (operands[2]) != -128)))
5767         {
5768           operands[2] = GEN_INT (-INTVAL (operands[2]));
5769           return "sub{l}\t{%2, %0|%0, %2}";
5770         }
5771       return "add{l}\t{%2, %0|%0, %2}";
5772     }
5773 }
5774   [(set (attr "type")
5775      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5776         (const_string "incdec")
5777         (const_string "alu")))
5778    (set_attr "mode" "SI")])
5779
5780 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5781 (define_insn "*addsi_3_zext"
5782   [(set (reg FLAGS_REG)
5783         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785    (set (match_operand:DI 0 "register_operand" "=r")
5786         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5787   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5788    && ix86_binary_operator_ok (PLUS, SImode, operands)
5789    /* Current assemblers are broken and do not allow @GOTOFF in
5790       ought but a memory context.  */
5791    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5792 {
5793   switch (get_attr_type (insn))
5794     {
5795     case TYPE_INCDEC:
5796       if (operands[2] == const1_rtx)
5797         return "inc{l}\t%k0";
5798       else if (operands[2] == constm1_rtx)
5799         return "dec{l}\t%k0";
5800       else
5801         abort();
5802
5803     default:
5804       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5806       if (GET_CODE (operands[2]) == CONST_INT
5807           && (INTVAL (operands[2]) == 128
5808               || (INTVAL (operands[2]) < 0
5809                   && INTVAL (operands[2]) != -128)))
5810         {
5811           operands[2] = GEN_INT (-INTVAL (operands[2]));
5812           return "sub{l}\t{%2, %k0|%k0, %2}";
5813         }
5814       return "add{l}\t{%2, %k0|%k0, %2}";
5815     }
5816 }
5817   [(set (attr "type")
5818      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5819         (const_string "incdec")
5820         (const_string "alu")))
5821    (set_attr "mode" "SI")])
5822
5823 ; For comparisons against 1, -1 and 128, we may generate better code
5824 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5825 ; is matched then.  We can't accept general immediate, because for
5826 ; case of overflows,  the result is messed up.
5827 ; This pattern also don't hold of 0x80000000, since the value overflows
5828 ; when negated.
5829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5830 ; only for comparisons not depending on it.
5831 (define_insn "*addsi_4"
5832   [(set (reg FLAGS_REG)
5833         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5834                  (match_operand:SI 2 "const_int_operand" "n")))
5835    (clobber (match_scratch:SI 0 "=rm"))]
5836   "ix86_match_ccmode (insn, CCGCmode)
5837    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5838 {
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == constm1_rtx)
5843         return "inc{l}\t%0";
5844       else if (operands[2] == const1_rtx)
5845         return "dec{l}\t%0";
5846       else
5847         abort();
5848
5849     default:
5850       if (! rtx_equal_p (operands[0], operands[1]))
5851         abort ();
5852       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5853          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5854       if ((INTVAL (operands[2]) == -128
5855            || (INTVAL (operands[2]) > 0
5856                && INTVAL (operands[2]) != 128)))
5857         return "sub{l}\t{%2, %0|%0, %2}";
5858       operands[2] = GEN_INT (-INTVAL (operands[2]));
5859       return "add{l}\t{%2, %0|%0, %2}";
5860     }
5861 }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set_attr "mode" "SI")])
5867
5868 (define_insn "*addsi_5"
5869   [(set (reg FLAGS_REG)
5870         (compare
5871           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5872                    (match_operand:SI 2 "general_operand" "rmni"))
5873           (const_int 0)))                       
5874    (clobber (match_scratch:SI 0 "=r"))]
5875   "ix86_match_ccmode (insn, CCGOCmode)
5876    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5877    /* Current assemblers are broken and do not allow @GOTOFF in
5878       ought but a memory context.  */
5879    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5880 {
5881   switch (get_attr_type (insn))
5882     {
5883     case TYPE_INCDEC:
5884       if (! rtx_equal_p (operands[0], operands[1]))
5885         abort ();
5886       if (operands[2] == const1_rtx)
5887         return "inc{l}\t%0";
5888       else if (operands[2] == constm1_rtx)
5889         return "dec{l}\t%0";
5890       else
5891         abort();
5892
5893     default:
5894       if (! rtx_equal_p (operands[0], operands[1]))
5895         abort ();
5896       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5897          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5898       if (GET_CODE (operands[2]) == CONST_INT
5899           && (INTVAL (operands[2]) == 128
5900               || (INTVAL (operands[2]) < 0
5901                   && INTVAL (operands[2]) != -128)))
5902         {
5903           operands[2] = GEN_INT (-INTVAL (operands[2]));
5904           return "sub{l}\t{%2, %0|%0, %2}";
5905         }
5906       return "add{l}\t{%2, %0|%0, %2}";
5907     }
5908 }
5909   [(set (attr "type")
5910      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911         (const_string "incdec")
5912         (const_string "alu")))
5913    (set_attr "mode" "SI")])
5914
5915 (define_expand "addhi3"
5916   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5917                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5918                             (match_operand:HI 2 "general_operand" "")))
5919               (clobber (reg:CC FLAGS_REG))])]
5920   "TARGET_HIMODE_MATH"
5921   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5922
5923 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5924 ;; type optimizations enabled by define-splits.  This is not important
5925 ;; for PII, and in fact harmful because of partial register stalls.
5926
5927 (define_insn "*addhi_1_lea"
5928   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5929         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5930                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5931    (clobber (reg:CC FLAGS_REG))]
5932   "!TARGET_PARTIAL_REG_STALL
5933    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5934 {
5935   switch (get_attr_type (insn))
5936     {
5937     case TYPE_LEA:
5938       return "#";
5939     case TYPE_INCDEC:
5940       if (operands[2] == const1_rtx)
5941         return "inc{w}\t%0";
5942       else if (operands[2] == constm1_rtx)
5943         return "dec{w}\t%0";
5944       abort();
5945
5946     default:
5947       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5948          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5949       if (GET_CODE (operands[2]) == CONST_INT
5950           && (INTVAL (operands[2]) == 128
5951               || (INTVAL (operands[2]) < 0
5952                   && INTVAL (operands[2]) != -128)))
5953         {
5954           operands[2] = GEN_INT (-INTVAL (operands[2]));
5955           return "sub{w}\t{%2, %0|%0, %2}";
5956         }
5957       return "add{w}\t{%2, %0|%0, %2}";
5958     }
5959 }
5960   [(set (attr "type")
5961      (if_then_else (eq_attr "alternative" "2")
5962         (const_string "lea")
5963         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5964            (const_string "incdec")
5965            (const_string "alu"))))
5966    (set_attr "mode" "HI,HI,SI")])
5967
5968 (define_insn "*addhi_1"
5969   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5970         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5971                  (match_operand:HI 2 "general_operand" "ri,rm")))
5972    (clobber (reg:CC FLAGS_REG))]
5973   "TARGET_PARTIAL_REG_STALL
5974    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5975 {
5976   switch (get_attr_type (insn))
5977     {
5978     case TYPE_INCDEC:
5979       if (operands[2] == const1_rtx)
5980         return "inc{w}\t%0";
5981       else if (operands[2] == constm1_rtx)
5982         return "dec{w}\t%0";
5983       abort();
5984
5985     default:
5986       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5987          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5988       if (GET_CODE (operands[2]) == CONST_INT
5989           && (INTVAL (operands[2]) == 128
5990               || (INTVAL (operands[2]) < 0
5991                   && INTVAL (operands[2]) != -128)))
5992         {
5993           operands[2] = GEN_INT (-INTVAL (operands[2]));
5994           return "sub{w}\t{%2, %0|%0, %2}";
5995         }
5996       return "add{w}\t{%2, %0|%0, %2}";
5997     }
5998 }
5999   [(set (attr "type")
6000      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001         (const_string "incdec")
6002         (const_string "alu")))
6003    (set_attr "mode" "HI")])
6004
6005 (define_insn "*addhi_2"
6006   [(set (reg FLAGS_REG)
6007         (compare
6008           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6009                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6010           (const_int 0)))                       
6011    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6012         (plus:HI (match_dup 1) (match_dup 2)))]
6013   "ix86_match_ccmode (insn, CCGOCmode)
6014    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6015 {
6016   switch (get_attr_type (insn))
6017     {
6018     case TYPE_INCDEC:
6019       if (operands[2] == const1_rtx)
6020         return "inc{w}\t%0";
6021       else if (operands[2] == constm1_rtx)
6022         return "dec{w}\t%0";
6023       abort();
6024
6025     default:
6026       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6028       if (GET_CODE (operands[2]) == CONST_INT
6029           && (INTVAL (operands[2]) == 128
6030               || (INTVAL (operands[2]) < 0
6031                   && INTVAL (operands[2]) != -128)))
6032         {
6033           operands[2] = GEN_INT (-INTVAL (operands[2]));
6034           return "sub{w}\t{%2, %0|%0, %2}";
6035         }
6036       return "add{w}\t{%2, %0|%0, %2}";
6037     }
6038 }
6039   [(set (attr "type")
6040      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041         (const_string "incdec")
6042         (const_string "alu")))
6043    (set_attr "mode" "HI")])
6044
6045 (define_insn "*addhi_3"
6046   [(set (reg FLAGS_REG)
6047         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6048                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6049    (clobber (match_scratch:HI 0 "=r"))]
6050   "ix86_match_ccmode (insn, CCZmode)
6051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6052 {
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_INCDEC:
6056       if (operands[2] == const1_rtx)
6057         return "inc{w}\t%0";
6058       else if (operands[2] == constm1_rtx)
6059         return "dec{w}\t%0";
6060       abort();
6061
6062     default:
6063       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065       if (GET_CODE (operands[2]) == CONST_INT
6066           && (INTVAL (operands[2]) == 128
6067               || (INTVAL (operands[2]) < 0
6068                   && INTVAL (operands[2]) != -128)))
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           return "sub{w}\t{%2, %0|%0, %2}";
6072         }
6073       return "add{w}\t{%2, %0|%0, %2}";
6074     }
6075 }
6076   [(set (attr "type")
6077      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078         (const_string "incdec")
6079         (const_string "alu")))
6080    (set_attr "mode" "HI")])
6081
6082 ; See comments above addsi_3_imm for details.
6083 (define_insn "*addhi_4"
6084   [(set (reg FLAGS_REG)
6085         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6086                  (match_operand:HI 2 "const_int_operand" "n")))
6087    (clobber (match_scratch:HI 0 "=rm"))]
6088   "ix86_match_ccmode (insn, CCGCmode)
6089    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6090 {
6091   switch (get_attr_type (insn))
6092     {
6093     case TYPE_INCDEC:
6094       if (operands[2] == constm1_rtx)
6095         return "inc{w}\t%0";
6096       else if (operands[2] == const1_rtx)
6097         return "dec{w}\t%0";
6098       else
6099         abort();
6100
6101     default:
6102       if (! rtx_equal_p (operands[0], operands[1]))
6103         abort ();
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if ((INTVAL (operands[2]) == -128
6107            || (INTVAL (operands[2]) > 0
6108                && INTVAL (operands[2]) != 128)))
6109         return "sub{w}\t{%2, %0|%0, %2}";
6110       operands[2] = GEN_INT (-INTVAL (operands[2]));
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" "SI")])
6119
6120
6121 (define_insn "*addhi_5"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6125                    (match_operand:HI 2 "general_operand" "rmni"))
6126           (const_int 0)))                       
6127    (clobber (match_scratch:HI 0 "=r"))]
6128   "ix86_match_ccmode (insn, CCGOCmode)
6129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[2] == const1_rtx)
6135         return "inc{w}\t%0";
6136       else if (operands[2] == constm1_rtx)
6137         return "dec{w}\t%0";
6138       abort();
6139
6140     default:
6141       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143       if (GET_CODE (operands[2]) == CONST_INT
6144           && (INTVAL (operands[2]) == 128
6145               || (INTVAL (operands[2]) < 0
6146                   && INTVAL (operands[2]) != -128)))
6147         {
6148           operands[2] = GEN_INT (-INTVAL (operands[2]));
6149           return "sub{w}\t{%2, %0|%0, %2}";
6150         }
6151       return "add{w}\t{%2, %0|%0, %2}";
6152     }
6153 }
6154   [(set (attr "type")
6155      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6156         (const_string "incdec")
6157         (const_string "alu")))
6158    (set_attr "mode" "HI")])
6159
6160 (define_expand "addqi3"
6161   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6162                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6163                             (match_operand:QI 2 "general_operand" "")))
6164               (clobber (reg:CC FLAGS_REG))])]
6165   "TARGET_QIMODE_MATH"
6166   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6167
6168 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6169 (define_insn "*addqi_1_lea"
6170   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6171         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6172                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6173    (clobber (reg:CC FLAGS_REG))]
6174   "!TARGET_PARTIAL_REG_STALL
6175    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176 {
6177   int widen = (which_alternative == 2);
6178   switch (get_attr_type (insn))
6179     {
6180     case TYPE_LEA:
6181       return "#";
6182     case TYPE_INCDEC:
6183       if (operands[2] == const1_rtx)
6184         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6185       else if (operands[2] == constm1_rtx)
6186         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6187       abort();
6188
6189     default:
6190       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6191          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6192       if (GET_CODE (operands[2]) == CONST_INT
6193           && (INTVAL (operands[2]) == 128
6194               || (INTVAL (operands[2]) < 0
6195                   && INTVAL (operands[2]) != -128)))
6196         {
6197           operands[2] = GEN_INT (-INTVAL (operands[2]));
6198           if (widen)
6199             return "sub{l}\t{%2, %k0|%k0, %2}";
6200           else
6201             return "sub{b}\t{%2, %0|%0, %2}";
6202         }
6203       if (widen)
6204         return "add{l}\t{%k2, %k0|%k0, %k2}";
6205       else
6206         return "add{b}\t{%2, %0|%0, %2}";
6207     }
6208 }
6209   [(set (attr "type")
6210      (if_then_else (eq_attr "alternative" "3")
6211         (const_string "lea")
6212         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6213            (const_string "incdec")
6214            (const_string "alu"))))
6215    (set_attr "mode" "QI,QI,SI,SI")])
6216
6217 (define_insn "*addqi_1"
6218   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6219         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6220                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6221    (clobber (reg:CC FLAGS_REG))]
6222   "TARGET_PARTIAL_REG_STALL
6223    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6224 {
6225   int widen = (which_alternative == 2);
6226   switch (get_attr_type (insn))
6227     {
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx)
6232         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233       abort();
6234
6235     default:
6236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           if (widen)
6245             return "sub{l}\t{%2, %k0|%k0, %2}";
6246           else
6247             return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       if (widen)
6250         return "add{l}\t{%k2, %k0|%k0, %k2}";
6251       else
6252         return "add{b}\t{%2, %0|%0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set_attr "mode" "QI,QI,SI")])
6260
6261 (define_insn "*addqi_1_slp"
6262   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6263         (plus:QI (match_dup 0)
6264                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6267    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6268 {
6269   switch (get_attr_type (insn))
6270     {
6271     case TYPE_INCDEC:
6272       if (operands[1] == const1_rtx)
6273         return "inc{b}\t%0";
6274       else if (operands[1] == constm1_rtx)
6275         return "dec{b}\t%0";
6276       abort();
6277
6278     default:
6279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6280       if (GET_CODE (operands[1]) == CONST_INT
6281           && INTVAL (operands[1]) < 0)
6282         {
6283           operands[1] = GEN_INT (-INTVAL (operands[1]));
6284           return "sub{b}\t{%1, %0|%0, %1}";
6285         }
6286       return "add{b}\t{%1, %0|%0, %1}";
6287     }
6288 }
6289   [(set (attr "type")
6290      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6291         (const_string "incdec")
6292         (const_string "alu1")))
6293    (set_attr "mode" "QI")])
6294
6295 (define_insn "*addqi_2"
6296   [(set (reg FLAGS_REG)
6297         (compare
6298           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6299                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6300           (const_int 0)))
6301    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6302         (plus:QI (match_dup 1) (match_dup 2)))]
6303   "ix86_match_ccmode (insn, CCGOCmode)
6304    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6305 {
6306   switch (get_attr_type (insn))
6307     {
6308     case TYPE_INCDEC:
6309       if (operands[2] == const1_rtx)
6310         return "inc{b}\t%0";
6311       else if (operands[2] == constm1_rtx
6312                || (GET_CODE (operands[2]) == CONST_INT
6313                    && INTVAL (operands[2]) == 255))
6314         return "dec{b}\t%0";
6315       abort();
6316
6317     default:
6318       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6319       if (GET_CODE (operands[2]) == CONST_INT
6320           && INTVAL (operands[2]) < 0)
6321         {
6322           operands[2] = GEN_INT (-INTVAL (operands[2]));
6323           return "sub{b}\t{%2, %0|%0, %2}";
6324         }
6325       return "add{b}\t{%2, %0|%0, %2}";
6326     }
6327 }
6328   [(set (attr "type")
6329      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6330         (const_string "incdec")
6331         (const_string "alu")))
6332    (set_attr "mode" "QI")])
6333
6334 (define_insn "*addqi_3"
6335   [(set (reg FLAGS_REG)
6336         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6337                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6338    (clobber (match_scratch:QI 0 "=q"))]
6339   "ix86_match_ccmode (insn, CCZmode)
6340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6341 {
6342   switch (get_attr_type (insn))
6343     {
6344     case TYPE_INCDEC:
6345       if (operands[2] == const1_rtx)
6346         return "inc{b}\t%0";
6347       else if (operands[2] == constm1_rtx
6348                || (GET_CODE (operands[2]) == CONST_INT
6349                    && INTVAL (operands[2]) == 255))
6350         return "dec{b}\t%0";
6351       abort();
6352
6353     default:
6354       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6355       if (GET_CODE (operands[2]) == CONST_INT
6356           && INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "sub{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "add{b}\t{%2, %0|%0, %2}";
6362     }
6363 }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6369
6370 ; See comments above addsi_3_imm for details.
6371 (define_insn "*addqi_4"
6372   [(set (reg FLAGS_REG)
6373         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6374                  (match_operand:QI 2 "const_int_operand" "n")))
6375    (clobber (match_scratch:QI 0 "=qm"))]
6376   "ix86_match_ccmode (insn, CCGCmode)
6377    && (INTVAL (operands[2]) & 0xff) != 0x80"
6378 {
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == constm1_rtx
6383           || (GET_CODE (operands[2]) == CONST_INT
6384               && INTVAL (operands[2]) == 255))
6385         return "inc{b}\t%0";
6386       else if (operands[2] == const1_rtx)
6387         return "dec{b}\t%0";
6388       else
6389         abort();
6390
6391     default:
6392       if (! rtx_equal_p (operands[0], operands[1]))
6393         abort ();
6394       if (INTVAL (operands[2]) < 0)
6395         {
6396           operands[2] = GEN_INT (-INTVAL (operands[2]));
6397           return "add{b}\t{%2, %0|%0, %2}";
6398         }
6399       return "sub{b}\t{%2, %0|%0, %2}";
6400     }
6401 }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set_attr "mode" "QI")])
6407
6408
6409 (define_insn "*addqi_5"
6410   [(set (reg FLAGS_REG)
6411         (compare
6412           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6413                    (match_operand:QI 2 "general_operand" "qmni"))
6414           (const_int 0)))
6415    (clobber (match_scratch:QI 0 "=q"))]
6416   "ix86_match_ccmode (insn, CCGOCmode)
6417    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6418 {
6419   switch (get_attr_type (insn))
6420     {
6421     case TYPE_INCDEC:
6422       if (operands[2] == const1_rtx)
6423         return "inc{b}\t%0";
6424       else if (operands[2] == constm1_rtx
6425                || (GET_CODE (operands[2]) == CONST_INT
6426                    && INTVAL (operands[2]) == 255))
6427         return "dec{b}\t%0";
6428       abort();
6429
6430     default:
6431       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6432       if (GET_CODE (operands[2]) == CONST_INT
6433           && INTVAL (operands[2]) < 0)
6434         {
6435           operands[2] = GEN_INT (-INTVAL (operands[2]));
6436           return "sub{b}\t{%2, %0|%0, %2}";
6437         }
6438       return "add{b}\t{%2, %0|%0, %2}";
6439     }
6440 }
6441   [(set (attr "type")
6442      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443         (const_string "incdec")
6444         (const_string "alu")))
6445    (set_attr "mode" "QI")])
6446
6447
6448 (define_insn "addqi_ext_1"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "0")
6455             (const_int 8)
6456             (const_int 8))
6457           (match_operand:QI 2 "general_operand" "Qmn")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "!TARGET_64BIT"
6460 {
6461   switch (get_attr_type (insn))
6462     {
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return "inc{b}\t%h0";
6466       else if (operands[2] == constm1_rtx
6467                || (GET_CODE (operands[2]) == CONST_INT
6468                    && INTVAL (operands[2]) == 255))
6469         return "dec{b}\t%h0";
6470       abort();
6471
6472     default:
6473       return "add{b}\t{%2, %h0|%h0, %2}";
6474     }
6475 }
6476   [(set (attr "type")
6477      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478         (const_string "incdec")
6479         (const_string "alu")))
6480    (set_attr "mode" "QI")])
6481
6482 (define_insn "*addqi_ext_1_rex64"
6483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6484                          (const_int 8)
6485                          (const_int 8))
6486         (plus:SI
6487           (zero_extract:SI
6488             (match_operand 1 "ext_register_operand" "0")
6489             (const_int 8)
6490             (const_int 8))
6491           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "TARGET_64BIT"
6494 {
6495   switch (get_attr_type (insn))
6496     {
6497     case TYPE_INCDEC:
6498       if (operands[2] == const1_rtx)
6499         return "inc{b}\t%h0";
6500       else if (operands[2] == constm1_rtx
6501                || (GET_CODE (operands[2]) == CONST_INT
6502                    && INTVAL (operands[2]) == 255))
6503         return "dec{b}\t%h0";
6504       abort();
6505
6506     default:
6507       return "add{b}\t{%2, %h0|%h0, %2}";
6508     }
6509 }
6510   [(set (attr "type")
6511      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6512         (const_string "incdec")
6513         (const_string "alu")))
6514    (set_attr "mode" "QI")])
6515
6516 (define_insn "*addqi_ext_2"
6517   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6518                          (const_int 8)
6519                          (const_int 8))
6520         (plus:SI
6521           (zero_extract:SI
6522             (match_operand 1 "ext_register_operand" "%0")
6523             (const_int 8)
6524             (const_int 8))
6525           (zero_extract:SI
6526             (match_operand 2 "ext_register_operand" "Q")
6527             (const_int 8)
6528             (const_int 8))))
6529    (clobber (reg:CC FLAGS_REG))]
6530   ""
6531   "add{b}\t{%h2, %h0|%h0, %h2}"
6532   [(set_attr "type" "alu")
6533    (set_attr "mode" "QI")])
6534
6535 ;; The patterns that match these are at the end of this file.
6536
6537 (define_expand "addxf3"
6538   [(set (match_operand:XF 0 "register_operand" "")
6539         (plus:XF (match_operand:XF 1 "register_operand" "")
6540                  (match_operand:XF 2 "register_operand" "")))]
6541   "TARGET_80387"
6542   "")
6543
6544 (define_expand "adddf3"
6545   [(set (match_operand:DF 0 "register_operand" "")
6546         (plus:DF (match_operand:DF 1 "register_operand" "")
6547                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6549   "")
6550
6551 (define_expand "addsf3"
6552   [(set (match_operand:SF 0 "register_operand" "")
6553         (plus:SF (match_operand:SF 1 "register_operand" "")
6554                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6555   "TARGET_80387 || TARGET_SSE_MATH"
6556   "")
6557 \f
6558 ;; Subtract instructions
6559
6560 ;; %%% splits for subsidi3
6561
6562 (define_expand "subdi3"
6563   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6564                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6565                              (match_operand:DI 2 "x86_64_general_operand" "")))
6566               (clobber (reg:CC FLAGS_REG))])]
6567   ""
6568   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6569
6570 (define_insn "*subdi3_1"
6571   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6572         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576   "#")
6577
6578 (define_split
6579   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6580         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6581                   (match_operand:DI 2 "general_operand" "")))
6582    (clobber (reg:CC FLAGS_REG))]
6583   "!TARGET_64BIT && reload_completed"
6584   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6585               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6586    (parallel [(set (match_dup 3)
6587                    (minus:SI (match_dup 4)
6588                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6589                                       (match_dup 5))))
6590               (clobber (reg:CC FLAGS_REG))])]
6591   "split_di (operands+0, 1, operands+0, operands+3);
6592    split_di (operands+1, 1, operands+1, operands+4);
6593    split_di (operands+2, 1, operands+2, operands+5);")
6594
6595 (define_insn "subdi3_carry_rex64"
6596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6599                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6602   "sbb{q}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "DI")])
6606
6607 (define_insn "*subdi_1_rex64"
6608   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6609         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6610                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "sub{q}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "DI")])
6616
6617 (define_insn "*subdi_2_rex64"
6618   [(set (reg FLAGS_REG)
6619         (compare
6620           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6622           (const_int 0)))
6623    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624         (minus:DI (match_dup 1) (match_dup 2)))]
6625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6626    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6627   "sub{q}\t{%2, %0|%0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "DI")])
6630
6631 (define_insn "*subdi_3_rex63"
6632   [(set (reg FLAGS_REG)
6633         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6634                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6635    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6636         (minus:DI (match_dup 1) (match_dup 2)))]
6637   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6638    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6639   "sub{q}\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "alu")
6641    (set_attr "mode" "DI")])
6642
6643 (define_insn "subqi3_carry"
6644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6645           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6646             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6647                (match_operand:QI 2 "general_operand" "qi,qm"))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6650   "sbb{b}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "QI")])
6654
6655 (define_insn "subhi3_carry"
6656   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6657           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6658             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6659                (match_operand:HI 2 "general_operand" "ri,rm"))))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6662   "sbb{w}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "pent_pair" "pu")
6665    (set_attr "mode" "HI")])
6666
6667 (define_insn "subsi3_carry"
6668   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6671                (match_operand:SI 2 "general_operand" "ri,rm"))))
6672    (clobber (reg:CC FLAGS_REG))]
6673   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sbb{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "pent_pair" "pu")
6677    (set_attr "mode" "SI")])
6678
6679 (define_insn "subsi3_carry_zext"
6680   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6681           (zero_extend:DI
6682             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6683               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6684                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6685    (clobber (reg:CC FLAGS_REG))]
6686   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6687   "sbb{l}\t{%2, %k0|%k0, %2}"
6688   [(set_attr "type" "alu")
6689    (set_attr "pent_pair" "pu")
6690    (set_attr "mode" "SI")])
6691
6692 (define_expand "subsi3"
6693   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6694                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6695                              (match_operand:SI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   ""
6698   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6699
6700 (define_insn "*subsi_1"
6701   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:SI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6706   "sub{l}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "SI")])
6709
6710 (define_insn "*subsi_1_zext"
6711   [(set (match_operand:DI 0 "register_operand" "=r")
6712         (zero_extend:DI
6713           (minus:SI (match_operand:SI 1 "register_operand" "0")
6714                     (match_operand:SI 2 "general_operand" "rim"))))
6715    (clobber (reg:CC FLAGS_REG))]
6716   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6717   "sub{l}\t{%2, %k0|%k0, %2}"
6718   [(set_attr "type" "alu")
6719    (set_attr "mode" "SI")])
6720
6721 (define_insn "*subsi_2"
6722   [(set (reg FLAGS_REG)
6723         (compare
6724           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6725                     (match_operand:SI 2 "general_operand" "ri,rm"))
6726           (const_int 0)))
6727    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6728         (minus:SI (match_dup 1) (match_dup 2)))]
6729   "ix86_match_ccmode (insn, CCGOCmode)
6730    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6731   "sub{l}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "SI")])
6734
6735 (define_insn "*subsi_2_zext"
6736   [(set (reg FLAGS_REG)
6737         (compare
6738           (minus:SI (match_operand:SI 1 "register_operand" "0")
6739                     (match_operand:SI 2 "general_operand" "rim"))
6740           (const_int 0)))
6741    (set (match_operand:DI 0 "register_operand" "=r")
6742         (zero_extend:DI
6743           (minus:SI (match_dup 1)
6744                     (match_dup 2))))]
6745   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6746    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747   "sub{l}\t{%2, %k0|%k0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "mode" "SI")])
6750
6751 (define_insn "*subsi_3"
6752   [(set (reg FLAGS_REG)
6753         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6754                  (match_operand:SI 2 "general_operand" "ri,rm")))
6755    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6756         (minus:SI (match_dup 1) (match_dup 2)))]
6757   "ix86_match_ccmode (insn, CCmode)
6758    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6759   "sub{l}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "SI")])
6762
6763 (define_insn "*subsi_3_zext"
6764   [(set (reg FLAGS_REG)
6765         (compare (match_operand:SI 1 "register_operand" "0")
6766                  (match_operand:SI 2 "general_operand" "rim")))
6767    (set (match_operand:DI 0 "register_operand" "=r")
6768         (zero_extend:DI
6769           (minus:SI (match_dup 1)
6770                     (match_dup 2))))]
6771   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6772    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6773   "sub{q}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "mode" "DI")])
6776
6777 (define_expand "subhi3"
6778   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6779                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6780                              (match_operand:HI 2 "general_operand" "")))
6781               (clobber (reg:CC FLAGS_REG))])]
6782   "TARGET_HIMODE_MATH"
6783   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6784
6785 (define_insn "*subhi_1"
6786   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6787         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6788                   (match_operand:HI 2 "general_operand" "ri,rm")))
6789    (clobber (reg:CC FLAGS_REG))]
6790   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6791   "sub{w}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "mode" "HI")])
6794
6795 (define_insn "*subhi_2"
6796   [(set (reg FLAGS_REG)
6797         (compare
6798           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799                     (match_operand:HI 2 "general_operand" "ri,rm"))
6800           (const_int 0)))
6801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:HI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCGOCmode)
6804    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805   "sub{w}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "HI")])
6808
6809 (define_insn "*subhi_3"
6810   [(set (reg FLAGS_REG)
6811         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6812                  (match_operand:HI 2 "general_operand" "ri,rm")))
6813    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6814         (minus:HI (match_dup 1) (match_dup 2)))]
6815   "ix86_match_ccmode (insn, CCmode)
6816    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6817   "sub{w}\t{%2, %0|%0, %2}"
6818   [(set_attr "type" "alu")
6819    (set_attr "mode" "HI")])
6820
6821 (define_expand "subqi3"
6822   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6823                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6824                              (match_operand:QI 2 "general_operand" "")))
6825               (clobber (reg:CC FLAGS_REG))])]
6826   "TARGET_QIMODE_MATH"
6827   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6828
6829 (define_insn "*subqi_1"
6830   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6831         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6832                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6835   "sub{b}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "QI")])
6838
6839 (define_insn "*subqi_1_slp"
6840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6841         (minus:QI (match_dup 0)
6842                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6846   "sub{b}\t{%1, %0|%0, %1}"
6847   [(set_attr "type" "alu1")
6848    (set_attr "mode" "QI")])
6849
6850 (define_insn "*subqi_2"
6851   [(set (reg FLAGS_REG)
6852         (compare
6853           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6854                     (match_operand:QI 2 "general_operand" "qi,qm"))
6855           (const_int 0)))
6856    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857         (minus:HI (match_dup 1) (match_dup 2)))]
6858   "ix86_match_ccmode (insn, CCGOCmode)
6859    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860   "sub{b}\t{%2, %0|%0, %2}"
6861   [(set_attr "type" "alu")
6862    (set_attr "mode" "QI")])
6863
6864 (define_insn "*subqi_3"
6865   [(set (reg FLAGS_REG)
6866         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6867                  (match_operand:QI 2 "general_operand" "qi,qm")))
6868    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6869         (minus:HI (match_dup 1) (match_dup 2)))]
6870   "ix86_match_ccmode (insn, CCmode)
6871    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6872   "sub{b}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "QI")])
6875
6876 ;; The patterns that match these are at the end of this file.
6877
6878 (define_expand "subxf3"
6879   [(set (match_operand:XF 0 "register_operand" "")
6880         (minus:XF (match_operand:XF 1 "register_operand" "")
6881                   (match_operand:XF 2 "register_operand" "")))]
6882   "TARGET_80387"
6883   "")
6884
6885 (define_expand "subdf3"
6886   [(set (match_operand:DF 0 "register_operand" "")
6887         (minus:DF (match_operand:DF 1 "register_operand" "")
6888                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6889   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6890   "")
6891
6892 (define_expand "subsf3"
6893   [(set (match_operand:SF 0 "register_operand" "")
6894         (minus:SF (match_operand:SF 1 "register_operand" "")
6895                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6896   "TARGET_80387 || TARGET_SSE_MATH"
6897   "")
6898 \f
6899 ;; Multiply instructions
6900
6901 (define_expand "muldi3"
6902   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6903                    (mult:DI (match_operand:DI 1 "register_operand" "")
6904                             (match_operand:DI 2 "x86_64_general_operand" "")))
6905               (clobber (reg:CC FLAGS_REG))])]
6906   "TARGET_64BIT"
6907   "")
6908
6909 (define_insn "*muldi3_1_rex64"
6910   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6911         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6912                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6913    (clobber (reg:CC FLAGS_REG))]
6914   "TARGET_64BIT
6915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6916   "@
6917    imul{q}\t{%2, %1, %0|%0, %1, %2}
6918    imul{q}\t{%2, %1, %0|%0, %1, %2}
6919    imul{q}\t{%2, %0|%0, %2}"
6920   [(set_attr "type" "imul")
6921    (set_attr "prefix_0f" "0,0,1")
6922    (set (attr "athlon_decode")
6923         (cond [(eq_attr "cpu" "athlon")
6924                   (const_string "vector")
6925                (eq_attr "alternative" "1")
6926                   (const_string "vector")
6927                (and (eq_attr "alternative" "2")
6928                     (match_operand 1 "memory_operand" ""))
6929                   (const_string "vector")]
6930               (const_string "direct")))
6931    (set_attr "mode" "DI")])
6932
6933 (define_expand "mulsi3"
6934   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6935                    (mult:SI (match_operand:SI 1 "register_operand" "")
6936                             (match_operand:SI 2 "general_operand" "")))
6937               (clobber (reg:CC FLAGS_REG))])]
6938   ""
6939   "")
6940
6941 (define_insn "*mulsi3_1"
6942   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6943         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6944                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6945    (clobber (reg:CC FLAGS_REG))]
6946   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6947   "@
6948    imul{l}\t{%2, %1, %0|%0, %1, %2}
6949    imul{l}\t{%2, %1, %0|%0, %1, %2}
6950    imul{l}\t{%2, %0|%0, %2}"
6951   [(set_attr "type" "imul")
6952    (set_attr "prefix_0f" "0,0,1")
6953    (set (attr "athlon_decode")
6954         (cond [(eq_attr "cpu" "athlon")
6955                   (const_string "vector")
6956                (eq_attr "alternative" "1")
6957                   (const_string "vector")
6958                (and (eq_attr "alternative" "2")
6959                     (match_operand 1 "memory_operand" ""))
6960                   (const_string "vector")]
6961               (const_string "direct")))
6962    (set_attr "mode" "SI")])
6963
6964 (define_insn "*mulsi3_1_zext"
6965   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6966         (zero_extend:DI
6967           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6968                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6969    (clobber (reg:CC FLAGS_REG))]
6970   "TARGET_64BIT
6971    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972   "@
6973    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6974    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975    imul{l}\t{%2, %k0|%k0, %2}"
6976   [(set_attr "type" "imul")
6977    (set_attr "prefix_0f" "0,0,1")
6978    (set (attr "athlon_decode")
6979         (cond [(eq_attr "cpu" "athlon")
6980                   (const_string "vector")
6981                (eq_attr "alternative" "1")
6982                   (const_string "vector")
6983                (and (eq_attr "alternative" "2")
6984                     (match_operand 1 "memory_operand" ""))
6985                   (const_string "vector")]
6986               (const_string "direct")))
6987    (set_attr "mode" "SI")])
6988
6989 (define_expand "mulhi3"
6990   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991                    (mult:HI (match_operand:HI 1 "register_operand" "")
6992                             (match_operand:HI 2 "general_operand" "")))
6993               (clobber (reg:CC FLAGS_REG))])]
6994   "TARGET_HIMODE_MATH"
6995   "")
6996
6997 (define_insn "*mulhi3_1"
6998   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6999         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7000                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7001    (clobber (reg:CC FLAGS_REG))]
7002   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7003   "@
7004    imul{w}\t{%2, %1, %0|%0, %1, %2}
7005    imul{w}\t{%2, %1, %0|%0, %1, %2}
7006    imul{w}\t{%2, %0|%0, %2}"
7007   [(set_attr "type" "imul")
7008    (set_attr "prefix_0f" "0,0,1")
7009    (set (attr "athlon_decode")
7010         (cond [(eq_attr "cpu" "athlon")
7011                   (const_string "vector")
7012                (eq_attr "alternative" "1,2")
7013                   (const_string "vector")]
7014               (const_string "direct")))
7015    (set_attr "mode" "HI")])
7016
7017 (define_expand "mulqi3"
7018   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7019                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7020                             (match_operand:QI 2 "register_operand" "")))
7021               (clobber (reg:CC FLAGS_REG))])]
7022   "TARGET_QIMODE_MATH"
7023   "")
7024
7025 (define_insn "*mulqi3_1"
7026   [(set (match_operand:QI 0 "register_operand" "=a")
7027         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7028                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7029    (clobber (reg:CC FLAGS_REG))]
7030   "TARGET_QIMODE_MATH
7031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7032   "mul{b}\t%2"
7033   [(set_attr "type" "imul")
7034    (set_attr "length_immediate" "0")
7035    (set (attr "athlon_decode")
7036      (if_then_else (eq_attr "cpu" "athlon")
7037         (const_string "vector")
7038         (const_string "direct")))
7039    (set_attr "mode" "QI")])
7040
7041 (define_expand "umulqihi3"
7042   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7043                    (mult:HI (zero_extend:HI
7044                               (match_operand:QI 1 "nonimmediate_operand" ""))
7045                             (zero_extend:HI
7046                               (match_operand:QI 2 "register_operand" ""))))
7047               (clobber (reg:CC FLAGS_REG))])]
7048   "TARGET_QIMODE_MATH"
7049   "")
7050
7051 (define_insn "*umulqihi3_1"
7052   [(set (match_operand:HI 0 "register_operand" "=a")
7053         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7054                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_QIMODE_MATH
7057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058   "mul{b}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "direct")))
7065    (set_attr "mode" "QI")])
7066
7067 (define_expand "mulqihi3"
7068   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7069                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7070                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   "TARGET_QIMODE_MATH"
7073   "")
7074
7075 (define_insn "*mulqihi3_insn"
7076   [(set (match_operand:HI 0 "register_operand" "=a")
7077         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7078                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "TARGET_QIMODE_MATH
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "imul{b}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "direct")))
7089    (set_attr "mode" "QI")])
7090
7091 (define_expand "umulditi3"
7092   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7093                    (mult:TI (zero_extend:TI
7094                               (match_operand:DI 1 "nonimmediate_operand" ""))
7095                             (zero_extend:TI
7096                               (match_operand:DI 2 "register_operand" ""))))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_64BIT"
7099   "")
7100
7101 (define_insn "*umulditi3_insn"
7102   [(set (match_operand:TI 0 "register_operand" "=A")
7103         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7104                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_64BIT
7107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108   "mul{q}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "double")))
7115    (set_attr "mode" "DI")])
7116
7117 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7118 (define_expand "umulsidi3"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120                    (mult:DI (zero_extend:DI
7121                               (match_operand:SI 1 "nonimmediate_operand" ""))
7122                             (zero_extend:DI
7123                               (match_operand:SI 2 "register_operand" ""))))
7124               (clobber (reg:CC FLAGS_REG))])]
7125   "!TARGET_64BIT"
7126   "")
7127
7128 (define_insn "*umulsidi3_insn"
7129   [(set (match_operand:DI 0 "register_operand" "=A")
7130         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "!TARGET_64BIT
7134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135   "mul{l}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "mode" "SI")])
7143
7144 (define_expand "mulditi3"
7145   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7146                    (mult:TI (sign_extend:TI
7147                               (match_operand:DI 1 "nonimmediate_operand" ""))
7148                             (sign_extend:TI
7149                               (match_operand:DI 2 "register_operand" ""))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "TARGET_64BIT"
7152   "")
7153
7154 (define_insn "*mulditi3_insn"
7155   [(set (match_operand:TI 0 "register_operand" "=A")
7156         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7157                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7158    (clobber (reg:CC FLAGS_REG))]
7159   "TARGET_64BIT
7160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7161   "imul{q}\t%2"
7162   [(set_attr "type" "imul")
7163    (set_attr "length_immediate" "0")
7164    (set (attr "athlon_decode")
7165      (if_then_else (eq_attr "cpu" "athlon")
7166         (const_string "vector")
7167         (const_string "double")))
7168    (set_attr "mode" "DI")])
7169
7170 (define_expand "mulsidi3"
7171   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7172                    (mult:DI (sign_extend:DI
7173                               (match_operand:SI 1 "nonimmediate_operand" ""))
7174                             (sign_extend:DI
7175                               (match_operand:SI 2 "register_operand" ""))))
7176               (clobber (reg:CC FLAGS_REG))])]
7177   "!TARGET_64BIT"
7178   "")
7179
7180 (define_insn "*mulsidi3_insn"
7181   [(set (match_operand:DI 0 "register_operand" "=A")
7182         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7183                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7184    (clobber (reg:CC FLAGS_REG))]
7185   "!TARGET_64BIT
7186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7187   "imul{l}\t%2"
7188   [(set_attr "type" "imul")
7189    (set_attr "length_immediate" "0")
7190    (set (attr "athlon_decode")
7191      (if_then_else (eq_attr "cpu" "athlon")
7192         (const_string "vector")
7193         (const_string "double")))
7194    (set_attr "mode" "SI")])
7195
7196 (define_expand "umuldi3_highpart"
7197   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7198                    (truncate:DI
7199                      (lshiftrt:TI
7200                        (mult:TI (zero_extend:TI
7201                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7202                                 (zero_extend:TI
7203                                   (match_operand:DI 2 "register_operand" "")))
7204                        (const_int 64))))
7205               (clobber (match_scratch:DI 3 ""))
7206               (clobber (reg:CC FLAGS_REG))])]
7207   "TARGET_64BIT"
7208   "")
7209
7210 (define_insn "*umuldi3_highpart_rex64"
7211   [(set (match_operand:DI 0 "register_operand" "=d")
7212         (truncate:DI
7213           (lshiftrt:TI
7214             (mult:TI (zero_extend:TI
7215                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7216                      (zero_extend:TI
7217                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7218             (const_int 64))))
7219    (clobber (match_scratch:DI 3 "=1"))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "TARGET_64BIT
7222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7223   "mul{q}\t%2"
7224   [(set_attr "type" "imul")
7225    (set_attr "length_immediate" "0")
7226    (set (attr "athlon_decode")
7227      (if_then_else (eq_attr "cpu" "athlon")
7228         (const_string "vector")
7229         (const_string "double")))
7230    (set_attr "mode" "DI")])
7231
7232 (define_expand "umulsi3_highpart"
7233   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7234                    (truncate:SI
7235                      (lshiftrt:DI
7236                        (mult:DI (zero_extend:DI
7237                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7238                                 (zero_extend:DI
7239                                   (match_operand:SI 2 "register_operand" "")))
7240                        (const_int 32))))
7241               (clobber (match_scratch:SI 3 ""))
7242               (clobber (reg:CC FLAGS_REG))])]
7243   ""
7244   "")
7245
7246 (define_insn "*umulsi3_highpart_insn"
7247   [(set (match_operand:SI 0 "register_operand" "=d")
7248         (truncate:SI
7249           (lshiftrt:DI
7250             (mult:DI (zero_extend:DI
7251                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7252                      (zero_extend:DI
7253                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7254             (const_int 32))))
7255    (clobber (match_scratch:SI 3 "=1"))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7258   "mul{l}\t%2"
7259   [(set_attr "type" "imul")
7260    (set_attr "length_immediate" "0")
7261    (set (attr "athlon_decode")
7262      (if_then_else (eq_attr "cpu" "athlon")
7263         (const_string "vector")
7264         (const_string "double")))
7265    (set_attr "mode" "SI")])
7266
7267 (define_insn "*umulsi3_highpart_zext"
7268   [(set (match_operand:DI 0 "register_operand" "=d")
7269         (zero_extend:DI (truncate:SI
7270           (lshiftrt:DI
7271             (mult:DI (zero_extend:DI
7272                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7273                      (zero_extend:DI
7274                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7275             (const_int 32)))))
7276    (clobber (match_scratch:SI 3 "=1"))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_64BIT
7279    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7280   "mul{l}\t%2"
7281   [(set_attr "type" "imul")
7282    (set_attr "length_immediate" "0")
7283    (set (attr "athlon_decode")
7284      (if_then_else (eq_attr "cpu" "athlon")
7285         (const_string "vector")
7286         (const_string "double")))
7287    (set_attr "mode" "SI")])
7288
7289 (define_expand "smuldi3_highpart"
7290   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7291                    (truncate:DI
7292                      (lshiftrt:TI
7293                        (mult:TI (sign_extend:TI
7294                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7295                                 (sign_extend:TI
7296                                   (match_operand:DI 2 "register_operand" "")))
7297                        (const_int 64))))
7298               (clobber (match_scratch:DI 3 ""))
7299               (clobber (reg:CC FLAGS_REG))])]
7300   "TARGET_64BIT"
7301   "")
7302
7303 (define_insn "*smuldi3_highpart_rex64"
7304   [(set (match_operand:DI 0 "register_operand" "=d")
7305         (truncate:DI
7306           (lshiftrt:TI
7307             (mult:TI (sign_extend:TI
7308                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7309                      (sign_extend:TI
7310                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7311             (const_int 64))))
7312    (clobber (match_scratch:DI 3 "=1"))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "TARGET_64BIT
7315    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7316   "imul{q}\t%2"
7317   [(set_attr "type" "imul")
7318    (set (attr "athlon_decode")
7319      (if_then_else (eq_attr "cpu" "athlon")
7320         (const_string "vector")
7321         (const_string "double")))
7322    (set_attr "mode" "DI")])
7323
7324 (define_expand "smulsi3_highpart"
7325   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7326                    (truncate:SI
7327                      (lshiftrt:DI
7328                        (mult:DI (sign_extend:DI
7329                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7330                                 (sign_extend:DI
7331                                   (match_operand:SI 2 "register_operand" "")))
7332                        (const_int 32))))
7333               (clobber (match_scratch:SI 3 ""))
7334               (clobber (reg:CC FLAGS_REG))])]
7335   ""
7336   "")
7337
7338 (define_insn "*smulsi3_highpart_insn"
7339   [(set (match_operand:SI 0 "register_operand" "=d")
7340         (truncate:SI
7341           (lshiftrt:DI
7342             (mult:DI (sign_extend:DI
7343                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7344                      (sign_extend:DI
7345                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7346             (const_int 32))))
7347    (clobber (match_scratch:SI 3 "=1"))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7350   "imul{l}\t%2"
7351   [(set_attr "type" "imul")
7352    (set (attr "athlon_decode")
7353      (if_then_else (eq_attr "cpu" "athlon")
7354         (const_string "vector")
7355         (const_string "double")))
7356    (set_attr "mode" "SI")])
7357
7358 (define_insn "*smulsi3_highpart_zext"
7359   [(set (match_operand:DI 0 "register_operand" "=d")
7360         (zero_extend:DI (truncate:SI
7361           (lshiftrt:DI
7362             (mult:DI (sign_extend:DI
7363                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7364                      (sign_extend:DI
7365                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7366             (const_int 32)))))
7367    (clobber (match_scratch:SI 3 "=1"))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "TARGET_64BIT
7370    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7371   "imul{l}\t%2"
7372   [(set_attr "type" "imul")
7373    (set (attr "athlon_decode")
7374      (if_then_else (eq_attr "cpu" "athlon")
7375         (const_string "vector")
7376         (const_string "double")))
7377    (set_attr "mode" "SI")])
7378
7379 ;; The patterns that match these are at the end of this file.
7380
7381 (define_expand "mulxf3"
7382   [(set (match_operand:XF 0 "register_operand" "")
7383         (mult:XF (match_operand:XF 1 "register_operand" "")
7384                  (match_operand:XF 2 "register_operand" "")))]
7385   "TARGET_80387"
7386   "")
7387
7388 (define_expand "muldf3"
7389   [(set (match_operand:DF 0 "register_operand" "")
7390         (mult:DF (match_operand:DF 1 "register_operand" "")
7391                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7392   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7393   "")
7394
7395 (define_expand "mulsf3"
7396   [(set (match_operand:SF 0 "register_operand" "")
7397         (mult:SF (match_operand:SF 1 "register_operand" "")
7398                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7399   "TARGET_80387 || TARGET_SSE_MATH"
7400   "")
7401 \f
7402 ;; Divide instructions
7403
7404 (define_insn "divqi3"
7405   [(set (match_operand:QI 0 "register_operand" "=a")
7406         (div:QI (match_operand:HI 1 "register_operand" "0")
7407                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7408    (clobber (reg:CC FLAGS_REG))]
7409   "TARGET_QIMODE_MATH"
7410   "idiv{b}\t%2"
7411   [(set_attr "type" "idiv")
7412    (set_attr "mode" "QI")])
7413
7414 (define_insn "udivqi3"
7415   [(set (match_operand:QI 0 "register_operand" "=a")
7416         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7417                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_QIMODE_MATH"
7420   "div{b}\t%2"
7421   [(set_attr "type" "idiv")
7422    (set_attr "mode" "QI")])
7423
7424 ;; The patterns that match these are at the end of this file.
7425
7426 (define_expand "divxf3"
7427   [(set (match_operand:XF 0 "register_operand" "")
7428         (div:XF (match_operand:XF 1 "register_operand" "")
7429                 (match_operand:XF 2 "register_operand" "")))]
7430   "TARGET_80387"
7431   "")
7432
7433 (define_expand "divdf3"
7434   [(set (match_operand:DF 0 "register_operand" "")
7435         (div:DF (match_operand:DF 1 "register_operand" "")
7436                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7437    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7438    "")
7439  
7440 (define_expand "divsf3"
7441   [(set (match_operand:SF 0 "register_operand" "")
7442         (div:SF (match_operand:SF 1 "register_operand" "")
7443                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7444   "TARGET_80387 || TARGET_SSE_MATH"
7445   "")
7446 \f
7447 ;; Remainder instructions.
7448
7449 (define_expand "divmoddi4"
7450   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7451                    (div:DI (match_operand:DI 1 "register_operand" "")
7452                            (match_operand:DI 2 "nonimmediate_operand" "")))
7453               (set (match_operand:DI 3 "register_operand" "")
7454                    (mod:DI (match_dup 1) (match_dup 2)))
7455               (clobber (reg:CC FLAGS_REG))])]
7456   "TARGET_64BIT"
7457   "")
7458
7459 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7460 ;; Penalize eax case slightly because it results in worse scheduling
7461 ;; of code.
7462 (define_insn "*divmoddi4_nocltd_rex64"
7463   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7464         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7465                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7466    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7467         (mod:DI (match_dup 2) (match_dup 3)))
7468    (clobber (reg:CC FLAGS_REG))]
7469   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7470   "#"
7471   [(set_attr "type" "multi")])
7472
7473 (define_insn "*divmoddi4_cltd_rex64"
7474   [(set (match_operand:DI 0 "register_operand" "=a")
7475         (div:DI (match_operand:DI 2 "register_operand" "a")
7476                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7477    (set (match_operand:DI 1 "register_operand" "=&d")
7478         (mod:DI (match_dup 2) (match_dup 3)))
7479    (clobber (reg:CC FLAGS_REG))]
7480   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7481   "#"
7482   [(set_attr "type" "multi")])
7483
7484 (define_insn "*divmoddi_noext_rex64"
7485   [(set (match_operand:DI 0 "register_operand" "=a")
7486         (div:DI (match_operand:DI 1 "register_operand" "0")
7487                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7488    (set (match_operand:DI 3 "register_operand" "=d")
7489         (mod:DI (match_dup 1) (match_dup 2)))
7490    (use (match_operand:DI 4 "register_operand" "3"))
7491    (clobber (reg:CC FLAGS_REG))]
7492   "TARGET_64BIT"
7493   "idiv{q}\t%2"
7494   [(set_attr "type" "idiv")
7495    (set_attr "mode" "DI")])
7496
7497 (define_split
7498   [(set (match_operand:DI 0 "register_operand" "")
7499         (div:DI (match_operand:DI 1 "register_operand" "")
7500                 (match_operand:DI 2 "nonimmediate_operand" "")))
7501    (set (match_operand:DI 3 "register_operand" "")
7502         (mod:DI (match_dup 1) (match_dup 2)))
7503    (clobber (reg:CC FLAGS_REG))]
7504   "TARGET_64BIT && reload_completed"
7505   [(parallel [(set (match_dup 3)
7506                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7507               (clobber (reg:CC FLAGS_REG))])
7508    (parallel [(set (match_dup 0)
7509                    (div:DI (reg:DI 0) (match_dup 2)))
7510               (set (match_dup 3)
7511                    (mod:DI (reg:DI 0) (match_dup 2)))
7512               (use (match_dup 3))
7513               (clobber (reg:CC FLAGS_REG))])]
7514 {
7515   /* Avoid use of cltd in favor of a mov+shift.  */
7516   if (!TARGET_USE_CLTD && !optimize_size)
7517     {
7518       if (true_regnum (operands[1]))
7519         emit_move_insn (operands[0], operands[1]);
7520       else
7521         emit_move_insn (operands[3], operands[1]);
7522       operands[4] = operands[3];
7523     }
7524   else
7525     {
7526       if (true_regnum (operands[1]))
7527         abort();
7528       operands[4] = operands[1];
7529     }
7530 })
7531
7532
7533 (define_expand "divmodsi4"
7534   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7535                    (div:SI (match_operand:SI 1 "register_operand" "")
7536                            (match_operand:SI 2 "nonimmediate_operand" "")))
7537               (set (match_operand:SI 3 "register_operand" "")
7538                    (mod:SI (match_dup 1) (match_dup 2)))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   ""
7541   "")
7542
7543 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7544 ;; Penalize eax case slightly because it results in worse scheduling
7545 ;; of code.
7546 (define_insn "*divmodsi4_nocltd"
7547   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7548         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7549                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7550    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7551         (mod:SI (match_dup 2) (match_dup 3)))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "!optimize_size && !TARGET_USE_CLTD"
7554   "#"
7555   [(set_attr "type" "multi")])
7556
7557 (define_insn "*divmodsi4_cltd"
7558   [(set (match_operand:SI 0 "register_operand" "=a")
7559         (div:SI (match_operand:SI 2 "register_operand" "a")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d")
7562         (mod:SI (match_dup 2) (match_dup 3)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "optimize_size || TARGET_USE_CLTD"
7565   "#"
7566   [(set_attr "type" "multi")])
7567
7568 (define_insn "*divmodsi_noext"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 1 "register_operand" "0")
7571                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 3 "register_operand" "=d")
7573         (mod:SI (match_dup 1) (match_dup 2)))
7574    (use (match_operand:SI 4 "register_operand" "3"))
7575    (clobber (reg:CC FLAGS_REG))]
7576   ""
7577   "idiv{l}\t%2"
7578   [(set_attr "type" "idiv")
7579    (set_attr "mode" "SI")])
7580
7581 (define_split
7582   [(set (match_operand:SI 0 "register_operand" "")
7583         (div:SI (match_operand:SI 1 "register_operand" "")
7584                 (match_operand:SI 2 "nonimmediate_operand" "")))
7585    (set (match_operand:SI 3 "register_operand" "")
7586         (mod:SI (match_dup 1) (match_dup 2)))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "reload_completed"
7589   [(parallel [(set (match_dup 3)
7590                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7591               (clobber (reg:CC FLAGS_REG))])
7592    (parallel [(set (match_dup 0)
7593                    (div:SI (reg:SI 0) (match_dup 2)))
7594               (set (match_dup 3)
7595                    (mod:SI (reg:SI 0) (match_dup 2)))
7596               (use (match_dup 3))
7597               (clobber (reg:CC FLAGS_REG))])]
7598 {
7599   /* Avoid use of cltd in favor of a mov+shift.  */
7600   if (!TARGET_USE_CLTD && !optimize_size)
7601     {
7602       if (true_regnum (operands[1]))
7603         emit_move_insn (operands[0], operands[1]);
7604       else
7605         emit_move_insn (operands[3], operands[1]);
7606       operands[4] = operands[3];
7607     }
7608   else
7609     {
7610       if (true_regnum (operands[1]))
7611         abort();
7612       operands[4] = operands[1];
7613     }
7614 })
7615 ;; %%% Split me.
7616 (define_insn "divmodhi4"
7617   [(set (match_operand:HI 0 "register_operand" "=a")
7618         (div:HI (match_operand:HI 1 "register_operand" "0")
7619                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7620    (set (match_operand:HI 3 "register_operand" "=&d")
7621         (mod:HI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_HIMODE_MATH"
7624   "cwtd\;idiv{w}\t%2"
7625   [(set_attr "type" "multi")
7626    (set_attr "length_immediate" "0")
7627    (set_attr "mode" "SI")])
7628
7629 (define_insn "udivmoddi4"
7630   [(set (match_operand:DI 0 "register_operand" "=a")
7631         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7632                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7633    (set (match_operand:DI 3 "register_operand" "=&d")
7634         (umod:DI (match_dup 1) (match_dup 2)))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "TARGET_64BIT"
7637   "xor{q}\t%3, %3\;div{q}\t%2"
7638   [(set_attr "type" "multi")
7639    (set_attr "length_immediate" "0")
7640    (set_attr "mode" "DI")])
7641
7642 (define_insn "*udivmoddi4_noext"
7643   [(set (match_operand:DI 0 "register_operand" "=a")
7644         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7645                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7646    (set (match_operand:DI 3 "register_operand" "=d")
7647         (umod:DI (match_dup 1) (match_dup 2)))
7648    (use (match_dup 3))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "TARGET_64BIT"
7651   "div{q}\t%2"
7652   [(set_attr "type" "idiv")
7653    (set_attr "mode" "DI")])
7654
7655 (define_split
7656   [(set (match_operand:DI 0 "register_operand" "")
7657         (udiv:DI (match_operand:DI 1 "register_operand" "")
7658                  (match_operand:DI 2 "nonimmediate_operand" "")))
7659    (set (match_operand:DI 3 "register_operand" "")
7660         (umod:DI (match_dup 1) (match_dup 2)))
7661    (clobber (reg:CC FLAGS_REG))]
7662   "TARGET_64BIT && reload_completed"
7663   [(set (match_dup 3) (const_int 0))
7664    (parallel [(set (match_dup 0)
7665                    (udiv:DI (match_dup 1) (match_dup 2)))
7666               (set (match_dup 3)
7667                    (umod:DI (match_dup 1) (match_dup 2)))
7668               (use (match_dup 3))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "")
7671
7672 (define_insn "udivmodsi4"
7673   [(set (match_operand:SI 0 "register_operand" "=a")
7674         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7675                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7676    (set (match_operand:SI 3 "register_operand" "=&d")
7677         (umod:SI (match_dup 1) (match_dup 2)))
7678    (clobber (reg:CC FLAGS_REG))]
7679   ""
7680   "xor{l}\t%3, %3\;div{l}\t%2"
7681   [(set_attr "type" "multi")
7682    (set_attr "length_immediate" "0")
7683    (set_attr "mode" "SI")])
7684
7685 (define_insn "*udivmodsi4_noext"
7686   [(set (match_operand:SI 0 "register_operand" "=a")
7687         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7688                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7689    (set (match_operand:SI 3 "register_operand" "=d")
7690         (umod:SI (match_dup 1) (match_dup 2)))
7691    (use (match_dup 3))
7692    (clobber (reg:CC FLAGS_REG))]
7693   ""
7694   "div{l}\t%2"
7695   [(set_attr "type" "idiv")
7696    (set_attr "mode" "SI")])
7697
7698 (define_split
7699   [(set (match_operand:SI 0 "register_operand" "")
7700         (udiv:SI (match_operand:SI 1 "register_operand" "")
7701                  (match_operand:SI 2 "nonimmediate_operand" "")))
7702    (set (match_operand:SI 3 "register_operand" "")
7703         (umod:SI (match_dup 1) (match_dup 2)))
7704    (clobber (reg:CC FLAGS_REG))]
7705   "reload_completed"
7706   [(set (match_dup 3) (const_int 0))
7707    (parallel [(set (match_dup 0)
7708                    (udiv:SI (match_dup 1) (match_dup 2)))
7709               (set (match_dup 3)
7710                    (umod:SI (match_dup 1) (match_dup 2)))
7711               (use (match_dup 3))
7712               (clobber (reg:CC FLAGS_REG))])]
7713   "")
7714
7715 (define_expand "udivmodhi4"
7716   [(set (match_dup 4) (const_int 0))
7717    (parallel [(set (match_operand:HI 0 "register_operand" "")
7718                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7719                             (match_operand:HI 2 "nonimmediate_operand" "")))
7720               (set (match_operand:HI 3 "register_operand" "")
7721                    (umod:HI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 4))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "TARGET_HIMODE_MATH"
7725   "operands[4] = gen_reg_rtx (HImode);")
7726
7727 (define_insn "*udivmodhi_noext"
7728   [(set (match_operand:HI 0 "register_operand" "=a")
7729         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7730                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7731    (set (match_operand:HI 3 "register_operand" "=d")
7732         (umod:HI (match_dup 1) (match_dup 2)))
7733    (use (match_operand:HI 4 "register_operand" "3"))
7734    (clobber (reg:CC FLAGS_REG))]
7735   ""
7736   "div{w}\t%2"
7737   [(set_attr "type" "idiv")
7738    (set_attr "mode" "HI")])
7739
7740 ;; We cannot use div/idiv for double division, because it causes
7741 ;; "division by zero" on the overflow and that's not what we expect
7742 ;; from truncate.  Because true (non truncating) double division is
7743 ;; never generated, we can't create this insn anyway.
7744 ;
7745 ;(define_insn ""
7746 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7747 ;       (truncate:SI
7748 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7749 ;                  (zero_extend:DI
7750 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7751 ;   (set (match_operand:SI 3 "register_operand" "=d")
7752 ;       (truncate:SI
7753 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7754 ;   (clobber (reg:CC FLAGS_REG))]
7755 ;  ""
7756 ;  "div{l}\t{%2, %0|%0, %2}"
7757 ;  [(set_attr "type" "idiv")])
7758 \f
7759 ;;- Logical AND instructions
7760
7761 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7762 ;; Note that this excludes ah.
7763
7764 (define_insn "*testdi_1_rex64"
7765   [(set (reg FLAGS_REG)
7766         (compare
7767           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7768                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7769           (const_int 0)))]
7770   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7771    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7772   "@
7773    test{l}\t{%k1, %k0|%k0, %k1}
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{q}\t{%1, %0|%0, %1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}"
7778   [(set_attr "type" "test")
7779    (set_attr "modrm" "0,1,0,1,1")
7780    (set_attr "mode" "SI,SI,DI,DI,DI")
7781    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7782
7783 (define_insn "testsi_1"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7787                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7788           (const_int 0)))]
7789   "ix86_match_ccmode (insn, CCNOmode)
7790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791   "test{l}\t{%1, %0|%0, %1}"
7792   [(set_attr "type" "test")
7793    (set_attr "modrm" "0,1,1")
7794    (set_attr "mode" "SI")
7795    (set_attr "pent_pair" "uv,np,uv")])
7796
7797 (define_expand "testsi_ccno_1"
7798   [(set (reg:CCNO FLAGS_REG)
7799         (compare:CCNO
7800           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7801                   (match_operand:SI 1 "nonmemory_operand" ""))
7802           (const_int 0)))]
7803   ""
7804   "")
7805
7806 (define_insn "*testhi_1"
7807   [(set (reg FLAGS_REG)
7808         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7809                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7810                  (const_int 0)))]
7811   "ix86_match_ccmode (insn, CCNOmode)
7812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7813   "test{w}\t{%1, %0|%0, %1}"
7814   [(set_attr "type" "test")
7815    (set_attr "modrm" "0,1,1")
7816    (set_attr "mode" "HI")
7817    (set_attr "pent_pair" "uv,np,uv")])
7818
7819 (define_expand "testqi_ccz_1"
7820   [(set (reg:CCZ FLAGS_REG)
7821         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7822                              (match_operand:QI 1 "nonmemory_operand" ""))
7823                  (const_int 0)))]
7824   ""
7825   "")
7826
7827 (define_insn "*testqi_1_maybe_si"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:QI
7831             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7832             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7833           (const_int 0)))]
7834    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7835     && ix86_match_ccmode (insn,
7836                          GET_CODE (operands[1]) == CONST_INT
7837                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7838 {
7839   if (which_alternative == 3)
7840     {
7841       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7842         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7843       return "test{l}\t{%1, %k0|%k0, %1}";
7844     }
7845   return "test{b}\t{%1, %0|%0, %1}";
7846 }
7847   [(set_attr "type" "test")
7848    (set_attr "modrm" "0,1,1,1")
7849    (set_attr "mode" "QI,QI,QI,SI")
7850    (set_attr "pent_pair" "uv,np,uv,np")])
7851
7852 (define_insn "*testqi_1"
7853   [(set (reg FLAGS_REG)
7854         (compare
7855           (and:QI
7856             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7857             (match_operand:QI 1 "general_operand" "n,n,qn"))
7858           (const_int 0)))]
7859   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860    && ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%1, %0|%0, %1}"
7862   [(set_attr "type" "test")
7863    (set_attr "modrm" "0,1,1")
7864    (set_attr "mode" "QI")
7865    (set_attr "pent_pair" "uv,np,uv")])
7866
7867 (define_expand "testqi_ext_ccno_0"
7868   [(set (reg:CCNO FLAGS_REG)
7869         (compare:CCNO
7870           (and:SI
7871             (zero_extract:SI
7872               (match_operand 0 "ext_register_operand" "")
7873               (const_int 8)
7874               (const_int 8))
7875             (match_operand 1 "const_int_operand" ""))
7876           (const_int 0)))]
7877   ""
7878   "")
7879
7880 (define_insn "*testqi_ext_0"
7881   [(set (reg FLAGS_REG)
7882         (compare
7883           (and:SI
7884             (zero_extract:SI
7885               (match_operand 0 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8))
7888             (match_operand 1 "const_int_operand" "n"))
7889           (const_int 0)))]
7890   "ix86_match_ccmode (insn, CCNOmode)"
7891   "test{b}\t{%1, %h0|%h0, %1}"
7892   [(set_attr "type" "test")
7893    (set_attr "mode" "QI")
7894    (set_attr "length_immediate" "1")
7895    (set_attr "pent_pair" "np")])
7896
7897 (define_insn "*testqi_ext_1"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (zero_extend:SI
7906               (match_operand:QI 1 "general_operand" "Qm")))
7907           (const_int 0)))]
7908   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7909    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910   "test{b}\t{%1, %h0|%h0, %1}"
7911   [(set_attr "type" "test")
7912    (set_attr "mode" "QI")])
7913
7914 (define_insn "*testqi_ext_1_rex64"
7915   [(set (reg FLAGS_REG)
7916         (compare
7917           (and:SI
7918             (zero_extract:SI
7919               (match_operand 0 "ext_register_operand" "Q")
7920               (const_int 8)
7921               (const_int 8))
7922             (zero_extend:SI
7923               (match_operand:QI 1 "register_operand" "Q")))
7924           (const_int 0)))]
7925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7926   "test{b}\t{%1, %h0|%h0, %1}"
7927   [(set_attr "type" "test")
7928    (set_attr "mode" "QI")])
7929
7930 (define_insn "*testqi_ext_2"
7931   [(set (reg FLAGS_REG)
7932         (compare
7933           (and:SI
7934             (zero_extract:SI
7935               (match_operand 0 "ext_register_operand" "Q")
7936               (const_int 8)
7937               (const_int 8))
7938             (zero_extract:SI
7939               (match_operand 1 "ext_register_operand" "Q")
7940               (const_int 8)
7941               (const_int 8)))
7942           (const_int 0)))]
7943   "ix86_match_ccmode (insn, CCNOmode)"
7944   "test{b}\t{%h1, %h0|%h0, %h1}"
7945   [(set_attr "type" "test")
7946    (set_attr "mode" "QI")])
7947
7948 ;; Combine likes to form bit extractions for some tests.  Humor it.
7949 (define_insn "*testqi_ext_3"
7950   [(set (reg FLAGS_REG)
7951         (compare (zero_extract:SI
7952                    (match_operand 0 "nonimmediate_operand" "rm")
7953                    (match_operand:SI 1 "const_int_operand" "")
7954                    (match_operand:SI 2 "const_int_operand" ""))
7955                  (const_int 0)))]
7956   "ix86_match_ccmode (insn, CCNOmode)
7957    && (GET_MODE (operands[0]) == SImode
7958        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7959        || GET_MODE (operands[0]) == HImode
7960        || GET_MODE (operands[0]) == QImode)"
7961   "#")
7962
7963 (define_insn "*testqi_ext_3_rex64"
7964   [(set (reg FLAGS_REG)
7965         (compare (zero_extract:DI
7966                    (match_operand 0 "nonimmediate_operand" "rm")
7967                    (match_operand:DI 1 "const_int_operand" "")
7968                    (match_operand:DI 2 "const_int_operand" ""))
7969                  (const_int 0)))]
7970   "TARGET_64BIT
7971    && ix86_match_ccmode (insn, CCNOmode)
7972    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7973    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7974    /* Ensure that resulting mask is zero or sign extended operand.  */
7975    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7976        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7977            && INTVAL (operands[1]) > 32))
7978    && (GET_MODE (operands[0]) == SImode
7979        || GET_MODE (operands[0]) == DImode
7980        || GET_MODE (operands[0]) == HImode
7981        || GET_MODE (operands[0]) == QImode)"
7982   "#")
7983
7984 (define_split
7985   [(set (match_operand 0 "flags_reg_operand" "")
7986         (match_operator 1 "compare_operator"
7987           [(zero_extract
7988              (match_operand 2 "nonimmediate_operand" "")
7989              (match_operand 3 "const_int_operand" "")
7990              (match_operand 4 "const_int_operand" ""))
7991            (const_int 0)]))]
7992   "ix86_match_ccmode (insn, CCNOmode)"
7993   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7994 {
7995   rtx val = operands[2];
7996   HOST_WIDE_INT len = INTVAL (operands[3]);
7997   HOST_WIDE_INT pos = INTVAL (operands[4]);
7998   HOST_WIDE_INT mask;
7999   enum machine_mode mode, submode;
8000
8001   mode = GET_MODE (val);
8002   if (GET_CODE (val) == MEM)
8003     {
8004       /* ??? Combine likes to put non-volatile mem extractions in QImode
8005          no matter the size of the test.  So find a mode that works.  */
8006       if (! MEM_VOLATILE_P (val))
8007         {
8008           mode = smallest_mode_for_size (pos + len, MODE_INT);
8009           val = adjust_address (val, mode, 0);
8010         }
8011     }
8012   else if (GET_CODE (val) == SUBREG
8013            && (submode = GET_MODE (SUBREG_REG (val)),
8014                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8015            && pos + len <= GET_MODE_BITSIZE (submode))
8016     {
8017       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8018       mode = submode;
8019       val = SUBREG_REG (val);
8020     }
8021   else if (mode == HImode && pos + len <= 8)
8022     {
8023       /* Small HImode tests can be converted to QImode.  */
8024       mode = QImode;
8025       val = gen_lowpart (QImode, val);
8026     }
8027
8028   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8029   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8030
8031   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8032 })
8033
8034 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8035 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8036 ;; this is relatively important trick.
8037 ;; Do the conversion only post-reload to avoid limiting of the register class
8038 ;; to QI regs.
8039 (define_split
8040   [(set (match_operand 0 "flags_reg_operand" "")
8041         (match_operator 1 "compare_operator"
8042           [(and (match_operand 2 "register_operand" "")
8043                 (match_operand 3 "const_int_operand" ""))
8044            (const_int 0)]))]
8045    "reload_completed
8046     && QI_REG_P (operands[2])
8047     && GET_MODE (operands[2]) != QImode
8048     && ((ix86_match_ccmode (insn, CCZmode)
8049          && !(INTVAL (operands[3]) & ~(255 << 8)))
8050         || (ix86_match_ccmode (insn, CCNOmode)
8051             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8052   [(set (match_dup 0)
8053         (match_op_dup 1
8054           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8055                    (match_dup 3))
8056            (const_int 0)]))]
8057   "operands[2] = gen_lowpart (SImode, operands[2]);
8058    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8059
8060 (define_split
8061   [(set (match_operand 0 "flags_reg_operand" "")
8062         (match_operator 1 "compare_operator"
8063           [(and (match_operand 2 "nonimmediate_operand" "")
8064                 (match_operand 3 "const_int_operand" ""))
8065            (const_int 0)]))]
8066    "reload_completed
8067     && GET_MODE (operands[2]) != QImode
8068     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8069     && ((ix86_match_ccmode (insn, CCZmode)
8070          && !(INTVAL (operands[3]) & ~255))
8071         || (ix86_match_ccmode (insn, CCNOmode)
8072             && !(INTVAL (operands[3]) & ~127)))"
8073   [(set (match_dup 0)
8074         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8075                          (const_int 0)]))]
8076   "operands[2] = gen_lowpart (QImode, operands[2]);
8077    operands[3] = gen_lowpart (QImode, operands[3]);")
8078
8079
8080 ;; %%% This used to optimize known byte-wide and operations to memory,
8081 ;; and sometimes to QImode registers.  If this is considered useful,
8082 ;; it should be done with splitters.
8083
8084 (define_expand "anddi3"
8085   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8086         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8087                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8088    (clobber (reg:CC FLAGS_REG))]
8089   "TARGET_64BIT"
8090   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8091
8092 (define_insn "*anddi_1_rex64"
8093   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8094         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8095                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8098 {
8099   switch (get_attr_type (insn))
8100     {
8101     case TYPE_IMOVX:
8102       {
8103         enum machine_mode mode;
8104
8105         if (GET_CODE (operands[2]) != CONST_INT)
8106           abort ();
8107         if (INTVAL (operands[2]) == 0xff)
8108           mode = QImode;
8109         else if (INTVAL (operands[2]) == 0xffff)
8110           mode = HImode;
8111         else
8112           abort ();
8113         
8114         operands[1] = gen_lowpart (mode, operands[1]);
8115         if (mode == QImode)
8116           return "movz{bq|x}\t{%1,%0|%0, %1}";
8117         else
8118           return "movz{wq|x}\t{%1,%0|%0, %1}";
8119       }
8120
8121     default:
8122       if (! rtx_equal_p (operands[0], operands[1]))
8123         abort ();
8124       if (get_attr_mode (insn) == MODE_SI)
8125         return "and{l}\t{%k2, %k0|%k0, %k2}";
8126       else
8127         return "and{q}\t{%2, %0|%0, %2}";
8128     }
8129 }
8130   [(set_attr "type" "alu,alu,alu,imovx")
8131    (set_attr "length_immediate" "*,*,*,0")
8132    (set_attr "mode" "SI,DI,DI,DI")])
8133
8134 (define_insn "*anddi_2"
8135   [(set (reg FLAGS_REG)
8136         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8137                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8138                  (const_int 0)))
8139    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8140         (and:DI (match_dup 1) (match_dup 2)))]
8141   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142    && ix86_binary_operator_ok (AND, DImode, operands)"
8143   "@
8144    and{l}\t{%k2, %k0|%k0, %k2}
8145    and{q}\t{%2, %0|%0, %2}
8146    and{q}\t{%2, %0|%0, %2}"
8147   [(set_attr "type" "alu")
8148    (set_attr "mode" "SI,DI,DI")])
8149
8150 (define_expand "andsi3"
8151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8152         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8153                 (match_operand:SI 2 "general_operand" "")))
8154    (clobber (reg:CC FLAGS_REG))]
8155   ""
8156   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8157
8158 (define_insn "*andsi_1"
8159   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8160         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8161                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "ix86_binary_operator_ok (AND, SImode, operands)"
8164 {
8165   switch (get_attr_type (insn))
8166     {
8167     case TYPE_IMOVX:
8168       {
8169         enum machine_mode mode;
8170
8171         if (GET_CODE (operands[2]) != CONST_INT)
8172           abort ();
8173         if (INTVAL (operands[2]) == 0xff)
8174           mode = QImode;
8175         else if (INTVAL (operands[2]) == 0xffff)
8176           mode = HImode;
8177         else
8178           abort ();
8179         
8180         operands[1] = gen_lowpart (mode, operands[1]);
8181         if (mode == QImode)
8182           return "movz{bl|x}\t{%1,%0|%0, %1}";
8183         else
8184           return "movz{wl|x}\t{%1,%0|%0, %1}";
8185       }
8186
8187     default:
8188       if (! rtx_equal_p (operands[0], operands[1]))
8189         abort ();
8190       return "and{l}\t{%2, %0|%0, %2}";
8191     }
8192 }
8193   [(set_attr "type" "alu,alu,imovx")
8194    (set_attr "length_immediate" "*,*,0")
8195    (set_attr "mode" "SI")])
8196
8197 (define_split
8198   [(set (match_operand 0 "register_operand" "")
8199         (and (match_dup 0)
8200              (const_int -65536)))
8201    (clobber (reg:CC FLAGS_REG))]
8202   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8203   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8204   "operands[1] = gen_lowpart (HImode, operands[0]);")
8205
8206 (define_split
8207   [(set (match_operand 0 "ext_register_operand" "")
8208         (and (match_dup 0)
8209              (const_int -256)))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8212   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8213   "operands[1] = gen_lowpart (QImode, operands[0]);")
8214
8215 (define_split
8216   [(set (match_operand 0 "ext_register_operand" "")
8217         (and (match_dup 0)
8218              (const_int -65281)))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8221   [(parallel [(set (zero_extract:SI (match_dup 0)
8222                                     (const_int 8)
8223                                     (const_int 8))
8224                    (xor:SI 
8225                      (zero_extract:SI (match_dup 0)
8226                                       (const_int 8)
8227                                       (const_int 8))
8228                      (zero_extract:SI (match_dup 0)
8229                                       (const_int 8)
8230                                       (const_int 8))))
8231               (clobber (reg:CC FLAGS_REG))])]
8232   "operands[0] = gen_lowpart (SImode, operands[0]);")
8233
8234 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8235 (define_insn "*andsi_1_zext"
8236   [(set (match_operand:DI 0 "register_operand" "=r")
8237         (zero_extend:DI
8238           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8239                   (match_operand:SI 2 "general_operand" "rim"))))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8242   "and{l}\t{%2, %k0|%k0, %2}"
8243   [(set_attr "type" "alu")
8244    (set_attr "mode" "SI")])
8245
8246 (define_insn "*andsi_2"
8247   [(set (reg FLAGS_REG)
8248         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8249                          (match_operand:SI 2 "general_operand" "rim,ri"))
8250                  (const_int 0)))
8251    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8252         (and:SI (match_dup 1) (match_dup 2)))]
8253   "ix86_match_ccmode (insn, CCNOmode)
8254    && ix86_binary_operator_ok (AND, SImode, operands)"
8255   "and{l}\t{%2, %0|%0, %2}"
8256   [(set_attr "type" "alu")
8257    (set_attr "mode" "SI")])
8258
8259 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260 (define_insn "*andsi_2_zext"
8261   [(set (reg FLAGS_REG)
8262         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8263                          (match_operand:SI 2 "general_operand" "rim"))
8264                  (const_int 0)))
8265    (set (match_operand:DI 0 "register_operand" "=r")
8266         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8267   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8268    && ix86_binary_operator_ok (AND, SImode, operands)"
8269   "and{l}\t{%2, %k0|%k0, %2}"
8270   [(set_attr "type" "alu")
8271    (set_attr "mode" "SI")])
8272
8273 (define_expand "andhi3"
8274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8275         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8276                 (match_operand:HI 2 "general_operand" "")))
8277    (clobber (reg:CC FLAGS_REG))]
8278   "TARGET_HIMODE_MATH"
8279   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8280
8281 (define_insn "*andhi_1"
8282   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8283         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8284                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8285    (clobber (reg:CC FLAGS_REG))]
8286   "ix86_binary_operator_ok (AND, HImode, operands)"
8287 {
8288   switch (get_attr_type (insn))
8289     {
8290     case TYPE_IMOVX:
8291       if (GET_CODE (operands[2]) != CONST_INT)
8292         abort ();
8293       if (INTVAL (operands[2]) == 0xff)
8294         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8295       abort ();
8296
8297     default:
8298       if (! rtx_equal_p (operands[0], operands[1]))
8299         abort ();
8300
8301       return "and{w}\t{%2, %0|%0, %2}";
8302     }
8303 }
8304   [(set_attr "type" "alu,alu,imovx")
8305    (set_attr "length_immediate" "*,*,0")
8306    (set_attr "mode" "HI,HI,SI")])
8307
8308 (define_insn "*andhi_2"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8311                          (match_operand:HI 2 "general_operand" "rim,ri"))
8312                  (const_int 0)))
8313    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8314         (and:HI (match_dup 1) (match_dup 2)))]
8315   "ix86_match_ccmode (insn, CCNOmode)
8316    && ix86_binary_operator_ok (AND, HImode, operands)"
8317   "and{w}\t{%2, %0|%0, %2}"
8318   [(set_attr "type" "alu")
8319    (set_attr "mode" "HI")])
8320
8321 (define_expand "andqi3"
8322   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8323         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8324                 (match_operand:QI 2 "general_operand" "")))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "TARGET_QIMODE_MATH"
8327   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8328
8329 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8330 (define_insn "*andqi_1"
8331   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8332         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8333                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "ix86_binary_operator_ok (AND, QImode, operands)"
8336   "@
8337    and{b}\t{%2, %0|%0, %2}
8338    and{b}\t{%2, %0|%0, %2}
8339    and{l}\t{%k2, %k0|%k0, %k2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "mode" "QI,QI,SI")])
8342
8343 (define_insn "*andqi_1_slp"
8344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8345         (and:QI (match_dup 0)
8346                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350   "and{b}\t{%1, %0|%0, %1}"
8351   [(set_attr "type" "alu1")
8352    (set_attr "mode" "QI")])
8353
8354 (define_insn "*andqi_2_maybe_si"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:QI
8357                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8359                  (const_int 0)))
8360    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8361         (and:QI (match_dup 1) (match_dup 2)))]
8362   "ix86_binary_operator_ok (AND, QImode, operands)
8363    && ix86_match_ccmode (insn,
8364                          GET_CODE (operands[2]) == CONST_INT
8365                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8366 {
8367   if (which_alternative == 2)
8368     {
8369       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8370         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371       return "and{l}\t{%2, %k0|%k0, %2}";
8372     }
8373   return "and{b}\t{%2, %0|%0, %2}";
8374 }
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "QI,QI,SI")])
8377
8378 (define_insn "*andqi_2"
8379   [(set (reg FLAGS_REG)
8380         (compare (and:QI
8381                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8382                    (match_operand:QI 2 "general_operand" "qim,qi"))
8383                  (const_int 0)))
8384    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8385         (and:QI (match_dup 1) (match_dup 2)))]
8386   "ix86_match_ccmode (insn, CCNOmode)
8387    && ix86_binary_operator_ok (AND, QImode, operands)"
8388   "and{b}\t{%2, %0|%0, %2}"
8389   [(set_attr "type" "alu")
8390    (set_attr "mode" "QI")])
8391
8392 (define_insn "*andqi_2_slp"
8393   [(set (reg FLAGS_REG)
8394         (compare (and:QI
8395                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8396                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8397                  (const_int 0)))
8398    (set (strict_low_part (match_dup 0))
8399         (and:QI (match_dup 0) (match_dup 1)))]
8400   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8401    && ix86_match_ccmode (insn, CCNOmode)
8402    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8403   "and{b}\t{%1, %0|%0, %1}"
8404   [(set_attr "type" "alu1")
8405    (set_attr "mode" "QI")])
8406
8407 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8408 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8409 ;; for a QImode operand, which of course failed.
8410
8411 (define_insn "andqi_ext_0"
8412   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413                          (const_int 8)
8414                          (const_int 8))
8415         (and:SI 
8416           (zero_extract:SI
8417             (match_operand 1 "ext_register_operand" "0")
8418             (const_int 8)
8419             (const_int 8))
8420           (match_operand 2 "const_int_operand" "n")))
8421    (clobber (reg:CC FLAGS_REG))]
8422   ""
8423   "and{b}\t{%2, %h0|%h0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "1")
8426    (set_attr "mode" "QI")])
8427
8428 ;; Generated by peephole translating test to and.  This shows up
8429 ;; often in fp comparisons.
8430
8431 (define_insn "*andqi_ext_0_cc"
8432   [(set (reg FLAGS_REG)
8433         (compare
8434           (and:SI
8435             (zero_extract:SI
8436               (match_operand 1 "ext_register_operand" "0")
8437               (const_int 8)
8438               (const_int 8))
8439             (match_operand 2 "const_int_operand" "n"))
8440           (const_int 0)))
8441    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442                          (const_int 8)
8443                          (const_int 8))
8444         (and:SI 
8445           (zero_extract:SI
8446             (match_dup 1)
8447             (const_int 8)
8448             (const_int 8))
8449           (match_dup 2)))]
8450   "ix86_match_ccmode (insn, CCNOmode)"
8451   "and{b}\t{%2, %h0|%h0, %2}"
8452   [(set_attr "type" "alu")
8453    (set_attr "length_immediate" "1")
8454    (set_attr "mode" "QI")])
8455
8456 (define_insn "*andqi_ext_1"
8457   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (and:SI 
8461           (zero_extract:SI
8462             (match_operand 1 "ext_register_operand" "0")
8463             (const_int 8)
8464             (const_int 8))
8465           (zero_extend:SI
8466             (match_operand:QI 2 "general_operand" "Qm"))))
8467    (clobber (reg:CC FLAGS_REG))]
8468   "!TARGET_64BIT"
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "QI")])
8473
8474 (define_insn "*andqi_ext_1_rex64"
8475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8476                          (const_int 8)
8477                          (const_int 8))
8478         (and:SI 
8479           (zero_extract:SI
8480             (match_operand 1 "ext_register_operand" "0")
8481             (const_int 8)
8482             (const_int 8))
8483           (zero_extend:SI
8484             (match_operand 2 "ext_register_operand" "Q"))))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_64BIT"
8487   "and{b}\t{%2, %h0|%h0, %2}"
8488   [(set_attr "type" "alu")
8489    (set_attr "length_immediate" "0")
8490    (set_attr "mode" "QI")])
8491
8492 (define_insn "*andqi_ext_2"
8493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494                          (const_int 8)
8495                          (const_int 8))
8496         (and:SI
8497           (zero_extract:SI
8498             (match_operand 1 "ext_register_operand" "%0")
8499             (const_int 8)
8500             (const_int 8))
8501           (zero_extract:SI
8502             (match_operand 2 "ext_register_operand" "Q")
8503             (const_int 8)
8504             (const_int 8))))
8505    (clobber (reg:CC FLAGS_REG))]
8506   ""
8507   "and{b}\t{%h2, %h0|%h0, %h2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "length_immediate" "0")
8510    (set_attr "mode" "QI")])
8511
8512 ;; Convert wide AND instructions with immediate operand to shorter QImode
8513 ;; equivalents when possible.
8514 ;; Don't do the splitting with memory operands, since it introduces risk
8515 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8516 ;; for size, but that can (should?) be handled by generic code instead.
8517 (define_split
8518   [(set (match_operand 0 "register_operand" "")
8519         (and (match_operand 1 "register_operand" "")
8520              (match_operand 2 "const_int_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522    "reload_completed
8523     && QI_REG_P (operands[0])
8524     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8525     && !(~INTVAL (operands[2]) & ~(255 << 8))
8526     && GET_MODE (operands[0]) != QImode"
8527   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8528                    (and:SI (zero_extract:SI (match_dup 1)
8529                                             (const_int 8) (const_int 8))
8530                            (match_dup 2)))
8531               (clobber (reg:CC FLAGS_REG))])]
8532   "operands[0] = gen_lowpart (SImode, operands[0]);
8533    operands[1] = gen_lowpart (SImode, operands[1]);
8534    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8535
8536 ;; Since AND can be encoded with sign extended immediate, this is only
8537 ;; profitable when 7th bit is not set.
8538 (define_split
8539   [(set (match_operand 0 "register_operand" "")
8540         (and (match_operand 1 "general_operand" "")
8541              (match_operand 2 "const_int_operand" "")))
8542    (clobber (reg:CC FLAGS_REG))]
8543    "reload_completed
8544     && ANY_QI_REG_P (operands[0])
8545     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8546     && !(~INTVAL (operands[2]) & ~255)
8547     && !(INTVAL (operands[2]) & 128)
8548     && GET_MODE (operands[0]) != QImode"
8549   [(parallel [(set (strict_low_part (match_dup 0))
8550                    (and:QI (match_dup 1)
8551                            (match_dup 2)))
8552               (clobber (reg:CC FLAGS_REG))])]
8553   "operands[0] = gen_lowpart (QImode, operands[0]);
8554    operands[1] = gen_lowpart (QImode, operands[1]);
8555    operands[2] = gen_lowpart (QImode, operands[2]);")
8556 \f
8557 ;; Logical inclusive OR instructions
8558
8559 ;; %%% This used to optimize known byte-wide and operations to memory.
8560 ;; If this is considered useful, it should be done with splitters.
8561
8562 (define_expand "iordi3"
8563   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8564         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8565                 (match_operand:DI 2 "x86_64_general_operand" "")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "TARGET_64BIT"
8568   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8569
8570 (define_insn "*iordi_1_rex64"
8571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8572         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8573                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "TARGET_64BIT
8576    && ix86_binary_operator_ok (IOR, DImode, operands)"
8577   "or{q}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "DI")])
8580
8581 (define_insn "*iordi_2_rex64"
8582   [(set (reg FLAGS_REG)
8583         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8585                  (const_int 0)))
8586    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8587         (ior:DI (match_dup 1) (match_dup 2)))]
8588   "TARGET_64BIT
8589    && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, DImode, operands)"
8591   "or{q}\t{%2, %0|%0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "DI")])
8594
8595 (define_insn "*iordi_3_rex64"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8598                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8599                  (const_int 0)))
8600    (clobber (match_scratch:DI 0 "=r"))]
8601   "TARGET_64BIT
8602    && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, DImode, operands)"
8604   "or{q}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "DI")])
8607
8608
8609 (define_expand "iorsi3"
8610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8611         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8612                 (match_operand:SI 2 "general_operand" "")))
8613    (clobber (reg:CC FLAGS_REG))]
8614   ""
8615   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8616
8617 (define_insn "*iorsi_1"
8618   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8619         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8620                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "ix86_binary_operator_ok (IOR, SImode, operands)"
8623   "or{l}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "SI")])
8626
8627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8628 (define_insn "*iorsi_1_zext"
8629   [(set (match_operand:DI 0 "register_operand" "=rm")
8630         (zero_extend:DI
8631           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8632                   (match_operand:SI 2 "general_operand" "rim"))))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8635   "or{l}\t{%2, %k0|%k0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "SI")])
8638
8639 (define_insn "*iorsi_1_zext_imm"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8642                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT"
8645   "or{l}\t{%2, %k0|%k0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8648
8649 (define_insn "*iorsi_2"
8650   [(set (reg FLAGS_REG)
8651         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8652                          (match_operand:SI 2 "general_operand" "rim,ri"))
8653                  (const_int 0)))
8654    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8655         (ior:SI (match_dup 1) (match_dup 2)))]
8656   "ix86_match_ccmode (insn, CCNOmode)
8657    && ix86_binary_operator_ok (IOR, SImode, operands)"
8658   "or{l}\t{%2, %0|%0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8661
8662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8663 ;; ??? Special case for immediate operand is missing - it is tricky.
8664 (define_insn "*iorsi_2_zext"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667                          (match_operand:SI 2 "general_operand" "rim"))
8668                  (const_int 0)))
8669    (set (match_operand:DI 0 "register_operand" "=r")
8670         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8671   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8672    && ix86_binary_operator_ok (IOR, SImode, operands)"
8673   "or{l}\t{%2, %k0|%k0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "SI")])
8676
8677 (define_insn "*iorsi_2_zext_imm"
8678   [(set (reg FLAGS_REG)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "register_operand" "=r")
8683         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (IOR, SImode, operands)"
8686   "or{l}\t{%2, %k0|%k0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "SI")])
8689
8690 (define_insn "*iorsi_3"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand:SI 2 "general_operand" "rim"))
8694                  (const_int 0)))
8695    (clobber (match_scratch:SI 0 "=r"))]
8696   "ix86_match_ccmode (insn, CCNOmode)
8697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8698   "or{l}\t{%2, %0|%0, %2}"
8699   [(set_attr "type" "alu")
8700    (set_attr "mode" "SI")])
8701
8702 (define_expand "iorhi3"
8703   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8704         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8705                 (match_operand:HI 2 "general_operand" "")))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "TARGET_HIMODE_MATH"
8708   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8709
8710 (define_insn "*iorhi_1"
8711   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8712         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8713                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8714    (clobber (reg:CC FLAGS_REG))]
8715   "ix86_binary_operator_ok (IOR, HImode, operands)"
8716   "or{w}\t{%2, %0|%0, %2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "HI")])
8719
8720 (define_insn "*iorhi_2"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723                          (match_operand:HI 2 "general_operand" "rim,ri"))
8724                  (const_int 0)))
8725    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8726         (ior:HI (match_dup 1) (match_dup 2)))]
8727   "ix86_match_ccmode (insn, CCNOmode)
8728    && ix86_binary_operator_ok (IOR, HImode, operands)"
8729   "or{w}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "HI")])
8732
8733 (define_insn "*iorhi_3"
8734   [(set (reg FLAGS_REG)
8735         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8736                          (match_operand:HI 2 "general_operand" "rim"))
8737                  (const_int 0)))
8738    (clobber (match_scratch:HI 0 "=r"))]
8739   "ix86_match_ccmode (insn, CCNOmode)
8740    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8741   "or{w}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "HI")])
8744
8745 (define_expand "iorqi3"
8746   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8747         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8748                 (match_operand:QI 2 "general_operand" "")))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_QIMODE_MATH"
8751   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8752
8753 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8754 (define_insn "*iorqi_1"
8755   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8756         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8757                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "ix86_binary_operator_ok (IOR, QImode, operands)"
8760   "@
8761    or{b}\t{%2, %0|%0, %2}
8762    or{b}\t{%2, %0|%0, %2}
8763    or{l}\t{%k2, %k0|%k0, %k2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "mode" "QI,QI,SI")])
8766
8767 (define_insn "*iorqi_1_slp"
8768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8769         (ior:QI (match_dup 0)
8770                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8774   "or{b}\t{%1, %0|%0, %1}"
8775   [(set_attr "type" "alu1")
8776    (set_attr "mode" "QI")])
8777
8778 (define_insn "*iorqi_2"
8779   [(set (reg FLAGS_REG)
8780         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8781                          (match_operand:QI 2 "general_operand" "qim,qi"))
8782                  (const_int 0)))
8783    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8784         (ior:QI (match_dup 1) (match_dup 2)))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && ix86_binary_operator_ok (IOR, QImode, operands)"
8787   "or{b}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_2_slp"
8792   [(set (reg FLAGS_REG)
8793         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8794                          (match_operand:QI 1 "general_operand" "qim,qi"))
8795                  (const_int 0)))
8796    (set (strict_low_part (match_dup 0))
8797         (ior:QI (match_dup 0) (match_dup 1)))]
8798   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8799    && ix86_match_ccmode (insn, CCNOmode)
8800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8801   "or{b}\t{%1, %0|%0, %1}"
8802   [(set_attr "type" "alu1")
8803    (set_attr "mode" "QI")])
8804
8805 (define_insn "*iorqi_3"
8806   [(set (reg FLAGS_REG)
8807         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8808                          (match_operand:QI 2 "general_operand" "qim"))
8809                  (const_int 0)))
8810    (clobber (match_scratch:QI 0 "=q"))]
8811   "ix86_match_ccmode (insn, CCNOmode)
8812    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8813   "or{b}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "QI")])
8816
8817 (define_insn "iorqi_ext_0"
8818   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8819                          (const_int 8)
8820                          (const_int 8))
8821         (ior:SI 
8822           (zero_extract:SI
8823             (match_operand 1 "ext_register_operand" "0")
8824             (const_int 8)
8825             (const_int 8))
8826           (match_operand 2 "const_int_operand" "n")))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829   "or{b}\t{%2, %h0|%h0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "1")
8832    (set_attr "mode" "QI")])
8833
8834 (define_insn "*iorqi_ext_1"
8835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836                          (const_int 8)
8837                          (const_int 8))
8838         (ior:SI 
8839           (zero_extract:SI
8840             (match_operand 1 "ext_register_operand" "0")
8841             (const_int 8)
8842             (const_int 8))
8843           (zero_extend:SI
8844             (match_operand:QI 2 "general_operand" "Qm"))))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "!TARGET_64BIT
8847    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848   "or{b}\t{%2, %h0|%h0, %2}"
8849   [(set_attr "type" "alu")
8850    (set_attr "length_immediate" "0")
8851    (set_attr "mode" "QI")])
8852
8853 (define_insn "*iorqi_ext_1_rex64"
8854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8855                          (const_int 8)
8856                          (const_int 8))
8857         (ior:SI 
8858           (zero_extract:SI
8859             (match_operand 1 "ext_register_operand" "0")
8860             (const_int 8)
8861             (const_int 8))
8862           (zero_extend:SI
8863             (match_operand 2 "ext_register_operand" "Q"))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT
8866    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867   "or{b}\t{%2, %h0|%h0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "length_immediate" "0")
8870    (set_attr "mode" "QI")])
8871
8872 (define_insn "*iorqi_ext_2"
8873   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8874                          (const_int 8)
8875                          (const_int 8))
8876         (ior:SI 
8877           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8878                            (const_int 8)
8879                            (const_int 8))
8880           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8881                            (const_int 8)
8882                            (const_int 8))))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885   "ior{b}\t{%h2, %h0|%h0, %h2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "length_immediate" "0")
8888    (set_attr "mode" "QI")])
8889
8890 (define_split
8891   [(set (match_operand 0 "register_operand" "")
8892         (ior (match_operand 1 "register_operand" "")
8893              (match_operand 2 "const_int_operand" "")))
8894    (clobber (reg:CC FLAGS_REG))]
8895    "reload_completed
8896     && QI_REG_P (operands[0])
8897     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8898     && !(INTVAL (operands[2]) & ~(255 << 8))
8899     && GET_MODE (operands[0]) != QImode"
8900   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8901                    (ior:SI (zero_extract:SI (match_dup 1)
8902                                             (const_int 8) (const_int 8))
8903                            (match_dup 2)))
8904               (clobber (reg:CC FLAGS_REG))])]
8905   "operands[0] = gen_lowpart (SImode, operands[0]);
8906    operands[1] = gen_lowpart (SImode, operands[1]);
8907    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8908
8909 ;; Since OR can be encoded with sign extended immediate, this is only
8910 ;; profitable when 7th bit is set.
8911 (define_split
8912   [(set (match_operand 0 "register_operand" "")
8913         (ior (match_operand 1 "general_operand" "")
8914              (match_operand 2 "const_int_operand" "")))
8915    (clobber (reg:CC FLAGS_REG))]
8916    "reload_completed
8917     && ANY_QI_REG_P (operands[0])
8918     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8919     && !(INTVAL (operands[2]) & ~255)
8920     && (INTVAL (operands[2]) & 128)
8921     && GET_MODE (operands[0]) != QImode"
8922   [(parallel [(set (strict_low_part (match_dup 0))
8923                    (ior:QI (match_dup 1)
8924                            (match_dup 2)))
8925               (clobber (reg:CC FLAGS_REG))])]
8926   "operands[0] = gen_lowpart (QImode, operands[0]);
8927    operands[1] = gen_lowpart (QImode, operands[1]);
8928    operands[2] = gen_lowpart (QImode, operands[2]);")
8929 \f
8930 ;; Logical XOR instructions
8931
8932 ;; %%% This used to optimize known byte-wide and operations to memory.
8933 ;; If this is considered useful, it should be done with splitters.
8934
8935 (define_expand "xordi3"
8936   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8937         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8938                 (match_operand:DI 2 "x86_64_general_operand" "")))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_64BIT"
8941   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8942
8943 (define_insn "*xordi_1_rex64"
8944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8945         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8947    (clobber (reg:CC FLAGS_REG))]
8948   "TARGET_64BIT
8949    && ix86_binary_operator_ok (XOR, DImode, operands)"
8950   "@
8951    xor{q}\t{%2, %0|%0, %2}
8952    xor{q}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "DI,DI")])
8955
8956 (define_insn "*xordi_2_rex64"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8962         (xor:DI (match_dup 1) (match_dup 2)))]
8963   "TARGET_64BIT
8964    && ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (XOR, DImode, operands)"
8966   "@
8967    xor{q}\t{%2, %0|%0, %2}
8968    xor{q}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "DI,DI")])
8971
8972 (define_insn "*xordi_3_rex64"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8975                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8976                  (const_int 0)))
8977    (clobber (match_scratch:DI 0 "=r"))]
8978   "TARGET_64BIT
8979    && ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, DImode, operands)"
8981   "xor{q}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "DI")])
8984
8985 (define_expand "xorsi3"
8986   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8987         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8988                 (match_operand:SI 2 "general_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   ""
8991   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8992
8993 (define_insn "*xorsi_1"
8994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8995         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8996                 (match_operand:SI 2 "general_operand" "ri,rm")))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "ix86_binary_operator_ok (XOR, SImode, operands)"
8999   "xor{l}\t{%2, %0|%0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "SI")])
9002
9003 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9004 ;; Add speccase for immediates
9005 (define_insn "*xorsi_1_zext"
9006   [(set (match_operand:DI 0 "register_operand" "=r")
9007         (zero_extend:DI
9008           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9009                   (match_operand:SI 2 "general_operand" "rim"))))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %k0|%k0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9015
9016 (define_insn "*xorsi_1_zext_imm"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9019                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %k0|%k0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 (define_insn "*xorsi_2"
9027   [(set (reg FLAGS_REG)
9028         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9029                          (match_operand:SI 2 "general_operand" "rim,ri"))
9030                  (const_int 0)))
9031    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9032         (xor:SI (match_dup 1) (match_dup 2)))]
9033   "ix86_match_ccmode (insn, CCNOmode)
9034    && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9038
9039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9040 ;; ??? Special case for immediate operand is missing - it is tricky.
9041 (define_insn "*xorsi_2_zext"
9042   [(set (reg FLAGS_REG)
9043         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044                          (match_operand:SI 2 "general_operand" "rim"))
9045                  (const_int 0)))
9046    (set (match_operand:DI 0 "register_operand" "=r")
9047         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (XOR, SImode, operands)"
9050   "xor{l}\t{%2, %k0|%k0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 (define_insn "*xorsi_2_zext_imm"
9055   [(set (reg FLAGS_REG)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9058                  (const_int 0)))
9059    (set (match_operand:DI 0 "register_operand" "=r")
9060         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_binary_operator_ok (XOR, SImode, operands)"
9063   "xor{l}\t{%2, %k0|%k0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "SI")])
9066
9067 (define_insn "*xorsi_3"
9068   [(set (reg FLAGS_REG)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand:SI 2 "general_operand" "rim"))
9071                  (const_int 0)))
9072    (clobber (match_scratch:SI 0 "=r"))]
9073   "ix86_match_ccmode (insn, CCNOmode)
9074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9075   "xor{l}\t{%2, %0|%0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "mode" "SI")])
9078
9079 (define_expand "xorhi3"
9080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9081         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9082                 (match_operand:HI 2 "general_operand" "")))
9083    (clobber (reg:CC FLAGS_REG))]
9084   "TARGET_HIMODE_MATH"
9085   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9086
9087 (define_insn "*xorhi_1"
9088   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9089         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "ix86_binary_operator_ok (XOR, HImode, operands)"
9093   "xor{w}\t{%2, %0|%0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "HI")])
9096
9097 (define_insn "*xorhi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:HI 2 "general_operand" "rim,ri"))
9101                  (const_int 0)))
9102    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9103         (xor:HI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (XOR, HImode, operands)"
9106   "xor{w}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "HI")])
9109
9110 (define_insn "*xorhi_3"
9111   [(set (reg FLAGS_REG)
9112         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9113                          (match_operand:HI 2 "general_operand" "rim"))
9114                  (const_int 0)))
9115    (clobber (match_scratch:HI 0 "=r"))]
9116   "ix86_match_ccmode (insn, CCNOmode)
9117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9118   "xor{w}\t{%2, %0|%0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "HI")])
9121
9122 (define_expand "xorqi3"
9123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9124         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9125                 (match_operand:QI 2 "general_operand" "")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "TARGET_QIMODE_MATH"
9128   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9129
9130 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9131 (define_insn "*xorqi_1"
9132   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9133         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "ix86_binary_operator_ok (XOR, QImode, operands)"
9137   "@
9138    xor{b}\t{%2, %0|%0, %2}
9139    xor{b}\t{%2, %0|%0, %2}
9140    xor{l}\t{%k2, %k0|%k0, %k2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "mode" "QI,QI,SI")])
9143
9144 (define_insn "*xorqi_1_slp"
9145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9146         (xor:QI (match_dup 0)
9147                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9151   "xor{b}\t{%1, %0|%0, %1}"
9152   [(set_attr "type" "alu1")
9153    (set_attr "mode" "QI")])
9154
9155 (define_insn "xorqi_ext_0"
9156   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9157                          (const_int 8)
9158                          (const_int 8))
9159         (xor:SI 
9160           (zero_extract:SI
9161             (match_operand 1 "ext_register_operand" "0")
9162             (const_int 8)
9163             (const_int 8))
9164           (match_operand 2 "const_int_operand" "n")))
9165    (clobber (reg:CC FLAGS_REG))]
9166   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "xor{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "1")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*xorqi_ext_1"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (xor:SI 
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand:QI 2 "general_operand" "Qm"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "!TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "xor{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9190
9191 (define_insn "*xorqi_ext_1_rex64"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (xor:SI 
9196           (zero_extract:SI
9197             (match_operand 1 "ext_register_operand" "0")
9198             (const_int 8)
9199             (const_int 8))
9200           (zero_extend:SI
9201             (match_operand 2 "ext_register_operand" "Q"))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "TARGET_64BIT
9204    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205   "xor{b}\t{%2, %h0|%h0, %2}"
9206   [(set_attr "type" "alu")
9207    (set_attr "length_immediate" "0")
9208    (set_attr "mode" "QI")])
9209
9210 (define_insn "*xorqi_ext_2"
9211   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9212                          (const_int 8)
9213                          (const_int 8))
9214         (xor:SI 
9215           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9216                            (const_int 8)
9217                            (const_int 8))
9218           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9219                            (const_int 8)
9220                            (const_int 8))))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223   "xor{b}\t{%h2, %h0|%h0, %h2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_cc_1"
9229   [(set (reg FLAGS_REG)
9230         (compare
9231           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9232                   (match_operand:QI 2 "general_operand" "qim,qi"))
9233           (const_int 0)))
9234    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9235         (xor:QI (match_dup 1) (match_dup 2)))]
9236   "ix86_match_ccmode (insn, CCNOmode)
9237    && ix86_binary_operator_ok (XOR, QImode, operands)"
9238   "xor{b}\t{%2, %0|%0, %2}"
9239   [(set_attr "type" "alu")
9240    (set_attr "mode" "QI")])
9241
9242 (define_insn "*xorqi_2_slp"
9243   [(set (reg FLAGS_REG)
9244         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9245                          (match_operand:QI 1 "general_operand" "qim,qi"))
9246                  (const_int 0)))
9247    (set (strict_low_part (match_dup 0))
9248         (xor:QI (match_dup 0) (match_dup 1)))]
9249   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9250    && ix86_match_ccmode (insn, CCNOmode)
9251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9252   "xor{b}\t{%1, %0|%0, %1}"
9253   [(set_attr "type" "alu1")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_cc_2"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9260                   (match_operand:QI 2 "general_operand" "qim"))
9261           (const_int 0)))
9262    (clobber (match_scratch:QI 0 "=q"))]
9263   "ix86_match_ccmode (insn, CCNOmode)
9264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9265   "xor{b}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "QI")])
9268
9269 (define_insn "*xorqi_cc_ext_1"
9270   [(set (reg FLAGS_REG)
9271         (compare
9272           (xor:SI
9273             (zero_extract:SI
9274               (match_operand 1 "ext_register_operand" "0")
9275               (const_int 8)
9276               (const_int 8))
9277             (match_operand:QI 2 "general_operand" "qmn"))
9278           (const_int 0)))
9279    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9280                          (const_int 8)
9281                          (const_int 8))
9282         (xor:SI 
9283           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9284           (match_dup 2)))]
9285   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9286   "xor{b}\t{%2, %h0|%h0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "QI")])
9289
9290 (define_insn "*xorqi_cc_ext_1_rex64"
9291   [(set (reg FLAGS_REG)
9292         (compare
9293           (xor:SI
9294             (zero_extract:SI
9295               (match_operand 1 "ext_register_operand" "0")
9296               (const_int 8)
9297               (const_int 8))
9298             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9299           (const_int 0)))
9300    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9301                          (const_int 8)
9302                          (const_int 8))
9303         (xor:SI 
9304           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9305           (match_dup 2)))]
9306   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9307   "xor{b}\t{%2, %h0|%h0, %2}"
9308   [(set_attr "type" "alu")
9309    (set_attr "mode" "QI")])
9310
9311 (define_expand "xorqi_cc_ext_1"
9312   [(parallel [
9313      (set (reg:CCNO FLAGS_REG)
9314           (compare:CCNO
9315             (xor:SI
9316               (zero_extract:SI
9317                 (match_operand 1 "ext_register_operand" "")
9318                 (const_int 8)
9319                 (const_int 8))
9320               (match_operand:QI 2 "general_operand" ""))
9321             (const_int 0)))
9322      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9323                            (const_int 8)
9324                            (const_int 8))
9325           (xor:SI 
9326             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9327             (match_dup 2)))])]
9328   ""
9329   "")
9330
9331 (define_split
9332   [(set (match_operand 0 "register_operand" "")
9333         (xor (match_operand 1 "register_operand" "")
9334              (match_operand 2 "const_int_operand" "")))
9335    (clobber (reg:CC FLAGS_REG))]
9336    "reload_completed
9337     && QI_REG_P (operands[0])
9338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339     && !(INTVAL (operands[2]) & ~(255 << 8))
9340     && GET_MODE (operands[0]) != QImode"
9341   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9342                    (xor:SI (zero_extract:SI (match_dup 1)
9343                                             (const_int 8) (const_int 8))
9344                            (match_dup 2)))
9345               (clobber (reg:CC FLAGS_REG))])]
9346   "operands[0] = gen_lowpart (SImode, operands[0]);
9347    operands[1] = gen_lowpart (SImode, operands[1]);
9348    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9349
9350 ;; Since XOR can be encoded with sign extended immediate, this is only
9351 ;; profitable when 7th bit is set.
9352 (define_split
9353   [(set (match_operand 0 "register_operand" "")
9354         (xor (match_operand 1 "general_operand" "")
9355              (match_operand 2 "const_int_operand" "")))
9356    (clobber (reg:CC FLAGS_REG))]
9357    "reload_completed
9358     && ANY_QI_REG_P (operands[0])
9359     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9360     && !(INTVAL (operands[2]) & ~255)
9361     && (INTVAL (operands[2]) & 128)
9362     && GET_MODE (operands[0]) != QImode"
9363   [(parallel [(set (strict_low_part (match_dup 0))
9364                    (xor:QI (match_dup 1)
9365                            (match_dup 2)))
9366               (clobber (reg:CC FLAGS_REG))])]
9367   "operands[0] = gen_lowpart (QImode, operands[0]);
9368    operands[1] = gen_lowpart (QImode, operands[1]);
9369    operands[2] = gen_lowpart (QImode, operands[2]);")
9370 \f
9371 ;; Negation instructions
9372
9373 (define_expand "negdi2"
9374   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9375                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9376               (clobber (reg:CC FLAGS_REG))])]
9377   ""
9378   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9379
9380 (define_insn "*negdi2_1"
9381   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9382         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "!TARGET_64BIT
9385    && ix86_unary_operator_ok (NEG, DImode, operands)"
9386   "#")
9387
9388 (define_split
9389   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390         (neg:DI (match_operand:DI 1 "general_operand" "")))
9391    (clobber (reg:CC FLAGS_REG))]
9392   "!TARGET_64BIT && reload_completed"
9393   [(parallel
9394     [(set (reg:CCZ FLAGS_REG)
9395           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9396      (set (match_dup 0) (neg:SI (match_dup 2)))])
9397    (parallel
9398     [(set (match_dup 1)
9399           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9400                             (match_dup 3))
9401                    (const_int 0)))
9402      (clobber (reg:CC FLAGS_REG))])
9403    (parallel
9404     [(set (match_dup 1)
9405           (neg:SI (match_dup 1)))
9406      (clobber (reg:CC FLAGS_REG))])]
9407   "split_di (operands+1, 1, operands+2, operands+3);
9408    split_di (operands+0, 1, operands+0, operands+1);")
9409
9410 (define_insn "*negdi2_1_rex64"
9411   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9413    (clobber (reg:CC FLAGS_REG))]
9414   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415   "neg{q}\t%0"
9416   [(set_attr "type" "negnot")
9417    (set_attr "mode" "DI")])
9418
9419 ;; The problem with neg is that it does not perform (compare x 0),
9420 ;; it really performs (compare 0 x), which leaves us with the zero
9421 ;; flag being the only useful item.
9422
9423 (define_insn "*negdi2_cmpz_rex64"
9424   [(set (reg:CCZ FLAGS_REG)
9425         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9426                      (const_int 0)))
9427    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9428         (neg:DI (match_dup 1)))]
9429   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9430   "neg{q}\t%0"
9431   [(set_attr "type" "negnot")
9432    (set_attr "mode" "DI")])
9433
9434
9435 (define_expand "negsi2"
9436   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9437                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9438               (clobber (reg:CC FLAGS_REG))])]
9439   ""
9440   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9441
9442 (define_insn "*negsi2_1"
9443   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9444         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "ix86_unary_operator_ok (NEG, SImode, operands)"
9447   "neg{l}\t%0"
9448   [(set_attr "type" "negnot")
9449    (set_attr "mode" "SI")])
9450
9451 ;; Combine is quite creative about this pattern.
9452 (define_insn "*negsi2_1_zext"
9453   [(set (match_operand:DI 0 "register_operand" "=r")
9454         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9455                                         (const_int 32)))
9456                      (const_int 32)))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9459   "neg{l}\t%k0"
9460   [(set_attr "type" "negnot")
9461    (set_attr "mode" "SI")])
9462
9463 ;; The problem with neg is that it does not perform (compare x 0),
9464 ;; it really performs (compare 0 x), which leaves us with the zero
9465 ;; flag being the only useful item.
9466
9467 (define_insn "*negsi2_cmpz"
9468   [(set (reg:CCZ FLAGS_REG)
9469         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9470                      (const_int 0)))
9471    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9472         (neg:SI (match_dup 1)))]
9473   "ix86_unary_operator_ok (NEG, SImode, operands)"
9474   "neg{l}\t%0"
9475   [(set_attr "type" "negnot")
9476    (set_attr "mode" "SI")])
9477
9478 (define_insn "*negsi2_cmpz_zext"
9479   [(set (reg:CCZ FLAGS_REG)
9480         (compare:CCZ (lshiftrt:DI
9481                        (neg:DI (ashift:DI
9482                                  (match_operand:DI 1 "register_operand" "0")
9483                                  (const_int 32)))
9484                        (const_int 32))
9485                      (const_int 0)))
9486    (set (match_operand:DI 0 "register_operand" "=r")
9487         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9488                                         (const_int 32)))
9489                      (const_int 32)))]
9490   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9491   "neg{l}\t%k0"
9492   [(set_attr "type" "negnot")
9493    (set_attr "mode" "SI")])
9494
9495 (define_expand "neghi2"
9496   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9497                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9498               (clobber (reg:CC FLAGS_REG))])]
9499   "TARGET_HIMODE_MATH"
9500   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9501
9502 (define_insn "*neghi2_1"
9503   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9504         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9505    (clobber (reg:CC FLAGS_REG))]
9506   "ix86_unary_operator_ok (NEG, HImode, operands)"
9507   "neg{w}\t%0"
9508   [(set_attr "type" "negnot")
9509    (set_attr "mode" "HI")])
9510
9511 (define_insn "*neghi2_cmpz"
9512   [(set (reg:CCZ FLAGS_REG)
9513         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9514                      (const_int 0)))
9515    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9516         (neg:HI (match_dup 1)))]
9517   "ix86_unary_operator_ok (NEG, HImode, operands)"
9518   "neg{w}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "HI")])
9521
9522 (define_expand "negqi2"
9523   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9524                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9525               (clobber (reg:CC FLAGS_REG))])]
9526   "TARGET_QIMODE_MATH"
9527   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9528
9529 (define_insn "*negqi2_1"
9530   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9531         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9532    (clobber (reg:CC FLAGS_REG))]
9533   "ix86_unary_operator_ok (NEG, QImode, operands)"
9534   "neg{b}\t%0"
9535   [(set_attr "type" "negnot")
9536    (set_attr "mode" "QI")])
9537
9538 (define_insn "*negqi2_cmpz"
9539   [(set (reg:CCZ FLAGS_REG)
9540         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9541                      (const_int 0)))
9542    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9543         (neg:QI (match_dup 1)))]
9544   "ix86_unary_operator_ok (NEG, QImode, operands)"
9545   "neg{b}\t%0"
9546   [(set_attr "type" "negnot")
9547    (set_attr "mode" "QI")])
9548
9549 ;; Changing of sign for FP values is doable using integer unit too.
9550
9551 (define_expand "negsf2"
9552   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9553         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9554   "TARGET_80387 || TARGET_SSE_MATH"
9555   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9556
9557 (define_expand "abssf2"
9558   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9559         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9560   "TARGET_80387 || TARGET_SSE_MATH"
9561   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9562
9563 (define_insn "*absnegsf2_mixed"
9564   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9565         (match_operator:SF 3 "absneg_operator"
9566           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9567    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9568    (clobber (reg:CC FLAGS_REG))]
9569   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9570    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9571   "#")
9572
9573 (define_insn "*absnegsf2_sse"
9574   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9575         (match_operator:SF 3 "absneg_operator"
9576           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9577    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_SSE_MATH
9580    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581   "#")
9582
9583 (define_insn "*absnegsf2_i387"
9584   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9585         (match_operator:SF 3 "absneg_operator"
9586           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9587    (use (match_operand 2 "" ""))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "TARGET_80387 && !TARGET_SSE_MATH
9590    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9591   "#")
9592
9593 (define_expand "negdf2"
9594   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9595         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9597   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9598
9599 (define_expand "absdf2"
9600   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9601         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9602   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9603   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9604
9605 (define_insn "*absnegdf2_mixed"
9606   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9607         (match_operator:DF 3 "absneg_operator"
9608           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9609    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9610    (clobber (reg:CC FLAGS_REG))]
9611   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9612    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9613   "#")
9614
9615 (define_insn "*absnegdf2_sse"
9616   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9617         (match_operator:DF 3 "absneg_operator"
9618           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9619    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "TARGET_SSE2 && TARGET_SSE_MATH
9622    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9623   "#")
9624
9625 (define_insn "*absnegdf2_i387"
9626   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9627         (match_operator:DF 3 "absneg_operator"
9628           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9629    (use (match_operand 2 "" ""))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9632    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9633   "#")
9634
9635 (define_expand "negxf2"
9636   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9637         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9638   "TARGET_80387"
9639   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9640
9641 (define_expand "absxf2"
9642   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9643         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9644   "TARGET_80387"
9645   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9646
9647 (define_insn "*absnegxf2_i387"
9648   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9649         (match_operator:XF 3 "absneg_operator"
9650           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9651    (use (match_operand 2 "" ""))
9652    (clobber (reg:CC FLAGS_REG))]
9653   "TARGET_80387
9654    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9655   "#")
9656
9657 ;; Splitters for fp abs and neg.
9658
9659 (define_split
9660   [(set (match_operand 0 "fp_register_operand" "")
9661         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9662    (use (match_operand 2 "" ""))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "reload_completed"
9665   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9666
9667 (define_split
9668   [(set (match_operand 0 "register_operand" "")
9669         (match_operator 3 "absneg_operator"
9670           [(match_operand 1 "register_operand" "")]))
9671    (use (match_operand 2 "nonimmediate_operand" ""))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "reload_completed && SSE_REG_P (operands[0])"
9674   [(set (match_dup 0) (match_dup 3))]
9675 {
9676   enum machine_mode mode = GET_MODE (operands[0]);
9677   enum machine_mode vmode = GET_MODE (operands[2]);
9678   rtx tmp;
9679   
9680   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9681   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9682   if (operands_match_p (operands[0], operands[2]))
9683     {
9684       tmp = operands[1];
9685       operands[1] = operands[2];
9686       operands[2] = tmp;
9687     }
9688   if (GET_CODE (operands[3]) == ABS)
9689     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9690   else
9691     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9692   operands[3] = tmp;
9693 })
9694
9695 (define_split
9696   [(set (match_operand:SF 0 "register_operand" "")
9697         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9698    (use (match_operand:V4SF 2 "" ""))
9699    (clobber (reg:CC FLAGS_REG))]
9700   "reload_completed"
9701   [(parallel [(set (match_dup 0) (match_dup 1))
9702               (clobber (reg:CC FLAGS_REG))])]
9703
9704   rtx tmp;
9705   operands[0] = gen_lowpart (SImode, operands[0]);
9706   if (GET_CODE (operands[1]) == ABS)
9707     {
9708       tmp = gen_int_mode (0x7fffffff, SImode);
9709       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9710     }
9711   else
9712     {
9713       tmp = gen_int_mode (0x80000000, SImode);
9714       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9715     }
9716   operands[1] = tmp;
9717 })
9718
9719 (define_split
9720   [(set (match_operand:DF 0 "register_operand" "")
9721         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed"
9725   [(parallel [(set (match_dup 0) (match_dup 1))
9726               (clobber (reg:CC FLAGS_REG))])]
9727 {
9728   rtx tmp;
9729   if (TARGET_64BIT)
9730     {
9731       tmp = gen_lowpart (DImode, operands[0]);
9732       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9733       operands[0] = tmp;
9734
9735       if (GET_CODE (operands[1]) == ABS)
9736         tmp = const0_rtx;
9737       else
9738         tmp = gen_rtx_NOT (DImode, tmp);
9739     }
9740   else
9741     {
9742       operands[0] = gen_highpart (SImode, operands[0]);
9743       if (GET_CODE (operands[1]) == ABS)
9744         {
9745           tmp = gen_int_mode (0x7fffffff, SImode);
9746           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747         }
9748       else
9749         {
9750           tmp = gen_int_mode (0x80000000, SImode);
9751           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752         }
9753     }
9754   operands[1] = tmp;
9755 })
9756
9757 (define_split
9758   [(set (match_operand:XF 0 "register_operand" "")
9759         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9760    (use (match_operand 2 "" ""))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "reload_completed"
9763   [(parallel [(set (match_dup 0) (match_dup 1))
9764               (clobber (reg:CC FLAGS_REG))])]
9765 {
9766   rtx tmp;
9767   operands[0] = gen_rtx_REG (SImode,
9768                              true_regnum (operands[0])
9769                              + (TARGET_64BIT ? 1 : 2));
9770   if (GET_CODE (operands[1]) == ABS)
9771     {
9772       tmp = GEN_INT (0x7fff);
9773       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9774     }
9775   else
9776     {
9777       tmp = GEN_INT (0x8000);
9778       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9779     }
9780   operands[1] = tmp;
9781 })
9782
9783 (define_split
9784   [(set (match_operand 0 "memory_operand" "")
9785         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9786    (use (match_operand 2 "" ""))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "reload_completed"
9789   [(parallel [(set (match_dup 0) (match_dup 1))
9790               (clobber (reg:CC FLAGS_REG))])]
9791 {
9792   enum machine_mode mode = GET_MODE (operands[0]);
9793   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9794   rtx tmp;
9795
9796   operands[0] = adjust_address (operands[0], QImode, size - 1);
9797   if (GET_CODE (operands[1]) == ABS)
9798     {
9799       tmp = gen_int_mode (0x7f, QImode);
9800       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9801     }
9802   else
9803     {
9804       tmp = gen_int_mode (0x80, QImode);
9805       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9806     }
9807   operands[1] = tmp;
9808 })
9809
9810 ;; Conditionalize these after reload. If they match before reload, we 
9811 ;; lose the clobber and ability to use integer instructions.
9812
9813 (define_insn "*negsf2_1"
9814   [(set (match_operand:SF 0 "register_operand" "=f")
9815         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9816   "TARGET_80387 && reload_completed"
9817   "fchs"
9818   [(set_attr "type" "fsgn")
9819    (set_attr "mode" "SF")])
9820
9821 (define_insn "*negdf2_1"
9822   [(set (match_operand:DF 0 "register_operand" "=f")
9823         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9824   "TARGET_80387 && reload_completed"
9825   "fchs"
9826   [(set_attr "type" "fsgn")
9827    (set_attr "mode" "DF")])
9828
9829 (define_insn "*negxf2_1"
9830   [(set (match_operand:XF 0 "register_operand" "=f")
9831         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9832   "TARGET_80387 && reload_completed"
9833   "fchs"
9834   [(set_attr "type" "fsgn")
9835    (set_attr "mode" "XF")])
9836
9837 (define_insn "*abssf2_1"
9838   [(set (match_operand:SF 0 "register_operand" "=f")
9839         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9840   "TARGET_80387 && reload_completed"
9841   "fabs"
9842   [(set_attr "type" "fsgn")
9843    (set_attr "mode" "SF")])
9844
9845 (define_insn "*absdf2_1"
9846   [(set (match_operand:DF 0 "register_operand" "=f")
9847         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9848   "TARGET_80387 && reload_completed"
9849   "fabs"
9850   [(set_attr "type" "fsgn")
9851    (set_attr "mode" "DF")])
9852
9853 (define_insn "*absxf2_1"
9854   [(set (match_operand:XF 0 "register_operand" "=f")
9855         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9856   "TARGET_80387 && reload_completed"
9857   "fabs"
9858   [(set_attr "type" "fsgn")
9859    (set_attr "mode" "DF")])
9860
9861 (define_insn "*negextendsfdf2"
9862   [(set (match_operand:DF 0 "register_operand" "=f")
9863         (neg:DF (float_extend:DF
9864                   (match_operand:SF 1 "register_operand" "0"))))]
9865   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9866   "fchs"
9867   [(set_attr "type" "fsgn")
9868    (set_attr "mode" "DF")])
9869
9870 (define_insn "*negextenddfxf2"
9871   [(set (match_operand:XF 0 "register_operand" "=f")
9872         (neg:XF (float_extend:XF
9873                   (match_operand:DF 1 "register_operand" "0"))))]
9874   "TARGET_80387"
9875   "fchs"
9876   [(set_attr "type" "fsgn")
9877    (set_attr "mode" "XF")])
9878
9879 (define_insn "*negextendsfxf2"
9880   [(set (match_operand:XF 0 "register_operand" "=f")
9881         (neg:XF (float_extend:XF
9882                   (match_operand:SF 1 "register_operand" "0"))))]
9883   "TARGET_80387"
9884   "fchs"
9885   [(set_attr "type" "fsgn")
9886    (set_attr "mode" "XF")])
9887
9888 (define_insn "*absextendsfdf2"
9889   [(set (match_operand:DF 0 "register_operand" "=f")
9890         (abs:DF (float_extend:DF
9891                   (match_operand:SF 1 "register_operand" "0"))))]
9892   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9893   "fabs"
9894   [(set_attr "type" "fsgn")
9895    (set_attr "mode" "DF")])
9896
9897 (define_insn "*absextenddfxf2"
9898   [(set (match_operand:XF 0 "register_operand" "=f")
9899         (abs:XF (float_extend:XF
9900           (match_operand:DF 1 "register_operand" "0"))))]
9901   "TARGET_80387"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "XF")])
9905
9906 (define_insn "*absextendsfxf2"
9907   [(set (match_operand:XF 0 "register_operand" "=f")
9908         (abs:XF (float_extend:XF
9909           (match_operand:SF 1 "register_operand" "0"))))]
9910   "TARGET_80387"
9911   "fabs"
9912   [(set_attr "type" "fsgn")
9913    (set_attr "mode" "XF")])
9914 \f
9915 ;; One complement instructions
9916
9917 (define_expand "one_cmpldi2"
9918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9920   "TARGET_64BIT"
9921   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9922
9923 (define_insn "*one_cmpldi2_1_rex64"
9924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9925         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9926   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9927   "not{q}\t%0"
9928   [(set_attr "type" "negnot")
9929    (set_attr "mode" "DI")])
9930
9931 (define_insn "*one_cmpldi2_2_rex64"
9932   [(set (reg FLAGS_REG)
9933         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9934                  (const_int 0)))
9935    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9936         (not:DI (match_dup 1)))]
9937   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9938    && ix86_unary_operator_ok (NOT, DImode, operands)"
9939   "#"
9940   [(set_attr "type" "alu1")
9941    (set_attr "mode" "DI")])
9942
9943 (define_split
9944   [(set (match_operand 0 "flags_reg_operand" "")
9945         (match_operator 2 "compare_operator"
9946           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9947            (const_int 0)]))
9948    (set (match_operand:DI 1 "nonimmediate_operand" "")
9949         (not:DI (match_dup 3)))]
9950   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9951   [(parallel [(set (match_dup 0)
9952                    (match_op_dup 2
9953                      [(xor:DI (match_dup 3) (const_int -1))
9954                       (const_int 0)]))
9955               (set (match_dup 1)
9956                    (xor:DI (match_dup 3) (const_int -1)))])]
9957   "")
9958
9959 (define_expand "one_cmplsi2"
9960   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9961         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9962   ""
9963   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9964
9965 (define_insn "*one_cmplsi2_1"
9966   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9967         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9968   "ix86_unary_operator_ok (NOT, SImode, operands)"
9969   "not{l}\t%0"
9970   [(set_attr "type" "negnot")
9971    (set_attr "mode" "SI")])
9972
9973 ;; ??? Currently never generated - xor is used instead.
9974 (define_insn "*one_cmplsi2_1_zext"
9975   [(set (match_operand:DI 0 "register_operand" "=r")
9976         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9977   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9978   "not{l}\t%k0"
9979   [(set_attr "type" "negnot")
9980    (set_attr "mode" "SI")])
9981
9982 (define_insn "*one_cmplsi2_2"
9983   [(set (reg FLAGS_REG)
9984         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9985                  (const_int 0)))
9986    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9987         (not:SI (match_dup 1)))]
9988   "ix86_match_ccmode (insn, CCNOmode)
9989    && ix86_unary_operator_ok (NOT, SImode, operands)"
9990   "#"
9991   [(set_attr "type" "alu1")
9992    (set_attr "mode" "SI")])
9993
9994 (define_split
9995   [(set (match_operand 0 "flags_reg_operand" "")
9996         (match_operator 2 "compare_operator"
9997           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9998            (const_int 0)]))
9999    (set (match_operand:SI 1 "nonimmediate_operand" "")
10000         (not:SI (match_dup 3)))]
10001   "ix86_match_ccmode (insn, CCNOmode)"
10002   [(parallel [(set (match_dup 0)
10003                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10004                                     (const_int 0)]))
10005               (set (match_dup 1)
10006                    (xor:SI (match_dup 3) (const_int -1)))])]
10007   "")
10008
10009 ;; ??? Currently never generated - xor is used instead.
10010 (define_insn "*one_cmplsi2_2_zext"
10011   [(set (reg FLAGS_REG)
10012         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10013                  (const_int 0)))
10014    (set (match_operand:DI 0 "register_operand" "=r")
10015         (zero_extend:DI (not:SI (match_dup 1))))]
10016   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10017    && ix86_unary_operator_ok (NOT, SImode, operands)"
10018   "#"
10019   [(set_attr "type" "alu1")
10020    (set_attr "mode" "SI")])
10021
10022 (define_split
10023   [(set (match_operand 0 "flags_reg_operand" "")
10024         (match_operator 2 "compare_operator"
10025           [(not:SI (match_operand:SI 3 "register_operand" ""))
10026            (const_int 0)]))
10027    (set (match_operand:DI 1 "register_operand" "")
10028         (zero_extend:DI (not:SI (match_dup 3))))]
10029   "ix86_match_ccmode (insn, CCNOmode)"
10030   [(parallel [(set (match_dup 0)
10031                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10032                                     (const_int 0)]))
10033               (set (match_dup 1)
10034                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10035   "")
10036
10037 (define_expand "one_cmplhi2"
10038   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10039         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10040   "TARGET_HIMODE_MATH"
10041   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10042
10043 (define_insn "*one_cmplhi2_1"
10044   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10045         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10046   "ix86_unary_operator_ok (NOT, HImode, operands)"
10047   "not{w}\t%0"
10048   [(set_attr "type" "negnot")
10049    (set_attr "mode" "HI")])
10050
10051 (define_insn "*one_cmplhi2_2"
10052   [(set (reg FLAGS_REG)
10053         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10054                  (const_int 0)))
10055    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10056         (not:HI (match_dup 1)))]
10057   "ix86_match_ccmode (insn, CCNOmode)
10058    && ix86_unary_operator_ok (NEG, HImode, operands)"
10059   "#"
10060   [(set_attr "type" "alu1")
10061    (set_attr "mode" "HI")])
10062
10063 (define_split
10064   [(set (match_operand 0 "flags_reg_operand" "")
10065         (match_operator 2 "compare_operator"
10066           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10067            (const_int 0)]))
10068    (set (match_operand:HI 1 "nonimmediate_operand" "")
10069         (not:HI (match_dup 3)))]
10070   "ix86_match_ccmode (insn, CCNOmode)"
10071   [(parallel [(set (match_dup 0)
10072                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10073                                     (const_int 0)]))
10074               (set (match_dup 1)
10075                    (xor:HI (match_dup 3) (const_int -1)))])]
10076   "")
10077
10078 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10079 (define_expand "one_cmplqi2"
10080   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10081         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10082   "TARGET_QIMODE_MATH"
10083   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10084
10085 (define_insn "*one_cmplqi2_1"
10086   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10087         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10088   "ix86_unary_operator_ok (NOT, QImode, operands)"
10089   "@
10090    not{b}\t%0
10091    not{l}\t%k0"
10092   [(set_attr "type" "negnot")
10093    (set_attr "mode" "QI,SI")])
10094
10095 (define_insn "*one_cmplqi2_2"
10096   [(set (reg FLAGS_REG)
10097         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10098                  (const_int 0)))
10099    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10100         (not:QI (match_dup 1)))]
10101   "ix86_match_ccmode (insn, CCNOmode)
10102    && ix86_unary_operator_ok (NOT, QImode, operands)"
10103   "#"
10104   [(set_attr "type" "alu1")
10105    (set_attr "mode" "QI")])
10106
10107 (define_split
10108   [(set (match_operand 0 "flags_reg_operand" "")
10109         (match_operator 2 "compare_operator"
10110           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10111            (const_int 0)]))
10112    (set (match_operand:QI 1 "nonimmediate_operand" "")
10113         (not:QI (match_dup 3)))]
10114   "ix86_match_ccmode (insn, CCNOmode)"
10115   [(parallel [(set (match_dup 0)
10116                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10117                                     (const_int 0)]))
10118               (set (match_dup 1)
10119                    (xor:QI (match_dup 3) (const_int -1)))])]
10120   "")
10121 \f
10122 ;; Arithmetic shift instructions
10123
10124 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10125 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10126 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10127 ;; from the assembler input.
10128 ;;
10129 ;; This instruction shifts the target reg/mem as usual, but instead of
10130 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10131 ;; is a left shift double, bits are taken from the high order bits of
10132 ;; reg, else if the insn is a shift right double, bits are taken from the
10133 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10134 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10135 ;;
10136 ;; Since sh[lr]d does not change the `reg' operand, that is done
10137 ;; separately, making all shifts emit pairs of shift double and normal
10138 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10139 ;; support a 63 bit shift, each shift where the count is in a reg expands
10140 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10141 ;;
10142 ;; If the shift count is a constant, we need never emit more than one
10143 ;; shift pair, instead using moves and sign extension for counts greater
10144 ;; than 31.
10145
10146 (define_expand "ashldi3"
10147   [(set (match_operand:DI 0 "shiftdi_operand" "")
10148         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10149                    (match_operand:QI 2 "nonmemory_operand" "")))]
10150   ""
10151   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10152
10153 (define_insn "*ashldi3_1_rex64"
10154   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10155         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10156                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10159 {
10160   switch (get_attr_type (insn))
10161     {
10162     case TYPE_ALU:
10163       if (operands[2] != const1_rtx)
10164         abort ();
10165       if (!rtx_equal_p (operands[0], operands[1]))
10166         abort ();
10167       return "add{q}\t{%0, %0|%0, %0}";
10168
10169     case TYPE_LEA:
10170       if (GET_CODE (operands[2]) != CONST_INT
10171           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10172         abort ();
10173       operands[1] = gen_rtx_MULT (DImode, operands[1],
10174                                   GEN_INT (1 << INTVAL (operands[2])));
10175       return "lea{q}\t{%a1, %0|%0, %a1}";
10176
10177     default:
10178       if (REG_P (operands[2]))
10179         return "sal{q}\t{%b2, %0|%0, %b2}";
10180       else if (operands[2] == const1_rtx
10181                && (TARGET_SHIFT1 || optimize_size))
10182         return "sal{q}\t%0";
10183       else
10184         return "sal{q}\t{%2, %0|%0, %2}";
10185     }
10186 }
10187   [(set (attr "type")
10188      (cond [(eq_attr "alternative" "1")
10189               (const_string "lea")
10190             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10191                           (const_int 0))
10192                       (match_operand 0 "register_operand" ""))
10193                  (match_operand 2 "const1_operand" ""))
10194               (const_string "alu")
10195            ]
10196            (const_string "ishift")))
10197    (set_attr "mode" "DI")])
10198
10199 ;; Convert lea to the lea pattern to avoid flags dependency.
10200 (define_split
10201   [(set (match_operand:DI 0 "register_operand" "")
10202         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10203                    (match_operand:QI 2 "immediate_operand" "")))
10204    (clobber (reg:CC FLAGS_REG))]
10205   "TARGET_64BIT && reload_completed
10206    && true_regnum (operands[0]) != true_regnum (operands[1])"
10207   [(set (match_dup 0)
10208         (mult:DI (match_dup 1)
10209                  (match_dup 2)))]
10210   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10211
10212 ;; This pattern can't accept a variable shift count, since shifts by
10213 ;; zero don't affect the flags.  We assume that shifts by constant
10214 ;; zero are optimized away.
10215 (define_insn "*ashldi3_cmp_rex64"
10216   [(set (reg FLAGS_REG)
10217         (compare
10218           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10219                      (match_operand:QI 2 "immediate_operand" "e"))
10220           (const_int 0)))
10221    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10222         (ashift:DI (match_dup 1) (match_dup 2)))]
10223   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10224    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10225 {
10226   switch (get_attr_type (insn))
10227     {
10228     case TYPE_ALU:
10229       if (operands[2] != const1_rtx)
10230         abort ();
10231       return "add{q}\t{%0, %0|%0, %0}";
10232
10233     default:
10234       if (REG_P (operands[2]))
10235         return "sal{q}\t{%b2, %0|%0, %b2}";
10236       else if (operands[2] == const1_rtx
10237                && (TARGET_SHIFT1 || optimize_size))
10238         return "sal{q}\t%0";
10239       else
10240         return "sal{q}\t{%2, %0|%0, %2}";
10241     }
10242 }
10243   [(set (attr "type")
10244      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10245                           (const_int 0))
10246                       (match_operand 0 "register_operand" ""))
10247                  (match_operand 2 "const1_operand" ""))
10248               (const_string "alu")
10249            ]
10250            (const_string "ishift")))
10251    (set_attr "mode" "DI")])
10252
10253 (define_insn "*ashldi3_1"
10254   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10255         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10256                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "!TARGET_64BIT"
10259   "#"
10260   [(set_attr "type" "multi")])
10261
10262 ;; By default we don't ask for a scratch register, because when DImode
10263 ;; values are manipulated, registers are already at a premium.  But if
10264 ;; we have one handy, we won't turn it away.
10265 (define_peephole2
10266   [(match_scratch:SI 3 "r")
10267    (parallel [(set (match_operand:DI 0 "register_operand" "")
10268                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10269                               (match_operand:QI 2 "nonmemory_operand" "")))
10270               (clobber (reg:CC FLAGS_REG))])
10271    (match_dup 3)]
10272   "!TARGET_64BIT && TARGET_CMOVE"
10273   [(const_int 0)]
10274   "ix86_split_ashldi (operands, operands[3]); DONE;")
10275
10276 (define_split
10277   [(set (match_operand:DI 0 "register_operand" "")
10278         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10279                    (match_operand:QI 2 "nonmemory_operand" "")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10282   [(const_int 0)]
10283   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10284
10285 (define_insn "x86_shld_1"
10286   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10287         (ior:SI (ashift:SI (match_dup 0)
10288                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10289                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10290                   (minus:QI (const_int 32) (match_dup 2)))))
10291    (clobber (reg:CC FLAGS_REG))]
10292   ""
10293   "@
10294    shld{l}\t{%2, %1, %0|%0, %1, %2}
10295    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10296   [(set_attr "type" "ishift")
10297    (set_attr "prefix_0f" "1")
10298    (set_attr "mode" "SI")
10299    (set_attr "pent_pair" "np")
10300    (set_attr "athlon_decode" "vector")])
10301
10302 (define_expand "x86_shift_adj_1"
10303   [(set (reg:CCZ FLAGS_REG)
10304         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10305                              (const_int 32))
10306                      (const_int 0)))
10307    (set (match_operand:SI 0 "register_operand" "")
10308         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10309                          (match_operand:SI 1 "register_operand" "")
10310                          (match_dup 0)))
10311    (set (match_dup 1)
10312         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10313                          (match_operand:SI 3 "register_operand" "r")
10314                          (match_dup 1)))]
10315   "TARGET_CMOVE"
10316   "")
10317
10318 (define_expand "x86_shift_adj_2"
10319   [(use (match_operand:SI 0 "register_operand" ""))
10320    (use (match_operand:SI 1 "register_operand" ""))
10321    (use (match_operand:QI 2 "register_operand" ""))]
10322   ""
10323 {
10324   rtx label = gen_label_rtx ();
10325   rtx tmp;
10326
10327   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10328
10329   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10330   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10331   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10332                               gen_rtx_LABEL_REF (VOIDmode, label),
10333                               pc_rtx);
10334   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10335   JUMP_LABEL (tmp) = label;
10336
10337   emit_move_insn (operands[0], operands[1]);
10338   ix86_expand_clear (operands[1]);
10339
10340   emit_label (label);
10341   LABEL_NUSES (label) = 1;
10342
10343   DONE;
10344 })
10345
10346 (define_expand "ashlsi3"
10347   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10348         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10349                    (match_operand:QI 2 "nonmemory_operand" "")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   ""
10352   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10353
10354 (define_insn "*ashlsi3_1"
10355   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10356         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10357                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10360 {
10361   switch (get_attr_type (insn))
10362     {
10363     case TYPE_ALU:
10364       if (operands[2] != const1_rtx)
10365         abort ();
10366       if (!rtx_equal_p (operands[0], operands[1]))
10367         abort ();
10368       return "add{l}\t{%0, %0|%0, %0}";
10369
10370     case TYPE_LEA:
10371       return "#";
10372
10373     default:
10374       if (REG_P (operands[2]))
10375         return "sal{l}\t{%b2, %0|%0, %b2}";
10376       else if (operands[2] == const1_rtx
10377                && (TARGET_SHIFT1 || optimize_size))
10378         return "sal{l}\t%0";
10379       else
10380         return "sal{l}\t{%2, %0|%0, %2}";
10381     }
10382 }
10383   [(set (attr "type")
10384      (cond [(eq_attr "alternative" "1")
10385               (const_string "lea")
10386             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387                           (const_int 0))
10388                       (match_operand 0 "register_operand" ""))
10389                  (match_operand 2 "const1_operand" ""))
10390               (const_string "alu")
10391            ]
10392            (const_string "ishift")))
10393    (set_attr "mode" "SI")])
10394
10395 ;; Convert lea to the lea pattern to avoid flags dependency.
10396 (define_split
10397   [(set (match_operand 0 "register_operand" "")
10398         (ashift (match_operand 1 "index_register_operand" "")
10399                 (match_operand:QI 2 "const_int_operand" "")))
10400    (clobber (reg:CC FLAGS_REG))]
10401   "reload_completed
10402    && true_regnum (operands[0]) != true_regnum (operands[1])
10403    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10404   [(const_int 0)]
10405 {
10406   rtx pat;
10407   enum machine_mode mode = GET_MODE (operands[0]);
10408
10409   if (GET_MODE_SIZE (mode) < 4)
10410     operands[0] = gen_lowpart (SImode, operands[0]);
10411   if (mode != Pmode)
10412     operands[1] = gen_lowpart (Pmode, operands[1]);
10413   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10414
10415   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10416   if (Pmode != SImode)
10417     pat = gen_rtx_SUBREG (SImode, pat, 0);
10418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10419   DONE;
10420 })
10421
10422 ;; Rare case of shifting RSP is handled by generating move and shift
10423 (define_split
10424   [(set (match_operand 0 "register_operand" "")
10425         (ashift (match_operand 1 "register_operand" "")
10426                 (match_operand:QI 2 "const_int_operand" "")))
10427    (clobber (reg:CC FLAGS_REG))]
10428   "reload_completed
10429    && true_regnum (operands[0]) != true_regnum (operands[1])"
10430   [(const_int 0)]
10431 {
10432   rtx pat, clob;
10433   emit_move_insn (operands[1], operands[0]);
10434   pat = gen_rtx_SET (VOIDmode, operands[0],
10435                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10436                                      operands[0], operands[2]));
10437   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10438   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10439   DONE;
10440 })
10441
10442 (define_insn "*ashlsi3_1_zext"
10443   [(set (match_operand:DI 0 "register_operand" "=r,r")
10444         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10445                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10446    (clobber (reg:CC FLAGS_REG))]
10447   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10448 {
10449   switch (get_attr_type (insn))
10450     {
10451     case TYPE_ALU:
10452       if (operands[2] != const1_rtx)
10453         abort ();
10454       return "add{l}\t{%k0, %k0|%k0, %k0}";
10455
10456     case TYPE_LEA:
10457       return "#";
10458
10459     default:
10460       if (REG_P (operands[2]))
10461         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10462       else if (operands[2] == const1_rtx
10463                && (TARGET_SHIFT1 || optimize_size))
10464         return "sal{l}\t%k0";
10465       else
10466         return "sal{l}\t{%2, %k0|%k0, %2}";
10467     }
10468 }
10469   [(set (attr "type")
10470      (cond [(eq_attr "alternative" "1")
10471               (const_string "lea")
10472             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10473                      (const_int 0))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "SI")])
10479
10480 ;; Convert lea to the lea pattern to avoid flags dependency.
10481 (define_split
10482   [(set (match_operand:DI 0 "register_operand" "")
10483         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10484                                 (match_operand:QI 2 "const_int_operand" ""))))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "TARGET_64BIT && reload_completed
10487    && true_regnum (operands[0]) != true_regnum (operands[1])"
10488   [(set (match_dup 0) (zero_extend:DI
10489                         (subreg:SI (mult:SI (match_dup 1)
10490                                             (match_dup 2)) 0)))]
10491 {
10492   operands[1] = gen_lowpart (Pmode, operands[1]);
10493   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10494 })
10495
10496 ;; This pattern can't accept a variable shift count, since shifts by
10497 ;; zero don't affect the flags.  We assume that shifts by constant
10498 ;; zero are optimized away.
10499 (define_insn "*ashlsi3_cmp"
10500   [(set (reg FLAGS_REG)
10501         (compare
10502           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10503                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10504           (const_int 0)))
10505    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10506         (ashift:SI (match_dup 1) (match_dup 2)))]
10507   "ix86_match_ccmode (insn, CCGOCmode)
10508    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10509 {
10510   switch (get_attr_type (insn))
10511     {
10512     case TYPE_ALU:
10513       if (operands[2] != const1_rtx)
10514         abort ();
10515       return "add{l}\t{%0, %0|%0, %0}";
10516
10517     default:
10518       if (REG_P (operands[2]))
10519         return "sal{l}\t{%b2, %0|%0, %b2}";
10520       else if (operands[2] == const1_rtx
10521                && (TARGET_SHIFT1 || optimize_size))
10522         return "sal{l}\t%0";
10523       else
10524         return "sal{l}\t{%2, %0|%0, %2}";
10525     }
10526 }
10527   [(set (attr "type")
10528      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10529                           (const_int 0))
10530                       (match_operand 0 "register_operand" ""))
10531                  (match_operand 2 "const1_operand" ""))
10532               (const_string "alu")
10533            ]
10534            (const_string "ishift")))
10535    (set_attr "mode" "SI")])
10536
10537 (define_insn "*ashlsi3_cmp_zext"
10538   [(set (reg FLAGS_REG)
10539         (compare
10540           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10541                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10542           (const_int 0)))
10543    (set (match_operand:DI 0 "register_operand" "=r")
10544         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10545   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10546    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10547 {
10548   switch (get_attr_type (insn))
10549     {
10550     case TYPE_ALU:
10551       if (operands[2] != const1_rtx)
10552         abort ();
10553       return "add{l}\t{%k0, %k0|%k0, %k0}";
10554
10555     default:
10556       if (REG_P (operands[2]))
10557         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10558       else if (operands[2] == const1_rtx
10559                && (TARGET_SHIFT1 || optimize_size))
10560         return "sal{l}\t%k0";
10561       else
10562         return "sal{l}\t{%2, %k0|%k0, %2}";
10563     }
10564 }
10565   [(set (attr "type")
10566      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10567                      (const_int 0))
10568                  (match_operand 2 "const1_operand" ""))
10569               (const_string "alu")
10570            ]
10571            (const_string "ishift")))
10572    (set_attr "mode" "SI")])
10573
10574 (define_expand "ashlhi3"
10575   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10576         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10577                    (match_operand:QI 2 "nonmemory_operand" "")))
10578    (clobber (reg:CC FLAGS_REG))]
10579   "TARGET_HIMODE_MATH"
10580   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10581
10582 (define_insn "*ashlhi3_1_lea"
10583   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10584         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10585                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "!TARGET_PARTIAL_REG_STALL
10588    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10589 {
10590   switch (get_attr_type (insn))
10591     {
10592     case TYPE_LEA:
10593       return "#";
10594     case TYPE_ALU:
10595       if (operands[2] != const1_rtx)
10596         abort ();
10597       return "add{w}\t{%0, %0|%0, %0}";
10598
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{w}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{w}\t%0";
10605       else
10606         return "sal{w}\t{%2, %0|%0, %2}";
10607     }
10608 }
10609   [(set (attr "type")
10610      (cond [(eq_attr "alternative" "1")
10611               (const_string "lea")
10612             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                           (const_int 0))
10614                       (match_operand 0 "register_operand" ""))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "HI,SI")])
10620
10621 (define_insn "*ashlhi3_1"
10622   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10623         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10624                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_PARTIAL_REG_STALL
10627    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10628 {
10629   switch (get_attr_type (insn))
10630     {
10631     case TYPE_ALU:
10632       if (operands[2] != const1_rtx)
10633         abort ();
10634       return "add{w}\t{%0, %0|%0, %0}";
10635
10636     default:
10637       if (REG_P (operands[2]))
10638         return "sal{w}\t{%b2, %0|%0, %b2}";
10639       else if (operands[2] == const1_rtx
10640                && (TARGET_SHIFT1 || optimize_size))
10641         return "sal{w}\t%0";
10642       else
10643         return "sal{w}\t{%2, %0|%0, %2}";
10644     }
10645 }
10646   [(set (attr "type")
10647      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10648                           (const_int 0))
10649                       (match_operand 0 "register_operand" ""))
10650                  (match_operand 2 "const1_operand" ""))
10651               (const_string "alu")
10652            ]
10653            (const_string "ishift")))
10654    (set_attr "mode" "HI")])
10655
10656 ;; This pattern can't accept a variable shift count, since shifts by
10657 ;; zero don't affect the flags.  We assume that shifts by constant
10658 ;; zero are optimized away.
10659 (define_insn "*ashlhi3_cmp"
10660   [(set (reg FLAGS_REG)
10661         (compare
10662           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10663                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10664           (const_int 0)))
10665    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10666         (ashift:HI (match_dup 1) (match_dup 2)))]
10667   "ix86_match_ccmode (insn, CCGOCmode)
10668    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10669 {
10670   switch (get_attr_type (insn))
10671     {
10672     case TYPE_ALU:
10673       if (operands[2] != const1_rtx)
10674         abort ();
10675       return "add{w}\t{%0, %0|%0, %0}";
10676
10677     default:
10678       if (REG_P (operands[2]))
10679         return "sal{w}\t{%b2, %0|%0, %b2}";
10680       else if (operands[2] == const1_rtx
10681                && (TARGET_SHIFT1 || optimize_size))
10682         return "sal{w}\t%0";
10683       else
10684         return "sal{w}\t{%2, %0|%0, %2}";
10685     }
10686 }
10687   [(set (attr "type")
10688      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10689                           (const_int 0))
10690                       (match_operand 0 "register_operand" ""))
10691                  (match_operand 2 "const1_operand" ""))
10692               (const_string "alu")
10693            ]
10694            (const_string "ishift")))
10695    (set_attr "mode" "HI")])
10696
10697 (define_expand "ashlqi3"
10698   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10699         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10700                    (match_operand:QI 2 "nonmemory_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "TARGET_QIMODE_MATH"
10703   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10704
10705 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10706
10707 (define_insn "*ashlqi3_1_lea"
10708   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10709         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10710                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10711    (clobber (reg:CC FLAGS_REG))]
10712   "!TARGET_PARTIAL_REG_STALL
10713    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10714 {
10715   switch (get_attr_type (insn))
10716     {
10717     case TYPE_LEA:
10718       return "#";
10719     case TYPE_ALU:
10720       if (operands[2] != const1_rtx)
10721         abort ();
10722       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10723         return "add{l}\t{%k0, %k0|%k0, %k0}";
10724       else
10725         return "add{b}\t{%0, %0|%0, %0}";
10726
10727     default:
10728       if (REG_P (operands[2]))
10729         {
10730           if (get_attr_mode (insn) == MODE_SI)
10731             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10732           else
10733             return "sal{b}\t{%b2, %0|%0, %b2}";
10734         }
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         {
10738           if (get_attr_mode (insn) == MODE_SI)
10739             return "sal{l}\t%0";
10740           else
10741             return "sal{b}\t%0";
10742         }
10743       else
10744         {
10745           if (get_attr_mode (insn) == MODE_SI)
10746             return "sal{l}\t{%2, %k0|%k0, %2}";
10747           else
10748             return "sal{b}\t{%2, %0|%0, %2}";
10749         }
10750     }
10751 }
10752   [(set (attr "type")
10753      (cond [(eq_attr "alternative" "2")
10754               (const_string "lea")
10755             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10756                           (const_int 0))
10757                       (match_operand 0 "register_operand" ""))
10758                  (match_operand 2 "const1_operand" ""))
10759               (const_string "alu")
10760            ]
10761            (const_string "ishift")))
10762    (set_attr "mode" "QI,SI,SI")])
10763
10764 (define_insn "*ashlqi3_1"
10765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10766         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10767                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10768    (clobber (reg:CC FLAGS_REG))]
10769   "TARGET_PARTIAL_REG_STALL
10770    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10771 {
10772   switch (get_attr_type (insn))
10773     {
10774     case TYPE_ALU:
10775       if (operands[2] != const1_rtx)
10776         abort ();
10777       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10778         return "add{l}\t{%k0, %k0|%k0, %k0}";
10779       else
10780         return "add{b}\t{%0, %0|%0, %0}";
10781
10782     default:
10783       if (REG_P (operands[2]))
10784         {
10785           if (get_attr_mode (insn) == MODE_SI)
10786             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10787           else
10788             return "sal{b}\t{%b2, %0|%0, %b2}";
10789         }
10790       else if (operands[2] == const1_rtx
10791                && (TARGET_SHIFT1 || optimize_size))
10792         {
10793           if (get_attr_mode (insn) == MODE_SI)
10794             return "sal{l}\t%0";
10795           else
10796             return "sal{b}\t%0";
10797         }
10798       else
10799         {
10800           if (get_attr_mode (insn) == MODE_SI)
10801             return "sal{l}\t{%2, %k0|%k0, %2}";
10802           else
10803             return "sal{b}\t{%2, %0|%0, %2}";
10804         }
10805     }
10806 }
10807   [(set (attr "type")
10808      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10809                           (const_int 0))
10810                       (match_operand 0 "register_operand" ""))
10811                  (match_operand 2 "const1_operand" ""))
10812               (const_string "alu")
10813            ]
10814            (const_string "ishift")))
10815    (set_attr "mode" "QI,SI")])
10816
10817 ;; This pattern can't accept a variable shift count, since shifts by
10818 ;; zero don't affect the flags.  We assume that shifts by constant
10819 ;; zero are optimized away.
10820 (define_insn "*ashlqi3_cmp"
10821   [(set (reg FLAGS_REG)
10822         (compare
10823           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10824                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10825           (const_int 0)))
10826    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10827         (ashift:QI (match_dup 1) (match_dup 2)))]
10828   "ix86_match_ccmode (insn, CCGOCmode)
10829    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10830 {
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       if (operands[2] != const1_rtx)
10835         abort ();
10836       return "add{b}\t{%0, %0|%0, %0}";
10837
10838     default:
10839       if (REG_P (operands[2]))
10840         return "sal{b}\t{%b2, %0|%0, %b2}";
10841       else if (operands[2] == const1_rtx
10842                && (TARGET_SHIFT1 || optimize_size))
10843         return "sal{b}\t%0";
10844       else
10845         return "sal{b}\t{%2, %0|%0, %2}";
10846     }
10847 }
10848   [(set (attr "type")
10849      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10850                           (const_int 0))
10851                       (match_operand 0 "register_operand" ""))
10852                  (match_operand 2 "const1_operand" ""))
10853               (const_string "alu")
10854            ]
10855            (const_string "ishift")))
10856    (set_attr "mode" "QI")])
10857
10858 ;; See comment above `ashldi3' about how this works.
10859
10860 (define_expand "ashrdi3"
10861   [(set (match_operand:DI 0 "shiftdi_operand" "")
10862         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10863                      (match_operand:QI 2 "nonmemory_operand" "")))]
10864   ""
10865   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10866
10867 (define_insn "*ashrdi3_63_rex64"
10868   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10869         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10870                      (match_operand:DI 2 "const_int_operand" "i,i")))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_64BIT && INTVAL (operands[2]) == 63
10873    && (TARGET_USE_CLTD || optimize_size)
10874    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10875   "@
10876    {cqto|cqo}
10877    sar{q}\t{%2, %0|%0, %2}"
10878   [(set_attr "type" "imovx,ishift")
10879    (set_attr "prefix_0f" "0,*")
10880    (set_attr "length_immediate" "0,*")
10881    (set_attr "modrm" "0,1")
10882    (set_attr "mode" "DI")])
10883
10884 (define_insn "*ashrdi3_1_one_bit_rex64"
10885   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10886         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10887                      (match_operand:QI 2 "const1_operand" "")))
10888    (clobber (reg:CC FLAGS_REG))]
10889   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10890    && (TARGET_SHIFT1 || optimize_size)"
10891   "sar{q}\t%0"
10892   [(set_attr "type" "ishift")
10893    (set (attr "length") 
10894      (if_then_else (match_operand:DI 0 "register_operand" "") 
10895         (const_string "2")
10896         (const_string "*")))])
10897
10898 (define_insn "*ashrdi3_1_rex64"
10899   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10900         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10901                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10904   "@
10905    sar{q}\t{%2, %0|%0, %2}
10906    sar{q}\t{%b2, %0|%0, %b2}"
10907   [(set_attr "type" "ishift")
10908    (set_attr "mode" "DI")])
10909
10910 ;; This pattern can't accept a variable shift count, since shifts by
10911 ;; zero don't affect the flags.  We assume that shifts by constant
10912 ;; zero are optimized away.
10913 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10914   [(set (reg FLAGS_REG)
10915         (compare
10916           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10917                        (match_operand:QI 2 "const1_operand" ""))
10918           (const_int 0)))
10919    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10920         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10921   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10922    && (TARGET_SHIFT1 || optimize_size)
10923    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10924   "sar{q}\t%0"
10925   [(set_attr "type" "ishift")
10926    (set (attr "length") 
10927      (if_then_else (match_operand:DI 0 "register_operand" "") 
10928         (const_string "2")
10929         (const_string "*")))])
10930
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags.  We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashrdi3_cmp_rex64"
10935   [(set (reg FLAGS_REG)
10936         (compare
10937           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10938                        (match_operand:QI 2 "const_int_operand" "n"))
10939           (const_int 0)))
10940    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10941         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10942   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10943    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10944   "sar{q}\t{%2, %0|%0, %2}"
10945   [(set_attr "type" "ishift")
10946    (set_attr "mode" "DI")])
10947
10948 (define_insn "*ashrdi3_1"
10949   [(set (match_operand:DI 0 "register_operand" "=r")
10950         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10951                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "!TARGET_64BIT"
10954   "#"
10955   [(set_attr "type" "multi")])
10956
10957 ;; By default we don't ask for a scratch register, because when DImode
10958 ;; values are manipulated, registers are already at a premium.  But if
10959 ;; we have one handy, we won't turn it away.
10960 (define_peephole2
10961   [(match_scratch:SI 3 "r")
10962    (parallel [(set (match_operand:DI 0 "register_operand" "")
10963                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10964                                 (match_operand:QI 2 "nonmemory_operand" "")))
10965               (clobber (reg:CC FLAGS_REG))])
10966    (match_dup 3)]
10967   "!TARGET_64BIT && TARGET_CMOVE"
10968   [(const_int 0)]
10969   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10970
10971 (define_split
10972   [(set (match_operand:DI 0 "register_operand" "")
10973         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10974                      (match_operand:QI 2 "nonmemory_operand" "")))
10975    (clobber (reg:CC FLAGS_REG))]
10976   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10977   [(const_int 0)]
10978   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10979
10980 (define_insn "x86_shrd_1"
10981   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10982         (ior:SI (ashiftrt:SI (match_dup 0)
10983                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10984                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10985                   (minus:QI (const_int 32) (match_dup 2)))))
10986    (clobber (reg:CC FLAGS_REG))]
10987   ""
10988   "@
10989    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10990    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10991   [(set_attr "type" "ishift")
10992    (set_attr "prefix_0f" "1")
10993    (set_attr "pent_pair" "np")
10994    (set_attr "mode" "SI")])
10995
10996 (define_expand "x86_shift_adj_3"
10997   [(use (match_operand:SI 0 "register_operand" ""))
10998    (use (match_operand:SI 1 "register_operand" ""))
10999    (use (match_operand:QI 2 "register_operand" ""))]
11000   ""
11001 {
11002   rtx label = gen_label_rtx ();
11003   rtx tmp;
11004
11005   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11006
11007   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11008   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11009   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11010                               gen_rtx_LABEL_REF (VOIDmode, label),
11011                               pc_rtx);
11012   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11013   JUMP_LABEL (tmp) = label;
11014
11015   emit_move_insn (operands[0], operands[1]);
11016   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11017
11018   emit_label (label);
11019   LABEL_NUSES (label) = 1;
11020
11021   DONE;
11022 })
11023
11024 (define_insn "ashrsi3_31"
11025   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11026         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11027                      (match_operand:SI 2 "const_int_operand" "i,i")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11030    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11031   "@
11032    {cltd|cdq}
11033    sar{l}\t{%2, %0|%0, %2}"
11034   [(set_attr "type" "imovx,ishift")
11035    (set_attr "prefix_0f" "0,*")
11036    (set_attr "length_immediate" "0,*")
11037    (set_attr "modrm" "0,1")
11038    (set_attr "mode" "SI")])
11039
11040 (define_insn "*ashrsi3_31_zext"
11041   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11042         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11043                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11046    && INTVAL (operands[2]) == 31
11047    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11048   "@
11049    {cltd|cdq}
11050    sar{l}\t{%2, %k0|%k0, %2}"
11051   [(set_attr "type" "imovx,ishift")
11052    (set_attr "prefix_0f" "0,*")
11053    (set_attr "length_immediate" "0,*")
11054    (set_attr "modrm" "0,1")
11055    (set_attr "mode" "SI")])
11056
11057 (define_expand "ashrsi3"
11058   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11059         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11060                      (match_operand:QI 2 "nonmemory_operand" "")))
11061    (clobber (reg:CC FLAGS_REG))]
11062   ""
11063   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11064
11065 (define_insn "*ashrsi3_1_one_bit"
11066   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11067         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068                      (match_operand:QI 2 "const1_operand" "")))
11069    (clobber (reg:CC FLAGS_REG))]
11070   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11071    && (TARGET_SHIFT1 || optimize_size)"
11072   "sar{l}\t%0"
11073   [(set_attr "type" "ishift")
11074    (set (attr "length") 
11075      (if_then_else (match_operand:SI 0 "register_operand" "") 
11076         (const_string "2")
11077         (const_string "*")))])
11078
11079 (define_insn "*ashrsi3_1_one_bit_zext"
11080   [(set (match_operand:DI 0 "register_operand" "=r")
11081         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11082                                      (match_operand:QI 2 "const1_operand" ""))))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11085    && (TARGET_SHIFT1 || optimize_size)"
11086   "sar{l}\t%k0"
11087   [(set_attr "type" "ishift")
11088    (set_attr "length" "2")])
11089
11090 (define_insn "*ashrsi3_1"
11091   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11092         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11093                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11096   "@
11097    sar{l}\t{%2, %0|%0, %2}
11098    sar{l}\t{%b2, %0|%0, %b2}"
11099   [(set_attr "type" "ishift")
11100    (set_attr "mode" "SI")])
11101
11102 (define_insn "*ashrsi3_1_zext"
11103   [(set (match_operand:DI 0 "register_operand" "=r,r")
11104         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11105                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11108   "@
11109    sar{l}\t{%2, %k0|%k0, %2}
11110    sar{l}\t{%b2, %k0|%k0, %b2}"
11111   [(set_attr "type" "ishift")
11112    (set_attr "mode" "SI")])
11113
11114 ;; This pattern can't accept a variable shift count, since shifts by
11115 ;; zero don't affect the flags.  We assume that shifts by constant
11116 ;; zero are optimized away.
11117 (define_insn "*ashrsi3_one_bit_cmp"
11118   [(set (reg FLAGS_REG)
11119         (compare
11120           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11121                        (match_operand:QI 2 "const1_operand" ""))
11122           (const_int 0)))
11123    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11124         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11125   "ix86_match_ccmode (insn, CCGOCmode)
11126    && (TARGET_SHIFT1 || optimize_size)
11127    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11128   "sar{l}\t%0"
11129   [(set_attr "type" "ishift")
11130    (set (attr "length") 
11131      (if_then_else (match_operand:SI 0 "register_operand" "") 
11132         (const_string "2")
11133         (const_string "*")))])
11134
11135 (define_insn "*ashrsi3_one_bit_cmp_zext"
11136   [(set (reg FLAGS_REG)
11137         (compare
11138           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11139                        (match_operand:QI 2 "const1_operand" ""))
11140           (const_int 0)))
11141    (set (match_operand:DI 0 "register_operand" "=r")
11142         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11143   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11144    && (TARGET_SHIFT1 || optimize_size)
11145    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11146   "sar{l}\t%k0"
11147   [(set_attr "type" "ishift")
11148    (set_attr "length" "2")])
11149
11150 ;; This pattern can't accept a variable shift count, since shifts by
11151 ;; zero don't affect the flags.  We assume that shifts by constant
11152 ;; zero are optimized away.
11153 (define_insn "*ashrsi3_cmp"
11154   [(set (reg FLAGS_REG)
11155         (compare
11156           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11157                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11158           (const_int 0)))
11159    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11160         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11161   "ix86_match_ccmode (insn, CCGOCmode)
11162    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11163   "sar{l}\t{%2, %0|%0, %2}"
11164   [(set_attr "type" "ishift")
11165    (set_attr "mode" "SI")])
11166
11167 (define_insn "*ashrsi3_cmp_zext"
11168   [(set (reg FLAGS_REG)
11169         (compare
11170           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11171                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11172           (const_int 0)))
11173    (set (match_operand:DI 0 "register_operand" "=r")
11174         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11175   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11176    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11177   "sar{l}\t{%2, %k0|%k0, %2}"
11178   [(set_attr "type" "ishift")
11179    (set_attr "mode" "SI")])
11180
11181 (define_expand "ashrhi3"
11182   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11183         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11184                      (match_operand:QI 2 "nonmemory_operand" "")))
11185    (clobber (reg:CC FLAGS_REG))]
11186   "TARGET_HIMODE_MATH"
11187   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11188
11189 (define_insn "*ashrhi3_1_one_bit"
11190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11191         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11192                      (match_operand:QI 2 "const1_operand" "")))
11193    (clobber (reg:CC FLAGS_REG))]
11194   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11195    && (TARGET_SHIFT1 || optimize_size)"
11196   "sar{w}\t%0"
11197   [(set_attr "type" "ishift")
11198    (set (attr "length") 
11199      (if_then_else (match_operand 0 "register_operand" "") 
11200         (const_string "2")
11201         (const_string "*")))])
11202
11203 (define_insn "*ashrhi3_1"
11204   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11205         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11206                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11207    (clobber (reg:CC FLAGS_REG))]
11208   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11209   "@
11210    sar{w}\t{%2, %0|%0, %2}
11211    sar{w}\t{%b2, %0|%0, %b2}"
11212   [(set_attr "type" "ishift")
11213    (set_attr "mode" "HI")])
11214
11215 ;; This pattern can't accept a variable shift count, since shifts by
11216 ;; zero don't affect the flags.  We assume that shifts by constant
11217 ;; zero are optimized away.
11218 (define_insn "*ashrhi3_one_bit_cmp"
11219   [(set (reg FLAGS_REG)
11220         (compare
11221           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11222                        (match_operand:QI 2 "const1_operand" ""))
11223           (const_int 0)))
11224    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11225         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11226   "ix86_match_ccmode (insn, CCGOCmode)
11227    && (TARGET_SHIFT1 || optimize_size)
11228    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11229   "sar{w}\t%0"
11230   [(set_attr "type" "ishift")
11231    (set (attr "length") 
11232      (if_then_else (match_operand 0 "register_operand" "") 
11233         (const_string "2")
11234         (const_string "*")))])
11235
11236 ;; This pattern can't accept a variable shift count, since shifts by
11237 ;; zero don't affect the flags.  We assume that shifts by constant
11238 ;; zero are optimized away.
11239 (define_insn "*ashrhi3_cmp"
11240   [(set (reg FLAGS_REG)
11241         (compare
11242           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11243                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11244           (const_int 0)))
11245    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11246         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11247   "ix86_match_ccmode (insn, CCGOCmode)
11248    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11249   "sar{w}\t{%2, %0|%0, %2}"
11250   [(set_attr "type" "ishift")
11251    (set_attr "mode" "HI")])
11252
11253 (define_expand "ashrqi3"
11254   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11255         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11256                      (match_operand:QI 2 "nonmemory_operand" "")))
11257    (clobber (reg:CC FLAGS_REG))]
11258   "TARGET_QIMODE_MATH"
11259   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11260
11261 (define_insn "*ashrqi3_1_one_bit"
11262   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11263         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11264                      (match_operand:QI 2 "const1_operand" "")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11267    && (TARGET_SHIFT1 || optimize_size)"
11268   "sar{b}\t%0"
11269   [(set_attr "type" "ishift")
11270    (set (attr "length") 
11271      (if_then_else (match_operand 0 "register_operand" "") 
11272         (const_string "2")
11273         (const_string "*")))])
11274
11275 (define_insn "*ashrqi3_1_one_bit_slp"
11276   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11277         (ashiftrt:QI (match_dup 0)
11278                      (match_operand:QI 1 "const1_operand" "")))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11281    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11282    && (TARGET_SHIFT1 || optimize_size)"
11283   "sar{b}\t%0"
11284   [(set_attr "type" "ishift1")
11285    (set (attr "length") 
11286      (if_then_else (match_operand 0 "register_operand" "") 
11287         (const_string "2")
11288         (const_string "*")))])
11289
11290 (define_insn "*ashrqi3_1"
11291   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11292         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11293                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11296   "@
11297    sar{b}\t{%2, %0|%0, %2}
11298    sar{b}\t{%b2, %0|%0, %b2}"
11299   [(set_attr "type" "ishift")
11300    (set_attr "mode" "QI")])
11301
11302 (define_insn "*ashrqi3_1_slp"
11303   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11304         (ashiftrt:QI (match_dup 0)
11305                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11308    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11309   "@
11310    sar{b}\t{%1, %0|%0, %1}
11311    sar{b}\t{%b1, %0|%0, %b1}"
11312   [(set_attr "type" "ishift1")
11313    (set_attr "mode" "QI")])
11314
11315 ;; This pattern can't accept a variable shift count, since shifts by
11316 ;; zero don't affect the flags.  We assume that shifts by constant
11317 ;; zero are optimized away.
11318 (define_insn "*ashrqi3_one_bit_cmp"
11319   [(set (reg FLAGS_REG)
11320         (compare
11321           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11322                        (match_operand:QI 2 "const1_operand" "I"))
11323           (const_int 0)))
11324    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11325         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11326   "ix86_match_ccmode (insn, CCGOCmode)
11327    && (TARGET_SHIFT1 || optimize_size)
11328    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11329   "sar{b}\t%0"
11330   [(set_attr "type" "ishift")
11331    (set (attr "length") 
11332      (if_then_else (match_operand 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11335
11336 ;; This pattern can't accept a variable shift count, since shifts by
11337 ;; zero don't affect the flags.  We assume that shifts by constant
11338 ;; zero are optimized away.
11339 (define_insn "*ashrqi3_cmp"
11340   [(set (reg FLAGS_REG)
11341         (compare
11342           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11343                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11344           (const_int 0)))
11345    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11346         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11347   "ix86_match_ccmode (insn, CCGOCmode)
11348    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11349   "sar{b}\t{%2, %0|%0, %2}"
11350   [(set_attr "type" "ishift")
11351    (set_attr "mode" "QI")])
11352 \f
11353 ;; Logical shift instructions
11354
11355 ;; See comment above `ashldi3' about how this works.
11356
11357 (define_expand "lshrdi3"
11358   [(set (match_operand:DI 0 "shiftdi_operand" "")
11359         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11360                      (match_operand:QI 2 "nonmemory_operand" "")))]
11361   ""
11362   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11363
11364 (define_insn "*lshrdi3_1_one_bit_rex64"
11365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11366         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11367                      (match_operand:QI 2 "const1_operand" "")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11370    && (TARGET_SHIFT1 || optimize_size)"
11371   "shr{q}\t%0"
11372   [(set_attr "type" "ishift")
11373    (set (attr "length") 
11374      (if_then_else (match_operand:DI 0 "register_operand" "") 
11375         (const_string "2")
11376         (const_string "*")))])
11377
11378 (define_insn "*lshrdi3_1_rex64"
11379   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11380         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11381                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11384   "@
11385    shr{q}\t{%2, %0|%0, %2}
11386    shr{q}\t{%b2, %0|%0, %b2}"
11387   [(set_attr "type" "ishift")
11388    (set_attr "mode" "DI")])
11389
11390 ;; This pattern can't accept a variable shift count, since shifts by
11391 ;; zero don't affect the flags.  We assume that shifts by constant
11392 ;; zero are optimized away.
11393 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11394   [(set (reg FLAGS_REG)
11395         (compare
11396           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397                        (match_operand:QI 2 "const1_operand" ""))
11398           (const_int 0)))
11399    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11400         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402    && (TARGET_SHIFT1 || optimize_size)
11403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11404   "shr{q}\t%0"
11405   [(set_attr "type" "ishift")
11406    (set (attr "length") 
11407      (if_then_else (match_operand:DI 0 "register_operand" "") 
11408         (const_string "2")
11409         (const_string "*")))])
11410
11411 ;; This pattern can't accept a variable shift count, since shifts by
11412 ;; zero don't affect the flags.  We assume that shifts by constant
11413 ;; zero are optimized away.
11414 (define_insn "*lshrdi3_cmp_rex64"
11415   [(set (reg FLAGS_REG)
11416         (compare
11417           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11418                        (match_operand:QI 2 "const_int_operand" "e"))
11419           (const_int 0)))
11420    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11421         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11422   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11423    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11424   "shr{q}\t{%2, %0|%0, %2}"
11425   [(set_attr "type" "ishift")
11426    (set_attr "mode" "DI")])
11427
11428 (define_insn "*lshrdi3_1"
11429   [(set (match_operand:DI 0 "register_operand" "=r")
11430         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11431                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "!TARGET_64BIT"
11434   "#"
11435   [(set_attr "type" "multi")])
11436
11437 ;; By default we don't ask for a scratch register, because when DImode
11438 ;; values are manipulated, registers are already at a premium.  But if
11439 ;; we have one handy, we won't turn it away.
11440 (define_peephole2
11441   [(match_scratch:SI 3 "r")
11442    (parallel [(set (match_operand:DI 0 "register_operand" "")
11443                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11444                                 (match_operand:QI 2 "nonmemory_operand" "")))
11445               (clobber (reg:CC FLAGS_REG))])
11446    (match_dup 3)]
11447   "!TARGET_64BIT && TARGET_CMOVE"
11448   [(const_int 0)]
11449   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11450
11451 (define_split 
11452   [(set (match_operand:DI 0 "register_operand" "")
11453         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11454                      (match_operand:QI 2 "nonmemory_operand" "")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11457   [(const_int 0)]
11458   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11459
11460 (define_expand "lshrsi3"
11461   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11462         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11463                      (match_operand:QI 2 "nonmemory_operand" "")))
11464    (clobber (reg:CC FLAGS_REG))]
11465   ""
11466   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11467
11468 (define_insn "*lshrsi3_1_one_bit"
11469   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11470         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11471                      (match_operand:QI 2 "const1_operand" "")))
11472    (clobber (reg:CC FLAGS_REG))]
11473   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11474    && (TARGET_SHIFT1 || optimize_size)"
11475   "shr{l}\t%0"
11476   [(set_attr "type" "ishift")
11477    (set (attr "length") 
11478      (if_then_else (match_operand:SI 0 "register_operand" "") 
11479         (const_string "2")
11480         (const_string "*")))])
11481
11482 (define_insn "*lshrsi3_1_one_bit_zext"
11483   [(set (match_operand:DI 0 "register_operand" "=r")
11484         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11485                      (match_operand:QI 2 "const1_operand" "")))
11486    (clobber (reg:CC FLAGS_REG))]
11487   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11488    && (TARGET_SHIFT1 || optimize_size)"
11489   "shr{l}\t%k0"
11490   [(set_attr "type" "ishift")
11491    (set_attr "length" "2")])
11492
11493 (define_insn "*lshrsi3_1"
11494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11495         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11496                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11497    (clobber (reg:CC FLAGS_REG))]
11498   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11499   "@
11500    shr{l}\t{%2, %0|%0, %2}
11501    shr{l}\t{%b2, %0|%0, %b2}"
11502   [(set_attr "type" "ishift")
11503    (set_attr "mode" "SI")])
11504
11505 (define_insn "*lshrsi3_1_zext"
11506   [(set (match_operand:DI 0 "register_operand" "=r,r")
11507         (zero_extend:DI
11508           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11509                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11512   "@
11513    shr{l}\t{%2, %k0|%k0, %2}
11514    shr{l}\t{%b2, %k0|%k0, %b2}"
11515   [(set_attr "type" "ishift")
11516    (set_attr "mode" "SI")])
11517
11518 ;; This pattern can't accept a variable shift count, since shifts by
11519 ;; zero don't affect the flags.  We assume that shifts by constant
11520 ;; zero are optimized away.
11521 (define_insn "*lshrsi3_one_bit_cmp"
11522   [(set (reg FLAGS_REG)
11523         (compare
11524           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11525                        (match_operand:QI 2 "const1_operand" ""))
11526           (const_int 0)))
11527    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11529   "ix86_match_ccmode (insn, CCGOCmode)
11530    && (TARGET_SHIFT1 || optimize_size)
11531    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11532   "shr{l}\t%0"
11533   [(set_attr "type" "ishift")
11534    (set (attr "length") 
11535      (if_then_else (match_operand:SI 0 "register_operand" "") 
11536         (const_string "2")
11537         (const_string "*")))])
11538
11539 (define_insn "*lshrsi3_cmp_one_bit_zext"
11540   [(set (reg FLAGS_REG)
11541         (compare
11542           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543                        (match_operand:QI 2 "const1_operand" ""))
11544           (const_int 0)))
11545    (set (match_operand:DI 0 "register_operand" "=r")
11546         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11547   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11548    && (TARGET_SHIFT1 || optimize_size)
11549    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550   "shr{l}\t%k0"
11551   [(set_attr "type" "ishift")
11552    (set_attr "length" "2")])
11553
11554 ;; This pattern can't accept a variable shift count, since shifts by
11555 ;; zero don't affect the flags.  We assume that shifts by constant
11556 ;; zero are optimized away.
11557 (define_insn "*lshrsi3_cmp"
11558   [(set (reg FLAGS_REG)
11559         (compare
11560           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11561                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11562           (const_int 0)))
11563    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11564         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11565   "ix86_match_ccmode (insn, CCGOCmode)
11566    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11567   "shr{l}\t{%2, %0|%0, %2}"
11568   [(set_attr "type" "ishift")
11569    (set_attr "mode" "SI")])
11570
11571 (define_insn "*lshrsi3_cmp_zext"
11572   [(set (reg FLAGS_REG)
11573         (compare
11574           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11575                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11576           (const_int 0)))
11577    (set (match_operand:DI 0 "register_operand" "=r")
11578         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11579   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11581   "shr{l}\t{%2, %k0|%k0, %2}"
11582   [(set_attr "type" "ishift")
11583    (set_attr "mode" "SI")])
11584
11585 (define_expand "lshrhi3"
11586   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11587         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11588                      (match_operand:QI 2 "nonmemory_operand" "")))
11589    (clobber (reg:CC FLAGS_REG))]
11590   "TARGET_HIMODE_MATH"
11591   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11592
11593 (define_insn "*lshrhi3_1_one_bit"
11594   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11595         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11596                      (match_operand:QI 2 "const1_operand" "")))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11599    && (TARGET_SHIFT1 || optimize_size)"
11600   "shr{w}\t%0"
11601   [(set_attr "type" "ishift")
11602    (set (attr "length") 
11603      (if_then_else (match_operand 0 "register_operand" "") 
11604         (const_string "2")
11605         (const_string "*")))])
11606
11607 (define_insn "*lshrhi3_1"
11608   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11609         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11610                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11613   "@
11614    shr{w}\t{%2, %0|%0, %2}
11615    shr{w}\t{%b2, %0|%0, %b2}"
11616   [(set_attr "type" "ishift")
11617    (set_attr "mode" "HI")])
11618
11619 ;; This pattern can't accept a variable shift count, since shifts by
11620 ;; zero don't affect the flags.  We assume that shifts by constant
11621 ;; zero are optimized away.
11622 (define_insn "*lshrhi3_one_bit_cmp"
11623   [(set (reg FLAGS_REG)
11624         (compare
11625           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11626                        (match_operand:QI 2 "const1_operand" ""))
11627           (const_int 0)))
11628    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11629         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11630   "ix86_match_ccmode (insn, CCGOCmode)
11631    && (TARGET_SHIFT1 || optimize_size)
11632    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633   "shr{w}\t%0"
11634   [(set_attr "type" "ishift")
11635    (set (attr "length") 
11636      (if_then_else (match_operand:SI 0 "register_operand" "") 
11637         (const_string "2")
11638         (const_string "*")))])
11639
11640 ;; This pattern can't accept a variable shift count, since shifts by
11641 ;; zero don't affect the flags.  We assume that shifts by constant
11642 ;; zero are optimized away.
11643 (define_insn "*lshrhi3_cmp"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11647                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11648           (const_int 0)))
11649    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11650         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11653   "shr{w}\t{%2, %0|%0, %2}"
11654   [(set_attr "type" "ishift")
11655    (set_attr "mode" "HI")])
11656
11657 (define_expand "lshrqi3"
11658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11659         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11660                      (match_operand:QI 2 "nonmemory_operand" "")))
11661    (clobber (reg:CC FLAGS_REG))]
11662   "TARGET_QIMODE_MATH"
11663   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11664
11665 (define_insn "*lshrqi3_1_one_bit"
11666   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11667         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11668                      (match_operand:QI 2 "const1_operand" "")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11671    && (TARGET_SHIFT1 || optimize_size)"
11672   "shr{b}\t%0"
11673   [(set_attr "type" "ishift")
11674    (set (attr "length") 
11675      (if_then_else (match_operand 0 "register_operand" "") 
11676         (const_string "2")
11677         (const_string "*")))])
11678
11679 (define_insn "*lshrqi3_1_one_bit_slp"
11680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11681         (lshiftrt:QI (match_dup 0)
11682                      (match_operand:QI 1 "const1_operand" "")))
11683    (clobber (reg:CC FLAGS_REG))]
11684   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11685    && (TARGET_SHIFT1 || optimize_size)"
11686   "shr{b}\t%0"
11687   [(set_attr "type" "ishift1")
11688    (set (attr "length") 
11689      (if_then_else (match_operand 0 "register_operand" "") 
11690         (const_string "2")
11691         (const_string "*")))])
11692
11693 (define_insn "*lshrqi3_1"
11694   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11695         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11696                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11697    (clobber (reg:CC FLAGS_REG))]
11698   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11699   "@
11700    shr{b}\t{%2, %0|%0, %2}
11701    shr{b}\t{%b2, %0|%0, %b2}"
11702   [(set_attr "type" "ishift")
11703    (set_attr "mode" "QI")])
11704
11705 (define_insn "*lshrqi3_1_slp"
11706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11707         (lshiftrt:QI (match_dup 0)
11708                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11711    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11712   "@
11713    shr{b}\t{%1, %0|%0, %1}
11714    shr{b}\t{%b1, %0|%0, %b1}"
11715   [(set_attr "type" "ishift1")
11716    (set_attr "mode" "QI")])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*lshrqi2_one_bit_cmp"
11722   [(set (reg FLAGS_REG)
11723         (compare
11724           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11728         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11732   "shr{b}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand:SI 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 ;; This pattern can't accept a variable shift count, since shifts by
11740 ;; zero don't affect the flags.  We assume that shifts by constant
11741 ;; zero are optimized away.
11742 (define_insn "*lshrqi2_cmp"
11743   [(set (reg FLAGS_REG)
11744         (compare
11745           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11746                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11747           (const_int 0)))
11748    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11749         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11750   "ix86_match_ccmode (insn, CCGOCmode)
11751    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11752   "shr{b}\t{%2, %0|%0, %2}"
11753   [(set_attr "type" "ishift")
11754    (set_attr "mode" "QI")])
11755 \f
11756 ;; Rotate instructions
11757
11758 (define_expand "rotldi3"
11759   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11760         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11761                    (match_operand:QI 2 "nonmemory_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "TARGET_64BIT"
11764   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11765
11766 (define_insn "*rotlsi3_1_one_bit_rex64"
11767   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11768         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11769                    (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "rol{q}\t%0"
11774   [(set_attr "type" "rotate")
11775    (set (attr "length") 
11776      (if_then_else (match_operand:DI 0 "register_operand" "") 
11777         (const_string "2")
11778         (const_string "*")))])
11779
11780 (define_insn "*rotldi3_1_rex64"
11781   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11782         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11783                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11786   "@
11787    rol{q}\t{%2, %0|%0, %2}
11788    rol{q}\t{%b2, %0|%0, %b2}"
11789   [(set_attr "type" "rotate")
11790    (set_attr "mode" "DI")])
11791
11792 (define_expand "rotlsi3"
11793   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11794         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11795                    (match_operand:QI 2 "nonmemory_operand" "")))
11796    (clobber (reg:CC FLAGS_REG))]
11797   ""
11798   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11799
11800 (define_insn "*rotlsi3_1_one_bit"
11801   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11802         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11803                    (match_operand:QI 2 "const1_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11806    && (TARGET_SHIFT1 || optimize_size)"
11807   "rol{l}\t%0"
11808   [(set_attr "type" "rotate")
11809    (set (attr "length") 
11810      (if_then_else (match_operand:SI 0 "register_operand" "") 
11811         (const_string "2")
11812         (const_string "*")))])
11813
11814 (define_insn "*rotlsi3_1_one_bit_zext"
11815   [(set (match_operand:DI 0 "register_operand" "=r")
11816         (zero_extend:DI
11817           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11818                      (match_operand:QI 2 "const1_operand" ""))))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11821    && (TARGET_SHIFT1 || optimize_size)"
11822   "rol{l}\t%k0"
11823   [(set_attr "type" "rotate")
11824    (set_attr "length" "2")])
11825
11826 (define_insn "*rotlsi3_1"
11827   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11828         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11829                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11832   "@
11833    rol{l}\t{%2, %0|%0, %2}
11834    rol{l}\t{%b2, %0|%0, %b2}"
11835   [(set_attr "type" "rotate")
11836    (set_attr "mode" "SI")])
11837
11838 (define_insn "*rotlsi3_1_zext"
11839   [(set (match_operand:DI 0 "register_operand" "=r,r")
11840         (zero_extend:DI
11841           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11842                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11845   "@
11846    rol{l}\t{%2, %k0|%k0, %2}
11847    rol{l}\t{%b2, %k0|%k0, %b2}"
11848   [(set_attr "type" "rotate")
11849    (set_attr "mode" "SI")])
11850
11851 (define_expand "rotlhi3"
11852   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11853         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11854                    (match_operand:QI 2 "nonmemory_operand" "")))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "TARGET_HIMODE_MATH"
11857   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11858
11859 (define_insn "*rotlhi3_1_one_bit"
11860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11861         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11862                    (match_operand:QI 2 "const1_operand" "")))
11863    (clobber (reg:CC FLAGS_REG))]
11864   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11865    && (TARGET_SHIFT1 || optimize_size)"
11866   "rol{w}\t%0"
11867   [(set_attr "type" "rotate")
11868    (set (attr "length") 
11869      (if_then_else (match_operand 0 "register_operand" "") 
11870         (const_string "2")
11871         (const_string "*")))])
11872
11873 (define_insn "*rotlhi3_1"
11874   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11875         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11876                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11879   "@
11880    rol{w}\t{%2, %0|%0, %2}
11881    rol{w}\t{%b2, %0|%0, %b2}"
11882   [(set_attr "type" "rotate")
11883    (set_attr "mode" "HI")])
11884
11885 (define_expand "rotlqi3"
11886   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11887         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11888                    (match_operand:QI 2 "nonmemory_operand" "")))
11889    (clobber (reg:CC FLAGS_REG))]
11890   "TARGET_QIMODE_MATH"
11891   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11892
11893 (define_insn "*rotlqi3_1_one_bit_slp"
11894   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11895         (rotate:QI (match_dup 0)
11896                    (match_operand:QI 1 "const1_operand" "")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11899    && (TARGET_SHIFT1 || optimize_size)"
11900   "rol{b}\t%0"
11901   [(set_attr "type" "rotate1")
11902    (set (attr "length") 
11903      (if_then_else (match_operand 0 "register_operand" "") 
11904         (const_string "2")
11905         (const_string "*")))])
11906
11907 (define_insn "*rotlqi3_1_one_bit"
11908   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11909         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11910                    (match_operand:QI 2 "const1_operand" "")))
11911    (clobber (reg:CC FLAGS_REG))]
11912   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11913    && (TARGET_SHIFT1 || optimize_size)"
11914   "rol{b}\t%0"
11915   [(set_attr "type" "rotate")
11916    (set (attr "length") 
11917      (if_then_else (match_operand 0 "register_operand" "") 
11918         (const_string "2")
11919         (const_string "*")))])
11920
11921 (define_insn "*rotlqi3_1_slp"
11922   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11923         (rotate:QI (match_dup 0)
11924                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11927    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11928   "@
11929    rol{b}\t{%1, %0|%0, %1}
11930    rol{b}\t{%b1, %0|%0, %b1}"
11931   [(set_attr "type" "rotate1")
11932    (set_attr "mode" "QI")])
11933
11934 (define_insn "*rotlqi3_1"
11935   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11936         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11937                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11940   "@
11941    rol{b}\t{%2, %0|%0, %2}
11942    rol{b}\t{%b2, %0|%0, %b2}"
11943   [(set_attr "type" "rotate")
11944    (set_attr "mode" "QI")])
11945
11946 (define_expand "rotrdi3"
11947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11948         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11949                      (match_operand:QI 2 "nonmemory_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "TARGET_64BIT"
11952   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11953
11954 (define_insn "*rotrdi3_1_one_bit_rex64"
11955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11956         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11957                      (match_operand:QI 2 "const1_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11960    && (TARGET_SHIFT1 || optimize_size)"
11961   "ror{q}\t%0"
11962   [(set_attr "type" "rotate")
11963    (set (attr "length") 
11964      (if_then_else (match_operand:DI 0 "register_operand" "") 
11965         (const_string "2")
11966         (const_string "*")))])
11967
11968 (define_insn "*rotrdi3_1_rex64"
11969   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11970         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11971                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11974   "@
11975    ror{q}\t{%2, %0|%0, %2}
11976    ror{q}\t{%b2, %0|%0, %b2}"
11977   [(set_attr "type" "rotate")
11978    (set_attr "mode" "DI")])
11979
11980 (define_expand "rotrsi3"
11981   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11982         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11983                      (match_operand:QI 2 "nonmemory_operand" "")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   ""
11986   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11987
11988 (define_insn "*rotrsi3_1_one_bit"
11989   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991                      (match_operand:QI 2 "const1_operand" "")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11994    && (TARGET_SHIFT1 || optimize_size)"
11995   "ror{l}\t%0"
11996   [(set_attr "type" "rotate")
11997    (set (attr "length") 
11998      (if_then_else (match_operand:SI 0 "register_operand" "") 
11999         (const_string "2")
12000         (const_string "*")))])
12001
12002 (define_insn "*rotrsi3_1_one_bit_zext"
12003   [(set (match_operand:DI 0 "register_operand" "=r")
12004         (zero_extend:DI
12005           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12006                        (match_operand:QI 2 "const1_operand" ""))))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12009    && (TARGET_SHIFT1 || optimize_size)"
12010   "ror{l}\t%k0"
12011   [(set_attr "type" "rotate")
12012    (set (attr "length") 
12013      (if_then_else (match_operand:SI 0 "register_operand" "") 
12014         (const_string "2")
12015         (const_string "*")))])
12016
12017 (define_insn "*rotrsi3_1"
12018   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12019         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12020                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12023   "@
12024    ror{l}\t{%2, %0|%0, %2}
12025    ror{l}\t{%b2, %0|%0, %b2}"
12026   [(set_attr "type" "rotate")
12027    (set_attr "mode" "SI")])
12028
12029 (define_insn "*rotrsi3_1_zext"
12030   [(set (match_operand:DI 0 "register_operand" "=r,r")
12031         (zero_extend:DI
12032           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12033                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12036   "@
12037    ror{l}\t{%2, %k0|%k0, %2}
12038    ror{l}\t{%b2, %k0|%k0, %b2}"
12039   [(set_attr "type" "rotate")
12040    (set_attr "mode" "SI")])
12041
12042 (define_expand "rotrhi3"
12043   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12044         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12045                      (match_operand:QI 2 "nonmemory_operand" "")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "TARGET_HIMODE_MATH"
12048   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12049
12050 (define_insn "*rotrhi3_one_bit"
12051   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12052         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12053                      (match_operand:QI 2 "const1_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12056    && (TARGET_SHIFT1 || optimize_size)"
12057   "ror{w}\t%0"
12058   [(set_attr "type" "rotate")
12059    (set (attr "length") 
12060      (if_then_else (match_operand 0 "register_operand" "") 
12061         (const_string "2")
12062         (const_string "*")))])
12063
12064 (define_insn "*rotrhi3"
12065   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12066         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12067                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12070   "@
12071    ror{w}\t{%2, %0|%0, %2}
12072    ror{w}\t{%b2, %0|%0, %b2}"
12073   [(set_attr "type" "rotate")
12074    (set_attr "mode" "HI")])
12075
12076 (define_expand "rotrqi3"
12077   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12078         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12079                      (match_operand:QI 2 "nonmemory_operand" "")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_QIMODE_MATH"
12082   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12083
12084 (define_insn "*rotrqi3_1_one_bit"
12085   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12086         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12087                      (match_operand:QI 2 "const1_operand" "")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12090    && (TARGET_SHIFT1 || optimize_size)"
12091   "ror{b}\t%0"
12092   [(set_attr "type" "rotate")
12093    (set (attr "length") 
12094      (if_then_else (match_operand 0 "register_operand" "") 
12095         (const_string "2")
12096         (const_string "*")))])
12097
12098 (define_insn "*rotrqi3_1_one_bit_slp"
12099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12100         (rotatert:QI (match_dup 0)
12101                      (match_operand:QI 1 "const1_operand" "")))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12104    && (TARGET_SHIFT1 || optimize_size)"
12105   "ror{b}\t%0"
12106   [(set_attr "type" "rotate1")
12107    (set (attr "length") 
12108      (if_then_else (match_operand 0 "register_operand" "") 
12109         (const_string "2")
12110         (const_string "*")))])
12111
12112 (define_insn "*rotrqi3_1"
12113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12114         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12115                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12118   "@
12119    ror{b}\t{%2, %0|%0, %2}
12120    ror{b}\t{%b2, %0|%0, %b2}"
12121   [(set_attr "type" "rotate")
12122    (set_attr "mode" "QI")])
12123
12124 (define_insn "*rotrqi3_1_slp"
12125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12126         (rotatert:QI (match_dup 0)
12127                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12131   "@
12132    ror{b}\t{%1, %0|%0, %1}
12133    ror{b}\t{%b1, %0|%0, %b1}"
12134   [(set_attr "type" "rotate1")
12135    (set_attr "mode" "QI")])
12136 \f
12137 ;; Bit set / bit test instructions
12138
12139 (define_expand "extv"
12140   [(set (match_operand:SI 0 "register_operand" "")
12141         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12142                          (match_operand:SI 2 "immediate_operand" "")
12143                          (match_operand:SI 3 "immediate_operand" "")))]
12144   ""
12145 {
12146   /* Handle extractions from %ah et al.  */
12147   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12148     FAIL;
12149
12150   /* From mips.md: extract_bit_field doesn't verify that our source
12151      matches the predicate, so check it again here.  */
12152   if (! ext_register_operand (operands[1], VOIDmode))
12153     FAIL;
12154 })
12155
12156 (define_expand "extzv"
12157   [(set (match_operand:SI 0 "register_operand" "")
12158         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12159                          (match_operand:SI 2 "immediate_operand" "")
12160                          (match_operand:SI 3 "immediate_operand" "")))]
12161   ""
12162 {
12163   /* Handle extractions from %ah et al.  */
12164   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12165     FAIL;
12166
12167   /* From mips.md: extract_bit_field doesn't verify that our source
12168      matches the predicate, so check it again here.  */
12169   if (! ext_register_operand (operands[1], VOIDmode))
12170     FAIL;
12171 })
12172
12173 (define_expand "insv"
12174   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12175                       (match_operand 1 "immediate_operand" "")
12176                       (match_operand 2 "immediate_operand" ""))
12177         (match_operand 3 "register_operand" ""))]
12178   ""
12179 {
12180   /* Handle extractions from %ah et al.  */
12181   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12182     FAIL;
12183
12184   /* From mips.md: insert_bit_field doesn't verify that our source
12185      matches the predicate, so check it again here.  */
12186   if (! ext_register_operand (operands[0], VOIDmode))
12187     FAIL;
12188
12189   if (TARGET_64BIT)
12190     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12191   else
12192     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12193
12194   DONE;
12195 })
12196
12197 ;; %%% bts, btr, btc, bt.
12198 ;; In general these instructions are *slow* when applied to memory,
12199 ;; since they enforce atomic operation.  When applied to registers,
12200 ;; it depends on the cpu implementation.  They're never faster than
12201 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12202 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12203 ;; within the instruction itself, so operating on bits in the high
12204 ;; 32-bits of a register becomes easier.
12205 ;;
12206 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12207 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12208 ;; negdf respectively, so they can never be disabled entirely.
12209
12210 (define_insn "*btsq"
12211   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12212                          (const_int 1)
12213                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12214         (const_int 1))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12217   "bts{q} %1,%0"
12218   [(set_attr "type" "alu1")])
12219
12220 (define_insn "*btrq"
12221   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12222                          (const_int 1)
12223                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12224         (const_int 0))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12227   "btr{q} %1,%0"
12228   [(set_attr "type" "alu1")])
12229
12230 (define_insn "*btcq"
12231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12232                          (const_int 1)
12233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12234         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12237   "btc{q} %1,%0"
12238   [(set_attr "type" "alu1")])
12239
12240 ;; Allow Nocona to avoid these instructions if a register is available.
12241
12242 (define_peephole2
12243   [(match_scratch:DI 2 "r")
12244    (parallel [(set (zero_extract:DI
12245                      (match_operand:DI 0 "register_operand" "")
12246                      (const_int 1)
12247                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12248                    (const_int 1))
12249               (clobber (reg:CC FLAGS_REG))])]
12250   "TARGET_64BIT && !TARGET_USE_BT"
12251   [(const_int 0)]
12252 {
12253   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12254   rtx op1;
12255
12256   if (HOST_BITS_PER_WIDE_INT >= 64)
12257     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12258   else if (i < HOST_BITS_PER_WIDE_INT)
12259     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12260   else
12261     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12262
12263   op1 = immed_double_const (lo, hi, DImode);
12264   if (i >= 31)
12265     {
12266       emit_move_insn (operands[2], op1);
12267       op1 = operands[2];
12268     }
12269
12270   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12271   DONE;
12272 })
12273
12274 (define_peephole2
12275   [(match_scratch:DI 2 "r")
12276    (parallel [(set (zero_extract:DI
12277                      (match_operand:DI 0 "register_operand" "")
12278                      (const_int 1)
12279                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12280                    (const_int 0))
12281               (clobber (reg:CC FLAGS_REG))])]
12282   "TARGET_64BIT && !TARGET_USE_BT"
12283   [(const_int 0)]
12284 {
12285   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12286   rtx op1;
12287
12288   if (HOST_BITS_PER_WIDE_INT >= 64)
12289     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12290   else if (i < HOST_BITS_PER_WIDE_INT)
12291     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12292   else
12293     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12294
12295   op1 = immed_double_const (~lo, ~hi, DImode);
12296   if (i >= 32)
12297     {
12298       emit_move_insn (operands[2], op1);
12299       op1 = operands[2];
12300     }
12301
12302   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12303   DONE;
12304 })
12305
12306 (define_peephole2
12307   [(match_scratch:DI 2 "r")
12308    (parallel [(set (zero_extract:DI
12309                      (match_operand:DI 0 "register_operand" "")
12310                      (const_int 1)
12311                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12312               (not:DI (zero_extract:DI
12313                         (match_dup 0) (const_int 1) (match_dup 1))))
12314               (clobber (reg:CC FLAGS_REG))])]
12315   "TARGET_64BIT && !TARGET_USE_BT"
12316   [(const_int 0)]
12317 {
12318   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12319   rtx op1;
12320
12321   if (HOST_BITS_PER_WIDE_INT >= 64)
12322     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12323   else if (i < HOST_BITS_PER_WIDE_INT)
12324     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12325   else
12326     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12327
12328   op1 = immed_double_const (lo, hi, DImode);
12329   if (i >= 31)
12330     {
12331       emit_move_insn (operands[2], op1);
12332       op1 = operands[2];
12333     }
12334
12335   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12336   DONE;
12337 })
12338 \f
12339 ;; Store-flag instructions.
12340
12341 ;; For all sCOND expanders, also expand the compare or test insn that
12342 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12343
12344 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12345 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12346 ;; way, which can later delete the movzx if only QImode is needed.
12347
12348 (define_expand "seq"
12349   [(set (match_operand:QI 0 "register_operand" "")
12350         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12351   ""
12352   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12353
12354 (define_expand "sne"
12355   [(set (match_operand:QI 0 "register_operand" "")
12356         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12357   ""
12358   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12359
12360 (define_expand "sgt"
12361   [(set (match_operand:QI 0 "register_operand" "")
12362         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12363   ""
12364   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12365
12366 (define_expand "sgtu"
12367   [(set (match_operand:QI 0 "register_operand" "")
12368         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12369   ""
12370   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12371
12372 (define_expand "slt"
12373   [(set (match_operand:QI 0 "register_operand" "")
12374         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12375   ""
12376   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12377
12378 (define_expand "sltu"
12379   [(set (match_operand:QI 0 "register_operand" "")
12380         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12381   ""
12382   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12383
12384 (define_expand "sge"
12385   [(set (match_operand:QI 0 "register_operand" "")
12386         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12387   ""
12388   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12389
12390 (define_expand "sgeu"
12391   [(set (match_operand:QI 0 "register_operand" "")
12392         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12393   ""
12394   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12395
12396 (define_expand "sle"
12397   [(set (match_operand:QI 0 "register_operand" "")
12398         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12399   ""
12400   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12401
12402 (define_expand "sleu"
12403   [(set (match_operand:QI 0 "register_operand" "")
12404         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12405   ""
12406   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12407
12408 (define_expand "sunordered"
12409   [(set (match_operand:QI 0 "register_operand" "")
12410         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12411   "TARGET_80387 || TARGET_SSE"
12412   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12413
12414 (define_expand "sordered"
12415   [(set (match_operand:QI 0 "register_operand" "")
12416         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12417   "TARGET_80387"
12418   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12419
12420 (define_expand "suneq"
12421   [(set (match_operand:QI 0 "register_operand" "")
12422         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12423   "TARGET_80387 || TARGET_SSE"
12424   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12425
12426 (define_expand "sunge"
12427   [(set (match_operand:QI 0 "register_operand" "")
12428         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12429   "TARGET_80387 || TARGET_SSE"
12430   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12431
12432 (define_expand "sungt"
12433   [(set (match_operand:QI 0 "register_operand" "")
12434         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12435   "TARGET_80387 || TARGET_SSE"
12436   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12437
12438 (define_expand "sunle"
12439   [(set (match_operand:QI 0 "register_operand" "")
12440         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12441   "TARGET_80387 || TARGET_SSE"
12442   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12443
12444 (define_expand "sunlt"
12445   [(set (match_operand:QI 0 "register_operand" "")
12446         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12447   "TARGET_80387 || TARGET_SSE"
12448   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12449
12450 (define_expand "sltgt"
12451   [(set (match_operand:QI 0 "register_operand" "")
12452         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12453   "TARGET_80387 || TARGET_SSE"
12454   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12455
12456 (define_insn "*setcc_1"
12457   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12458         (match_operator:QI 1 "ix86_comparison_operator"
12459           [(reg FLAGS_REG) (const_int 0)]))]
12460   ""
12461   "set%C1\t%0"
12462   [(set_attr "type" "setcc")
12463    (set_attr "mode" "QI")])
12464
12465 (define_insn "*setcc_2"
12466   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12467         (match_operator:QI 1 "ix86_comparison_operator"
12468           [(reg FLAGS_REG) (const_int 0)]))]
12469   ""
12470   "set%C1\t%0"
12471   [(set_attr "type" "setcc")
12472    (set_attr "mode" "QI")])
12473
12474 ;; In general it is not safe to assume too much about CCmode registers,
12475 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12476 ;; conditions this is safe on x86, so help combine not create
12477 ;;
12478 ;;      seta    %al
12479 ;;      testb   %al, %al
12480 ;;      sete    %al
12481
12482 (define_split 
12483   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12484         (ne:QI (match_operator 1 "ix86_comparison_operator"
12485                  [(reg FLAGS_REG) (const_int 0)])
12486             (const_int 0)))]
12487   ""
12488   [(set (match_dup 0) (match_dup 1))]
12489 {
12490   PUT_MODE (operands[1], QImode);
12491 })
12492
12493 (define_split 
12494   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12495         (ne:QI (match_operator 1 "ix86_comparison_operator"
12496                  [(reg FLAGS_REG) (const_int 0)])
12497             (const_int 0)))]
12498   ""
12499   [(set (match_dup 0) (match_dup 1))]
12500 {
12501   PUT_MODE (operands[1], QImode);
12502 })
12503
12504 (define_split 
12505   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12506         (eq:QI (match_operator 1 "ix86_comparison_operator"
12507                  [(reg FLAGS_REG) (const_int 0)])
12508             (const_int 0)))]
12509   ""
12510   [(set (match_dup 0) (match_dup 1))]
12511 {
12512   rtx new_op1 = copy_rtx (operands[1]);
12513   operands[1] = new_op1;
12514   PUT_MODE (new_op1, QImode);
12515   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12516                                              GET_MODE (XEXP (new_op1, 0))));
12517
12518   /* Make sure that (a) the CCmode we have for the flags is strong
12519      enough for the reversed compare or (b) we have a valid FP compare.  */
12520   if (! ix86_comparison_operator (new_op1, VOIDmode))
12521     FAIL;
12522 })
12523
12524 (define_split 
12525   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12526         (eq:QI (match_operator 1 "ix86_comparison_operator"
12527                  [(reg FLAGS_REG) (const_int 0)])
12528             (const_int 0)))]
12529   ""
12530   [(set (match_dup 0) (match_dup 1))]
12531 {
12532   rtx new_op1 = copy_rtx (operands[1]);
12533   operands[1] = new_op1;
12534   PUT_MODE (new_op1, QImode);
12535   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12536                                              GET_MODE (XEXP (new_op1, 0))));
12537
12538   /* Make sure that (a) the CCmode we have for the flags is strong
12539      enough for the reversed compare or (b) we have a valid FP compare.  */
12540   if (! ix86_comparison_operator (new_op1, VOIDmode))
12541     FAIL;
12542 })
12543
12544 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12545 ;; subsequent logical operations are used to imitate conditional moves.
12546 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12547 ;; it directly.  Further holding this value in pseudo register might bring
12548 ;; problem in implicit normalization in spill code.
12549 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12550 ;; instructions after reload by splitting the conditional move patterns.
12551
12552 (define_insn "*sse_setccsf"
12553   [(set (match_operand:SF 0 "register_operand" "=x")
12554         (match_operator:SF 1 "sse_comparison_operator"
12555           [(match_operand:SF 2 "register_operand" "0")
12556            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12557   "TARGET_SSE && reload_completed"
12558   "cmp%D1ss\t{%3, %0|%0, %3}"
12559   [(set_attr "type" "ssecmp")
12560    (set_attr "mode" "SF")])
12561
12562 (define_insn "*sse_setccdf"
12563   [(set (match_operand:DF 0 "register_operand" "=Y")
12564         (match_operator:DF 1 "sse_comparison_operator"
12565           [(match_operand:DF 2 "register_operand" "0")
12566            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12567   "TARGET_SSE2 && reload_completed"
12568   "cmp%D1sd\t{%3, %0|%0, %3}"
12569   [(set_attr "type" "ssecmp")
12570    (set_attr "mode" "DF")])
12571 \f
12572 ;; Basic conditional jump instructions.
12573 ;; We ignore the overflow flag for signed branch instructions.
12574
12575 ;; For all bCOND expanders, also expand the compare or test insn that
12576 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12577
12578 (define_expand "beq"
12579   [(set (pc)
12580         (if_then_else (match_dup 1)
12581                       (label_ref (match_operand 0 "" ""))
12582                       (pc)))]
12583   ""
12584   "ix86_expand_branch (EQ, operands[0]); DONE;")
12585
12586 (define_expand "bne"
12587   [(set (pc)
12588         (if_then_else (match_dup 1)
12589                       (label_ref (match_operand 0 "" ""))
12590                       (pc)))]
12591   ""
12592   "ix86_expand_branch (NE, operands[0]); DONE;")
12593
12594 (define_expand "bgt"
12595   [(set (pc)
12596         (if_then_else (match_dup 1)
12597                       (label_ref (match_operand 0 "" ""))
12598                       (pc)))]
12599   ""
12600   "ix86_expand_branch (GT, operands[0]); DONE;")
12601
12602 (define_expand "bgtu"
12603   [(set (pc)
12604         (if_then_else (match_dup 1)
12605                       (label_ref (match_operand 0 "" ""))
12606                       (pc)))]
12607   ""
12608   "ix86_expand_branch (GTU, operands[0]); DONE;")
12609
12610 (define_expand "blt"
12611   [(set (pc)
12612         (if_then_else (match_dup 1)
12613                       (label_ref (match_operand 0 "" ""))
12614                       (pc)))]
12615   ""
12616   "ix86_expand_branch (LT, operands[0]); DONE;")
12617
12618 (define_expand "bltu"
12619   [(set (pc)
12620         (if_then_else (match_dup 1)
12621                       (label_ref (match_operand 0 "" ""))
12622                       (pc)))]
12623   ""
12624   "ix86_expand_branch (LTU, operands[0]); DONE;")
12625
12626 (define_expand "bge"
12627   [(set (pc)
12628         (if_then_else (match_dup 1)
12629                       (label_ref (match_operand 0 "" ""))
12630                       (pc)))]
12631   ""
12632   "ix86_expand_branch (GE, operands[0]); DONE;")
12633
12634 (define_expand "bgeu"
12635   [(set (pc)
12636         (if_then_else (match_dup 1)
12637                       (label_ref (match_operand 0 "" ""))
12638                       (pc)))]
12639   ""
12640   "ix86_expand_branch (GEU, operands[0]); DONE;")
12641
12642 (define_expand "ble"
12643   [(set (pc)
12644         (if_then_else (match_dup 1)
12645                       (label_ref (match_operand 0 "" ""))
12646                       (pc)))]
12647   ""
12648   "ix86_expand_branch (LE, operands[0]); DONE;")
12649
12650 (define_expand "bleu"
12651   [(set (pc)
12652         (if_then_else (match_dup 1)
12653                       (label_ref (match_operand 0 "" ""))
12654                       (pc)))]
12655   ""
12656   "ix86_expand_branch (LEU, operands[0]); DONE;")
12657
12658 (define_expand "bunordered"
12659   [(set (pc)
12660         (if_then_else (match_dup 1)
12661                       (label_ref (match_operand 0 "" ""))
12662                       (pc)))]
12663   "TARGET_80387 || TARGET_SSE"
12664   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12665
12666 (define_expand "bordered"
12667   [(set (pc)
12668         (if_then_else (match_dup 1)
12669                       (label_ref (match_operand 0 "" ""))
12670                       (pc)))]
12671   "TARGET_80387 || TARGET_SSE"
12672   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12673
12674 (define_expand "buneq"
12675   [(set (pc)
12676         (if_then_else (match_dup 1)
12677                       (label_ref (match_operand 0 "" ""))
12678                       (pc)))]
12679   "TARGET_80387 || TARGET_SSE"
12680   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12681
12682 (define_expand "bunge"
12683   [(set (pc)
12684         (if_then_else (match_dup 1)
12685                       (label_ref (match_operand 0 "" ""))
12686                       (pc)))]
12687   "TARGET_80387 || TARGET_SSE"
12688   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12689
12690 (define_expand "bungt"
12691   [(set (pc)
12692         (if_then_else (match_dup 1)
12693                       (label_ref (match_operand 0 "" ""))
12694                       (pc)))]
12695   "TARGET_80387 || TARGET_SSE"
12696   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12697
12698 (define_expand "bunle"
12699   [(set (pc)
12700         (if_then_else (match_dup 1)
12701                       (label_ref (match_operand 0 "" ""))
12702                       (pc)))]
12703   "TARGET_80387 || TARGET_SSE"
12704   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12705
12706 (define_expand "bunlt"
12707   [(set (pc)
12708         (if_then_else (match_dup 1)
12709                       (label_ref (match_operand 0 "" ""))
12710                       (pc)))]
12711   "TARGET_80387 || TARGET_SSE"
12712   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12713
12714 (define_expand "bltgt"
12715   [(set (pc)
12716         (if_then_else (match_dup 1)
12717                       (label_ref (match_operand 0 "" ""))
12718                       (pc)))]
12719   "TARGET_80387 || TARGET_SSE"
12720   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12721
12722 (define_insn "*jcc_1"
12723   [(set (pc)
12724         (if_then_else (match_operator 1 "ix86_comparison_operator"
12725                                       [(reg FLAGS_REG) (const_int 0)])
12726                       (label_ref (match_operand 0 "" ""))
12727                       (pc)))]
12728   ""
12729   "%+j%C1\t%l0"
12730   [(set_attr "type" "ibr")
12731    (set_attr "modrm" "0")
12732    (set (attr "length")
12733            (if_then_else (and (ge (minus (match_dup 0) (pc))
12734                                   (const_int -126))
12735                               (lt (minus (match_dup 0) (pc))
12736                                   (const_int 128)))
12737              (const_int 2)
12738              (const_int 6)))])
12739
12740 (define_insn "*jcc_2"
12741   [(set (pc)
12742         (if_then_else (match_operator 1 "ix86_comparison_operator"
12743                                       [(reg FLAGS_REG) (const_int 0)])
12744                       (pc)
12745                       (label_ref (match_operand 0 "" ""))))]
12746   ""
12747   "%+j%c1\t%l0"
12748   [(set_attr "type" "ibr")
12749    (set_attr "modrm" "0")
12750    (set (attr "length")
12751            (if_then_else (and (ge (minus (match_dup 0) (pc))
12752                                   (const_int -126))
12753                               (lt (minus (match_dup 0) (pc))
12754                                   (const_int 128)))
12755              (const_int 2)
12756              (const_int 6)))])
12757
12758 ;; In general it is not safe to assume too much about CCmode registers,
12759 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12760 ;; conditions this is safe on x86, so help combine not create
12761 ;;
12762 ;;      seta    %al
12763 ;;      testb   %al, %al
12764 ;;      je      Lfoo
12765
12766 (define_split 
12767   [(set (pc)
12768         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12769                                       [(reg FLAGS_REG) (const_int 0)])
12770                           (const_int 0))
12771                       (label_ref (match_operand 1 "" ""))
12772                       (pc)))]
12773   ""
12774   [(set (pc)
12775         (if_then_else (match_dup 0)
12776                       (label_ref (match_dup 1))
12777                       (pc)))]
12778 {
12779   PUT_MODE (operands[0], VOIDmode);
12780 })
12781   
12782 (define_split 
12783   [(set (pc)
12784         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12785                                       [(reg FLAGS_REG) (const_int 0)])
12786                           (const_int 0))
12787                       (label_ref (match_operand 1 "" ""))
12788                       (pc)))]
12789   ""
12790   [(set (pc)
12791         (if_then_else (match_dup 0)
12792                       (label_ref (match_dup 1))
12793                       (pc)))]
12794 {
12795   rtx new_op0 = copy_rtx (operands[0]);
12796   operands[0] = new_op0;
12797   PUT_MODE (new_op0, VOIDmode);
12798   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12799                                              GET_MODE (XEXP (new_op0, 0))));
12800
12801   /* Make sure that (a) the CCmode we have for the flags is strong
12802      enough for the reversed compare or (b) we have a valid FP compare.  */
12803   if (! ix86_comparison_operator (new_op0, VOIDmode))
12804     FAIL;
12805 })
12806
12807 ;; Define combination compare-and-branch fp compare instructions to use
12808 ;; during early optimization.  Splitting the operation apart early makes
12809 ;; for bad code when we want to reverse the operation.
12810
12811 (define_insn "*fp_jcc_1"
12812   [(set (pc)
12813         (if_then_else (match_operator 0 "comparison_operator"
12814                         [(match_operand 1 "register_operand" "f")
12815                          (match_operand 2 "register_operand" "f")])
12816           (label_ref (match_operand 3 "" ""))
12817           (pc)))
12818    (clobber (reg:CCFP FPSR_REG))
12819    (clobber (reg:CCFP FLAGS_REG))]
12820   "TARGET_CMOVE && TARGET_80387
12821    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12822    && FLOAT_MODE_P (GET_MODE (operands[1]))
12823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12824    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12825   "#")
12826
12827 (define_insn "*fp_jcc_1_sse"
12828   [(set (pc)
12829         (if_then_else (match_operator 0 "comparison_operator"
12830                         [(match_operand 1 "register_operand" "f#x,x#f")
12831                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12832           (label_ref (match_operand 3 "" ""))
12833           (pc)))
12834    (clobber (reg:CCFP FPSR_REG))
12835    (clobber (reg:CCFP FLAGS_REG))]
12836   "TARGET_80387
12837    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12838    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12840   "#")
12841
12842 (define_insn "*fp_jcc_1_sse_only"
12843   [(set (pc)
12844         (if_then_else (match_operator 0 "comparison_operator"
12845                         [(match_operand 1 "register_operand" "x")
12846                          (match_operand 2 "nonimmediate_operand" "xm")])
12847           (label_ref (match_operand 3 "" ""))
12848           (pc)))
12849    (clobber (reg:CCFP FPSR_REG))
12850    (clobber (reg:CCFP FLAGS_REG))]
12851   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12852    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12853    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12854   "#")
12855
12856 (define_insn "*fp_jcc_2"
12857   [(set (pc)
12858         (if_then_else (match_operator 0 "comparison_operator"
12859                         [(match_operand 1 "register_operand" "f")
12860                          (match_operand 2 "register_operand" "f")])
12861           (pc)
12862           (label_ref (match_operand 3 "" ""))))
12863    (clobber (reg:CCFP FPSR_REG))
12864    (clobber (reg:CCFP FLAGS_REG))]
12865   "TARGET_CMOVE && TARGET_80387
12866    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12867    && FLOAT_MODE_P (GET_MODE (operands[1]))
12868    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12869    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12870   "#")
12871
12872 (define_insn "*fp_jcc_2_sse"
12873   [(set (pc)
12874         (if_then_else (match_operator 0 "comparison_operator"
12875                         [(match_operand 1 "register_operand" "f#x,x#f")
12876                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12877           (pc)
12878           (label_ref (match_operand 3 "" ""))))
12879    (clobber (reg:CCFP FPSR_REG))
12880    (clobber (reg:CCFP FLAGS_REG))]
12881   "TARGET_80387
12882    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12883    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12884    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12885   "#")
12886
12887 (define_insn "*fp_jcc_2_sse_only"
12888   [(set (pc)
12889         (if_then_else (match_operator 0 "comparison_operator"
12890                         [(match_operand 1 "register_operand" "x")
12891                          (match_operand 2 "nonimmediate_operand" "xm")])
12892           (pc)
12893           (label_ref (match_operand 3 "" ""))))
12894    (clobber (reg:CCFP FPSR_REG))
12895    (clobber (reg:CCFP FLAGS_REG))]
12896   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12897    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12898    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12899   "#")
12900
12901 (define_insn "*fp_jcc_3"
12902   [(set (pc)
12903         (if_then_else (match_operator 0 "comparison_operator"
12904                         [(match_operand 1 "register_operand" "f")
12905                          (match_operand 2 "nonimmediate_operand" "fm")])
12906           (label_ref (match_operand 3 "" ""))
12907           (pc)))
12908    (clobber (reg:CCFP FPSR_REG))
12909    (clobber (reg:CCFP FLAGS_REG))
12910    (clobber (match_scratch:HI 4 "=a"))]
12911   "TARGET_80387
12912    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12913    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12914    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12915    && SELECT_CC_MODE (GET_CODE (operands[0]),
12916                       operands[1], operands[2]) == CCFPmode
12917    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12918   "#")
12919
12920 (define_insn "*fp_jcc_4"
12921   [(set (pc)
12922         (if_then_else (match_operator 0 "comparison_operator"
12923                         [(match_operand 1 "register_operand" "f")
12924                          (match_operand 2 "nonimmediate_operand" "fm")])
12925           (pc)
12926           (label_ref (match_operand 3 "" ""))))
12927    (clobber (reg:CCFP FPSR_REG))
12928    (clobber (reg:CCFP FLAGS_REG))
12929    (clobber (match_scratch:HI 4 "=a"))]
12930   "TARGET_80387
12931    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12932    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12933    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12934    && SELECT_CC_MODE (GET_CODE (operands[0]),
12935                       operands[1], operands[2]) == CCFPmode
12936    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12937   "#")
12938
12939 (define_insn "*fp_jcc_5"
12940   [(set (pc)
12941         (if_then_else (match_operator 0 "comparison_operator"
12942                         [(match_operand 1 "register_operand" "f")
12943                          (match_operand 2 "register_operand" "f")])
12944           (label_ref (match_operand 3 "" ""))
12945           (pc)))
12946    (clobber (reg:CCFP FPSR_REG))
12947    (clobber (reg:CCFP FLAGS_REG))
12948    (clobber (match_scratch:HI 4 "=a"))]
12949   "TARGET_80387
12950    && FLOAT_MODE_P (GET_MODE (operands[1]))
12951    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12952    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12953   "#")
12954
12955 (define_insn "*fp_jcc_6"
12956   [(set (pc)
12957         (if_then_else (match_operator 0 "comparison_operator"
12958                         [(match_operand 1 "register_operand" "f")
12959                          (match_operand 2 "register_operand" "f")])
12960           (pc)
12961           (label_ref (match_operand 3 "" ""))))
12962    (clobber (reg:CCFP FPSR_REG))
12963    (clobber (reg:CCFP FLAGS_REG))
12964    (clobber (match_scratch:HI 4 "=a"))]
12965   "TARGET_80387
12966    && FLOAT_MODE_P (GET_MODE (operands[1]))
12967    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12968    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12969   "#")
12970
12971 (define_insn "*fp_jcc_7"
12972   [(set (pc)
12973         (if_then_else (match_operator 0 "comparison_operator"
12974                         [(match_operand 1 "register_operand" "f")
12975                          (match_operand 2 "const_double_operand" "C")])
12976           (label_ref (match_operand 3 "" ""))
12977           (pc)))
12978    (clobber (reg:CCFP FPSR_REG))
12979    (clobber (reg:CCFP FLAGS_REG))
12980    (clobber (match_scratch:HI 4 "=a"))]
12981   "TARGET_80387
12982    && FLOAT_MODE_P (GET_MODE (operands[1]))
12983    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12984    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12985    && SELECT_CC_MODE (GET_CODE (operands[0]),
12986                       operands[1], operands[2]) == CCFPmode
12987    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12988   "#")
12989
12990 ;; The order of operands in *fp_jcc_8 is forced by combine in
12991 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12992 ;; with a precedence over other operators and is always put in the first
12993 ;; place. Swap condition and operands to match ficom instruction.
12994
12995 (define_insn "*fp_jcc_8"
12996   [(set (pc)
12997         (if_then_else (match_operator 0 "comparison_operator"
12998                         [(match_operator 1 "float_operator"
12999                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13000                            (match_operand 3 "register_operand" "f,f")])
13001           (label_ref (match_operand 4 "" ""))
13002           (pc)))
13003    (clobber (reg:CCFP FPSR_REG))
13004    (clobber (reg:CCFP FLAGS_REG))
13005    (clobber (match_scratch:HI 5 "=a,a"))]
13006   "TARGET_80387 && TARGET_USE_FIOP
13007    && FLOAT_MODE_P (GET_MODE (operands[3]))
13008    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13009    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13010    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13011    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13012   "#")
13013
13014 (define_split
13015   [(set (pc)
13016         (if_then_else (match_operator 0 "comparison_operator"
13017                         [(match_operand 1 "register_operand" "")
13018                          (match_operand 2 "nonimmediate_operand" "")])
13019           (match_operand 3 "" "")
13020           (match_operand 4 "" "")))
13021    (clobber (reg:CCFP FPSR_REG))
13022    (clobber (reg:CCFP FLAGS_REG))]
13023   "reload_completed"
13024   [(const_int 0)]
13025 {
13026   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13027                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13028   DONE;
13029 })
13030
13031 (define_split
13032   [(set (pc)
13033         (if_then_else (match_operator 0 "comparison_operator"
13034                         [(match_operand 1 "register_operand" "")
13035                          (match_operand 2 "general_operand" "")])
13036           (match_operand 3 "" "")
13037           (match_operand 4 "" "")))
13038    (clobber (reg:CCFP FPSR_REG))
13039    (clobber (reg:CCFP FLAGS_REG))
13040    (clobber (match_scratch:HI 5 "=a"))]
13041   "reload_completed"
13042   [(const_int 0)]
13043 {
13044   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13045                         operands[3], operands[4], operands[5], NULL_RTX);
13046   DONE;
13047 })
13048
13049 (define_split
13050   [(set (pc)
13051         (if_then_else (match_operator 0 "comparison_operator"
13052                         [(match_operator 1 "float_operator"
13053                            [(match_operand:SI 2 "memory_operand" "")])
13054                            (match_operand 3 "register_operand" "")])
13055           (match_operand 4 "" "")
13056           (match_operand 5 "" "")))
13057    (clobber (reg:CCFP FPSR_REG))
13058    (clobber (reg:CCFP FLAGS_REG))
13059    (clobber (match_scratch:HI 6 "=a"))]
13060   "reload_completed"
13061   [(const_int 0)]
13062 {
13063   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13064   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13065                         operands[3], operands[7],
13066                         operands[4], operands[5], operands[6], NULL_RTX);
13067   DONE;
13068 })
13069
13070 ;; %%% Kill this when reload knows how to do it.
13071 (define_split
13072   [(set (pc)
13073         (if_then_else (match_operator 0 "comparison_operator"
13074                         [(match_operator 1 "float_operator"
13075                            [(match_operand:SI 2 "register_operand" "")])
13076                            (match_operand 3 "register_operand" "")])
13077           (match_operand 4 "" "")
13078           (match_operand 5 "" "")))
13079    (clobber (reg:CCFP FPSR_REG))
13080    (clobber (reg:CCFP FLAGS_REG))
13081    (clobber (match_scratch:HI 6 "=a"))]
13082   "reload_completed"
13083   [(const_int 0)]
13084 {
13085   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13086   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13087   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13088                         operands[3], operands[7],
13089                         operands[4], operands[5], operands[6], operands[2]);
13090   DONE;
13091 })
13092 \f
13093 ;; Unconditional and other jump instructions
13094
13095 (define_insn "jump"
13096   [(set (pc)
13097         (label_ref (match_operand 0 "" "")))]
13098   ""
13099   "jmp\t%l0"
13100   [(set_attr "type" "ibr")
13101    (set (attr "length")
13102            (if_then_else (and (ge (minus (match_dup 0) (pc))
13103                                   (const_int -126))
13104                               (lt (minus (match_dup 0) (pc))
13105                                   (const_int 128)))
13106              (const_int 2)
13107              (const_int 5)))
13108    (set_attr "modrm" "0")])
13109
13110 (define_expand "indirect_jump"
13111   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13112   ""
13113   "")
13114
13115 (define_insn "*indirect_jump"
13116   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13117   "!TARGET_64BIT"
13118   "jmp\t%A0"
13119   [(set_attr "type" "ibr")
13120    (set_attr "length_immediate" "0")])
13121
13122 (define_insn "*indirect_jump_rtx64"
13123   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13124   "TARGET_64BIT"
13125   "jmp\t%A0"
13126   [(set_attr "type" "ibr")
13127    (set_attr "length_immediate" "0")])
13128
13129 (define_expand "tablejump"
13130   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13131               (use (label_ref (match_operand 1 "" "")))])]
13132   ""
13133 {
13134   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13135      relative.  Convert the relative address to an absolute address.  */
13136   if (flag_pic)
13137     {
13138       rtx op0, op1;
13139       enum rtx_code code;
13140
13141       if (TARGET_64BIT)
13142         {
13143           code = PLUS;
13144           op0 = operands[0];
13145           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13146         }
13147       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13148         {
13149           code = PLUS;
13150           op0 = operands[0];
13151           op1 = pic_offset_table_rtx;
13152         }
13153       else
13154         {
13155           code = MINUS;
13156           op0 = pic_offset_table_rtx;
13157           op1 = operands[0];
13158         }
13159
13160       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13161                                          OPTAB_DIRECT);
13162     }
13163 })
13164
13165 (define_insn "*tablejump_1"
13166   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13167    (use (label_ref (match_operand 1 "" "")))]
13168   "!TARGET_64BIT"
13169   "jmp\t%A0"
13170   [(set_attr "type" "ibr")
13171    (set_attr "length_immediate" "0")])
13172
13173 (define_insn "*tablejump_1_rtx64"
13174   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13175    (use (label_ref (match_operand 1 "" "")))]
13176   "TARGET_64BIT"
13177   "jmp\t%A0"
13178   [(set_attr "type" "ibr")
13179    (set_attr "length_immediate" "0")])
13180 \f
13181 ;; Loop instruction
13182 ;;
13183 ;; This is all complicated by the fact that since this is a jump insn
13184 ;; we must handle our own reloads.
13185
13186 (define_expand "doloop_end"
13187   [(use (match_operand 0 "" ""))        ; loop pseudo
13188    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13189    (use (match_operand 2 "" ""))        ; max iterations
13190    (use (match_operand 3 "" ""))        ; loop level 
13191    (use (match_operand 4 "" ""))]       ; label
13192   "!TARGET_64BIT && TARGET_USE_LOOP"
13193   "                                 
13194 {
13195   /* Only use cloop on innermost loops.  */
13196   if (INTVAL (operands[3]) > 1)
13197     FAIL;
13198   if (GET_MODE (operands[0]) != SImode)
13199     FAIL;
13200   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13201                                            operands[0]));
13202   DONE;
13203 }")
13204
13205 (define_insn "doloop_end_internal"
13206   [(set (pc)
13207         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13208                           (const_int 1))
13209                       (label_ref (match_operand 0 "" ""))
13210                       (pc)))
13211    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13212         (plus:SI (match_dup 1)
13213                  (const_int -1)))
13214    (clobber (match_scratch:SI 3 "=X,X,r"))
13215    (clobber (reg:CC FLAGS_REG))]
13216   "!TARGET_64BIT && TARGET_USE_LOOP
13217    && (reload_in_progress || reload_completed
13218        || register_operand (operands[2], VOIDmode))"
13219 {
13220   if (which_alternative != 0)
13221     return "#";
13222   if (get_attr_length (insn) == 2)
13223     return "%+loop\t%l0";
13224   else
13225     return "dec{l}\t%1\;%+jne\t%l0";
13226 }
13227   [(set (attr "length")
13228         (if_then_else (and (eq_attr "alternative" "0")
13229                            (and (ge (minus (match_dup 0) (pc))
13230                                     (const_int -126))
13231                                 (lt (minus (match_dup 0) (pc))
13232                                     (const_int 128))))
13233                       (const_int 2)
13234                       (const_int 16)))
13235    ;; We don't know the type before shorten branches.  Optimistically expect
13236    ;; the loop instruction to match.
13237    (set (attr "type") (const_string "ibr"))])
13238
13239 (define_split
13240   [(set (pc)
13241         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13242                           (const_int 1))
13243                       (match_operand 0 "" "")
13244                       (pc)))
13245    (set (match_dup 1)
13246         (plus:SI (match_dup 1)
13247                  (const_int -1)))
13248    (clobber (match_scratch:SI 2 ""))
13249    (clobber (reg:CC FLAGS_REG))]
13250   "!TARGET_64BIT && TARGET_USE_LOOP
13251    && reload_completed
13252    && REGNO (operands[1]) != 2"
13253   [(parallel [(set (reg:CCZ FLAGS_REG)
13254                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13255                                  (const_int 0)))
13256               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13257    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13258                            (match_dup 0)
13259                            (pc)))]
13260   "")
13261   
13262 (define_split
13263   [(set (pc)
13264         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13265                           (const_int 1))
13266                       (match_operand 0 "" "")
13267                       (pc)))
13268    (set (match_operand:SI 2 "nonimmediate_operand" "")
13269         (plus:SI (match_dup 1)
13270                  (const_int -1)))
13271    (clobber (match_scratch:SI 3 ""))
13272    (clobber (reg:CC FLAGS_REG))]
13273   "!TARGET_64BIT && TARGET_USE_LOOP
13274    && reload_completed
13275    && (! REG_P (operands[2])
13276        || ! rtx_equal_p (operands[1], operands[2]))"
13277   [(set (match_dup 3) (match_dup 1))
13278    (parallel [(set (reg:CCZ FLAGS_REG)
13279                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13280                                 (const_int 0)))
13281               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13282    (set (match_dup 2) (match_dup 3))
13283    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13284                            (match_dup 0)
13285                            (pc)))]
13286   "")
13287
13288 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13289
13290 (define_peephole2
13291   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13292    (set (match_operand:QI 1 "register_operand" "")
13293         (match_operator:QI 2 "ix86_comparison_operator"
13294           [(reg FLAGS_REG) (const_int 0)]))
13295    (set (match_operand 3 "q_regs_operand" "")
13296         (zero_extend (match_dup 1)))]
13297   "(peep2_reg_dead_p (3, operands[1])
13298     || operands_match_p (operands[1], operands[3]))
13299    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13300   [(set (match_dup 4) (match_dup 0))
13301    (set (strict_low_part (match_dup 5))
13302         (match_dup 2))]
13303 {
13304   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13305   operands[5] = gen_lowpart (QImode, operands[3]);
13306   ix86_expand_clear (operands[3]);
13307 })
13308
13309 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13310
13311 (define_peephole2
13312   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13313    (set (match_operand:QI 1 "register_operand" "")
13314         (match_operator:QI 2 "ix86_comparison_operator"
13315           [(reg FLAGS_REG) (const_int 0)]))
13316    (parallel [(set (match_operand 3 "q_regs_operand" "")
13317                    (zero_extend (match_dup 1)))
13318               (clobber (reg:CC FLAGS_REG))])]
13319   "(peep2_reg_dead_p (3, operands[1])
13320     || operands_match_p (operands[1], operands[3]))
13321    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13322   [(set (match_dup 4) (match_dup 0))
13323    (set (strict_low_part (match_dup 5))
13324         (match_dup 2))]
13325 {
13326   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13327   operands[5] = gen_lowpart (QImode, operands[3]);
13328   ix86_expand_clear (operands[3]);
13329 })
13330 \f
13331 ;; Call instructions.
13332
13333 ;; The predicates normally associated with named expanders are not properly
13334 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13335 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13336
13337 ;; Call subroutine returning no value.
13338
13339 (define_expand "call_pop"
13340   [(parallel [(call (match_operand:QI 0 "" "")
13341                     (match_operand:SI 1 "" ""))
13342               (set (reg:SI SP_REG)
13343                    (plus:SI (reg:SI SP_REG)
13344                             (match_operand:SI 3 "" "")))])]
13345   "!TARGET_64BIT"
13346 {
13347   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13348   DONE;
13349 })
13350
13351 (define_insn "*call_pop_0"
13352   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13353          (match_operand:SI 1 "" ""))
13354    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13355                             (match_operand:SI 2 "immediate_operand" "")))]
13356   "!TARGET_64BIT"
13357 {
13358   if (SIBLING_CALL_P (insn))
13359     return "jmp\t%P0";
13360   else
13361     return "call\t%P0";
13362 }
13363   [(set_attr "type" "call")])
13364   
13365 (define_insn "*call_pop_1"
13366   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13367          (match_operand:SI 1 "" ""))
13368    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13369                             (match_operand:SI 2 "immediate_operand" "i")))]
13370   "!TARGET_64BIT"
13371 {
13372   if (constant_call_address_operand (operands[0], Pmode))
13373     {
13374       if (SIBLING_CALL_P (insn))
13375         return "jmp\t%P0";
13376       else
13377         return "call\t%P0";
13378     }
13379   if (SIBLING_CALL_P (insn))
13380     return "jmp\t%A0";
13381   else
13382     return "call\t%A0";
13383 }
13384   [(set_attr "type" "call")])
13385
13386 (define_expand "call"
13387   [(call (match_operand:QI 0 "" "")
13388          (match_operand 1 "" ""))
13389    (use (match_operand 2 "" ""))]
13390   ""
13391 {
13392   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13393   DONE;
13394 })
13395
13396 (define_expand "sibcall"
13397   [(call (match_operand:QI 0 "" "")
13398          (match_operand 1 "" ""))
13399    (use (match_operand 2 "" ""))]
13400   ""
13401 {
13402   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13403   DONE;
13404 })
13405
13406 (define_insn "*call_0"
13407   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13408          (match_operand 1 "" ""))]
13409   ""
13410 {
13411   if (SIBLING_CALL_P (insn))
13412     return "jmp\t%P0";
13413   else
13414     return "call\t%P0";
13415 }
13416   [(set_attr "type" "call")])
13417
13418 (define_insn "*call_1"
13419   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13420          (match_operand 1 "" ""))]
13421   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13422 {
13423   if (constant_call_address_operand (operands[0], Pmode))
13424     return "call\t%P0";
13425   return "call\t%A0";
13426 }
13427   [(set_attr "type" "call")])
13428
13429 (define_insn "*sibcall_1"
13430   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13431          (match_operand 1 "" ""))]
13432   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13433 {
13434   if (constant_call_address_operand (operands[0], Pmode))
13435     return "jmp\t%P0";
13436   return "jmp\t%A0";
13437 }
13438   [(set_attr "type" "call")])
13439
13440 (define_insn "*call_1_rex64"
13441   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13442          (match_operand 1 "" ""))]
13443   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13444 {
13445   if (constant_call_address_operand (operands[0], Pmode))
13446     return "call\t%P0";
13447   return "call\t%A0";
13448 }
13449   [(set_attr "type" "call")])
13450
13451 (define_insn "*sibcall_1_rex64"
13452   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13453          (match_operand 1 "" ""))]
13454   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13455   "jmp\t%P0"
13456   [(set_attr "type" "call")])
13457
13458 (define_insn "*sibcall_1_rex64_v"
13459   [(call (mem:QI (reg:DI 40))
13460          (match_operand 0 "" ""))]
13461   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13462   "jmp\t*%%r11"
13463   [(set_attr "type" "call")])
13464
13465
13466 ;; Call subroutine, returning value in operand 0
13467
13468 (define_expand "call_value_pop"
13469   [(parallel [(set (match_operand 0 "" "")
13470                    (call (match_operand:QI 1 "" "")
13471                          (match_operand:SI 2 "" "")))
13472               (set (reg:SI SP_REG)
13473                    (plus:SI (reg:SI SP_REG)
13474                             (match_operand:SI 4 "" "")))])]
13475   "!TARGET_64BIT"
13476 {
13477   ix86_expand_call (operands[0], operands[1], operands[2],
13478                     operands[3], operands[4], 0);
13479   DONE;
13480 })
13481
13482 (define_expand "call_value"
13483   [(set (match_operand 0 "" "")
13484         (call (match_operand:QI 1 "" "")
13485               (match_operand:SI 2 "" "")))
13486    (use (match_operand:SI 3 "" ""))]
13487   ;; Operand 2 not used on the i386.
13488   ""
13489 {
13490   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13491   DONE;
13492 })
13493
13494 (define_expand "sibcall_value"
13495   [(set (match_operand 0 "" "")
13496         (call (match_operand:QI 1 "" "")
13497               (match_operand:SI 2 "" "")))
13498    (use (match_operand:SI 3 "" ""))]
13499   ;; Operand 2 not used on the i386.
13500   ""
13501 {
13502   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13503   DONE;
13504 })
13505
13506 ;; Call subroutine returning any type.
13507
13508 (define_expand "untyped_call"
13509   [(parallel [(call (match_operand 0 "" "")
13510                     (const_int 0))
13511               (match_operand 1 "" "")
13512               (match_operand 2 "" "")])]
13513   ""
13514 {
13515   int i;
13516
13517   /* In order to give reg-stack an easier job in validating two
13518      coprocessor registers as containing a possible return value,
13519      simply pretend the untyped call returns a complex long double
13520      value.  */
13521
13522   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13523                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13524                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13525                     NULL, 0);
13526
13527   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13528     {
13529       rtx set = XVECEXP (operands[2], 0, i);
13530       emit_move_insn (SET_DEST (set), SET_SRC (set));
13531     }
13532
13533   /* The optimizer does not know that the call sets the function value
13534      registers we stored in the result block.  We avoid problems by
13535      claiming that all hard registers are used and clobbered at this
13536      point.  */
13537   emit_insn (gen_blockage (const0_rtx));
13538
13539   DONE;
13540 })
13541 \f
13542 ;; Prologue and epilogue instructions
13543
13544 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13545 ;; all of memory.  This blocks insns from being moved across this point.
13546
13547 (define_insn "blockage"
13548   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13549   ""
13550   ""
13551   [(set_attr "length" "0")])
13552
13553 ;; Insn emitted into the body of a function to return from a function.
13554 ;; This is only done if the function's epilogue is known to be simple.
13555 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13556
13557 (define_expand "return"
13558   [(return)]
13559   "ix86_can_use_return_insn_p ()"
13560 {
13561   if (current_function_pops_args)
13562     {
13563       rtx popc = GEN_INT (current_function_pops_args);
13564       emit_jump_insn (gen_return_pop_internal (popc));
13565       DONE;
13566     }
13567 })
13568
13569 (define_insn "return_internal"
13570   [(return)]
13571   "reload_completed"
13572   "ret"
13573   [(set_attr "length" "1")
13574    (set_attr "length_immediate" "0")
13575    (set_attr "modrm" "0")])
13576
13577 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13578 ;; instruction Athlon and K8 have.
13579
13580 (define_insn "return_internal_long"
13581   [(return)
13582    (unspec [(const_int 0)] UNSPEC_REP)]
13583   "reload_completed"
13584   "rep {;} ret"
13585   [(set_attr "length" "1")
13586    (set_attr "length_immediate" "0")
13587    (set_attr "prefix_rep" "1")
13588    (set_attr "modrm" "0")])
13589
13590 (define_insn "return_pop_internal"
13591   [(return)
13592    (use (match_operand:SI 0 "const_int_operand" ""))]
13593   "reload_completed"
13594   "ret\t%0"
13595   [(set_attr "length" "3")
13596    (set_attr "length_immediate" "2")
13597    (set_attr "modrm" "0")])
13598
13599 (define_insn "return_indirect_internal"
13600   [(return)
13601    (use (match_operand:SI 0 "register_operand" "r"))]
13602   "reload_completed"
13603   "jmp\t%A0"
13604   [(set_attr "type" "ibr")
13605    (set_attr "length_immediate" "0")])
13606
13607 (define_insn "nop"
13608   [(const_int 0)]
13609   ""
13610   "nop"
13611   [(set_attr "length" "1")
13612    (set_attr "length_immediate" "0")
13613    (set_attr "modrm" "0")])
13614
13615 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13616 ;; branch prediction penalty for the third jump in a 16-byte
13617 ;; block on K8.
13618
13619 (define_insn "align"
13620   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13621   ""
13622 {
13623 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13624   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13625 #else
13626   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13627      The align insn is used to avoid 3 jump instructions in the row to improve
13628      branch prediction and the benefits hardly outweight the cost of extra 8
13629      nops on the average inserted by full alignment pseudo operation.  */
13630 #endif
13631   return "";
13632 }
13633   [(set_attr "length" "16")])
13634
13635 (define_expand "prologue"
13636   [(const_int 1)]
13637   ""
13638   "ix86_expand_prologue (); DONE;")
13639
13640 (define_insn "set_got"
13641   [(set (match_operand:SI 0 "register_operand" "=r")
13642         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13643    (clobber (reg:CC FLAGS_REG))]
13644   "!TARGET_64BIT"
13645   { return output_set_got (operands[0]); }
13646   [(set_attr "type" "multi")
13647    (set_attr "length" "12")])
13648
13649 (define_expand "epilogue"
13650   [(const_int 1)]
13651   ""
13652   "ix86_expand_epilogue (1); DONE;")
13653
13654 (define_expand "sibcall_epilogue"
13655   [(const_int 1)]
13656   ""
13657   "ix86_expand_epilogue (0); DONE;")
13658
13659 (define_expand "eh_return"
13660   [(use (match_operand 0 "register_operand" ""))]
13661   ""
13662 {
13663   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13664
13665   /* Tricky bit: we write the address of the handler to which we will
13666      be returning into someone else's stack frame, one word below the
13667      stack address we wish to restore.  */
13668   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13669   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13670   tmp = gen_rtx_MEM (Pmode, tmp);
13671   emit_move_insn (tmp, ra);
13672
13673   if (Pmode == SImode)
13674     emit_jump_insn (gen_eh_return_si (sa));
13675   else
13676     emit_jump_insn (gen_eh_return_di (sa));
13677   emit_barrier ();
13678   DONE;
13679 })
13680
13681 (define_insn_and_split "eh_return_si"
13682   [(set (pc) 
13683         (unspec [(match_operand:SI 0 "register_operand" "c")]
13684                  UNSPEC_EH_RETURN))]
13685   "!TARGET_64BIT"
13686   "#"
13687   "reload_completed"
13688   [(const_int 1)]
13689   "ix86_expand_epilogue (2); DONE;")
13690
13691 (define_insn_and_split "eh_return_di"
13692   [(set (pc) 
13693         (unspec [(match_operand:DI 0 "register_operand" "c")]
13694                  UNSPEC_EH_RETURN))]
13695   "TARGET_64BIT"
13696   "#"
13697   "reload_completed"
13698   [(const_int 1)]
13699   "ix86_expand_epilogue (2); DONE;")
13700
13701 (define_insn "leave"
13702   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13703    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13704    (clobber (mem:BLK (scratch)))]
13705   "!TARGET_64BIT"
13706   "leave"
13707   [(set_attr "type" "leave")])
13708
13709 (define_insn "leave_rex64"
13710   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13711    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13712    (clobber (mem:BLK (scratch)))]
13713   "TARGET_64BIT"
13714   "leave"
13715   [(set_attr "type" "leave")])
13716 \f
13717 (define_expand "ffssi2"
13718   [(parallel
13719      [(set (match_operand:SI 0 "register_operand" "") 
13720            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13721       (clobber (match_scratch:SI 2 ""))
13722       (clobber (reg:CC FLAGS_REG))])]
13723   ""
13724   "")
13725
13726 (define_insn_and_split "*ffs_cmove"
13727   [(set (match_operand:SI 0 "register_operand" "=r") 
13728         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13729    (clobber (match_scratch:SI 2 "=&r"))
13730    (clobber (reg:CC FLAGS_REG))]
13731   "TARGET_CMOVE"
13732   "#"
13733   "&& reload_completed"
13734   [(set (match_dup 2) (const_int -1))
13735    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13736               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13737    (set (match_dup 0) (if_then_else:SI
13738                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13739                         (match_dup 2)
13740                         (match_dup 0)))
13741    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13742               (clobber (reg:CC FLAGS_REG))])]
13743   "")
13744
13745 (define_insn_and_split "*ffs_no_cmove"
13746   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13747         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13748    (clobber (match_scratch:SI 2 "=&q"))
13749    (clobber (reg:CC FLAGS_REG))]
13750   ""
13751   "#"
13752   "reload_completed"
13753   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13754               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13755    (set (strict_low_part (match_dup 3))
13756         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13757    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13758               (clobber (reg:CC FLAGS_REG))])
13759    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13760               (clobber (reg:CC FLAGS_REG))])
13761    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13762               (clobber (reg:CC FLAGS_REG))])]
13763 {
13764   operands[3] = gen_lowpart (QImode, operands[2]);
13765   ix86_expand_clear (operands[2]);
13766 })
13767
13768 (define_insn "*ffssi_1"
13769   [(set (reg:CCZ FLAGS_REG)
13770         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13771                      (const_int 0)))
13772    (set (match_operand:SI 0 "register_operand" "=r")
13773         (ctz:SI (match_dup 1)))]
13774   ""
13775   "bsf{l}\t{%1, %0|%0, %1}"
13776   [(set_attr "prefix_0f" "1")])
13777
13778 (define_expand "ffsdi2"
13779   [(parallel
13780      [(set (match_operand:DI 0 "register_operand" "") 
13781            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13782       (clobber (match_scratch:DI 2 ""))
13783       (clobber (reg:CC FLAGS_REG))])]
13784   "TARGET_64BIT && TARGET_CMOVE"
13785   "")
13786
13787 (define_insn_and_split "*ffs_rex64"
13788   [(set (match_operand:DI 0 "register_operand" "=r") 
13789         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13790    (clobber (match_scratch:DI 2 "=&r"))
13791    (clobber (reg:CC FLAGS_REG))]
13792   "TARGET_64BIT && TARGET_CMOVE"
13793   "#"
13794   "&& reload_completed"
13795   [(set (match_dup 2) (const_int -1))
13796    (parallel [(set (reg:CCZ FLAGS_REG)
13797                    (compare:CCZ (match_dup 1) (const_int 0)))
13798               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13799    (set (match_dup 0) (if_then_else:DI
13800                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13801                         (match_dup 2)
13802                         (match_dup 0)))
13803    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13804               (clobber (reg:CC FLAGS_REG))])]
13805   "")
13806
13807 (define_insn "*ffsdi_1"
13808   [(set (reg:CCZ FLAGS_REG)
13809         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13810                      (const_int 0)))
13811    (set (match_operand:DI 0 "register_operand" "=r")
13812         (ctz:DI (match_dup 1)))]
13813   "TARGET_64BIT"
13814   "bsf{q}\t{%1, %0|%0, %1}"
13815   [(set_attr "prefix_0f" "1")])
13816
13817 (define_insn "ctzsi2"
13818   [(set (match_operand:SI 0 "register_operand" "=r")
13819         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13820    (clobber (reg:CC FLAGS_REG))]
13821   ""
13822   "bsf{l}\t{%1, %0|%0, %1}"
13823   [(set_attr "prefix_0f" "1")])
13824
13825 (define_insn "ctzdi2"
13826   [(set (match_operand:DI 0 "register_operand" "=r")
13827         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13828    (clobber (reg:CC FLAGS_REG))]
13829   "TARGET_64BIT"
13830   "bsf{q}\t{%1, %0|%0, %1}"
13831   [(set_attr "prefix_0f" "1")])
13832
13833 (define_expand "clzsi2"
13834   [(parallel
13835      [(set (match_operand:SI 0 "register_operand" "")
13836            (minus:SI (const_int 31)
13837                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13838       (clobber (reg:CC FLAGS_REG))])
13839    (parallel
13840      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13841       (clobber (reg:CC FLAGS_REG))])]
13842   ""
13843   "")
13844
13845 (define_insn "*bsr"
13846   [(set (match_operand:SI 0 "register_operand" "=r")
13847         (minus:SI (const_int 31)
13848                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13849    (clobber (reg:CC FLAGS_REG))]
13850   ""
13851   "bsr{l}\t{%1, %0|%0, %1}"
13852   [(set_attr "prefix_0f" "1")])
13853
13854 (define_expand "clzdi2"
13855   [(parallel
13856      [(set (match_operand:DI 0 "register_operand" "")
13857            (minus:DI (const_int 63)
13858                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13859       (clobber (reg:CC FLAGS_REG))])
13860    (parallel
13861      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13862       (clobber (reg:CC FLAGS_REG))])]
13863   "TARGET_64BIT"
13864   "")
13865
13866 (define_insn "*bsr_rex64"
13867   [(set (match_operand:DI 0 "register_operand" "=r")
13868         (minus:DI (const_int 63)
13869                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13870    (clobber (reg:CC FLAGS_REG))]
13871   "TARGET_64BIT"
13872   "bsr{q}\t{%1, %0|%0, %1}"
13873   [(set_attr "prefix_0f" "1")])
13874 \f
13875 ;; Thread-local storage patterns for ELF.
13876 ;;
13877 ;; Note that these code sequences must appear exactly as shown
13878 ;; in order to allow linker relaxation.
13879
13880 (define_insn "*tls_global_dynamic_32_gnu"
13881   [(set (match_operand:SI 0 "register_operand" "=a")
13882         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13883                     (match_operand:SI 2 "tls_symbolic_operand" "")
13884                     (match_operand:SI 3 "call_insn_operand" "")]
13885                     UNSPEC_TLS_GD))
13886    (clobber (match_scratch:SI 4 "=d"))
13887    (clobber (match_scratch:SI 5 "=c"))
13888    (clobber (reg:CC FLAGS_REG))]
13889   "!TARGET_64BIT && TARGET_GNU_TLS"
13890   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13891   [(set_attr "type" "multi")
13892    (set_attr "length" "12")])
13893
13894 (define_insn "*tls_global_dynamic_32_sun"
13895   [(set (match_operand:SI 0 "register_operand" "=a")
13896         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13897                     (match_operand:SI 2 "tls_symbolic_operand" "")
13898                     (match_operand:SI 3 "call_insn_operand" "")]
13899                     UNSPEC_TLS_GD))
13900    (clobber (match_scratch:SI 4 "=d"))
13901    (clobber (match_scratch:SI 5 "=c"))
13902    (clobber (reg:CC FLAGS_REG))]
13903   "!TARGET_64BIT && TARGET_SUN_TLS"
13904   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13905         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13906   [(set_attr "type" "multi")
13907    (set_attr "length" "14")])
13908
13909 (define_expand "tls_global_dynamic_32"
13910   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13911                    (unspec:SI
13912                     [(match_dup 2)
13913                      (match_operand:SI 1 "tls_symbolic_operand" "")
13914                      (match_dup 3)]
13915                     UNSPEC_TLS_GD))
13916               (clobber (match_scratch:SI 4 ""))
13917               (clobber (match_scratch:SI 5 ""))
13918               (clobber (reg:CC FLAGS_REG))])]
13919   ""
13920 {
13921   if (flag_pic)
13922     operands[2] = pic_offset_table_rtx;
13923   else
13924     {
13925       operands[2] = gen_reg_rtx (Pmode);
13926       emit_insn (gen_set_got (operands[2]));
13927     }
13928   operands[3] = ix86_tls_get_addr ();
13929 })
13930
13931 (define_insn "*tls_global_dynamic_64"
13932   [(set (match_operand:DI 0 "register_operand" "=a")
13933         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13934                       (match_operand:DI 3 "" "")))
13935    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13936               UNSPEC_TLS_GD)]
13937   "TARGET_64BIT"
13938   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13939   [(set_attr "type" "multi")
13940    (set_attr "length" "16")])
13941
13942 (define_expand "tls_global_dynamic_64"
13943   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13944                    (call (mem:QI (match_dup 2)) (const_int 0)))
13945               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13946                          UNSPEC_TLS_GD)])]
13947   ""
13948 {
13949   operands[2] = ix86_tls_get_addr ();
13950 })
13951
13952 (define_insn "*tls_local_dynamic_base_32_gnu"
13953   [(set (match_operand:SI 0 "register_operand" "=a")
13954         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13955                     (match_operand:SI 2 "call_insn_operand" "")]
13956                    UNSPEC_TLS_LD_BASE))
13957    (clobber (match_scratch:SI 3 "=d"))
13958    (clobber (match_scratch:SI 4 "=c"))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "!TARGET_64BIT && TARGET_GNU_TLS"
13961   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13962   [(set_attr "type" "multi")
13963    (set_attr "length" "11")])
13964
13965 (define_insn "*tls_local_dynamic_base_32_sun"
13966   [(set (match_operand:SI 0 "register_operand" "=a")
13967         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13968                     (match_operand:SI 2 "call_insn_operand" "")]
13969                    UNSPEC_TLS_LD_BASE))
13970    (clobber (match_scratch:SI 3 "=d"))
13971    (clobber (match_scratch:SI 4 "=c"))
13972    (clobber (reg:CC FLAGS_REG))]
13973   "!TARGET_64BIT && TARGET_SUN_TLS"
13974   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13975         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13976   [(set_attr "type" "multi")
13977    (set_attr "length" "13")])
13978
13979 (define_expand "tls_local_dynamic_base_32"
13980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13981                    (unspec:SI [(match_dup 1) (match_dup 2)]
13982                               UNSPEC_TLS_LD_BASE))
13983               (clobber (match_scratch:SI 3 ""))
13984               (clobber (match_scratch:SI 4 ""))
13985               (clobber (reg:CC FLAGS_REG))])]
13986   ""
13987 {
13988   if (flag_pic)
13989     operands[1] = pic_offset_table_rtx;
13990   else
13991     {
13992       operands[1] = gen_reg_rtx (Pmode);
13993       emit_insn (gen_set_got (operands[1]));
13994     }
13995   operands[2] = ix86_tls_get_addr ();
13996 })
13997
13998 (define_insn "*tls_local_dynamic_base_64"
13999   [(set (match_operand:DI 0 "register_operand" "=a")
14000         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14001                       (match_operand:DI 2 "" "")))
14002    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14003   "TARGET_64BIT"
14004   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14005   [(set_attr "type" "multi")
14006    (set_attr "length" "12")])
14007
14008 (define_expand "tls_local_dynamic_base_64"
14009   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14010                    (call (mem:QI (match_dup 1)) (const_int 0)))
14011               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14012   ""
14013 {
14014   operands[1] = ix86_tls_get_addr ();
14015 })
14016
14017 ;; Local dynamic of a single variable is a lose.  Show combine how
14018 ;; to convert that back to global dynamic.
14019
14020 (define_insn_and_split "*tls_local_dynamic_32_once"
14021   [(set (match_operand:SI 0 "register_operand" "=a")
14022         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14023                              (match_operand:SI 2 "call_insn_operand" "")]
14024                             UNSPEC_TLS_LD_BASE)
14025                  (const:SI (unspec:SI
14026                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14027                             UNSPEC_DTPOFF))))
14028    (clobber (match_scratch:SI 4 "=d"))
14029    (clobber (match_scratch:SI 5 "=c"))
14030    (clobber (reg:CC FLAGS_REG))]
14031   ""
14032   "#"
14033   ""
14034   [(parallel [(set (match_dup 0)
14035                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14036                               UNSPEC_TLS_GD))
14037               (clobber (match_dup 4))
14038               (clobber (match_dup 5))
14039               (clobber (reg:CC FLAGS_REG))])]
14040   "")
14041
14042 ;; Load and add the thread base pointer from %gs:0.
14043
14044 (define_insn "*load_tp_si"
14045   [(set (match_operand:SI 0 "register_operand" "=r")
14046         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14047   "!TARGET_64BIT"
14048   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14049   [(set_attr "type" "imov")
14050    (set_attr "modrm" "0")
14051    (set_attr "length" "7")
14052    (set_attr "memory" "load")
14053    (set_attr "imm_disp" "false")])
14054
14055 (define_insn "*add_tp_si"
14056   [(set (match_operand:SI 0 "register_operand" "=r")
14057         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14058                  (match_operand:SI 1 "register_operand" "0")))
14059    (clobber (reg:CC FLAGS_REG))]
14060   "!TARGET_64BIT"
14061   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14062   [(set_attr "type" "alu")
14063    (set_attr "modrm" "0")
14064    (set_attr "length" "7")
14065    (set_attr "memory" "load")
14066    (set_attr "imm_disp" "false")])
14067
14068 (define_insn "*load_tp_di"
14069   [(set (match_operand:DI 0 "register_operand" "=r")
14070         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14071   "TARGET_64BIT"
14072   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14073   [(set_attr "type" "imov")
14074    (set_attr "modrm" "0")
14075    (set_attr "length" "7")
14076    (set_attr "memory" "load")
14077    (set_attr "imm_disp" "false")])
14078
14079 (define_insn "*add_tp_di"
14080   [(set (match_operand:DI 0 "register_operand" "=r")
14081         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14082                  (match_operand:DI 1 "register_operand" "0")))
14083    (clobber (reg:CC FLAGS_REG))]
14084   "TARGET_64BIT"
14085   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14086   [(set_attr "type" "alu")
14087    (set_attr "modrm" "0")
14088    (set_attr "length" "7")
14089    (set_attr "memory" "load")
14090    (set_attr "imm_disp" "false")])
14091 \f
14092 ;; These patterns match the binary 387 instructions for addM3, subM3,
14093 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14094 ;; SFmode.  The first is the normal insn, the second the same insn but
14095 ;; with one operand a conversion, and the third the same insn but with
14096 ;; the other operand a conversion.  The conversion may be SFmode or
14097 ;; SImode if the target mode DFmode, but only SImode if the target mode
14098 ;; is SFmode.
14099
14100 ;; Gcc is slightly more smart about handling normal two address instructions
14101 ;; so use special patterns for add and mull.
14102
14103 (define_insn "*fop_sf_comm_mixed"
14104   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14105         (match_operator:SF 3 "binary_fp_operator"
14106                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14107                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14108   "TARGET_MIX_SSE_I387
14109    && COMMUTATIVE_ARITH_P (operands[3])
14110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14111   "* return output_387_binary_op (insn, operands);"
14112   [(set (attr "type") 
14113         (if_then_else (eq_attr "alternative" "1")
14114            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14115               (const_string "ssemul")
14116               (const_string "sseadd"))
14117            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14118               (const_string "fmul")
14119               (const_string "fop"))))
14120    (set_attr "mode" "SF")])
14121
14122 (define_insn "*fop_sf_comm_sse"
14123   [(set (match_operand:SF 0 "register_operand" "=x")
14124         (match_operator:SF 3 "binary_fp_operator"
14125                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14126                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14127   "TARGET_SSE_MATH
14128    && COMMUTATIVE_ARITH_P (operands[3])
14129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14130   "* return output_387_binary_op (insn, operands);"
14131   [(set (attr "type") 
14132         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14133            (const_string "ssemul")
14134            (const_string "sseadd")))
14135    (set_attr "mode" "SF")])
14136
14137 (define_insn "*fop_sf_comm_i387"
14138   [(set (match_operand:SF 0 "register_operand" "=f")
14139         (match_operator:SF 3 "binary_fp_operator"
14140                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14141                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14142   "TARGET_80387
14143    && COMMUTATIVE_ARITH_P (operands[3])
14144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14145   "* return output_387_binary_op (insn, operands);"
14146   [(set (attr "type") 
14147         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14148            (const_string "fmul")
14149            (const_string "fop")))
14150    (set_attr "mode" "SF")])
14151
14152 (define_insn "*fop_sf_1_mixed"
14153   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14154         (match_operator:SF 3 "binary_fp_operator"
14155                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14156                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14157   "TARGET_MIX_SSE_I387
14158    && !COMMUTATIVE_ARITH_P (operands[3])
14159    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14160   "* return output_387_binary_op (insn, operands);"
14161   [(set (attr "type") 
14162         (cond [(and (eq_attr "alternative" "2")
14163                     (match_operand:SF 3 "mult_operator" ""))
14164                  (const_string "ssemul")
14165                (and (eq_attr "alternative" "2")
14166                     (match_operand:SF 3 "div_operator" ""))
14167                  (const_string "ssediv")
14168                (eq_attr "alternative" "2")
14169                  (const_string "sseadd")
14170                (match_operand:SF 3 "mult_operator" "") 
14171                  (const_string "fmul")
14172                (match_operand:SF 3 "div_operator" "") 
14173                  (const_string "fdiv")
14174               ]
14175               (const_string "fop")))
14176    (set_attr "mode" "SF")])
14177
14178 (define_insn "*fop_sf_1_sse"
14179   [(set (match_operand:SF 0 "register_operand" "=x")
14180         (match_operator:SF 3 "binary_fp_operator"
14181                         [(match_operand:SF 1 "register_operand" "0")
14182                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14183   "TARGET_SSE_MATH
14184    && !COMMUTATIVE_ARITH_P (operands[3])"
14185   "* return output_387_binary_op (insn, operands);"
14186   [(set (attr "type") 
14187         (cond [(match_operand:SF 3 "mult_operator" "")
14188                  (const_string "ssemul")
14189                (match_operand:SF 3 "div_operator" "")
14190                  (const_string "ssediv")
14191               ]
14192               (const_string "sseadd")))
14193    (set_attr "mode" "SF")])
14194
14195 (define_insn "*fop_sf_1_i387"
14196   [(set (match_operand:SF 0 "register_operand" "=f,f")
14197         (match_operator:SF 3 "binary_fp_operator"
14198                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14199                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14200   "TARGET_80387
14201    && !COMMUTATIVE_ARITH_P (operands[3])
14202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14203   "* return output_387_binary_op (insn, operands);"
14204   [(set (attr "type") 
14205         (cond [(match_operand:SF 3 "mult_operator" "") 
14206                  (const_string "fmul")
14207                (match_operand:SF 3 "div_operator" "") 
14208                  (const_string "fdiv")
14209               ]
14210               (const_string "fop")))
14211    (set_attr "mode" "SF")])
14212
14213
14214 ;; ??? Add SSE splitters for these!
14215 (define_insn "*fop_sf_2_i387"
14216   [(set (match_operand:SF 0 "register_operand" "=f,f")
14217         (match_operator:SF 3 "binary_fp_operator"
14218           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14219            (match_operand:SF 2 "register_operand" "0,0")]))]
14220   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14221   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14222   [(set (attr "type") 
14223         (cond [(match_operand:SF 3 "mult_operator" "") 
14224                  (const_string "fmul")
14225                (match_operand:SF 3 "div_operator" "") 
14226                  (const_string "fdiv")
14227               ]
14228               (const_string "fop")))
14229    (set_attr "fp_int_src" "true")
14230    (set_attr "mode" "SI")])
14231
14232 (define_insn "*fop_sf_3_i387"
14233   [(set (match_operand:SF 0 "register_operand" "=f,f")
14234         (match_operator:SF 3 "binary_fp_operator"
14235           [(match_operand:SF 1 "register_operand" "0,0")
14236            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14237   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14238   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14239   [(set (attr "type") 
14240         (cond [(match_operand:SF 3 "mult_operator" "") 
14241                  (const_string "fmul")
14242                (match_operand:SF 3 "div_operator" "") 
14243                  (const_string "fdiv")
14244               ]
14245               (const_string "fop")))
14246    (set_attr "fp_int_src" "true")
14247    (set_attr "mode" "SI")])
14248
14249 (define_insn "*fop_df_comm_mixed"
14250   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14251         (match_operator:DF 3 "binary_fp_operator"
14252                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14253                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14254   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14255    && COMMUTATIVE_ARITH_P (operands[3])
14256    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14257   "* return output_387_binary_op (insn, operands);"
14258   [(set (attr "type") 
14259         (if_then_else (eq_attr "alternative" "1")
14260            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14261               (const_string "ssemul")
14262               (const_string "sseadd"))
14263            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14264               (const_string "fmul")
14265               (const_string "fop"))))
14266    (set_attr "mode" "DF")])
14267
14268 (define_insn "*fop_df_comm_sse"
14269   [(set (match_operand:DF 0 "register_operand" "=Y")
14270         (match_operator:DF 3 "binary_fp_operator"
14271                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14272                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14273   "TARGET_SSE2 && TARGET_SSE_MATH
14274    && COMMUTATIVE_ARITH_P (operands[3])
14275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276   "* return output_387_binary_op (insn, operands);"
14277   [(set (attr "type") 
14278         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14279            (const_string "ssemul")
14280            (const_string "sseadd")))
14281    (set_attr "mode" "DF")])
14282
14283 (define_insn "*fop_df_comm_i387"
14284   [(set (match_operand:DF 0 "register_operand" "=f")
14285         (match_operator:DF 3 "binary_fp_operator"
14286                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14287                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14288   "TARGET_80387
14289    && COMMUTATIVE_ARITH_P (operands[3])
14290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14291   "* return output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14294            (const_string "fmul")
14295            (const_string "fop")))
14296    (set_attr "mode" "DF")])
14297
14298 (define_insn "*fop_df_1_mixed"
14299   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14300         (match_operator:DF 3 "binary_fp_operator"
14301                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14302                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14303   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14304    && !COMMUTATIVE_ARITH_P (operands[3])
14305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14306   "* return output_387_binary_op (insn, operands);"
14307   [(set (attr "type") 
14308         (cond [(and (eq_attr "alternative" "2")
14309                     (match_operand:SF 3 "mult_operator" ""))
14310                  (const_string "ssemul")
14311                (and (eq_attr "alternative" "2")
14312                     (match_operand:SF 3 "div_operator" ""))
14313                  (const_string "ssediv")
14314                (eq_attr "alternative" "2")
14315                  (const_string "sseadd")
14316                (match_operand:DF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:DF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "mode" "DF")])
14323
14324 (define_insn "*fop_df_1_sse"
14325   [(set (match_operand:DF 0 "register_operand" "=Y")
14326         (match_operator:DF 3 "binary_fp_operator"
14327                         [(match_operand:DF 1 "register_operand" "0")
14328                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14329   "TARGET_SSE2 && TARGET_SSE_MATH
14330    && !COMMUTATIVE_ARITH_P (operands[3])"
14331   "* return output_387_binary_op (insn, operands);"
14332   [(set_attr "mode" "DF")
14333    (set (attr "type") 
14334         (cond [(match_operand:SF 3 "mult_operator" "")
14335                  (const_string "ssemul")
14336                (match_operand:SF 3 "div_operator" "")
14337                  (const_string "ssediv")
14338               ]
14339               (const_string "sseadd")))])
14340
14341 (define_insn "*fop_df_1_i387"
14342   [(set (match_operand:DF 0 "register_operand" "=f,f")
14343         (match_operator:DF 3 "binary_fp_operator"
14344                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14345                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14346   "TARGET_80387
14347    && !COMMUTATIVE_ARITH_P (operands[3])
14348    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14349   "* return output_387_binary_op (insn, operands);"
14350   [(set (attr "type") 
14351         (cond [(match_operand:DF 3 "mult_operator" "") 
14352                  (const_string "fmul")
14353                (match_operand:DF 3 "div_operator" "")
14354                  (const_string "fdiv")
14355               ]
14356               (const_string "fop")))
14357    (set_attr "mode" "DF")])
14358
14359 ;; ??? Add SSE splitters for these!
14360 (define_insn "*fop_df_2_i387"
14361   [(set (match_operand:DF 0 "register_operand" "=f,f")
14362         (match_operator:DF 3 "binary_fp_operator"
14363            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14364             (match_operand:DF 2 "register_operand" "0,0")]))]
14365   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14366   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14367   [(set (attr "type") 
14368         (cond [(match_operand:DF 3 "mult_operator" "") 
14369                  (const_string "fmul")
14370                (match_operand:DF 3 "div_operator" "") 
14371                  (const_string "fdiv")
14372               ]
14373               (const_string "fop")))
14374    (set_attr "fp_int_src" "true")
14375    (set_attr "mode" "SI")])
14376
14377 (define_insn "*fop_df_3_i387"
14378   [(set (match_operand:DF 0 "register_operand" "=f,f")
14379         (match_operator:DF 3 "binary_fp_operator"
14380            [(match_operand:DF 1 "register_operand" "0,0")
14381             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14382   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14383   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (cond [(match_operand:DF 3 "mult_operator" "") 
14386                  (const_string "fmul")
14387                (match_operand:DF 3 "div_operator" "") 
14388                  (const_string "fdiv")
14389               ]
14390               (const_string "fop")))
14391    (set_attr "fp_int_src" "true")
14392    (set_attr "mode" "SI")])
14393
14394 (define_insn "*fop_df_4_i387"
14395   [(set (match_operand:DF 0 "register_operand" "=f,f")
14396         (match_operator:DF 3 "binary_fp_operator"
14397            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14398             (match_operand:DF 2 "register_operand" "0,f")]))]
14399   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14400    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14401   "* return output_387_binary_op (insn, operands);"
14402   [(set (attr "type") 
14403         (cond [(match_operand:DF 3 "mult_operator" "") 
14404                  (const_string "fmul")
14405                (match_operand:DF 3 "div_operator" "") 
14406                  (const_string "fdiv")
14407               ]
14408               (const_string "fop")))
14409    (set_attr "mode" "SF")])
14410
14411 (define_insn "*fop_df_5_i387"
14412   [(set (match_operand:DF 0 "register_operand" "=f,f")
14413         (match_operator:DF 3 "binary_fp_operator"
14414           [(match_operand:DF 1 "register_operand" "0,f")
14415            (float_extend:DF
14416             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14417   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14418   "* return output_387_binary_op (insn, operands);"
14419   [(set (attr "type") 
14420         (cond [(match_operand:DF 3 "mult_operator" "") 
14421                  (const_string "fmul")
14422                (match_operand:DF 3 "div_operator" "") 
14423                  (const_string "fdiv")
14424               ]
14425               (const_string "fop")))
14426    (set_attr "mode" "SF")])
14427
14428 (define_insn "*fop_df_6_i387"
14429   [(set (match_operand:DF 0 "register_operand" "=f,f")
14430         (match_operator:DF 3 "binary_fp_operator"
14431           [(float_extend:DF
14432             (match_operand:SF 1 "register_operand" "0,f"))
14433            (float_extend:DF
14434             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14435   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14436   "* return output_387_binary_op (insn, operands);"
14437   [(set (attr "type") 
14438         (cond [(match_operand:DF 3 "mult_operator" "") 
14439                  (const_string "fmul")
14440                (match_operand:DF 3 "div_operator" "") 
14441                  (const_string "fdiv")
14442               ]
14443               (const_string "fop")))
14444    (set_attr "mode" "SF")])
14445
14446 (define_insn "*fop_xf_comm_i387"
14447   [(set (match_operand:XF 0 "register_operand" "=f")
14448         (match_operator:XF 3 "binary_fp_operator"
14449                         [(match_operand:XF 1 "register_operand" "%0")
14450                          (match_operand:XF 2 "register_operand" "f")]))]
14451   "TARGET_80387
14452    && COMMUTATIVE_ARITH_P (operands[3])"
14453   "* return output_387_binary_op (insn, operands);"
14454   [(set (attr "type") 
14455         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14456            (const_string "fmul")
14457            (const_string "fop")))
14458    (set_attr "mode" "XF")])
14459
14460 (define_insn "*fop_xf_1_i387"
14461   [(set (match_operand:XF 0 "register_operand" "=f,f")
14462         (match_operator:XF 3 "binary_fp_operator"
14463                         [(match_operand:XF 1 "register_operand" "0,f")
14464                          (match_operand:XF 2 "register_operand" "f,0")]))]
14465   "TARGET_80387
14466    && !COMMUTATIVE_ARITH_P (operands[3])"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (cond [(match_operand:XF 3 "mult_operator" "") 
14470                  (const_string "fmul")
14471                (match_operand:XF 3 "div_operator" "") 
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "mode" "XF")])
14476
14477 (define_insn "*fop_xf_2_i387"
14478   [(set (match_operand:XF 0 "register_operand" "=f,f")
14479         (match_operator:XF 3 "binary_fp_operator"
14480            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14481             (match_operand:XF 2 "register_operand" "0,0")]))]
14482   "TARGET_80387 && TARGET_USE_FIOP"
14483   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14484   [(set (attr "type") 
14485         (cond [(match_operand:XF 3 "mult_operator" "") 
14486                  (const_string "fmul")
14487                (match_operand:XF 3 "div_operator" "") 
14488                  (const_string "fdiv")
14489               ]
14490               (const_string "fop")))
14491    (set_attr "fp_int_src" "true")
14492    (set_attr "mode" "SI")])
14493
14494 (define_insn "*fop_xf_3_i387"
14495   [(set (match_operand:XF 0 "register_operand" "=f,f")
14496         (match_operator:XF 3 "binary_fp_operator"
14497           [(match_operand:XF 1 "register_operand" "0,0")
14498            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14499   "TARGET_80387 && TARGET_USE_FIOP"
14500   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14501   [(set (attr "type") 
14502         (cond [(match_operand:XF 3 "mult_operator" "") 
14503                  (const_string "fmul")
14504                (match_operand:XF 3 "div_operator" "") 
14505                  (const_string "fdiv")
14506               ]
14507               (const_string "fop")))
14508    (set_attr "fp_int_src" "true")
14509    (set_attr "mode" "SI")])
14510
14511 (define_insn "*fop_xf_4_i387"
14512   [(set (match_operand:XF 0 "register_operand" "=f,f")
14513         (match_operator:XF 3 "binary_fp_operator"
14514            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14515             (match_operand:XF 2 "register_operand" "0,f")]))]
14516   "TARGET_80387"
14517   "* return output_387_binary_op (insn, operands);"
14518   [(set (attr "type") 
14519         (cond [(match_operand:XF 3 "mult_operator" "") 
14520                  (const_string "fmul")
14521                (match_operand:XF 3 "div_operator" "") 
14522                  (const_string "fdiv")
14523               ]
14524               (const_string "fop")))
14525    (set_attr "mode" "SF")])
14526
14527 (define_insn "*fop_xf_5_i387"
14528   [(set (match_operand:XF 0 "register_operand" "=f,f")
14529         (match_operator:XF 3 "binary_fp_operator"
14530           [(match_operand:XF 1 "register_operand" "0,f")
14531            (float_extend:XF
14532             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14533   "TARGET_80387"
14534   "* return output_387_binary_op (insn, operands);"
14535   [(set (attr "type") 
14536         (cond [(match_operand:XF 3 "mult_operator" "") 
14537                  (const_string "fmul")
14538                (match_operand:XF 3 "div_operator" "") 
14539                  (const_string "fdiv")
14540               ]
14541               (const_string "fop")))
14542    (set_attr "mode" "SF")])
14543
14544 (define_insn "*fop_xf_6_i387"
14545   [(set (match_operand:XF 0 "register_operand" "=f,f")
14546         (match_operator:XF 3 "binary_fp_operator"
14547           [(float_extend:XF
14548             (match_operand 1 "register_operand" "0,f"))
14549            (float_extend:XF
14550             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14551   "TARGET_80387"
14552   "* return output_387_binary_op (insn, operands);"
14553   [(set (attr "type") 
14554         (cond [(match_operand:XF 3 "mult_operator" "") 
14555                  (const_string "fmul")
14556                (match_operand:XF 3 "div_operator" "") 
14557                  (const_string "fdiv")
14558               ]
14559               (const_string "fop")))
14560    (set_attr "mode" "SF")])
14561
14562 (define_split
14563   [(set (match_operand 0 "register_operand" "")
14564         (match_operator 3 "binary_fp_operator"
14565            [(float (match_operand:SI 1 "register_operand" ""))
14566             (match_operand 2 "register_operand" "")]))]
14567   "TARGET_80387 && reload_completed
14568    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14569   [(const_int 0)]
14570
14571   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14572   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14573   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14574                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14575                                           GET_MODE (operands[3]),
14576                                           operands[4],
14577                                           operands[2])));
14578   ix86_free_from_memory (GET_MODE (operands[1]));
14579   DONE;
14580 })
14581
14582 (define_split
14583   [(set (match_operand 0 "register_operand" "")
14584         (match_operator 3 "binary_fp_operator"
14585            [(match_operand 1 "register_operand" "")
14586             (float (match_operand:SI 2 "register_operand" ""))]))]
14587   "TARGET_80387 && reload_completed
14588    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14589   [(const_int 0)]
14590 {
14591   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14592   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14593   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14594                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14595                                           GET_MODE (operands[3]),
14596                                           operands[1],
14597                                           operands[4])));
14598   ix86_free_from_memory (GET_MODE (operands[2]));
14599   DONE;
14600 })
14601 \f
14602 ;; FPU special functions.
14603
14604 (define_expand "sqrtsf2"
14605   [(set (match_operand:SF 0 "register_operand" "")
14606         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14607   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14608 {
14609   if (!TARGET_SSE_MATH)
14610     operands[1] = force_reg (SFmode, operands[1]);
14611 })
14612
14613 (define_insn "*sqrtsf2_mixed"
14614   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14615         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14616   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14617   "@
14618    fsqrt
14619    sqrtss\t{%1, %0|%0, %1}"
14620   [(set_attr "type" "fpspc,sse")
14621    (set_attr "mode" "SF,SF")
14622    (set_attr "athlon_decode" "direct,*")])
14623
14624 (define_insn "*sqrtsf2_sse"
14625   [(set (match_operand:SF 0 "register_operand" "=x")
14626         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14627   "TARGET_SSE_MATH"
14628   "sqrtss\t{%1, %0|%0, %1}"
14629   [(set_attr "type" "sse")
14630    (set_attr "mode" "SF")
14631    (set_attr "athlon_decode" "*")])
14632
14633 (define_insn "*sqrtsf2_i387"
14634   [(set (match_operand:SF 0 "register_operand" "=f")
14635         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14636   "TARGET_USE_FANCY_MATH_387"
14637   "fsqrt"
14638   [(set_attr "type" "fpspc")
14639    (set_attr "mode" "SF")
14640    (set_attr "athlon_decode" "direct")])
14641
14642 (define_expand "sqrtdf2"
14643   [(set (match_operand:DF 0 "register_operand" "")
14644         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14645   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14646 {
14647   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14648     operands[1] = force_reg (DFmode, operands[1]);
14649 })
14650
14651 (define_insn "*sqrtdf2_mixed"
14652   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14653         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14654   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14655   "@
14656    fsqrt
14657    sqrtsd\t{%1, %0|%0, %1}"
14658   [(set_attr "type" "fpspc,sse")
14659    (set_attr "mode" "DF,DF")
14660    (set_attr "athlon_decode" "direct,*")])
14661
14662 (define_insn "*sqrtdf2_sse"
14663   [(set (match_operand:DF 0 "register_operand" "=Y")
14664         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14665   "TARGET_SSE2 && TARGET_SSE_MATH"
14666   "sqrtsd\t{%1, %0|%0, %1}"
14667   [(set_attr "type" "sse")
14668    (set_attr "mode" "DF")
14669    (set_attr "athlon_decode" "*")])
14670
14671 (define_insn "*sqrtdf2_i387"
14672   [(set (match_operand:DF 0 "register_operand" "=f")
14673         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14674   "TARGET_USE_FANCY_MATH_387"
14675   "fsqrt"
14676   [(set_attr "type" "fpspc")
14677    (set_attr "mode" "DF")
14678    (set_attr "athlon_decode" "direct")])
14679
14680 (define_insn "*sqrtextendsfdf2_i387"
14681   [(set (match_operand:DF 0 "register_operand" "=f")
14682         (sqrt:DF (float_extend:DF
14683                   (match_operand:SF 1 "register_operand" "0"))))]
14684   "TARGET_USE_FANCY_MATH_387
14685    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14686   "fsqrt"
14687   [(set_attr "type" "fpspc")
14688    (set_attr "mode" "DF")
14689    (set_attr "athlon_decode" "direct")])
14690
14691 (define_insn "sqrtxf2"
14692   [(set (match_operand:XF 0 "register_operand" "=f")
14693         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14694   "TARGET_USE_FANCY_MATH_387 
14695    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14696   "fsqrt"
14697   [(set_attr "type" "fpspc")
14698    (set_attr "mode" "XF")
14699    (set_attr "athlon_decode" "direct")])
14700
14701 (define_insn "*sqrtextendsfxf2_i387"
14702   [(set (match_operand:XF 0 "register_operand" "=f")
14703         (sqrt:XF (float_extend:XF
14704                   (match_operand:SF 1 "register_operand" "0"))))]
14705   "TARGET_USE_FANCY_MATH_387"
14706   "fsqrt"
14707   [(set_attr "type" "fpspc")
14708    (set_attr "mode" "XF")
14709    (set_attr "athlon_decode" "direct")])
14710
14711 (define_insn "*sqrtextenddfxf2_i387"
14712   [(set (match_operand:XF 0 "register_operand" "=f")
14713         (sqrt:XF (float_extend:XF
14714                   (match_operand:DF 1 "register_operand" "0"))))]
14715   "TARGET_USE_FANCY_MATH_387"
14716   "fsqrt"
14717   [(set_attr "type" "fpspc")
14718    (set_attr "mode" "XF")
14719    (set_attr "athlon_decode" "direct")])
14720
14721 (define_insn "fpremxf4"
14722   [(set (match_operand:XF 0 "register_operand" "=f")
14723         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14724                     (match_operand:XF 3 "register_operand" "1")]
14725                    UNSPEC_FPREM_F))
14726    (set (match_operand:XF 1 "register_operand" "=u")
14727         (unspec:XF [(match_dup 2) (match_dup 3)]
14728                    UNSPEC_FPREM_U))
14729    (set (reg:CCFP FPSR_REG)
14730         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14731   "TARGET_USE_FANCY_MATH_387
14732    && flag_unsafe_math_optimizations"
14733   "fprem"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "XF")])
14736
14737 (define_expand "fmodsf3"
14738   [(use (match_operand:SF 0 "register_operand" ""))
14739    (use (match_operand:SF 1 "register_operand" ""))
14740    (use (match_operand:SF 2 "register_operand" ""))]
14741   "TARGET_USE_FANCY_MATH_387
14742    && flag_unsafe_math_optimizations"
14743 {
14744   rtx label = gen_label_rtx ();
14745
14746   rtx op1 = gen_reg_rtx (XFmode);
14747   rtx op2 = gen_reg_rtx (XFmode);
14748
14749   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14750   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14751
14752   emit_label (label);
14753
14754   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14755   ix86_emit_fp_unordered_jump (label);
14756
14757   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14758   DONE;
14759 })
14760
14761 (define_expand "fmoddf3"
14762   [(use (match_operand:DF 0 "register_operand" ""))
14763    (use (match_operand:DF 1 "register_operand" ""))
14764    (use (match_operand:DF 2 "register_operand" ""))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && flag_unsafe_math_optimizations"
14767 {
14768   rtx label = gen_label_rtx ();
14769
14770   rtx op1 = gen_reg_rtx (XFmode);
14771   rtx op2 = gen_reg_rtx (XFmode);
14772
14773   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14774   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14775
14776   emit_label (label);
14777
14778   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14779   ix86_emit_fp_unordered_jump (label);
14780
14781   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14782   DONE;
14783 })
14784
14785 (define_expand "fmodxf3"
14786   [(use (match_operand:XF 0 "register_operand" ""))
14787    (use (match_operand:XF 1 "register_operand" ""))
14788    (use (match_operand:XF 2 "register_operand" ""))]
14789   "TARGET_USE_FANCY_MATH_387
14790    && flag_unsafe_math_optimizations"
14791 {
14792   rtx label = gen_label_rtx ();
14793
14794   emit_label (label);
14795
14796   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14797                            operands[1], operands[2]));
14798   ix86_emit_fp_unordered_jump (label);
14799
14800   emit_move_insn (operands[0], operands[1]);
14801   DONE;
14802 })
14803
14804 (define_insn "fprem1xf4"
14805   [(set (match_operand:XF 0 "register_operand" "=f")
14806         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14807                     (match_operand:XF 3 "register_operand" "1")]
14808                    UNSPEC_FPREM1_F))
14809    (set (match_operand:XF 1 "register_operand" "=u")
14810         (unspec:XF [(match_dup 2) (match_dup 3)]
14811                    UNSPEC_FPREM1_U))
14812    (set (reg:CCFP FPSR_REG)
14813         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && flag_unsafe_math_optimizations"
14816   "fprem1"
14817   [(set_attr "type" "fpspc")
14818    (set_attr "mode" "XF")])
14819
14820 (define_expand "dremsf3"
14821   [(use (match_operand:SF 0 "register_operand" ""))
14822    (use (match_operand:SF 1 "register_operand" ""))
14823    (use (match_operand:SF 2 "register_operand" ""))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14826 {
14827   rtx label = gen_label_rtx ();
14828
14829   rtx op1 = gen_reg_rtx (XFmode);
14830   rtx op2 = gen_reg_rtx (XFmode);
14831
14832   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14833   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14834
14835   emit_label (label);
14836
14837   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14838   ix86_emit_fp_unordered_jump (label);
14839
14840   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14841   DONE;
14842 })
14843
14844 (define_expand "dremdf3"
14845   [(use (match_operand:DF 0 "register_operand" ""))
14846    (use (match_operand:DF 1 "register_operand" ""))
14847    (use (match_operand:DF 2 "register_operand" ""))]
14848   "TARGET_USE_FANCY_MATH_387
14849    && flag_unsafe_math_optimizations"
14850 {
14851   rtx label = gen_label_rtx ();
14852
14853   rtx op1 = gen_reg_rtx (XFmode);
14854   rtx op2 = gen_reg_rtx (XFmode);
14855
14856   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14857   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14858
14859   emit_label (label);
14860
14861   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14862   ix86_emit_fp_unordered_jump (label);
14863
14864   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14865   DONE;
14866 })
14867
14868 (define_expand "dremxf3"
14869   [(use (match_operand:XF 0 "register_operand" ""))
14870    (use (match_operand:XF 1 "register_operand" ""))
14871    (use (match_operand:XF 2 "register_operand" ""))]
14872   "TARGET_USE_FANCY_MATH_387
14873    && flag_unsafe_math_optimizations"
14874 {
14875   rtx label = gen_label_rtx ();
14876
14877   emit_label (label);
14878
14879   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14880                             operands[1], operands[2]));
14881   ix86_emit_fp_unordered_jump (label);
14882
14883   emit_move_insn (operands[0], operands[1]);
14884   DONE;
14885 })
14886
14887 (define_insn "*sindf2"
14888   [(set (match_operand:DF 0 "register_operand" "=f")
14889         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && flag_unsafe_math_optimizations"
14892   "fsin"
14893   [(set_attr "type" "fpspc")
14894    (set_attr "mode" "DF")])
14895
14896 (define_insn "*sinsf2"
14897   [(set (match_operand:SF 0 "register_operand" "=f")
14898         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14899   "TARGET_USE_FANCY_MATH_387
14900    && flag_unsafe_math_optimizations"
14901   "fsin"
14902   [(set_attr "type" "fpspc")
14903    (set_attr "mode" "SF")])
14904
14905 (define_insn "*sinextendsfdf2"
14906   [(set (match_operand:DF 0 "register_operand" "=f")
14907         (unspec:DF [(float_extend:DF
14908                      (match_operand:SF 1 "register_operand" "0"))]
14909                    UNSPEC_SIN))]
14910   "TARGET_USE_FANCY_MATH_387
14911    && flag_unsafe_math_optimizations"
14912   "fsin"
14913   [(set_attr "type" "fpspc")
14914    (set_attr "mode" "DF")])
14915
14916 (define_insn "*sinxf2"
14917   [(set (match_operand:XF 0 "register_operand" "=f")
14918         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations"
14921   "fsin"
14922   [(set_attr "type" "fpspc")
14923    (set_attr "mode" "XF")])
14924
14925 (define_insn "*cosdf2"
14926   [(set (match_operand:DF 0 "register_operand" "=f")
14927         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && flag_unsafe_math_optimizations"
14930   "fcos"
14931   [(set_attr "type" "fpspc")
14932    (set_attr "mode" "DF")])
14933
14934 (define_insn "*cossf2"
14935   [(set (match_operand:SF 0 "register_operand" "=f")
14936         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14937   "TARGET_USE_FANCY_MATH_387
14938    && flag_unsafe_math_optimizations"
14939   "fcos"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "SF")])
14942
14943 (define_insn "*cosextendsfdf2"
14944   [(set (match_operand:DF 0 "register_operand" "=f")
14945         (unspec:DF [(float_extend:DF
14946                      (match_operand:SF 1 "register_operand" "0"))]
14947                    UNSPEC_COS))]
14948   "TARGET_USE_FANCY_MATH_387
14949    && flag_unsafe_math_optimizations"
14950   "fcos"
14951   [(set_attr "type" "fpspc")
14952    (set_attr "mode" "DF")])
14953
14954 (define_insn "*cosxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14957   "TARGET_USE_FANCY_MATH_387
14958    && flag_unsafe_math_optimizations"
14959   "fcos"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")])
14962
14963 ;; With sincos pattern defined, sin and cos builtin function will be
14964 ;; expanded to sincos pattern with one of its outputs left unused. 
14965 ;; Cse pass  will detected, if two sincos patterns can be combined,
14966 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14967 ;; depending on the unused output.
14968
14969 (define_insn "sincosdf3"
14970   [(set (match_operand:DF 0 "register_operand" "=f")
14971         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14972                    UNSPEC_SINCOS_COS))
14973    (set (match_operand:DF 1 "register_operand" "=u")
14974         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && flag_unsafe_math_optimizations"
14977   "fsincos"
14978   [(set_attr "type" "fpspc")
14979    (set_attr "mode" "DF")])
14980
14981 (define_split
14982   [(set (match_operand:DF 0 "register_operand" "")
14983         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14984                    UNSPEC_SINCOS_COS))
14985    (set (match_operand:DF 1 "register_operand" "")
14986         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14987   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14988    && !reload_completed && !reload_in_progress"
14989   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14990   "")
14991
14992 (define_split
14993   [(set (match_operand:DF 0 "register_operand" "")
14994         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14995                    UNSPEC_SINCOS_COS))
14996    (set (match_operand:DF 1 "register_operand" "")
14997         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14998   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14999    && !reload_completed && !reload_in_progress"
15000   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15001   "")
15002
15003 (define_insn "sincossf3"
15004   [(set (match_operand:SF 0 "register_operand" "=f")
15005         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15006                    UNSPEC_SINCOS_COS))
15007    (set (match_operand:SF 1 "register_operand" "=u")
15008         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15009   "TARGET_USE_FANCY_MATH_387
15010    && flag_unsafe_math_optimizations"
15011   "fsincos"
15012   [(set_attr "type" "fpspc")
15013    (set_attr "mode" "SF")])
15014
15015 (define_split
15016   [(set (match_operand:SF 0 "register_operand" "")
15017         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15018                    UNSPEC_SINCOS_COS))
15019    (set (match_operand:SF 1 "register_operand" "")
15020         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15021   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15022    && !reload_completed && !reload_in_progress"
15023   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15024   "")
15025
15026 (define_split
15027   [(set (match_operand:SF 0 "register_operand" "")
15028         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15029                    UNSPEC_SINCOS_COS))
15030    (set (match_operand:SF 1 "register_operand" "")
15031         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15033    && !reload_completed && !reload_in_progress"
15034   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15035   "")
15036
15037 (define_insn "*sincosextendsfdf3"
15038   [(set (match_operand:DF 0 "register_operand" "=f")
15039         (unspec:DF [(float_extend:DF
15040                      (match_operand:SF 2 "register_operand" "0"))]
15041                    UNSPEC_SINCOS_COS))
15042    (set (match_operand:DF 1 "register_operand" "=u")
15043         (unspec:DF [(float_extend:DF
15044                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15045   "TARGET_USE_FANCY_MATH_387
15046    && flag_unsafe_math_optimizations"
15047   "fsincos"
15048   [(set_attr "type" "fpspc")
15049    (set_attr "mode" "DF")])
15050
15051 (define_split
15052   [(set (match_operand:DF 0 "register_operand" "")
15053         (unspec:DF [(float_extend:DF
15054                      (match_operand:SF 2 "register_operand" ""))]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:DF 1 "register_operand" "")
15057         (unspec:DF [(float_extend:DF
15058                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15059   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15060    && !reload_completed && !reload_in_progress"
15061   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15062                                    (match_dup 2))] UNSPEC_SIN))]
15063   "")
15064
15065 (define_split
15066   [(set (match_operand:DF 0 "register_operand" "")
15067         (unspec:DF [(float_extend:DF
15068                      (match_operand:SF 2 "register_operand" ""))]
15069                    UNSPEC_SINCOS_COS))
15070    (set (match_operand:DF 1 "register_operand" "")
15071         (unspec:DF [(float_extend:DF
15072                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15073   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15074    && !reload_completed && !reload_in_progress"
15075   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15076                                    (match_dup 2))] UNSPEC_COS))]
15077   "")
15078
15079 (define_insn "sincosxf3"
15080   [(set (match_operand:XF 0 "register_operand" "=f")
15081         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15082                    UNSPEC_SINCOS_COS))
15083    (set (match_operand:XF 1 "register_operand" "=u")
15084         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations"
15087   "fsincos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "XF")])
15090
15091 (define_split
15092   [(set (match_operand:XF 0 "register_operand" "")
15093         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15094                    UNSPEC_SINCOS_COS))
15095    (set (match_operand:XF 1 "register_operand" "")
15096         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15097   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15098    && !reload_completed && !reload_in_progress"
15099   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15100   "")
15101
15102 (define_split
15103   [(set (match_operand:XF 0 "register_operand" "")
15104         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15105                    UNSPEC_SINCOS_COS))
15106    (set (match_operand:XF 1 "register_operand" "")
15107         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15108   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15109    && !reload_completed && !reload_in_progress"
15110   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15111   "")
15112
15113 (define_insn "*tandf3_1"
15114   [(set (match_operand:DF 0 "register_operand" "=f")
15115         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15116                    UNSPEC_TAN_ONE))
15117    (set (match_operand:DF 1 "register_operand" "=u")
15118         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15119   "TARGET_USE_FANCY_MATH_387
15120    && flag_unsafe_math_optimizations"
15121   "fptan"
15122   [(set_attr "type" "fpspc")
15123    (set_attr "mode" "DF")])
15124
15125 ;; optimize sequence: fptan
15126 ;;                    fstp    %st(0)
15127 ;;                    fld1
15128 ;; into fptan insn.
15129
15130 (define_peephole2
15131   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15132                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15133                              UNSPEC_TAN_ONE))
15134              (set (match_operand:DF 1 "register_operand" "")
15135                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15136    (set (match_dup 0)
15137         (match_operand:DF 3 "immediate_operand" ""))]
15138   "standard_80387_constant_p (operands[3]) == 2"
15139   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15140              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15141   "")
15142
15143 (define_expand "tandf2"
15144   [(parallel [(set (match_dup 2)
15145                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15146                               UNSPEC_TAN_ONE))
15147               (set (match_operand:DF 0 "register_operand" "")
15148                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15149   "TARGET_USE_FANCY_MATH_387
15150    && flag_unsafe_math_optimizations"
15151 {
15152   operands[2] = gen_reg_rtx (DFmode);
15153 })
15154
15155 (define_insn "*tansf3_1"
15156   [(set (match_operand:SF 0 "register_operand" "=f")
15157         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15158                    UNSPEC_TAN_ONE))
15159    (set (match_operand:SF 1 "register_operand" "=u")
15160         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15161   "TARGET_USE_FANCY_MATH_387
15162    && flag_unsafe_math_optimizations"
15163   "fptan"
15164   [(set_attr "type" "fpspc")
15165    (set_attr "mode" "SF")])
15166
15167 ;; optimize sequence: fptan
15168 ;;                    fstp    %st(0)
15169 ;;                    fld1
15170 ;; into fptan insn.
15171
15172 (define_peephole2
15173   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15174                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15175                              UNSPEC_TAN_ONE))
15176              (set (match_operand:SF 1 "register_operand" "")
15177                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15178    (set (match_dup 0)
15179         (match_operand:SF 3 "immediate_operand" ""))]
15180   "standard_80387_constant_p (operands[3]) == 2"
15181   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15182              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15183   "")
15184
15185 (define_expand "tansf2"
15186   [(parallel [(set (match_dup 2)
15187                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15188                               UNSPEC_TAN_ONE))
15189               (set (match_operand:SF 0 "register_operand" "")
15190                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15191   "TARGET_USE_FANCY_MATH_387
15192    && flag_unsafe_math_optimizations"
15193 {
15194   operands[2] = gen_reg_rtx (SFmode);
15195 })
15196
15197 (define_insn "*tanxf3_1"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15200                    UNSPEC_TAN_ONE))
15201    (set (match_operand:XF 1 "register_operand" "=u")
15202         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && flag_unsafe_math_optimizations"
15205   "fptan"
15206   [(set_attr "type" "fpspc")
15207    (set_attr "mode" "XF")])
15208
15209 ;; optimize sequence: fptan
15210 ;;                    fstp    %st(0)
15211 ;;                    fld1
15212 ;; into fptan insn.
15213
15214 (define_peephole2
15215   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15216                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15217                              UNSPEC_TAN_ONE))
15218              (set (match_operand:XF 1 "register_operand" "")
15219                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15220    (set (match_dup 0)
15221         (match_operand:XF 3 "immediate_operand" ""))]
15222   "standard_80387_constant_p (operands[3]) == 2"
15223   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15224              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15225   "")
15226
15227 (define_expand "tanxf2"
15228   [(parallel [(set (match_dup 2)
15229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15230                               UNSPEC_TAN_ONE))
15231               (set (match_operand:XF 0 "register_operand" "")
15232                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15233   "TARGET_USE_FANCY_MATH_387
15234    && flag_unsafe_math_optimizations"
15235 {
15236   operands[2] = gen_reg_rtx (XFmode);
15237 })
15238
15239 (define_insn "atan2df3_1"
15240   [(set (match_operand:DF 0 "register_operand" "=f")
15241         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15242                     (match_operand:DF 1 "register_operand" "u")]
15243                    UNSPEC_FPATAN))
15244    (clobber (match_scratch:DF 3 "=1"))]
15245   "TARGET_USE_FANCY_MATH_387
15246    && flag_unsafe_math_optimizations"
15247   "fpatan"
15248   [(set_attr "type" "fpspc")
15249    (set_attr "mode" "DF")])
15250
15251 (define_expand "atan2df3"
15252   [(use (match_operand:DF 0 "register_operand" "=f"))
15253    (use (match_operand:DF 2 "register_operand" "0"))
15254    (use (match_operand:DF 1 "register_operand" "u"))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && flag_unsafe_math_optimizations"
15257 {
15258   rtx copy = gen_reg_rtx (DFmode);
15259   emit_move_insn (copy, operands[1]);
15260   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15261   DONE;
15262 })
15263
15264 (define_expand "atandf2"
15265   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15266                    (unspec:DF [(match_dup 2)
15267                                (match_operand:DF 1 "register_operand" "")]
15268                     UNSPEC_FPATAN))
15269               (clobber (match_scratch:DF 3 ""))])]
15270   "TARGET_USE_FANCY_MATH_387
15271    && flag_unsafe_math_optimizations"
15272 {
15273   operands[2] = gen_reg_rtx (DFmode);
15274   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15275 })
15276
15277 (define_insn "atan2sf3_1"
15278   [(set (match_operand:SF 0 "register_operand" "=f")
15279         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15280                     (match_operand:SF 1 "register_operand" "u")]
15281                    UNSPEC_FPATAN))
15282    (clobber (match_scratch:SF 3 "=1"))]
15283   "TARGET_USE_FANCY_MATH_387
15284    && flag_unsafe_math_optimizations"
15285   "fpatan"
15286   [(set_attr "type" "fpspc")
15287    (set_attr "mode" "SF")])
15288
15289 (define_expand "atan2sf3"
15290   [(use (match_operand:SF 0 "register_operand" "=f"))
15291    (use (match_operand:SF 2 "register_operand" "0"))
15292    (use (match_operand:SF 1 "register_operand" "u"))]
15293   "TARGET_USE_FANCY_MATH_387
15294    && flag_unsafe_math_optimizations"
15295 {
15296   rtx copy = gen_reg_rtx (SFmode);
15297   emit_move_insn (copy, operands[1]);
15298   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15299   DONE;
15300 })
15301
15302 (define_expand "atansf2"
15303   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15304                    (unspec:SF [(match_dup 2)
15305                                (match_operand:SF 1 "register_operand" "")]
15306                     UNSPEC_FPATAN))
15307               (clobber (match_scratch:SF 3 ""))])]
15308   "TARGET_USE_FANCY_MATH_387
15309    && flag_unsafe_math_optimizations"
15310 {
15311   operands[2] = gen_reg_rtx (SFmode);
15312   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15313 })
15314
15315 (define_insn "atan2xf3_1"
15316   [(set (match_operand:XF 0 "register_operand" "=f")
15317         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15318                     (match_operand:XF 1 "register_operand" "u")]
15319                    UNSPEC_FPATAN))
15320    (clobber (match_scratch:XF 3 "=1"))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15323   "fpatan"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "XF")])
15326
15327 (define_expand "atan2xf3"
15328   [(use (match_operand:XF 0 "register_operand" "=f"))
15329    (use (match_operand:XF 2 "register_operand" "0"))
15330    (use (match_operand:XF 1 "register_operand" "u"))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15333 {
15334   rtx copy = gen_reg_rtx (XFmode);
15335   emit_move_insn (copy, operands[1]);
15336   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15337   DONE;
15338 })
15339
15340 (define_expand "atanxf2"
15341   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15342                    (unspec:XF [(match_dup 2)
15343                                (match_operand:XF 1 "register_operand" "")]
15344                     UNSPEC_FPATAN))
15345               (clobber (match_scratch:XF 3 ""))])]
15346   "TARGET_USE_FANCY_MATH_387
15347    && flag_unsafe_math_optimizations"
15348 {
15349   operands[2] = gen_reg_rtx (XFmode);
15350   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15351 })
15352
15353 (define_expand "asindf2"
15354   [(set (match_dup 2)
15355         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15356    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15357    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15358    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15359    (parallel [(set (match_dup 7)
15360                    (unspec:XF [(match_dup 6) (match_dup 2)]
15361                               UNSPEC_FPATAN))
15362               (clobber (match_scratch:XF 8 ""))])
15363    (set (match_operand:DF 0 "register_operand" "")
15364         (float_truncate:DF (match_dup 7)))]
15365   "TARGET_USE_FANCY_MATH_387
15366    && flag_unsafe_math_optimizations"
15367 {
15368   int i;
15369
15370   for (i=2; i<8; i++)
15371     operands[i] = gen_reg_rtx (XFmode);
15372
15373   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15374 })
15375
15376 (define_expand "asinsf2"
15377   [(set (match_dup 2)
15378         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15379    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15380    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15381    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15382    (parallel [(set (match_dup 7)
15383                    (unspec:XF [(match_dup 6) (match_dup 2)]
15384                               UNSPEC_FPATAN))
15385               (clobber (match_scratch:XF 8 ""))])
15386    (set (match_operand:SF 0 "register_operand" "")
15387         (float_truncate:SF (match_dup 7)))]
15388   "TARGET_USE_FANCY_MATH_387
15389    && flag_unsafe_math_optimizations"
15390 {
15391   int i;
15392
15393   for (i=2; i<8; i++)
15394     operands[i] = gen_reg_rtx (XFmode);
15395
15396   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15397 })
15398
15399 (define_expand "asinxf2"
15400   [(set (match_dup 2)
15401         (mult:XF (match_operand:XF 1 "register_operand" "")
15402                  (match_dup 1)))
15403    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15404    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15405    (parallel [(set (match_operand:XF 0 "register_operand" "")
15406                    (unspec:XF [(match_dup 5) (match_dup 1)]
15407                               UNSPEC_FPATAN))
15408               (clobber (match_scratch:XF 6 ""))])]
15409   "TARGET_USE_FANCY_MATH_387
15410    && flag_unsafe_math_optimizations"
15411 {
15412   int i;
15413
15414   for (i=2; i<6; i++)
15415     operands[i] = gen_reg_rtx (XFmode);
15416
15417   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15418 })
15419
15420 (define_expand "acosdf2"
15421   [(set (match_dup 2)
15422         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15423    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15424    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15425    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15426    (parallel [(set (match_dup 7)
15427                    (unspec:XF [(match_dup 2) (match_dup 6)]
15428                               UNSPEC_FPATAN))
15429               (clobber (match_scratch:XF 8 ""))])
15430    (set (match_operand:DF 0 "register_operand" "")
15431         (float_truncate:DF (match_dup 7)))]
15432   "TARGET_USE_FANCY_MATH_387
15433    && flag_unsafe_math_optimizations"
15434 {
15435   int i;
15436
15437   for (i=2; i<8; i++)
15438     operands[i] = gen_reg_rtx (XFmode);
15439
15440   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15441 })
15442
15443 (define_expand "acossf2"
15444   [(set (match_dup 2)
15445         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15446    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15447    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15448    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15449    (parallel [(set (match_dup 7)
15450                    (unspec:XF [(match_dup 2) (match_dup 6)]
15451                               UNSPEC_FPATAN))
15452               (clobber (match_scratch:XF 8 ""))])
15453    (set (match_operand:SF 0 "register_operand" "")
15454         (float_truncate:SF (match_dup 7)))]
15455   "TARGET_USE_FANCY_MATH_387
15456    && flag_unsafe_math_optimizations"
15457 {
15458   int i;
15459
15460   for (i=2; i<8; i++)
15461     operands[i] = gen_reg_rtx (XFmode);
15462
15463   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15464 })
15465
15466 (define_expand "acosxf2"
15467   [(set (match_dup 2)
15468         (mult:XF (match_operand:XF 1 "register_operand" "")
15469                  (match_dup 1)))
15470    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15471    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15472    (parallel [(set (match_operand:XF 0 "register_operand" "")
15473                    (unspec:XF [(match_dup 1) (match_dup 5)]
15474                               UNSPEC_FPATAN))
15475               (clobber (match_scratch:XF 6 ""))])]
15476   "TARGET_USE_FANCY_MATH_387
15477    && flag_unsafe_math_optimizations"
15478 {
15479   int i;
15480
15481   for (i=2; i<6; i++)
15482     operands[i] = gen_reg_rtx (XFmode);
15483
15484   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15485 })
15486
15487 (define_insn "fyl2x_xf3"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490                     (match_operand:XF 1 "register_operand" "u")]
15491                    UNSPEC_FYL2X))
15492    (clobber (match_scratch:XF 3 "=1"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && flag_unsafe_math_optimizations"
15495   "fyl2x"
15496   [(set_attr "type" "fpspc")
15497    (set_attr "mode" "XF")])
15498
15499 (define_expand "logsf2"
15500   [(set (match_dup 2)
15501         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15502    (parallel [(set (match_dup 4)
15503                    (unspec:XF [(match_dup 2)
15504                                (match_dup 3)] UNSPEC_FYL2X))
15505               (clobber (match_scratch:XF 5 ""))])
15506    (set (match_operand:SF 0 "register_operand" "")
15507         (float_truncate:SF (match_dup 4)))]
15508   "TARGET_USE_FANCY_MATH_387
15509    && flag_unsafe_math_optimizations"
15510 {
15511   rtx temp;
15512
15513   operands[2] = gen_reg_rtx (XFmode);
15514   operands[3] = gen_reg_rtx (XFmode);
15515   operands[4] = gen_reg_rtx (XFmode);
15516
15517   temp = standard_80387_constant_rtx (4); /* fldln2 */
15518   emit_move_insn (operands[3], temp);
15519 })
15520
15521 (define_expand "logdf2"
15522   [(set (match_dup 2)
15523         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15524    (parallel [(set (match_dup 4)
15525                    (unspec:XF [(match_dup 2)
15526                                (match_dup 3)] UNSPEC_FYL2X))
15527               (clobber (match_scratch:XF 5 ""))])
15528    (set (match_operand:DF 0 "register_operand" "")
15529         (float_truncate:DF (match_dup 4)))]
15530   "TARGET_USE_FANCY_MATH_387
15531    && flag_unsafe_math_optimizations"
15532 {
15533   rtx temp;
15534
15535   operands[2] = gen_reg_rtx (XFmode);
15536   operands[3] = gen_reg_rtx (XFmode);
15537   operands[4] = gen_reg_rtx (XFmode);
15538
15539   temp = standard_80387_constant_rtx (4); /* fldln2 */
15540   emit_move_insn (operands[3], temp);
15541 })
15542
15543 (define_expand "logxf2"
15544   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15545                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15546                                (match_dup 2)] UNSPEC_FYL2X))
15547               (clobber (match_scratch:XF 3 ""))])]
15548   "TARGET_USE_FANCY_MATH_387
15549    && flag_unsafe_math_optimizations"
15550 {
15551   rtx temp;
15552
15553   operands[2] = gen_reg_rtx (XFmode);
15554   temp = standard_80387_constant_rtx (4); /* fldln2 */
15555   emit_move_insn (operands[2], temp);
15556 })
15557
15558 (define_expand "log10sf2"
15559   [(set (match_dup 2)
15560         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15561    (parallel [(set (match_dup 4)
15562                    (unspec:XF [(match_dup 2)
15563                                (match_dup 3)] UNSPEC_FYL2X))
15564               (clobber (match_scratch:XF 5 ""))])
15565    (set (match_operand:SF 0 "register_operand" "")
15566         (float_truncate:SF (match_dup 4)))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15569 {
15570   rtx temp;
15571
15572   operands[2] = gen_reg_rtx (XFmode);
15573   operands[3] = gen_reg_rtx (XFmode);
15574   operands[4] = gen_reg_rtx (XFmode);
15575
15576   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15577   emit_move_insn (operands[3], temp);
15578 })
15579
15580 (define_expand "log10df2"
15581   [(set (match_dup 2)
15582         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15583    (parallel [(set (match_dup 4)
15584                    (unspec:XF [(match_dup 2)
15585                                (match_dup 3)] UNSPEC_FYL2X))
15586               (clobber (match_scratch:XF 5 ""))])
15587    (set (match_operand:DF 0 "register_operand" "")
15588         (float_truncate:DF (match_dup 4)))]
15589   "TARGET_USE_FANCY_MATH_387
15590    && flag_unsafe_math_optimizations"
15591 {
15592   rtx temp;
15593
15594   operands[2] = gen_reg_rtx (XFmode);
15595   operands[3] = gen_reg_rtx (XFmode);
15596   operands[4] = gen_reg_rtx (XFmode);
15597
15598   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15599   emit_move_insn (operands[3], temp);
15600 })
15601
15602 (define_expand "log10xf2"
15603   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15604                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15605                                (match_dup 2)] UNSPEC_FYL2X))
15606               (clobber (match_scratch:XF 3 ""))])]
15607   "TARGET_USE_FANCY_MATH_387
15608    && flag_unsafe_math_optimizations"
15609 {
15610   rtx temp;
15611
15612   operands[2] = gen_reg_rtx (XFmode);
15613   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15614   emit_move_insn (operands[2], temp);
15615 })
15616
15617 (define_expand "log2sf2"
15618   [(set (match_dup 2)
15619         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15620    (parallel [(set (match_dup 4)
15621                    (unspec:XF [(match_dup 2)
15622                                (match_dup 3)] UNSPEC_FYL2X))
15623               (clobber (match_scratch:XF 5 ""))])
15624    (set (match_operand:SF 0 "register_operand" "")
15625         (float_truncate:SF (match_dup 4)))]
15626   "TARGET_USE_FANCY_MATH_387
15627    && flag_unsafe_math_optimizations"
15628 {
15629   operands[2] = gen_reg_rtx (XFmode);
15630   operands[3] = gen_reg_rtx (XFmode);
15631   operands[4] = gen_reg_rtx (XFmode);
15632
15633   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15634 })
15635
15636 (define_expand "log2df2"
15637   [(set (match_dup 2)
15638         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15639    (parallel [(set (match_dup 4)
15640                    (unspec:XF [(match_dup 2)
15641                                (match_dup 3)] UNSPEC_FYL2X))
15642               (clobber (match_scratch:XF 5 ""))])
15643    (set (match_operand:DF 0 "register_operand" "")
15644         (float_truncate:DF (match_dup 4)))]
15645   "TARGET_USE_FANCY_MATH_387
15646    && flag_unsafe_math_optimizations"
15647 {
15648   operands[2] = gen_reg_rtx (XFmode);
15649   operands[3] = gen_reg_rtx (XFmode);
15650   operands[4] = gen_reg_rtx (XFmode);
15651
15652   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15653 })
15654
15655 (define_expand "log2xf2"
15656   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15657                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15658                                (match_dup 2)] UNSPEC_FYL2X))
15659               (clobber (match_scratch:XF 3 ""))])]
15660   "TARGET_USE_FANCY_MATH_387
15661    && flag_unsafe_math_optimizations"
15662 {
15663   operands[2] = gen_reg_rtx (XFmode);
15664   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15665 })
15666
15667 (define_insn "fyl2xp1_xf3"
15668   [(set (match_operand:XF 0 "register_operand" "=f")
15669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15670                     (match_operand:XF 1 "register_operand" "u")]
15671                    UNSPEC_FYL2XP1))
15672    (clobber (match_scratch:XF 3 "=1"))]
15673   "TARGET_USE_FANCY_MATH_387
15674    && flag_unsafe_math_optimizations"
15675   "fyl2xp1"
15676   [(set_attr "type" "fpspc")
15677    (set_attr "mode" "XF")])
15678
15679 (define_expand "log1psf2"
15680   [(use (match_operand:XF 0 "register_operand" ""))
15681    (use (match_operand:XF 1 "register_operand" ""))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684 {
15685   rtx op0 = gen_reg_rtx (XFmode);
15686   rtx op1 = gen_reg_rtx (XFmode);
15687
15688   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15689   ix86_emit_i387_log1p (op0, op1);
15690   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15691   DONE;
15692 })
15693
15694 (define_expand "log1pdf2"
15695   [(use (match_operand:XF 0 "register_operand" ""))
15696    (use (match_operand:XF 1 "register_operand" ""))]
15697   "TARGET_USE_FANCY_MATH_387
15698    && flag_unsafe_math_optimizations"
15699 {
15700   rtx op0 = gen_reg_rtx (XFmode);
15701   rtx op1 = gen_reg_rtx (XFmode);
15702
15703   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15704   ix86_emit_i387_log1p (op0, op1);
15705   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15706   DONE;
15707 })
15708
15709 (define_expand "log1pxf2"
15710   [(use (match_operand:XF 0 "register_operand" ""))
15711    (use (match_operand:XF 1 "register_operand" ""))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && flag_unsafe_math_optimizations"
15714 {
15715   ix86_emit_i387_log1p (operands[0], operands[1]);
15716   DONE;
15717 })
15718
15719 (define_insn "*fxtractxf3"
15720   [(set (match_operand:XF 0 "register_operand" "=f")
15721         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15722                    UNSPEC_XTRACT_FRACT))
15723    (set (match_operand:XF 1 "register_operand" "=u")
15724         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727   "fxtract"
15728   [(set_attr "type" "fpspc")
15729    (set_attr "mode" "XF")])
15730
15731 (define_expand "logbsf2"
15732   [(set (match_dup 2)
15733         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15734    (parallel [(set (match_dup 3)
15735                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15736               (set (match_dup 4)
15737                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15738    (set (match_operand:SF 0 "register_operand" "")
15739         (float_truncate:SF (match_dup 4)))]
15740   "TARGET_USE_FANCY_MATH_387
15741    && flag_unsafe_math_optimizations"
15742 {
15743   operands[2] = gen_reg_rtx (XFmode);
15744   operands[3] = gen_reg_rtx (XFmode);
15745   operands[4] = gen_reg_rtx (XFmode);
15746 })
15747
15748 (define_expand "logbdf2"
15749   [(set (match_dup 2)
15750         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15751    (parallel [(set (match_dup 3)
15752                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15753               (set (match_dup 4)
15754                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15755    (set (match_operand:DF 0 "register_operand" "")
15756         (float_truncate:DF (match_dup 4)))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && flag_unsafe_math_optimizations"
15759 {
15760   operands[2] = gen_reg_rtx (XFmode);
15761   operands[3] = gen_reg_rtx (XFmode);
15762   operands[4] = gen_reg_rtx (XFmode);
15763 })
15764
15765 (define_expand "logbxf2"
15766   [(parallel [(set (match_dup 2)
15767                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15768                               UNSPEC_XTRACT_FRACT))
15769               (set (match_operand:XF 0 "register_operand" "")
15770                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773 {
15774   operands[2] = gen_reg_rtx (XFmode);
15775 })
15776
15777 (define_expand "ilogbsi2"
15778   [(parallel [(set (match_dup 2)
15779                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15780                               UNSPEC_XTRACT_FRACT))
15781               (set (match_operand:XF 3 "register_operand" "")
15782                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15783    (parallel [(set (match_operand:SI 0 "register_operand" "")
15784                    (fix:SI (match_dup 3)))
15785               (clobber (reg:CC FLAGS_REG))])]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788 {
15789   operands[2] = gen_reg_rtx (XFmode);
15790   operands[3] = gen_reg_rtx (XFmode);
15791 })
15792
15793 (define_insn "*f2xm1xf2"
15794   [(set (match_operand:XF 0 "register_operand" "=f")
15795         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15796          UNSPEC_F2XM1))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && flag_unsafe_math_optimizations"
15799   "f2xm1"
15800   [(set_attr "type" "fpspc")
15801    (set_attr "mode" "XF")])
15802
15803 (define_insn "*fscalexf4"
15804   [(set (match_operand:XF 0 "register_operand" "=f")
15805         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15806                     (match_operand:XF 3 "register_operand" "1")]
15807                    UNSPEC_FSCALE_FRACT))
15808    (set (match_operand:XF 1 "register_operand" "=u")
15809         (unspec:XF [(match_dup 2) (match_dup 3)]
15810                    UNSPEC_FSCALE_EXP))]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813   "fscale"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "XF")])
15816
15817 (define_expand "expsf2"
15818   [(set (match_dup 2)
15819         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15820    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15821    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15822    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15823    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15824    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15825    (parallel [(set (match_dup 10)
15826                    (unspec:XF [(match_dup 9) (match_dup 5)]
15827                               UNSPEC_FSCALE_FRACT))
15828               (set (match_dup 11)
15829                    (unspec:XF [(match_dup 9) (match_dup 5)]
15830                               UNSPEC_FSCALE_EXP))])
15831    (set (match_operand:SF 0 "register_operand" "")
15832         (float_truncate:SF (match_dup 10)))]
15833   "TARGET_USE_FANCY_MATH_387
15834    && flag_unsafe_math_optimizations"
15835 {
15836   rtx temp;
15837   int i;
15838
15839   for (i=2; i<12; i++)
15840     operands[i] = gen_reg_rtx (XFmode);
15841   temp = standard_80387_constant_rtx (5); /* fldl2e */
15842   emit_move_insn (operands[3], temp);
15843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15844 })
15845
15846 (define_expand "expdf2"
15847   [(set (match_dup 2)
15848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15854    (parallel [(set (match_dup 10)
15855                    (unspec:XF [(match_dup 9) (match_dup 5)]
15856                               UNSPEC_FSCALE_FRACT))
15857               (set (match_dup 11)
15858                    (unspec:XF [(match_dup 9) (match_dup 5)]
15859                               UNSPEC_FSCALE_EXP))])
15860    (set (match_operand:DF 0 "register_operand" "")
15861         (float_truncate:DF (match_dup 10)))]
15862   "TARGET_USE_FANCY_MATH_387
15863    && flag_unsafe_math_optimizations"
15864 {
15865   rtx temp;
15866   int i;
15867
15868   for (i=2; i<12; i++)
15869     operands[i] = gen_reg_rtx (XFmode);
15870   temp = standard_80387_constant_rtx (5); /* fldl2e */
15871   emit_move_insn (operands[3], temp);
15872   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15873 })
15874
15875 (define_expand "expxf2"
15876   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15877                                (match_dup 2)))
15878    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15879    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15880    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15881    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15882    (parallel [(set (match_operand:XF 0 "register_operand" "")
15883                    (unspec:XF [(match_dup 8) (match_dup 4)]
15884                               UNSPEC_FSCALE_FRACT))
15885               (set (match_dup 9)
15886                    (unspec:XF [(match_dup 8) (match_dup 4)]
15887                               UNSPEC_FSCALE_EXP))])]
15888   "TARGET_USE_FANCY_MATH_387
15889    && flag_unsafe_math_optimizations"
15890 {
15891   rtx temp;
15892   int i;
15893
15894   for (i=2; i<10; i++)
15895     operands[i] = gen_reg_rtx (XFmode);
15896   temp = standard_80387_constant_rtx (5); /* fldl2e */
15897   emit_move_insn (operands[2], temp);
15898   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15899 })
15900
15901 (define_expand "exp10sf2"
15902   [(set (match_dup 2)
15903         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15904    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15905    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15906    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15907    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15908    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15909    (parallel [(set (match_dup 10)
15910                    (unspec:XF [(match_dup 9) (match_dup 5)]
15911                               UNSPEC_FSCALE_FRACT))
15912               (set (match_dup 11)
15913                    (unspec:XF [(match_dup 9) (match_dup 5)]
15914                               UNSPEC_FSCALE_EXP))])
15915    (set (match_operand:SF 0 "register_operand" "")
15916         (float_truncate:SF (match_dup 10)))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && flag_unsafe_math_optimizations"
15919 {
15920   rtx temp;
15921   int i;
15922
15923   for (i=2; i<12; i++)
15924     operands[i] = gen_reg_rtx (XFmode);
15925   temp = standard_80387_constant_rtx (6); /* fldl2t */
15926   emit_move_insn (operands[3], temp);
15927   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15928 })
15929
15930 (define_expand "exp10df2"
15931   [(set (match_dup 2)
15932         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15933    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15934    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15935    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15936    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15937    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15938    (parallel [(set (match_dup 10)
15939                    (unspec:XF [(match_dup 9) (match_dup 5)]
15940                               UNSPEC_FSCALE_FRACT))
15941               (set (match_dup 11)
15942                    (unspec:XF [(match_dup 9) (match_dup 5)]
15943                               UNSPEC_FSCALE_EXP))])
15944    (set (match_operand:DF 0 "register_operand" "")
15945         (float_truncate:DF (match_dup 10)))]
15946   "TARGET_USE_FANCY_MATH_387
15947    && flag_unsafe_math_optimizations"
15948 {
15949   rtx temp;
15950   int i;
15951
15952   for (i=2; i<12; i++)
15953     operands[i] = gen_reg_rtx (XFmode);
15954   temp = standard_80387_constant_rtx (6); /* fldl2t */
15955   emit_move_insn (operands[3], temp);
15956   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15957 })
15958
15959 (define_expand "exp10xf2"
15960   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15961                                (match_dup 2)))
15962    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15963    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15964    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15965    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15966    (parallel [(set (match_operand:XF 0 "register_operand" "")
15967                    (unspec:XF [(match_dup 8) (match_dup 4)]
15968                               UNSPEC_FSCALE_FRACT))
15969               (set (match_dup 9)
15970                    (unspec:XF [(match_dup 8) (match_dup 4)]
15971                               UNSPEC_FSCALE_EXP))])]
15972   "TARGET_USE_FANCY_MATH_387
15973    && flag_unsafe_math_optimizations"
15974 {
15975   rtx temp;
15976   int i;
15977
15978   for (i=2; i<10; i++)
15979     operands[i] = gen_reg_rtx (XFmode);
15980   temp = standard_80387_constant_rtx (6); /* fldl2t */
15981   emit_move_insn (operands[2], temp);
15982   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15983 })
15984
15985 (define_expand "exp2sf2"
15986   [(set (match_dup 2)
15987         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15988    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15989    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15990    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15991    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15992    (parallel [(set (match_dup 8)
15993                    (unspec:XF [(match_dup 7) (match_dup 3)]
15994                               UNSPEC_FSCALE_FRACT))
15995               (set (match_dup 9)
15996                    (unspec:XF [(match_dup 7) (match_dup 3)]
15997                               UNSPEC_FSCALE_EXP))])
15998    (set (match_operand:SF 0 "register_operand" "")
15999         (float_truncate:SF (match_dup 8)))]
16000   "TARGET_USE_FANCY_MATH_387
16001    && flag_unsafe_math_optimizations"
16002 {
16003   int i;
16004
16005   for (i=2; i<10; i++)
16006     operands[i] = gen_reg_rtx (XFmode);
16007   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16008 })
16009
16010 (define_expand "exp2df2"
16011   [(set (match_dup 2)
16012         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16013    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16014    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16015    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16016    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16017    (parallel [(set (match_dup 8)
16018                    (unspec:XF [(match_dup 7) (match_dup 3)]
16019                               UNSPEC_FSCALE_FRACT))
16020               (set (match_dup 9)
16021                    (unspec:XF [(match_dup 7) (match_dup 3)]
16022                               UNSPEC_FSCALE_EXP))])
16023    (set (match_operand:DF 0 "register_operand" "")
16024         (float_truncate:DF (match_dup 8)))]
16025   "TARGET_USE_FANCY_MATH_387
16026    && flag_unsafe_math_optimizations"
16027 {
16028   int i;
16029
16030   for (i=2; i<10; i++)
16031     operands[i] = gen_reg_rtx (XFmode);
16032   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16033 })
16034
16035 (define_expand "exp2xf2"
16036   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16037    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16038    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16039    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16040    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16041    (parallel [(set (match_operand:XF 0 "register_operand" "")
16042                    (unspec:XF [(match_dup 7) (match_dup 3)]
16043                               UNSPEC_FSCALE_FRACT))
16044               (set (match_dup 8)
16045                    (unspec:XF [(match_dup 7) (match_dup 3)]
16046                               UNSPEC_FSCALE_EXP))])]
16047   "TARGET_USE_FANCY_MATH_387
16048    && flag_unsafe_math_optimizations"
16049 {
16050   int i;
16051
16052   for (i=2; i<9; i++)
16053     operands[i] = gen_reg_rtx (XFmode);
16054   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16055 })
16056
16057 (define_expand "expm1df2"
16058   [(set (match_dup 2)
16059         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16060    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16061    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16062    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16063    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16064    (parallel [(set (match_dup 8)
16065                    (unspec:XF [(match_dup 7) (match_dup 5)]
16066                               UNSPEC_FSCALE_FRACT))
16067                    (set (match_dup 9)
16068                    (unspec:XF [(match_dup 7) (match_dup 5)]
16069                               UNSPEC_FSCALE_EXP))])
16070    (parallel [(set (match_dup 11)
16071                    (unspec:XF [(match_dup 10) (match_dup 9)]
16072                               UNSPEC_FSCALE_FRACT))
16073               (set (match_dup 12)
16074                    (unspec:XF [(match_dup 10) (match_dup 9)]
16075                               UNSPEC_FSCALE_EXP))])
16076    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16077    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16078    (set (match_operand:DF 0 "register_operand" "")
16079         (float_truncate:DF (match_dup 14)))]
16080   "TARGET_USE_FANCY_MATH_387
16081    && flag_unsafe_math_optimizations"
16082 {
16083   rtx temp;
16084   int i;
16085
16086   for (i=2; i<15; i++)
16087     operands[i] = gen_reg_rtx (XFmode);
16088   temp = standard_80387_constant_rtx (5); /* fldl2e */
16089   emit_move_insn (operands[3], temp);
16090   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16091 })
16092
16093 (define_expand "expm1sf2"
16094   [(set (match_dup 2)
16095         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16096    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16097    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16098    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16099    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16100    (parallel [(set (match_dup 8)
16101                    (unspec:XF [(match_dup 7) (match_dup 5)]
16102                               UNSPEC_FSCALE_FRACT))
16103                    (set (match_dup 9)
16104                    (unspec:XF [(match_dup 7) (match_dup 5)]
16105                               UNSPEC_FSCALE_EXP))])
16106    (parallel [(set (match_dup 11)
16107                    (unspec:XF [(match_dup 10) (match_dup 9)]
16108                               UNSPEC_FSCALE_FRACT))
16109               (set (match_dup 12)
16110                    (unspec:XF [(match_dup 10) (match_dup 9)]
16111                               UNSPEC_FSCALE_EXP))])
16112    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16113    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16114    (set (match_operand:SF 0 "register_operand" "")
16115         (float_truncate:SF (match_dup 14)))]
16116   "TARGET_USE_FANCY_MATH_387
16117    && flag_unsafe_math_optimizations"
16118 {
16119   rtx temp;
16120   int i;
16121
16122   for (i=2; i<15; i++)
16123     operands[i] = gen_reg_rtx (XFmode);
16124   temp = standard_80387_constant_rtx (5); /* fldl2e */
16125   emit_move_insn (operands[3], temp);
16126   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16127 })
16128
16129 (define_expand "expm1xf2"
16130   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16131                                (match_dup 2)))
16132    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16133    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16134    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16135    (parallel [(set (match_dup 7)
16136                    (unspec:XF [(match_dup 6) (match_dup 4)]
16137                               UNSPEC_FSCALE_FRACT))
16138                    (set (match_dup 8)
16139                    (unspec:XF [(match_dup 6) (match_dup 4)]
16140                               UNSPEC_FSCALE_EXP))])
16141    (parallel [(set (match_dup 10)
16142                    (unspec:XF [(match_dup 9) (match_dup 8)]
16143                               UNSPEC_FSCALE_FRACT))
16144               (set (match_dup 11)
16145                    (unspec:XF [(match_dup 9) (match_dup 8)]
16146                               UNSPEC_FSCALE_EXP))])
16147    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16148    (set (match_operand:XF 0 "register_operand" "")
16149         (plus:XF (match_dup 12) (match_dup 7)))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && flag_unsafe_math_optimizations"
16152 {
16153   rtx temp;
16154   int i;
16155
16156   for (i=2; i<13; i++)
16157     operands[i] = gen_reg_rtx (XFmode);
16158   temp = standard_80387_constant_rtx (5); /* fldl2e */
16159   emit_move_insn (operands[2], temp);
16160   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16161 })
16162 \f
16163
16164 (define_insn "frndintxf2"
16165   [(set (match_operand:XF 0 "register_operand" "=f")
16166         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16167          UNSPEC_FRNDINT))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && flag_unsafe_math_optimizations"
16170   "frndint"
16171   [(set_attr "type" "fpspc")
16172    (set_attr "mode" "XF")])
16173
16174 (define_expand "rintdf2"
16175   [(use (match_operand:DF 0 "register_operand" ""))
16176    (use (match_operand:DF 1 "register_operand" ""))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && flag_unsafe_math_optimizations"
16179 {
16180   rtx op0 = gen_reg_rtx (XFmode);
16181   rtx op1 = gen_reg_rtx (XFmode);
16182
16183   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16184   emit_insn (gen_frndintxf2 (op0, op1));
16185
16186   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16187   DONE;
16188 })
16189
16190 (define_expand "rintsf2"
16191   [(use (match_operand:SF 0 "register_operand" ""))
16192    (use (match_operand:SF 1 "register_operand" ""))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && flag_unsafe_math_optimizations"
16195 {
16196   rtx op0 = gen_reg_rtx (XFmode);
16197   rtx op1 = gen_reg_rtx (XFmode);
16198
16199   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16200   emit_insn (gen_frndintxf2 (op0, op1));
16201
16202   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16203   DONE;
16204 })
16205
16206 (define_expand "rintxf2"
16207   [(use (match_operand:XF 0 "register_operand" ""))
16208    (use (match_operand:XF 1 "register_operand" ""))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && flag_unsafe_math_optimizations"
16211 {
16212   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16213   DONE;
16214 })
16215
16216 (define_insn "frndintxf2_floor"
16217   [(set (match_operand:XF 0 "register_operand" "=f")
16218         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16219          UNSPEC_FRNDINT_FLOOR))
16220    (use (match_operand:HI 2 "memory_operand" "m"))
16221    (use (match_operand:HI 3 "memory_operand" "m"))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16225   [(set_attr "type" "frndint")
16226    (set_attr "i387_cw" "floor")
16227    (set_attr "mode" "XF")])
16228
16229 (define_expand "floordf2"
16230   [(use (match_operand:DF 0 "register_operand" ""))
16231    (use (match_operand:DF 1 "register_operand" ""))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && flag_unsafe_math_optimizations"
16234 {
16235   rtx op0 = gen_reg_rtx (XFmode);
16236   rtx op1 = gen_reg_rtx (XFmode);
16237   rtx op2 = assign_386_stack_local (HImode, 1);
16238   rtx op3 = assign_386_stack_local (HImode, 2);
16239         
16240   ix86_optimize_mode_switching = 1;
16241
16242   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16243   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16244
16245   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16246   DONE;
16247 })
16248
16249 (define_expand "floorsf2"
16250   [(use (match_operand:SF 0 "register_operand" ""))
16251    (use (match_operand:SF 1 "register_operand" ""))]
16252   "TARGET_USE_FANCY_MATH_387
16253    && flag_unsafe_math_optimizations"
16254 {
16255   rtx op0 = gen_reg_rtx (XFmode);
16256   rtx op1 = gen_reg_rtx (XFmode);
16257   rtx op2 = assign_386_stack_local (HImode, 1);
16258   rtx op3 = assign_386_stack_local (HImode, 2);
16259         
16260   ix86_optimize_mode_switching = 1;
16261
16262   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16263   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16264
16265   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16266   DONE;
16267 })
16268
16269 (define_expand "floorxf2"
16270   [(use (match_operand:XF 0 "register_operand" ""))
16271    (use (match_operand:XF 1 "register_operand" ""))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16274 {
16275   rtx op2 = assign_386_stack_local (HImode, 1);
16276   rtx op3 = assign_386_stack_local (HImode, 2);
16277         
16278   ix86_optimize_mode_switching = 1;
16279
16280   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16281   DONE;
16282 })
16283
16284 (define_insn "frndintxf2_ceil"
16285   [(set (match_operand:XF 0 "register_operand" "=f")
16286         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16287          UNSPEC_FRNDINT_CEIL))
16288    (use (match_operand:HI 2 "memory_operand" "m"))
16289    (use (match_operand:HI 3 "memory_operand" "m"))]
16290   "TARGET_USE_FANCY_MATH_387
16291    && flag_unsafe_math_optimizations"
16292   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16293   [(set_attr "type" "frndint")
16294    (set_attr "i387_cw" "ceil")
16295    (set_attr "mode" "XF")])
16296
16297 (define_expand "ceildf2"
16298   [(use (match_operand:DF 0 "register_operand" ""))
16299    (use (match_operand:DF 1 "register_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations"
16302 {
16303   rtx op0 = gen_reg_rtx (XFmode);
16304   rtx op1 = gen_reg_rtx (XFmode);
16305   rtx op2 = assign_386_stack_local (HImode, 1);
16306   rtx op3 = assign_386_stack_local (HImode, 2);
16307         
16308   ix86_optimize_mode_switching = 1;
16309
16310   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16311   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16312
16313   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16314   DONE;
16315 })
16316
16317 (define_expand "ceilsf2"
16318   [(use (match_operand:SF 0 "register_operand" ""))
16319    (use (match_operand:SF 1 "register_operand" ""))]
16320   "TARGET_USE_FANCY_MATH_387
16321    && flag_unsafe_math_optimizations"
16322 {
16323   rtx op0 = gen_reg_rtx (XFmode);
16324   rtx op1 = gen_reg_rtx (XFmode);
16325   rtx op2 = assign_386_stack_local (HImode, 1);
16326   rtx op3 = assign_386_stack_local (HImode, 2);
16327         
16328   ix86_optimize_mode_switching = 1;
16329
16330   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16331   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16332
16333   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16334   DONE;
16335 })
16336
16337 (define_expand "ceilxf2"
16338   [(use (match_operand:XF 0 "register_operand" ""))
16339    (use (match_operand:XF 1 "register_operand" ""))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342 {
16343   rtx op2 = assign_386_stack_local (HImode, 1);
16344   rtx op3 = assign_386_stack_local (HImode, 2);
16345         
16346   ix86_optimize_mode_switching = 1;
16347
16348   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16349   DONE;
16350 })
16351
16352 (define_insn "frndintxf2_trunc"
16353   [(set (match_operand:XF 0 "register_operand" "=f")
16354         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16355          UNSPEC_FRNDINT_TRUNC))
16356    (use (match_operand:HI 2 "memory_operand" "m"))
16357    (use (match_operand:HI 3 "memory_operand" "m"))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && flag_unsafe_math_optimizations"
16360   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16361   [(set_attr "type" "frndint")
16362    (set_attr "i387_cw" "trunc")
16363    (set_attr "mode" "XF")])
16364
16365 (define_expand "btruncdf2"
16366   [(use (match_operand:DF 0 "register_operand" ""))
16367    (use (match_operand:DF 1 "register_operand" ""))]
16368   "TARGET_USE_FANCY_MATH_387
16369    && flag_unsafe_math_optimizations"
16370 {
16371   rtx op0 = gen_reg_rtx (XFmode);
16372   rtx op1 = gen_reg_rtx (XFmode);
16373   rtx op2 = assign_386_stack_local (HImode, 1);
16374   rtx op3 = assign_386_stack_local (HImode, 2);
16375         
16376   ix86_optimize_mode_switching = 1;
16377
16378   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16379   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16380
16381   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16382   DONE;
16383 })
16384
16385 (define_expand "btruncsf2"
16386   [(use (match_operand:SF 0 "register_operand" ""))
16387    (use (match_operand:SF 1 "register_operand" ""))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16390 {
16391   rtx op0 = gen_reg_rtx (XFmode);
16392   rtx op1 = gen_reg_rtx (XFmode);
16393   rtx op2 = assign_386_stack_local (HImode, 1);
16394   rtx op3 = assign_386_stack_local (HImode, 2);
16395         
16396   ix86_optimize_mode_switching = 1;
16397
16398   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16399   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16400
16401   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16402   DONE;
16403 })
16404
16405 (define_expand "btruncxf2"
16406   [(use (match_operand:XF 0 "register_operand" ""))
16407    (use (match_operand:XF 1 "register_operand" ""))]
16408   "TARGET_USE_FANCY_MATH_387
16409    && flag_unsafe_math_optimizations"
16410 {
16411   rtx op2 = assign_386_stack_local (HImode, 1);
16412   rtx op3 = assign_386_stack_local (HImode, 2);
16413         
16414   ix86_optimize_mode_switching = 1;
16415
16416   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16417   DONE;
16418 })
16419
16420 (define_insn "frndintxf2_mask_pm"
16421   [(set (match_operand:XF 0 "register_operand" "=f")
16422         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16423          UNSPEC_FRNDINT_MASK_PM))
16424    (use (match_operand:HI 2 "memory_operand" "m"))
16425    (use (match_operand:HI 3 "memory_operand" "m"))]
16426   "TARGET_USE_FANCY_MATH_387
16427    && flag_unsafe_math_optimizations"
16428   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16429   [(set_attr "type" "frndint")
16430    (set_attr "i387_cw" "mask_pm")
16431    (set_attr "mode" "XF")])
16432
16433 (define_expand "nearbyintdf2"
16434   [(use (match_operand:DF 0 "register_operand" ""))
16435    (use (match_operand:DF 1 "register_operand" ""))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && flag_unsafe_math_optimizations"
16438 {
16439   rtx op0 = gen_reg_rtx (XFmode);
16440   rtx op1 = gen_reg_rtx (XFmode);
16441   rtx op2 = assign_386_stack_local (HImode, 1);
16442   rtx op3 = assign_386_stack_local (HImode, 2);
16443         
16444   ix86_optimize_mode_switching = 1;
16445
16446   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16447   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16448
16449   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16450   DONE;
16451 })
16452
16453 (define_expand "nearbyintsf2"
16454   [(use (match_operand:SF 0 "register_operand" ""))
16455    (use (match_operand:SF 1 "register_operand" ""))]
16456   "TARGET_USE_FANCY_MATH_387
16457    && flag_unsafe_math_optimizations"
16458 {
16459   rtx op0 = gen_reg_rtx (XFmode);
16460   rtx op1 = gen_reg_rtx (XFmode);
16461   rtx op2 = assign_386_stack_local (HImode, 1);
16462   rtx op3 = assign_386_stack_local (HImode, 2);
16463         
16464   ix86_optimize_mode_switching = 1;
16465
16466   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16467   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16468
16469   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16470   DONE;
16471 })
16472
16473 (define_expand "nearbyintxf2"
16474   [(use (match_operand:XF 0 "register_operand" ""))
16475    (use (match_operand:XF 1 "register_operand" ""))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && flag_unsafe_math_optimizations"
16478 {
16479   rtx op2 = assign_386_stack_local (HImode, 1);
16480   rtx op3 = assign_386_stack_local (HImode, 2);
16481         
16482   ix86_optimize_mode_switching = 1;
16483
16484   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16485                                      op2, op3));
16486   DONE;
16487 })
16488
16489 \f
16490 ;; Block operation instructions
16491
16492 (define_insn "cld"
16493  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16494  ""
16495  "cld"
16496   [(set_attr "type" "cld")])
16497
16498 (define_expand "movmemsi"
16499   [(use (match_operand:BLK 0 "memory_operand" ""))
16500    (use (match_operand:BLK 1 "memory_operand" ""))
16501    (use (match_operand:SI 2 "nonmemory_operand" ""))
16502    (use (match_operand:SI 3 "const_int_operand" ""))]
16503   "! optimize_size"
16504 {
16505  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16506    DONE;
16507  else
16508    FAIL;
16509 })
16510
16511 (define_expand "movmemdi"
16512   [(use (match_operand:BLK 0 "memory_operand" ""))
16513    (use (match_operand:BLK 1 "memory_operand" ""))
16514    (use (match_operand:DI 2 "nonmemory_operand" ""))
16515    (use (match_operand:DI 3 "const_int_operand" ""))]
16516   "TARGET_64BIT"
16517 {
16518  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16519    DONE;
16520  else
16521    FAIL;
16522 })
16523
16524 ;; Most CPUs don't like single string operations
16525 ;; Handle this case here to simplify previous expander.
16526
16527 (define_expand "strmov"
16528   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16529    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16530    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16531               (clobber (reg:CC FLAGS_REG))])
16532    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16533               (clobber (reg:CC FLAGS_REG))])]
16534   ""
16535 {
16536   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16537
16538   /* If .md ever supports :P for Pmode, these can be directly
16539      in the pattern above.  */
16540   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16541   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16542
16543   if (TARGET_SINGLE_STRINGOP || optimize_size)
16544     {
16545       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16546                                       operands[2], operands[3],
16547                                       operands[5], operands[6]));
16548       DONE;
16549     }
16550
16551   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16552 })
16553
16554 (define_expand "strmov_singleop"
16555   [(parallel [(set (match_operand 1 "memory_operand" "")
16556                    (match_operand 3 "memory_operand" ""))
16557               (set (match_operand 0 "register_operand" "")
16558                    (match_operand 4 "" ""))
16559               (set (match_operand 2 "register_operand" "")
16560                    (match_operand 5 "" ""))
16561               (use (reg:SI DIRFLAG_REG))])]
16562   "TARGET_SINGLE_STRINGOP || optimize_size"
16563   "")
16564
16565 (define_insn "*strmovdi_rex_1"
16566   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16567         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16568    (set (match_operand:DI 0 "register_operand" "=D")
16569         (plus:DI (match_dup 2)
16570                  (const_int 8)))
16571    (set (match_operand:DI 1 "register_operand" "=S")
16572         (plus:DI (match_dup 3)
16573                  (const_int 8)))
16574    (use (reg:SI DIRFLAG_REG))]
16575   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16576   "movsq"
16577   [(set_attr "type" "str")
16578    (set_attr "mode" "DI")
16579    (set_attr "memory" "both")])
16580
16581 (define_insn "*strmovsi_1"
16582   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16583         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16584    (set (match_operand:SI 0 "register_operand" "=D")
16585         (plus:SI (match_dup 2)
16586                  (const_int 4)))
16587    (set (match_operand:SI 1 "register_operand" "=S")
16588         (plus:SI (match_dup 3)
16589                  (const_int 4)))
16590    (use (reg:SI DIRFLAG_REG))]
16591   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16592   "{movsl|movsd}"
16593   [(set_attr "type" "str")
16594    (set_attr "mode" "SI")
16595    (set_attr "memory" "both")])
16596
16597 (define_insn "*strmovsi_rex_1"
16598   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16599         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16600    (set (match_operand:DI 0 "register_operand" "=D")
16601         (plus:DI (match_dup 2)
16602                  (const_int 4)))
16603    (set (match_operand:DI 1 "register_operand" "=S")
16604         (plus:DI (match_dup 3)
16605                  (const_int 4)))
16606    (use (reg:SI DIRFLAG_REG))]
16607   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16608   "{movsl|movsd}"
16609   [(set_attr "type" "str")
16610    (set_attr "mode" "SI")
16611    (set_attr "memory" "both")])
16612
16613 (define_insn "*strmovhi_1"
16614   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16615         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16616    (set (match_operand:SI 0 "register_operand" "=D")
16617         (plus:SI (match_dup 2)
16618                  (const_int 2)))
16619    (set (match_operand:SI 1 "register_operand" "=S")
16620         (plus:SI (match_dup 3)
16621                  (const_int 2)))
16622    (use (reg:SI DIRFLAG_REG))]
16623   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16624   "movsw"
16625   [(set_attr "type" "str")
16626    (set_attr "memory" "both")
16627    (set_attr "mode" "HI")])
16628
16629 (define_insn "*strmovhi_rex_1"
16630   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16631         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16632    (set (match_operand:DI 0 "register_operand" "=D")
16633         (plus:DI (match_dup 2)
16634                  (const_int 2)))
16635    (set (match_operand:DI 1 "register_operand" "=S")
16636         (plus:DI (match_dup 3)
16637                  (const_int 2)))
16638    (use (reg:SI DIRFLAG_REG))]
16639   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16640   "movsw"
16641   [(set_attr "type" "str")
16642    (set_attr "memory" "both")
16643    (set_attr "mode" "HI")])
16644
16645 (define_insn "*strmovqi_1"
16646   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16647         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16648    (set (match_operand:SI 0 "register_operand" "=D")
16649         (plus:SI (match_dup 2)
16650                  (const_int 1)))
16651    (set (match_operand:SI 1 "register_operand" "=S")
16652         (plus:SI (match_dup 3)
16653                  (const_int 1)))
16654    (use (reg:SI DIRFLAG_REG))]
16655   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16656   "movsb"
16657   [(set_attr "type" "str")
16658    (set_attr "memory" "both")
16659    (set_attr "mode" "QI")])
16660
16661 (define_insn "*strmovqi_rex_1"
16662   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16663         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16664    (set (match_operand:DI 0 "register_operand" "=D")
16665         (plus:DI (match_dup 2)
16666                  (const_int 1)))
16667    (set (match_operand:DI 1 "register_operand" "=S")
16668         (plus:DI (match_dup 3)
16669                  (const_int 1)))
16670    (use (reg:SI DIRFLAG_REG))]
16671   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16672   "movsb"
16673   [(set_attr "type" "str")
16674    (set_attr "memory" "both")
16675    (set_attr "mode" "QI")])
16676
16677 (define_expand "rep_mov"
16678   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16679               (set (match_operand 0 "register_operand" "")
16680                    (match_operand 5 "" ""))
16681               (set (match_operand 2 "register_operand" "")
16682                    (match_operand 6 "" ""))
16683               (set (match_operand 1 "memory_operand" "")
16684                    (match_operand 3 "memory_operand" ""))
16685               (use (match_dup 4))
16686               (use (reg:SI DIRFLAG_REG))])]
16687   ""
16688   "")
16689
16690 (define_insn "*rep_movdi_rex64"
16691   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16692    (set (match_operand:DI 0 "register_operand" "=D") 
16693         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16694                             (const_int 3))
16695                  (match_operand:DI 3 "register_operand" "0")))
16696    (set (match_operand:DI 1 "register_operand" "=S") 
16697         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16698                  (match_operand:DI 4 "register_operand" "1")))
16699    (set (mem:BLK (match_dup 3))
16700         (mem:BLK (match_dup 4)))
16701    (use (match_dup 5))
16702    (use (reg:SI DIRFLAG_REG))]
16703   "TARGET_64BIT"
16704   "{rep\;movsq|rep movsq}"
16705   [(set_attr "type" "str")
16706    (set_attr "prefix_rep" "1")
16707    (set_attr "memory" "both")
16708    (set_attr "mode" "DI")])
16709
16710 (define_insn "*rep_movsi"
16711   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16712    (set (match_operand:SI 0 "register_operand" "=D") 
16713         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16714                             (const_int 2))
16715                  (match_operand:SI 3 "register_operand" "0")))
16716    (set (match_operand:SI 1 "register_operand" "=S") 
16717         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16718                  (match_operand:SI 4 "register_operand" "1")))
16719    (set (mem:BLK (match_dup 3))
16720         (mem:BLK (match_dup 4)))
16721    (use (match_dup 5))
16722    (use (reg:SI DIRFLAG_REG))]
16723   "!TARGET_64BIT"
16724   "{rep\;movsl|rep movsd}"
16725   [(set_attr "type" "str")
16726    (set_attr "prefix_rep" "1")
16727    (set_attr "memory" "both")
16728    (set_attr "mode" "SI")])
16729
16730 (define_insn "*rep_movsi_rex64"
16731   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16732    (set (match_operand:DI 0 "register_operand" "=D") 
16733         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16734                             (const_int 2))
16735                  (match_operand:DI 3 "register_operand" "0")))
16736    (set (match_operand:DI 1 "register_operand" "=S") 
16737         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16738                  (match_operand:DI 4 "register_operand" "1")))
16739    (set (mem:BLK (match_dup 3))
16740         (mem:BLK (match_dup 4)))
16741    (use (match_dup 5))
16742    (use (reg:SI DIRFLAG_REG))]
16743   "TARGET_64BIT"
16744   "{rep\;movsl|rep movsd}"
16745   [(set_attr "type" "str")
16746    (set_attr "prefix_rep" "1")
16747    (set_attr "memory" "both")
16748    (set_attr "mode" "SI")])
16749
16750 (define_insn "*rep_movqi"
16751   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16752    (set (match_operand:SI 0 "register_operand" "=D") 
16753         (plus:SI (match_operand:SI 3 "register_operand" "0")
16754                  (match_operand:SI 5 "register_operand" "2")))
16755    (set (match_operand:SI 1 "register_operand" "=S") 
16756         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16757    (set (mem:BLK (match_dup 3))
16758         (mem:BLK (match_dup 4)))
16759    (use (match_dup 5))
16760    (use (reg:SI DIRFLAG_REG))]
16761   "!TARGET_64BIT"
16762   "{rep\;movsb|rep movsb}"
16763   [(set_attr "type" "str")
16764    (set_attr "prefix_rep" "1")
16765    (set_attr "memory" "both")
16766    (set_attr "mode" "SI")])
16767
16768 (define_insn "*rep_movqi_rex64"
16769   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16770    (set (match_operand:DI 0 "register_operand" "=D") 
16771         (plus:DI (match_operand:DI 3 "register_operand" "0")
16772                  (match_operand:DI 5 "register_operand" "2")))
16773    (set (match_operand:DI 1 "register_operand" "=S") 
16774         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16775    (set (mem:BLK (match_dup 3))
16776         (mem:BLK (match_dup 4)))
16777    (use (match_dup 5))
16778    (use (reg:SI DIRFLAG_REG))]
16779   "TARGET_64BIT"
16780   "{rep\;movsb|rep movsb}"
16781   [(set_attr "type" "str")
16782    (set_attr "prefix_rep" "1")
16783    (set_attr "memory" "both")
16784    (set_attr "mode" "SI")])
16785
16786 (define_expand "clrmemsi"
16787    [(use (match_operand:BLK 0 "memory_operand" ""))
16788     (use (match_operand:SI 1 "nonmemory_operand" ""))
16789     (use (match_operand 2 "const_int_operand" ""))]
16790   ""
16791 {
16792  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16793    DONE;
16794  else
16795    FAIL;
16796 })
16797
16798 (define_expand "clrmemdi"
16799    [(use (match_operand:BLK 0 "memory_operand" ""))
16800     (use (match_operand:DI 1 "nonmemory_operand" ""))
16801     (use (match_operand 2 "const_int_operand" ""))]
16802   "TARGET_64BIT"
16803 {
16804  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16805    DONE;
16806  else
16807    FAIL;
16808 })
16809
16810 ;; Most CPUs don't like single string operations
16811 ;; Handle this case here to simplify previous expander.
16812
16813 (define_expand "strset"
16814   [(set (match_operand 1 "memory_operand" "")
16815         (match_operand 2 "register_operand" ""))
16816    (parallel [(set (match_operand 0 "register_operand" "")
16817                    (match_dup 3))
16818               (clobber (reg:CC FLAGS_REG))])]
16819   ""
16820 {
16821   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16822     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16823
16824   /* If .md ever supports :P for Pmode, this can be directly
16825      in the pattern above.  */
16826   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16827                               GEN_INT (GET_MODE_SIZE (GET_MODE
16828                                                       (operands[2]))));
16829   if (TARGET_SINGLE_STRINGOP || optimize_size)
16830     {
16831       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16832                                       operands[3]));
16833       DONE;
16834     }
16835 })
16836
16837 (define_expand "strset_singleop"
16838   [(parallel [(set (match_operand 1 "memory_operand" "")
16839                    (match_operand 2 "register_operand" ""))
16840               (set (match_operand 0 "register_operand" "")
16841                    (match_operand 3 "" ""))
16842               (use (reg:SI DIRFLAG_REG))])]
16843   "TARGET_SINGLE_STRINGOP || optimize_size"
16844   "")
16845
16846 (define_insn "*strsetdi_rex_1"
16847   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16848         (match_operand:DI 2 "register_operand" "a"))
16849    (set (match_operand:DI 0 "register_operand" "=D")
16850         (plus:DI (match_dup 1)
16851                  (const_int 8)))
16852    (use (reg:SI DIRFLAG_REG))]
16853   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16854   "stosq"
16855   [(set_attr "type" "str")
16856    (set_attr "memory" "store")
16857    (set_attr "mode" "DI")])
16858
16859 (define_insn "*strsetsi_1"
16860   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16861         (match_operand:SI 2 "register_operand" "a"))
16862    (set (match_operand:SI 0 "register_operand" "=D")
16863         (plus:SI (match_dup 1)
16864                  (const_int 4)))
16865    (use (reg:SI DIRFLAG_REG))]
16866   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867   "{stosl|stosd}"
16868   [(set_attr "type" "str")
16869    (set_attr "memory" "store")
16870    (set_attr "mode" "SI")])
16871
16872 (define_insn "*strsetsi_rex_1"
16873   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16874         (match_operand:SI 2 "register_operand" "a"))
16875    (set (match_operand:DI 0 "register_operand" "=D")
16876         (plus:DI (match_dup 1)
16877                  (const_int 4)))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880   "{stosl|stosd}"
16881   [(set_attr "type" "str")
16882    (set_attr "memory" "store")
16883    (set_attr "mode" "SI")])
16884
16885 (define_insn "*strsethi_1"
16886   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16887         (match_operand:HI 2 "register_operand" "a"))
16888    (set (match_operand:SI 0 "register_operand" "=D")
16889         (plus:SI (match_dup 1)
16890                  (const_int 2)))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893   "stosw"
16894   [(set_attr "type" "str")
16895    (set_attr "memory" "store")
16896    (set_attr "mode" "HI")])
16897
16898 (define_insn "*strsethi_rex_1"
16899   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16900         (match_operand:HI 2 "register_operand" "a"))
16901    (set (match_operand:DI 0 "register_operand" "=D")
16902         (plus:DI (match_dup 1)
16903                  (const_int 2)))
16904    (use (reg:SI DIRFLAG_REG))]
16905   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906   "stosw"
16907   [(set_attr "type" "str")
16908    (set_attr "memory" "store")
16909    (set_attr "mode" "HI")])
16910
16911 (define_insn "*strsetqi_1"
16912   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16913         (match_operand:QI 2 "register_operand" "a"))
16914    (set (match_operand:SI 0 "register_operand" "=D")
16915         (plus:SI (match_dup 1)
16916                  (const_int 1)))
16917    (use (reg:SI DIRFLAG_REG))]
16918   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919   "stosb"
16920   [(set_attr "type" "str")
16921    (set_attr "memory" "store")
16922    (set_attr "mode" "QI")])
16923
16924 (define_insn "*strsetqi_rex_1"
16925   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16926         (match_operand:QI 2 "register_operand" "a"))
16927    (set (match_operand:DI 0 "register_operand" "=D")
16928         (plus:DI (match_dup 1)
16929                  (const_int 1)))
16930    (use (reg:SI DIRFLAG_REG))]
16931   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932   "stosb"
16933   [(set_attr "type" "str")
16934    (set_attr "memory" "store")
16935    (set_attr "mode" "QI")])
16936
16937 (define_expand "rep_stos"
16938   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16939               (set (match_operand 0 "register_operand" "")
16940                    (match_operand 4 "" ""))
16941               (set (match_operand 2 "memory_operand" "") (const_int 0))
16942               (use (match_operand 3 "register_operand" ""))
16943               (use (match_dup 1))
16944               (use (reg:SI DIRFLAG_REG))])]
16945   ""
16946   "")
16947
16948 (define_insn "*rep_stosdi_rex64"
16949   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16950    (set (match_operand:DI 0 "register_operand" "=D") 
16951         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16952                             (const_int 3))
16953                  (match_operand:DI 3 "register_operand" "0")))
16954    (set (mem:BLK (match_dup 3))
16955         (const_int 0))
16956    (use (match_operand:DI 2 "register_operand" "a"))
16957    (use (match_dup 4))
16958    (use (reg:SI DIRFLAG_REG))]
16959   "TARGET_64BIT"
16960   "{rep\;stosq|rep stosq}"
16961   [(set_attr "type" "str")
16962    (set_attr "prefix_rep" "1")
16963    (set_attr "memory" "store")
16964    (set_attr "mode" "DI")])
16965
16966 (define_insn "*rep_stossi"
16967   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16968    (set (match_operand:SI 0 "register_operand" "=D") 
16969         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16970                             (const_int 2))
16971                  (match_operand:SI 3 "register_operand" "0")))
16972    (set (mem:BLK (match_dup 3))
16973         (const_int 0))
16974    (use (match_operand:SI 2 "register_operand" "a"))
16975    (use (match_dup 4))
16976    (use (reg:SI DIRFLAG_REG))]
16977   "!TARGET_64BIT"
16978   "{rep\;stosl|rep stosd}"
16979   [(set_attr "type" "str")
16980    (set_attr "prefix_rep" "1")
16981    (set_attr "memory" "store")
16982    (set_attr "mode" "SI")])
16983
16984 (define_insn "*rep_stossi_rex64"
16985   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16986    (set (match_operand:DI 0 "register_operand" "=D") 
16987         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16988                             (const_int 2))
16989                  (match_operand:DI 3 "register_operand" "0")))
16990    (set (mem:BLK (match_dup 3))
16991         (const_int 0))
16992    (use (match_operand:SI 2 "register_operand" "a"))
16993    (use (match_dup 4))
16994    (use (reg:SI DIRFLAG_REG))]
16995   "TARGET_64BIT"
16996   "{rep\;stosl|rep stosd}"
16997   [(set_attr "type" "str")
16998    (set_attr "prefix_rep" "1")
16999    (set_attr "memory" "store")
17000    (set_attr "mode" "SI")])
17001
17002 (define_insn "*rep_stosqi"
17003   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17004    (set (match_operand:SI 0 "register_operand" "=D") 
17005         (plus:SI (match_operand:SI 3 "register_operand" "0")
17006                  (match_operand:SI 4 "register_operand" "1")))
17007    (set (mem:BLK (match_dup 3))
17008         (const_int 0))
17009    (use (match_operand:QI 2 "register_operand" "a"))
17010    (use (match_dup 4))
17011    (use (reg:SI DIRFLAG_REG))]
17012   "!TARGET_64BIT"
17013   "{rep\;stosb|rep stosb}"
17014   [(set_attr "type" "str")
17015    (set_attr "prefix_rep" "1")
17016    (set_attr "memory" "store")
17017    (set_attr "mode" "QI")])
17018
17019 (define_insn "*rep_stosqi_rex64"
17020   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17021    (set (match_operand:DI 0 "register_operand" "=D") 
17022         (plus:DI (match_operand:DI 3 "register_operand" "0")
17023                  (match_operand:DI 4 "register_operand" "1")))
17024    (set (mem:BLK (match_dup 3))
17025         (const_int 0))
17026    (use (match_operand:QI 2 "register_operand" "a"))
17027    (use (match_dup 4))
17028    (use (reg:SI DIRFLAG_REG))]
17029   "TARGET_64BIT"
17030   "{rep\;stosb|rep stosb}"
17031   [(set_attr "type" "str")
17032    (set_attr "prefix_rep" "1")
17033    (set_attr "memory" "store")
17034    (set_attr "mode" "QI")])
17035
17036 (define_expand "cmpstrsi"
17037   [(set (match_operand:SI 0 "register_operand" "")
17038         (compare:SI (match_operand:BLK 1 "general_operand" "")
17039                     (match_operand:BLK 2 "general_operand" "")))
17040    (use (match_operand 3 "general_operand" ""))
17041    (use (match_operand 4 "immediate_operand" ""))]
17042   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17043 {
17044   rtx addr1, addr2, out, outlow, count, countreg, align;
17045
17046   /* Can't use this if the user has appropriated esi or edi.  */
17047   if (global_regs[4] || global_regs[5])
17048     FAIL;
17049
17050   out = operands[0];
17051   if (GET_CODE (out) != REG)
17052     out = gen_reg_rtx (SImode);
17053
17054   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17055   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17056   if (addr1 != XEXP (operands[1], 0))
17057     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17058   if (addr2 != XEXP (operands[2], 0))
17059     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17060
17061   count = operands[3];
17062   countreg = ix86_zero_extend_to_Pmode (count);
17063
17064   /* %%% Iff we are testing strict equality, we can use known alignment
17065      to good advantage.  This may be possible with combine, particularly
17066      once cc0 is dead.  */
17067   align = operands[4];
17068
17069   emit_insn (gen_cld ());
17070   if (GET_CODE (count) == CONST_INT)
17071     {
17072       if (INTVAL (count) == 0)
17073         {
17074           emit_move_insn (operands[0], const0_rtx);
17075           DONE;
17076         }
17077       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17078                                     operands[1], operands[2]));
17079     }
17080   else
17081     {
17082       if (TARGET_64BIT)
17083         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17084       else
17085         emit_insn (gen_cmpsi_1 (countreg, countreg));
17086       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17087                                  operands[1], operands[2]));
17088     }
17089
17090   outlow = gen_lowpart (QImode, out);
17091   emit_insn (gen_cmpintqi (outlow));
17092   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17093
17094   if (operands[0] != out)
17095     emit_move_insn (operands[0], out);
17096
17097   DONE;
17098 })
17099
17100 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17101
17102 (define_expand "cmpintqi"
17103   [(set (match_dup 1)
17104         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17105    (set (match_dup 2)
17106         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17107    (parallel [(set (match_operand:QI 0 "register_operand" "")
17108                    (minus:QI (match_dup 1)
17109                              (match_dup 2)))
17110               (clobber (reg:CC FLAGS_REG))])]
17111   ""
17112   "operands[1] = gen_reg_rtx (QImode);
17113    operands[2] = gen_reg_rtx (QImode);")
17114
17115 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17116 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17117
17118 (define_expand "cmpstrqi_nz_1"
17119   [(parallel [(set (reg:CC FLAGS_REG)
17120                    (compare:CC (match_operand 4 "memory_operand" "")
17121                                (match_operand 5 "memory_operand" "")))
17122               (use (match_operand 2 "register_operand" ""))
17123               (use (match_operand:SI 3 "immediate_operand" ""))
17124               (use (reg:SI DIRFLAG_REG))
17125               (clobber (match_operand 0 "register_operand" ""))
17126               (clobber (match_operand 1 "register_operand" ""))
17127               (clobber (match_dup 2))])]
17128   ""
17129   "")
17130
17131 (define_insn "*cmpstrqi_nz_1"
17132   [(set (reg:CC FLAGS_REG)
17133         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17134                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17135    (use (match_operand:SI 6 "register_operand" "2"))
17136    (use (match_operand:SI 3 "immediate_operand" "i"))
17137    (use (reg:SI DIRFLAG_REG))
17138    (clobber (match_operand:SI 0 "register_operand" "=S"))
17139    (clobber (match_operand:SI 1 "register_operand" "=D"))
17140    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17141   "!TARGET_64BIT"
17142   "repz{\;| }cmpsb"
17143   [(set_attr "type" "str")
17144    (set_attr "mode" "QI")
17145    (set_attr "prefix_rep" "1")])
17146
17147 (define_insn "*cmpstrqi_nz_rex_1"
17148   [(set (reg:CC FLAGS_REG)
17149         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17150                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17151    (use (match_operand:DI 6 "register_operand" "2"))
17152    (use (match_operand:SI 3 "immediate_operand" "i"))
17153    (use (reg:SI DIRFLAG_REG))
17154    (clobber (match_operand:DI 0 "register_operand" "=S"))
17155    (clobber (match_operand:DI 1 "register_operand" "=D"))
17156    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17157   "TARGET_64BIT"
17158   "repz{\;| }cmpsb"
17159   [(set_attr "type" "str")
17160    (set_attr "mode" "QI")
17161    (set_attr "prefix_rep" "1")])
17162
17163 ;; The same, but the count is not known to not be zero.
17164
17165 (define_expand "cmpstrqi_1"
17166   [(parallel [(set (reg:CC FLAGS_REG)
17167                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17168                                      (const_int 0))
17169                   (compare:CC (match_operand 4 "memory_operand" "")
17170                               (match_operand 5 "memory_operand" ""))
17171                   (const_int 0)))
17172               (use (match_operand:SI 3 "immediate_operand" ""))
17173               (use (reg:CC FLAGS_REG))
17174               (use (reg:SI DIRFLAG_REG))
17175               (clobber (match_operand 0 "register_operand" ""))
17176               (clobber (match_operand 1 "register_operand" ""))
17177               (clobber (match_dup 2))])]
17178   ""
17179   "")
17180
17181 (define_insn "*cmpstrqi_1"
17182   [(set (reg:CC FLAGS_REG)
17183         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17184                              (const_int 0))
17185           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17186                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17187           (const_int 0)))
17188    (use (match_operand:SI 3 "immediate_operand" "i"))
17189    (use (reg:CC FLAGS_REG))
17190    (use (reg:SI DIRFLAG_REG))
17191    (clobber (match_operand:SI 0 "register_operand" "=S"))
17192    (clobber (match_operand:SI 1 "register_operand" "=D"))
17193    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17194   "!TARGET_64BIT"
17195   "repz{\;| }cmpsb"
17196   [(set_attr "type" "str")
17197    (set_attr "mode" "QI")
17198    (set_attr "prefix_rep" "1")])
17199
17200 (define_insn "*cmpstrqi_rex_1"
17201   [(set (reg:CC FLAGS_REG)
17202         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17203                              (const_int 0))
17204           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17205                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17206           (const_int 0)))
17207    (use (match_operand:SI 3 "immediate_operand" "i"))
17208    (use (reg:CC FLAGS_REG))
17209    (use (reg:SI DIRFLAG_REG))
17210    (clobber (match_operand:DI 0 "register_operand" "=S"))
17211    (clobber (match_operand:DI 1 "register_operand" "=D"))
17212    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17213   "TARGET_64BIT"
17214   "repz{\;| }cmpsb"
17215   [(set_attr "type" "str")
17216    (set_attr "mode" "QI")
17217    (set_attr "prefix_rep" "1")])
17218
17219 (define_expand "strlensi"
17220   [(set (match_operand:SI 0 "register_operand" "")
17221         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17222                     (match_operand:QI 2 "immediate_operand" "")
17223                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17224   ""
17225 {
17226  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17227    DONE;
17228  else
17229    FAIL;
17230 })
17231
17232 (define_expand "strlendi"
17233   [(set (match_operand:DI 0 "register_operand" "")
17234         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17235                     (match_operand:QI 2 "immediate_operand" "")
17236                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17237   ""
17238 {
17239  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17240    DONE;
17241  else
17242    FAIL;
17243 })
17244
17245 (define_expand "strlenqi_1"
17246   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17247               (use (reg:SI DIRFLAG_REG))
17248               (clobber (match_operand 1 "register_operand" ""))
17249               (clobber (reg:CC FLAGS_REG))])]
17250   ""
17251   "")
17252
17253 (define_insn "*strlenqi_1"
17254   [(set (match_operand:SI 0 "register_operand" "=&c")
17255         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17256                     (match_operand:QI 2 "register_operand" "a")
17257                     (match_operand:SI 3 "immediate_operand" "i")
17258                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17259    (use (reg:SI DIRFLAG_REG))
17260    (clobber (match_operand:SI 1 "register_operand" "=D"))
17261    (clobber (reg:CC FLAGS_REG))]
17262   "!TARGET_64BIT"
17263   "repnz{\;| }scasb"
17264   [(set_attr "type" "str")
17265    (set_attr "mode" "QI")
17266    (set_attr "prefix_rep" "1")])
17267
17268 (define_insn "*strlenqi_rex_1"
17269   [(set (match_operand:DI 0 "register_operand" "=&c")
17270         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17271                     (match_operand:QI 2 "register_operand" "a")
17272                     (match_operand:DI 3 "immediate_operand" "i")
17273                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17274    (use (reg:SI DIRFLAG_REG))
17275    (clobber (match_operand:DI 1 "register_operand" "=D"))
17276    (clobber (reg:CC FLAGS_REG))]
17277   "TARGET_64BIT"
17278   "repnz{\;| }scasb"
17279   [(set_attr "type" "str")
17280    (set_attr "mode" "QI")
17281    (set_attr "prefix_rep" "1")])
17282
17283 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17284 ;; handled in combine, but it is not currently up to the task.
17285 ;; When used for their truth value, the cmpstr* expanders generate
17286 ;; code like this:
17287 ;;
17288 ;;   repz cmpsb
17289 ;;   seta       %al
17290 ;;   setb       %dl
17291 ;;   cmpb       %al, %dl
17292 ;;   jcc        label
17293 ;;
17294 ;; The intermediate three instructions are unnecessary.
17295
17296 ;; This one handles cmpstr*_nz_1...
17297 (define_peephole2
17298   [(parallel[
17299      (set (reg:CC FLAGS_REG)
17300           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17301                       (mem:BLK (match_operand 5 "register_operand" ""))))
17302      (use (match_operand 6 "register_operand" ""))
17303      (use (match_operand:SI 3 "immediate_operand" ""))
17304      (use (reg:SI DIRFLAG_REG))
17305      (clobber (match_operand 0 "register_operand" ""))
17306      (clobber (match_operand 1 "register_operand" ""))
17307      (clobber (match_operand 2 "register_operand" ""))])
17308    (set (match_operand:QI 7 "register_operand" "")
17309         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17310    (set (match_operand:QI 8 "register_operand" "")
17311         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17312    (set (reg FLAGS_REG)
17313         (compare (match_dup 7) (match_dup 8)))
17314   ]
17315   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17316   [(parallel[
17317      (set (reg:CC FLAGS_REG)
17318           (compare:CC (mem:BLK (match_dup 4))
17319                       (mem:BLK (match_dup 5))))
17320      (use (match_dup 6))
17321      (use (match_dup 3))
17322      (use (reg:SI DIRFLAG_REG))
17323      (clobber (match_dup 0))
17324      (clobber (match_dup 1))
17325      (clobber (match_dup 2))])]
17326   "")
17327
17328 ;; ...and this one handles cmpstr*_1.
17329 (define_peephole2
17330   [(parallel[
17331      (set (reg:CC FLAGS_REG)
17332           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17333                                (const_int 0))
17334             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17335                         (mem:BLK (match_operand 5 "register_operand" "")))
17336             (const_int 0)))
17337      (use (match_operand:SI 3 "immediate_operand" ""))
17338      (use (reg:CC FLAGS_REG))
17339      (use (reg:SI DIRFLAG_REG))
17340      (clobber (match_operand 0 "register_operand" ""))
17341      (clobber (match_operand 1 "register_operand" ""))
17342      (clobber (match_operand 2 "register_operand" ""))])
17343    (set (match_operand:QI 7 "register_operand" "")
17344         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17345    (set (match_operand:QI 8 "register_operand" "")
17346         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17347    (set (reg FLAGS_REG)
17348         (compare (match_dup 7) (match_dup 8)))
17349   ]
17350   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17351   [(parallel[
17352      (set (reg:CC FLAGS_REG)
17353           (if_then_else:CC (ne (match_dup 6)
17354                                (const_int 0))
17355             (compare:CC (mem:BLK (match_dup 4))
17356                         (mem:BLK (match_dup 5)))
17357             (const_int 0)))
17358      (use (match_dup 3))
17359      (use (reg:CC FLAGS_REG))
17360      (use (reg:SI DIRFLAG_REG))
17361      (clobber (match_dup 0))
17362      (clobber (match_dup 1))
17363      (clobber (match_dup 2))])]
17364   "")
17365
17366
17367 \f
17368 ;; Conditional move instructions.
17369
17370 (define_expand "movdicc"
17371   [(set (match_operand:DI 0 "register_operand" "")
17372         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17373                          (match_operand:DI 2 "general_operand" "")
17374                          (match_operand:DI 3 "general_operand" "")))]
17375   "TARGET_64BIT"
17376   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17377
17378 (define_insn "x86_movdicc_0_m1_rex64"
17379   [(set (match_operand:DI 0 "register_operand" "=r")
17380         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17381           (const_int -1)
17382           (const_int 0)))
17383    (clobber (reg:CC FLAGS_REG))]
17384   "TARGET_64BIT"
17385   "sbb{q}\t%0, %0"
17386   ; Since we don't have the proper number of operands for an alu insn,
17387   ; fill in all the blanks.
17388   [(set_attr "type" "alu")
17389    (set_attr "pent_pair" "pu")
17390    (set_attr "memory" "none")
17391    (set_attr "imm_disp" "false")
17392    (set_attr "mode" "DI")
17393    (set_attr "length_immediate" "0")])
17394
17395 (define_insn "movdicc_c_rex64"
17396   [(set (match_operand:DI 0 "register_operand" "=r,r")
17397         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17398                                 [(reg FLAGS_REG) (const_int 0)])
17399                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17400                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17401   "TARGET_64BIT && TARGET_CMOVE
17402    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17403   "@
17404    cmov%O2%C1\t{%2, %0|%0, %2}
17405    cmov%O2%c1\t{%3, %0|%0, %3}"
17406   [(set_attr "type" "icmov")
17407    (set_attr "mode" "DI")])
17408
17409 (define_expand "movsicc"
17410   [(set (match_operand:SI 0 "register_operand" "")
17411         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17412                          (match_operand:SI 2 "general_operand" "")
17413                          (match_operand:SI 3 "general_operand" "")))]
17414   ""
17415   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17416
17417 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17418 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17419 ;; So just document what we're doing explicitly.
17420
17421 (define_insn "x86_movsicc_0_m1"
17422   [(set (match_operand:SI 0 "register_operand" "=r")
17423         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17424           (const_int -1)
17425           (const_int 0)))
17426    (clobber (reg:CC FLAGS_REG))]
17427   ""
17428   "sbb{l}\t%0, %0"
17429   ; Since we don't have the proper number of operands for an alu insn,
17430   ; fill in all the blanks.
17431   [(set_attr "type" "alu")
17432    (set_attr "pent_pair" "pu")
17433    (set_attr "memory" "none")
17434    (set_attr "imm_disp" "false")
17435    (set_attr "mode" "SI")
17436    (set_attr "length_immediate" "0")])
17437
17438 (define_insn "*movsicc_noc"
17439   [(set (match_operand:SI 0 "register_operand" "=r,r")
17440         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17441                                 [(reg FLAGS_REG) (const_int 0)])
17442                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17443                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17444   "TARGET_CMOVE
17445    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17446   "@
17447    cmov%O2%C1\t{%2, %0|%0, %2}
17448    cmov%O2%c1\t{%3, %0|%0, %3}"
17449   [(set_attr "type" "icmov")
17450    (set_attr "mode" "SI")])
17451
17452 (define_expand "movhicc"
17453   [(set (match_operand:HI 0 "register_operand" "")
17454         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17455                          (match_operand:HI 2 "general_operand" "")
17456                          (match_operand:HI 3 "general_operand" "")))]
17457   "TARGET_HIMODE_MATH"
17458   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17459
17460 (define_insn "*movhicc_noc"
17461   [(set (match_operand:HI 0 "register_operand" "=r,r")
17462         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17463                                 [(reg FLAGS_REG) (const_int 0)])
17464                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17465                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17466   "TARGET_CMOVE
17467    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17468   "@
17469    cmov%O2%C1\t{%2, %0|%0, %2}
17470    cmov%O2%c1\t{%3, %0|%0, %3}"
17471   [(set_attr "type" "icmov")
17472    (set_attr "mode" "HI")])
17473
17474 (define_expand "movqicc"
17475   [(set (match_operand:QI 0 "register_operand" "")
17476         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17477                          (match_operand:QI 2 "general_operand" "")
17478                          (match_operand:QI 3 "general_operand" "")))]
17479   "TARGET_QIMODE_MATH"
17480   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17481
17482 (define_insn_and_split "*movqicc_noc"
17483   [(set (match_operand:QI 0 "register_operand" "=r,r")
17484         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17485                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17486                       (match_operand:QI 2 "register_operand" "r,0")
17487                       (match_operand:QI 3 "register_operand" "0,r")))]
17488   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17489   "#"
17490   "&& reload_completed"
17491   [(set (match_dup 0)
17492         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17493                       (match_dup 2)
17494                       (match_dup 3)))]
17495   "operands[0] = gen_lowpart (SImode, operands[0]);
17496    operands[2] = gen_lowpart (SImode, operands[2]);
17497    operands[3] = gen_lowpart (SImode, operands[3]);"
17498   [(set_attr "type" "icmov")
17499    (set_attr "mode" "SI")])
17500
17501 (define_expand "movsfcc"
17502   [(set (match_operand:SF 0 "register_operand" "")
17503         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17504                          (match_operand:SF 2 "register_operand" "")
17505                          (match_operand:SF 3 "register_operand" "")))]
17506   "TARGET_CMOVE"
17507   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17508
17509 (define_insn "*movsfcc_1"
17510   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17511         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17512                                 [(reg FLAGS_REG) (const_int 0)])
17513                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17514                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17515   "TARGET_CMOVE
17516    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17517   "@
17518    fcmov%F1\t{%2, %0|%0, %2}
17519    fcmov%f1\t{%3, %0|%0, %3}
17520    cmov%O2%C1\t{%2, %0|%0, %2}
17521    cmov%O2%c1\t{%3, %0|%0, %3}"
17522   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17523    (set_attr "mode" "SF,SF,SI,SI")])
17524
17525 (define_expand "movdfcc"
17526   [(set (match_operand:DF 0 "register_operand" "")
17527         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17528                          (match_operand:DF 2 "register_operand" "")
17529                          (match_operand:DF 3 "register_operand" "")))]
17530   "TARGET_CMOVE"
17531   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17532
17533 (define_insn "*movdfcc_1"
17534   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17535         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17536                                 [(reg FLAGS_REG) (const_int 0)])
17537                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17538                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17539   "!TARGET_64BIT && TARGET_CMOVE
17540    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17541   "@
17542    fcmov%F1\t{%2, %0|%0, %2}
17543    fcmov%f1\t{%3, %0|%0, %3}
17544    #
17545    #"
17546   [(set_attr "type" "fcmov,fcmov,multi,multi")
17547    (set_attr "mode" "DF")])
17548
17549 (define_insn "*movdfcc_1_rex64"
17550   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17551         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17552                                 [(reg FLAGS_REG) (const_int 0)])
17553                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17554                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17555   "TARGET_64BIT && TARGET_CMOVE
17556    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17557   "@
17558    fcmov%F1\t{%2, %0|%0, %2}
17559    fcmov%f1\t{%3, %0|%0, %3}
17560    cmov%O2%C1\t{%2, %0|%0, %2}
17561    cmov%O2%c1\t{%3, %0|%0, %3}"
17562   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17563    (set_attr "mode" "DF")])
17564
17565 (define_split
17566   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17567         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17568                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17569                       (match_operand:DF 2 "nonimmediate_operand" "")
17570                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17571   "!TARGET_64BIT && reload_completed"
17572   [(set (match_dup 2)
17573         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17574                       (match_dup 5)
17575                       (match_dup 7)))
17576    (set (match_dup 3)
17577         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17578                       (match_dup 6)
17579                       (match_dup 8)))]
17580   "split_di (operands+2, 1, operands+5, operands+6);
17581    split_di (operands+3, 1, operands+7, operands+8);
17582    split_di (operands, 1, operands+2, operands+3);")
17583
17584 (define_expand "movxfcc"
17585   [(set (match_operand:XF 0 "register_operand" "")
17586         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17587                          (match_operand:XF 2 "register_operand" "")
17588                          (match_operand:XF 3 "register_operand" "")))]
17589   "TARGET_CMOVE"
17590   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17591
17592 (define_insn "*movxfcc_1"
17593   [(set (match_operand:XF 0 "register_operand" "=f,f")
17594         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17595                                 [(reg FLAGS_REG) (const_int 0)])
17596                       (match_operand:XF 2 "register_operand" "f,0")
17597                       (match_operand:XF 3 "register_operand" "0,f")))]
17598   "TARGET_CMOVE"
17599   "@
17600    fcmov%F1\t{%2, %0|%0, %2}
17601    fcmov%f1\t{%3, %0|%0, %3}"
17602   [(set_attr "type" "fcmov")
17603    (set_attr "mode" "XF")])
17604
17605 (define_expand "minsf3"
17606   [(parallel [
17607      (set (match_operand:SF 0 "register_operand" "")
17608           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17609                                (match_operand:SF 2 "nonimmediate_operand" ""))
17610                            (match_dup 1)
17611                            (match_dup 2)))
17612      (clobber (reg:CC FLAGS_REG))])]
17613   "TARGET_SSE"
17614   "")
17615
17616 (define_insn "*minsf"
17617   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17618         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17619                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17620                          (match_dup 1)
17621                          (match_dup 2)))
17622    (clobber (reg:CC FLAGS_REG))]
17623   "TARGET_SSE && TARGET_IEEE_FP"
17624   "#")
17625
17626 (define_insn "*minsf_nonieee"
17627   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17628         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17629                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17630                          (match_dup 1)
17631                          (match_dup 2)))
17632    (clobber (reg:CC FLAGS_REG))]
17633   "TARGET_SSE && !TARGET_IEEE_FP
17634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17635   "#")
17636
17637 (define_split
17638   [(set (match_operand:SF 0 "register_operand" "")
17639         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17640                              (match_operand:SF 2 "nonimmediate_operand" ""))
17641                          (match_operand:SF 3 "register_operand" "")
17642                          (match_operand:SF 4 "nonimmediate_operand" "")))
17643    (clobber (reg:CC FLAGS_REG))]
17644   "SSE_REG_P (operands[0]) && reload_completed
17645    && ((operands_match_p (operands[1], operands[3])
17646         && operands_match_p (operands[2], operands[4]))
17647        || (operands_match_p (operands[1], operands[4])
17648            && operands_match_p (operands[2], operands[3])))"
17649   [(set (match_dup 0)
17650         (if_then_else:SF (lt (match_dup 1)
17651                              (match_dup 2))
17652                          (match_dup 1)
17653                          (match_dup 2)))])
17654
17655 ;; Conditional addition patterns
17656 (define_expand "addqicc"
17657   [(match_operand:QI 0 "register_operand" "")
17658    (match_operand 1 "comparison_operator" "")
17659    (match_operand:QI 2 "register_operand" "")
17660    (match_operand:QI 3 "const_int_operand" "")]
17661   ""
17662   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17663
17664 (define_expand "addhicc"
17665   [(match_operand:HI 0 "register_operand" "")
17666    (match_operand 1 "comparison_operator" "")
17667    (match_operand:HI 2 "register_operand" "")
17668    (match_operand:HI 3 "const_int_operand" "")]
17669   ""
17670   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17671
17672 (define_expand "addsicc"
17673   [(match_operand:SI 0 "register_operand" "")
17674    (match_operand 1 "comparison_operator" "")
17675    (match_operand:SI 2 "register_operand" "")
17676    (match_operand:SI 3 "const_int_operand" "")]
17677   ""
17678   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17679
17680 (define_expand "adddicc"
17681   [(match_operand:DI 0 "register_operand" "")
17682    (match_operand 1 "comparison_operator" "")
17683    (match_operand:DI 2 "register_operand" "")
17684    (match_operand:DI 3 "const_int_operand" "")]
17685   "TARGET_64BIT"
17686   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17687
17688 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17689
17690 (define_split
17691   [(set (match_operand:SF 0 "fp_register_operand" "")
17692         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17693                              (match_operand:SF 2 "register_operand" ""))
17694                          (match_operand:SF 3 "register_operand" "")
17695                          (match_operand:SF 4 "register_operand" "")))
17696    (clobber (reg:CC FLAGS_REG))]
17697   "reload_completed
17698    && ((operands_match_p (operands[1], operands[3])
17699         && operands_match_p (operands[2], operands[4]))
17700        || (operands_match_p (operands[1], operands[4])
17701            && operands_match_p (operands[2], operands[3])))"
17702   [(set (reg:CCFP FLAGS_REG)
17703         (compare:CCFP (match_dup 2)
17704                       (match_dup 1)))
17705    (set (match_dup 0)
17706         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17707                          (match_dup 1)
17708                          (match_dup 2)))])
17709
17710 (define_insn "*minsf_sse"
17711   [(set (match_operand:SF 0 "register_operand" "=x")
17712         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17713                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17714                          (match_dup 1)
17715                          (match_dup 2)))]
17716   "TARGET_SSE && reload_completed"
17717   "minss\t{%2, %0|%0, %2}"
17718   [(set_attr "type" "sse")
17719    (set_attr "mode" "SF")])
17720
17721 (define_expand "mindf3"
17722   [(parallel [
17723      (set (match_operand:DF 0 "register_operand" "")
17724           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17725                                (match_operand:DF 2 "nonimmediate_operand" ""))
17726                            (match_dup 1)
17727                            (match_dup 2)))
17728      (clobber (reg:CC FLAGS_REG))])]
17729   "TARGET_SSE2 && TARGET_SSE_MATH"
17730   "#")
17731
17732 (define_insn "*mindf"
17733   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17734         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17735                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17736                          (match_dup 1)
17737                          (match_dup 2)))
17738    (clobber (reg:CC FLAGS_REG))]
17739   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17740   "#")
17741
17742 (define_insn "*mindf_nonieee"
17743   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17744         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17745                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17746                          (match_dup 1)
17747                          (match_dup 2)))
17748    (clobber (reg:CC FLAGS_REG))]
17749   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17751   "#")
17752
17753 (define_split
17754   [(set (match_operand:DF 0 "register_operand" "")
17755         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17756                              (match_operand:DF 2 "nonimmediate_operand" ""))
17757                          (match_operand:DF 3 "register_operand" "")
17758                          (match_operand:DF 4 "nonimmediate_operand" "")))
17759    (clobber (reg:CC FLAGS_REG))]
17760   "SSE_REG_P (operands[0]) && reload_completed
17761    && ((operands_match_p (operands[1], operands[3])
17762         && operands_match_p (operands[2], operands[4]))
17763        || (operands_match_p (operands[1], operands[4])
17764            && operands_match_p (operands[2], operands[3])))"
17765   [(set (match_dup 0)
17766         (if_then_else:DF (lt (match_dup 1)
17767                              (match_dup 2))
17768                          (match_dup 1)
17769                          (match_dup 2)))])
17770
17771 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17772 (define_split
17773   [(set (match_operand:DF 0 "fp_register_operand" "")
17774         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17775                              (match_operand:DF 2 "register_operand" ""))
17776                          (match_operand:DF 3 "register_operand" "")
17777                          (match_operand:DF 4 "register_operand" "")))
17778    (clobber (reg:CC FLAGS_REG))]
17779   "reload_completed
17780    && ((operands_match_p (operands[1], operands[3])
17781         && operands_match_p (operands[2], operands[4]))
17782        || (operands_match_p (operands[1], operands[4])
17783            && operands_match_p (operands[2], operands[3])))"
17784   [(set (reg:CCFP FLAGS_REG)
17785         (compare:CCFP (match_dup 2)
17786                       (match_dup 1)))
17787    (set (match_dup 0)
17788         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17789                          (match_dup 1)
17790                          (match_dup 2)))])
17791
17792 (define_insn "*mindf_sse"
17793   [(set (match_operand:DF 0 "register_operand" "=Y")
17794         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17795                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17796                          (match_dup 1)
17797                          (match_dup 2)))]
17798   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17799   "minsd\t{%2, %0|%0, %2}"
17800   [(set_attr "type" "sse")
17801    (set_attr "mode" "DF")])
17802
17803 (define_expand "maxsf3"
17804   [(parallel [
17805      (set (match_operand:SF 0 "register_operand" "")
17806           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17807                                (match_operand:SF 2 "nonimmediate_operand" ""))
17808                            (match_dup 1)
17809                            (match_dup 2)))
17810      (clobber (reg:CC FLAGS_REG))])]
17811   "TARGET_SSE"
17812   "#")
17813
17814 (define_insn "*maxsf"
17815   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17816         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17817                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17818                          (match_dup 1)
17819                          (match_dup 2)))
17820    (clobber (reg:CC FLAGS_REG))]
17821   "TARGET_SSE && TARGET_IEEE_FP"
17822   "#")
17823
17824 (define_insn "*maxsf_nonieee"
17825   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17826         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17827                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17828                          (match_dup 1)
17829                          (match_dup 2)))
17830    (clobber (reg:CC FLAGS_REG))]
17831   "TARGET_SSE && !TARGET_IEEE_FP
17832    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17833   "#")
17834
17835 (define_split
17836   [(set (match_operand:SF 0 "register_operand" "")
17837         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17838                              (match_operand:SF 2 "nonimmediate_operand" ""))
17839                          (match_operand:SF 3 "register_operand" "")
17840                          (match_operand:SF 4 "nonimmediate_operand" "")))
17841    (clobber (reg:CC FLAGS_REG))]
17842   "SSE_REG_P (operands[0]) && reload_completed
17843    && ((operands_match_p (operands[1], operands[3])
17844         && operands_match_p (operands[2], operands[4]))
17845        || (operands_match_p (operands[1], operands[4])
17846            && operands_match_p (operands[2], operands[3])))"
17847   [(set (match_dup 0)
17848         (if_then_else:SF (gt (match_dup 1)
17849                              (match_dup 2))
17850                          (match_dup 1)
17851                          (match_dup 2)))])
17852
17853 (define_split
17854   [(set (match_operand:SF 0 "fp_register_operand" "")
17855         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17856                              (match_operand:SF 2 "register_operand" ""))
17857                          (match_operand:SF 3 "register_operand" "")
17858                          (match_operand:SF 4 "register_operand" "")))
17859    (clobber (reg:CC FLAGS_REG))]
17860   "reload_completed
17861    && ((operands_match_p (operands[1], operands[3])
17862         && operands_match_p (operands[2], operands[4]))
17863        || (operands_match_p (operands[1], operands[4])
17864            && operands_match_p (operands[2], operands[3])))"
17865   [(set (reg:CCFP FLAGS_REG)
17866         (compare:CCFP (match_dup 1)
17867                       (match_dup 2)))
17868    (set (match_dup 0)
17869         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17870                          (match_dup 1)
17871                          (match_dup 2)))])
17872
17873 (define_insn "*maxsf_sse"
17874   [(set (match_operand:SF 0 "register_operand" "=x")
17875         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17876                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17877                          (match_dup 1)
17878                          (match_dup 2)))]
17879   "TARGET_SSE && reload_completed"
17880   "maxss\t{%2, %0|%0, %2}"
17881   [(set_attr "type" "sse")
17882    (set_attr "mode" "SF")])
17883
17884 (define_expand "maxdf3"
17885   [(parallel [
17886      (set (match_operand:DF 0 "register_operand" "")
17887           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17888                                (match_operand:DF 2 "nonimmediate_operand" ""))
17889                            (match_dup 1)
17890                            (match_dup 2)))
17891      (clobber (reg:CC FLAGS_REG))])]
17892   "TARGET_SSE2 && TARGET_SSE_MATH"
17893   "#")
17894
17895 (define_insn "*maxdf"
17896   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17897         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17898                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17899                          (match_dup 1)
17900                          (match_dup 2)))
17901    (clobber (reg:CC FLAGS_REG))]
17902   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17903   "#")
17904
17905 (define_insn "*maxdf_nonieee"
17906   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17907         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17908                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17909                          (match_dup 1)
17910                          (match_dup 2)))
17911    (clobber (reg:CC FLAGS_REG))]
17912   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17914   "#")
17915
17916 (define_split
17917   [(set (match_operand:DF 0 "register_operand" "")
17918         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17919                              (match_operand:DF 2 "nonimmediate_operand" ""))
17920                          (match_operand:DF 3 "register_operand" "")
17921                          (match_operand:DF 4 "nonimmediate_operand" "")))
17922    (clobber (reg:CC FLAGS_REG))]
17923   "SSE_REG_P (operands[0]) && reload_completed
17924    && ((operands_match_p (operands[1], operands[3])
17925         && operands_match_p (operands[2], operands[4]))
17926        || (operands_match_p (operands[1], operands[4])
17927            && operands_match_p (operands[2], operands[3])))"
17928   [(set (match_dup 0)
17929         (if_then_else:DF (gt (match_dup 1)
17930                              (match_dup 2))
17931                          (match_dup 1)
17932                          (match_dup 2)))])
17933
17934 (define_split
17935   [(set (match_operand:DF 0 "fp_register_operand" "")
17936         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17937                              (match_operand:DF 2 "register_operand" ""))
17938                          (match_operand:DF 3 "register_operand" "")
17939                          (match_operand:DF 4 "register_operand" "")))
17940    (clobber (reg:CC FLAGS_REG))]
17941   "reload_completed
17942    && ((operands_match_p (operands[1], operands[3])
17943         && operands_match_p (operands[2], operands[4]))
17944        || (operands_match_p (operands[1], operands[4])
17945            && operands_match_p (operands[2], operands[3])))"
17946   [(set (reg:CCFP FLAGS_REG)
17947         (compare:CCFP (match_dup 1)
17948                       (match_dup 2)))
17949    (set (match_dup 0)
17950         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17951                          (match_dup 1)
17952                          (match_dup 2)))])
17953
17954 (define_insn "*maxdf_sse"
17955   [(set (match_operand:DF 0 "register_operand" "=Y")
17956         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17957                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17958                          (match_dup 1)
17959                          (match_dup 2)))]
17960   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17961   "maxsd\t{%2, %0|%0, %2}"
17962   [(set_attr "type" "sse")
17963    (set_attr "mode" "DF")])
17964 \f
17965 ;; Misc patterns (?)
17966
17967 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17968 ;; Otherwise there will be nothing to keep
17969 ;; 
17970 ;; [(set (reg ebp) (reg esp))]
17971 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17972 ;;  (clobber (eflags)]
17973 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17974 ;;
17975 ;; in proper program order.
17976 (define_insn "pro_epilogue_adjust_stack_1"
17977   [(set (match_operand:SI 0 "register_operand" "=r,r")
17978         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17979                  (match_operand:SI 2 "immediate_operand" "i,i")))
17980    (clobber (reg:CC FLAGS_REG))
17981    (clobber (mem:BLK (scratch)))]
17982   "!TARGET_64BIT"
17983 {
17984   switch (get_attr_type (insn))
17985     {
17986     case TYPE_IMOV:
17987       return "mov{l}\t{%1, %0|%0, %1}";
17988
17989     case TYPE_ALU:
17990       if (GET_CODE (operands[2]) == CONST_INT
17991           && (INTVAL (operands[2]) == 128
17992               || (INTVAL (operands[2]) < 0
17993                   && INTVAL (operands[2]) != -128)))
17994         {
17995           operands[2] = GEN_INT (-INTVAL (operands[2]));
17996           return "sub{l}\t{%2, %0|%0, %2}";
17997         }
17998       return "add{l}\t{%2, %0|%0, %2}";
17999
18000     case TYPE_LEA:
18001       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18002       return "lea{l}\t{%a2, %0|%0, %a2}";
18003
18004     default:
18005       abort ();
18006     }
18007 }
18008   [(set (attr "type")
18009         (cond [(eq_attr "alternative" "0")
18010                  (const_string "alu")
18011                (match_operand:SI 2 "const0_operand" "")
18012                  (const_string "imov")
18013               ]
18014               (const_string "lea")))
18015    (set_attr "mode" "SI")])
18016
18017 (define_insn "pro_epilogue_adjust_stack_rex64"
18018   [(set (match_operand:DI 0 "register_operand" "=r,r")
18019         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18020                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18021    (clobber (reg:CC FLAGS_REG))
18022    (clobber (mem:BLK (scratch)))]
18023   "TARGET_64BIT"
18024 {
18025   switch (get_attr_type (insn))
18026     {
18027     case TYPE_IMOV:
18028       return "mov{q}\t{%1, %0|%0, %1}";
18029
18030     case TYPE_ALU:
18031       if (GET_CODE (operands[2]) == CONST_INT
18032           /* Avoid overflows.  */
18033           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18034           && (INTVAL (operands[2]) == 128
18035               || (INTVAL (operands[2]) < 0
18036                   && INTVAL (operands[2]) != -128)))
18037         {
18038           operands[2] = GEN_INT (-INTVAL (operands[2]));
18039           return "sub{q}\t{%2, %0|%0, %2}";
18040         }
18041       return "add{q}\t{%2, %0|%0, %2}";
18042
18043     case TYPE_LEA:
18044       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18045       return "lea{q}\t{%a2, %0|%0, %a2}";
18046
18047     default:
18048       abort ();
18049     }
18050 }
18051   [(set (attr "type")
18052         (cond [(eq_attr "alternative" "0")
18053                  (const_string "alu")
18054                (match_operand:DI 2 "const0_operand" "")
18055                  (const_string "imov")
18056               ]
18057               (const_string "lea")))
18058    (set_attr "mode" "DI")])
18059
18060 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18061   [(set (match_operand:DI 0 "register_operand" "=r,r")
18062         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18063                  (match_operand:DI 3 "immediate_operand" "i,i")))
18064    (use (match_operand:DI 2 "register_operand" "r,r"))
18065    (clobber (reg:CC FLAGS_REG))
18066    (clobber (mem:BLK (scratch)))]
18067   "TARGET_64BIT"
18068 {
18069   switch (get_attr_type (insn))
18070     {
18071     case TYPE_ALU:
18072       return "add{q}\t{%2, %0|%0, %2}";
18073
18074     case TYPE_LEA:
18075       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18076       return "lea{q}\t{%a2, %0|%0, %a2}";
18077
18078     default:
18079       abort ();
18080     }
18081 }
18082   [(set_attr "type" "alu,lea")
18083    (set_attr "mode" "DI")])
18084
18085 ;; Placeholder for the conditional moves.  This one is split either to SSE
18086 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18087 ;; fact is that compares supported by the cmp??ss instructions are exactly
18088 ;; swapped of those supported by cmove sequence.
18089 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18090 ;; supported by i387 comparisons and we do need to emit two conditional moves
18091 ;; in tandem.
18092
18093 (define_insn "sse_movsfcc"
18094   [(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")
18095         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18096                         [(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")
18097                          (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")])
18098                       (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")
18099                       (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")))
18100    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18101    (clobber (reg:CC FLAGS_REG))]
18102   "TARGET_SSE
18103    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18104    /* Avoid combine from being smart and converting min/max
18105       instruction patterns into conditional moves.  */
18106    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18107         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18108        || !rtx_equal_p (operands[4], operands[2])
18109        || !rtx_equal_p (operands[5], operands[3]))
18110    && (!TARGET_IEEE_FP
18111        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18112   "#")
18113
18114 (define_insn "sse_movsfcc_eq"
18115   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18116         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18117                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18118                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18119                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18120    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18121    (clobber (reg:CC FLAGS_REG))]
18122   "TARGET_SSE
18123    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18124   "#")
18125
18126 (define_insn "sse_movdfcc"
18127   [(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")
18128         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18129                         [(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")
18130                          (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")])
18131                       (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")
18132                       (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")))
18133    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18134    (clobber (reg:CC FLAGS_REG))]
18135   "TARGET_SSE2
18136    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18137    /* Avoid combine from being smart and converting min/max
18138       instruction patterns into conditional moves.  */
18139    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18140         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18141        || !rtx_equal_p (operands[4], operands[2])
18142        || !rtx_equal_p (operands[5], operands[3]))
18143    && (!TARGET_IEEE_FP
18144        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18145   "#")
18146
18147 (define_insn "sse_movdfcc_eq"
18148   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18149         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18150                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18151                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18152                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18153    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18154    (clobber (reg:CC FLAGS_REG))]
18155   "TARGET_SSE
18156    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18157   "#")
18158
18159 ;; For non-sse moves just expand the usual cmove sequence.
18160 (define_split
18161   [(set (match_operand 0 "register_operand" "")
18162         (if_then_else (match_operator 1 "comparison_operator"
18163                         [(match_operand 4 "nonimmediate_operand" "")
18164                          (match_operand 5 "register_operand" "")])
18165                       (match_operand 2 "nonimmediate_operand" "")
18166                       (match_operand 3 "nonimmediate_operand" "")))
18167    (clobber (match_operand 6 "" ""))
18168    (clobber (reg:CC FLAGS_REG))]
18169   "!SSE_REG_P (operands[0]) && reload_completed
18170    && (GET_MODE (operands[0]) == SFmode
18171        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18172   [(const_int 0)]
18173 {
18174    ix86_compare_op0 = operands[5];
18175    ix86_compare_op1 = operands[4];
18176    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18177                                  VOIDmode, operands[5], operands[4]);
18178    ix86_expand_fp_movcc (operands);
18179    DONE;
18180 })
18181
18182 ;; Split SSE based conditional move into sequence:
18183 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18184 ;; and   op2, op0   -  zero op2 if comparison was false
18185 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18186 ;; or    op2, op0   -  get the nonzero one into the result.
18187 (define_split
18188   [(set (match_operand:SF 0 "register_operand" "")
18189         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18190                            [(match_operand:SF 4 "register_operand" "")
18191                             (match_operand:SF 5 "nonimmediate_operand" "")])
18192                          (match_operand:SF 2 "register_operand" "")
18193                          (match_operand:SF 3 "register_operand" "")))
18194    (clobber (match_operand 6 "" ""))
18195    (clobber (reg:CC FLAGS_REG))]
18196   "SSE_REG_P (operands[0]) && reload_completed"
18197   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18198    (set (match_dup 2) (and:V4SF (match_dup 2)
18199                                 (match_dup 8)))
18200    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18201                                           (match_dup 3)))
18202    (set (match_dup 0) (ior:V4SF (match_dup 6)
18203                                 (match_dup 7)))]
18204 {
18205   /* If op2 == op3, op3 would be clobbered before it is used.  */
18206   if (operands_match_p (operands[2], operands[3]))
18207     {
18208       emit_move_insn (operands[0], operands[2]);
18209       DONE;
18210     }
18211
18212   PUT_MODE (operands[1], GET_MODE (operands[0]));
18213   if (operands_match_p (operands[0], operands[4]))
18214     operands[6] = operands[4], operands[7] = operands[2];
18215   else
18216     operands[6] = operands[2], operands[7] = operands[4];
18217   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18218   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18219   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18220   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18221   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18222   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18223 })
18224
18225 (define_split
18226   [(set (match_operand:DF 0 "register_operand" "")
18227         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18228                            [(match_operand:DF 4 "register_operand" "")
18229                             (match_operand:DF 5 "nonimmediate_operand" "")])
18230                          (match_operand:DF 2 "register_operand" "")
18231                          (match_operand:DF 3 "register_operand" "")))
18232    (clobber (match_operand 6 "" ""))
18233    (clobber (reg:CC FLAGS_REG))]
18234   "SSE_REG_P (operands[0]) && reload_completed"
18235   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18236    (set (match_dup 2) (and:V2DF (match_dup 2)
18237                                 (match_dup 8)))
18238    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18239                                           (match_dup 3)))
18240    (set (match_dup 0) (ior:V2DF (match_dup 6)
18241                                 (match_dup 7)))]
18242 {
18243   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18244     {
18245       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18246       emit_insn (gen_sse2_unpcklpd (op, op, op));
18247       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18248       emit_insn (gen_sse2_unpcklpd (op, op, op));
18249     }
18250
18251   /* If op2 == op3, op3 would be clobbered before it is used.  */
18252   if (operands_match_p (operands[2], operands[3]))
18253     {
18254       emit_move_insn (operands[0], operands[2]);
18255       DONE;
18256     }
18257
18258   PUT_MODE (operands[1], GET_MODE (operands[0]));
18259   if (operands_match_p (operands[0], operands[4]))
18260     operands[6] = operands[4], operands[7] = operands[2];
18261   else
18262     operands[6] = operands[2], operands[7] = operands[4];
18263   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18264   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18265   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18266   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18267   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18268   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18269 })
18270
18271 ;; Special case of conditional move we can handle effectively.
18272 ;; Do not brother with the integer/floating point case, since these are
18273 ;; bot considerably slower, unlike in the generic case.
18274 (define_insn "*sse_movsfcc_const0_1"
18275   [(set (match_operand:SF 0 "register_operand" "=&x")
18276         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18277                         [(match_operand:SF 4 "register_operand" "0")
18278                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18279                       (match_operand:SF 2 "register_operand" "x")
18280                       (match_operand:SF 3 "const0_operand" "X")))]
18281   "TARGET_SSE"
18282   "#")
18283
18284 (define_insn "*sse_movsfcc_const0_2"
18285   [(set (match_operand:SF 0 "register_operand" "=&x")
18286         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18287                         [(match_operand:SF 4 "register_operand" "0")
18288                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18289                       (match_operand:SF 2 "const0_operand" "X")
18290                       (match_operand:SF 3 "register_operand" "x")))]
18291   "TARGET_SSE"
18292   "#")
18293
18294 (define_insn "*sse_movsfcc_const0_3"
18295   [(set (match_operand:SF 0 "register_operand" "=&x")
18296         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18297                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18298                          (match_operand:SF 5 "register_operand" "0")])
18299                       (match_operand:SF 2 "register_operand" "x")
18300                       (match_operand:SF 3 "const0_operand" "X")))]
18301   "TARGET_SSE"
18302   "#")
18303
18304 (define_insn "*sse_movsfcc_const0_4"
18305   [(set (match_operand:SF 0 "register_operand" "=&x")
18306         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18307                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18308                          (match_operand:SF 5 "register_operand" "0")])
18309                       (match_operand:SF 2 "const0_operand" "X")
18310                       (match_operand:SF 3 "register_operand" "x")))]
18311   "TARGET_SSE"
18312   "#")
18313
18314 (define_insn "*sse_movdfcc_const0_1"
18315   [(set (match_operand:DF 0 "register_operand" "=&Y")
18316         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18317                         [(match_operand:DF 4 "register_operand" "0")
18318                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18319                       (match_operand:DF 2 "register_operand" "Y")
18320                       (match_operand:DF 3 "const0_operand" "X")))]
18321   "TARGET_SSE2"
18322   "#")
18323
18324 (define_insn "*sse_movdfcc_const0_2"
18325   [(set (match_operand:DF 0 "register_operand" "=&Y")
18326         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18327                         [(match_operand:DF 4 "register_operand" "0")
18328                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18329                       (match_operand:DF 2 "const0_operand" "X")
18330                       (match_operand:DF 3 "register_operand" "Y")))]
18331   "TARGET_SSE2"
18332   "#")
18333
18334 (define_insn "*sse_movdfcc_const0_3"
18335   [(set (match_operand:DF 0 "register_operand" "=&Y")
18336         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18337                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18338                          (match_operand:DF 5 "register_operand" "0")])
18339                       (match_operand:DF 2 "register_operand" "Y")
18340                       (match_operand:DF 3 "const0_operand" "X")))]
18341   "TARGET_SSE2"
18342   "#")
18343
18344 (define_insn "*sse_movdfcc_const0_4"
18345   [(set (match_operand:DF 0 "register_operand" "=&Y")
18346         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18347                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18348                          (match_operand:DF 5 "register_operand" "0")])
18349                       (match_operand:DF 2 "const0_operand" "X")
18350                       (match_operand:DF 3 "register_operand" "Y")))]
18351   "TARGET_SSE2"
18352   "#")
18353
18354 (define_split
18355   [(set (match_operand:SF 0 "register_operand" "")
18356         (if_then_else:SF (match_operator 1 "comparison_operator"
18357                            [(match_operand:SF 4 "nonimmediate_operand" "")
18358                             (match_operand:SF 5 "nonimmediate_operand" "")])
18359                          (match_operand:SF 2 "nonmemory_operand" "")
18360                          (match_operand:SF 3 "nonmemory_operand" "")))]
18361   "SSE_REG_P (operands[0]) && reload_completed
18362    && (const0_operand (operands[2], GET_MODE (operands[0]))
18363        || const0_operand (operands[3], GET_MODE (operands[0])))"
18364   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18365    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18366 {
18367   PUT_MODE (operands[1], GET_MODE (operands[0]));
18368   if (!sse_comparison_operator (operands[1], VOIDmode)
18369       || !rtx_equal_p (operands[0], operands[4]))
18370     {
18371       rtx tmp = operands[5];
18372       operands[5] = operands[4];
18373       operands[4] = tmp;
18374       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18375     }
18376   if (!rtx_equal_p (operands[0], operands[4]))
18377     abort ();
18378   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18379   if (const0_operand (operands[2], GET_MODE (operands[2])))
18380     {
18381       operands[7] = operands[3];
18382       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18383     }
18384   else
18385     {
18386       operands[7] = operands[2];
18387       operands[6] = operands[8];
18388     }
18389   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18390 })
18391
18392 (define_split
18393   [(set (match_operand:DF 0 "register_operand" "")
18394         (if_then_else:DF (match_operator 1 "comparison_operator"
18395                            [(match_operand:DF 4 "nonimmediate_operand" "")
18396                             (match_operand:DF 5 "nonimmediate_operand" "")])
18397                          (match_operand:DF 2 "nonmemory_operand" "")
18398                          (match_operand:DF 3 "nonmemory_operand" "")))]
18399   "SSE_REG_P (operands[0]) && reload_completed
18400    && (const0_operand (operands[2], GET_MODE (operands[0]))
18401        || const0_operand (operands[3], GET_MODE (operands[0])))"
18402   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18403    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18404 {
18405   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18406     {
18407       if (REG_P (operands[2]))
18408         {
18409           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18410           emit_insn (gen_sse2_unpcklpd (op, op, op));
18411         }
18412       if (REG_P (operands[3]))
18413         {
18414           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18415           emit_insn (gen_sse2_unpcklpd (op, op, op));
18416         }
18417     }
18418   PUT_MODE (operands[1], GET_MODE (operands[0]));
18419   if (!sse_comparison_operator (operands[1], VOIDmode)
18420       || !rtx_equal_p (operands[0], operands[4]))
18421     {
18422       rtx tmp = operands[5];
18423       operands[5] = operands[4];
18424       operands[4] = tmp;
18425       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18426     }
18427   if (!rtx_equal_p (operands[0], operands[4]))
18428     abort ();
18429   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18430   if (const0_operand (operands[2], GET_MODE (operands[2])))
18431     {
18432       operands[7] = operands[3];
18433       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18434     }
18435   else
18436     {
18437       operands[7] = operands[2];
18438       operands[6] = operands[8];
18439     }
18440   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18441 })
18442
18443 (define_expand "allocate_stack_worker"
18444   [(match_operand:SI 0 "register_operand" "")]
18445   "TARGET_STACK_PROBE"
18446 {
18447   if (reload_completed)
18448     {
18449       if (TARGET_64BIT)
18450         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18451       else
18452         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18453     }
18454   else
18455     {
18456       if (TARGET_64BIT)
18457         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18458       else
18459         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18460     }
18461   DONE;
18462 })
18463
18464 (define_insn "allocate_stack_worker_1"
18465   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18466     UNSPECV_STACK_PROBE)
18467    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18468    (clobber (match_scratch:SI 1 "=0"))
18469    (clobber (reg:CC FLAGS_REG))]
18470   "!TARGET_64BIT && TARGET_STACK_PROBE"
18471   "call\t__alloca"
18472   [(set_attr "type" "multi")
18473    (set_attr "length" "5")])
18474
18475 (define_expand "allocate_stack_worker_postreload"
18476   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18477                                     UNSPECV_STACK_PROBE)
18478               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18479               (clobber (match_dup 0))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   ""
18482   "")
18483
18484 (define_insn "allocate_stack_worker_rex64"
18485   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18486     UNSPECV_STACK_PROBE)
18487    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18488    (clobber (match_scratch:DI 1 "=0"))
18489    (clobber (reg:CC FLAGS_REG))]
18490   "TARGET_64BIT && TARGET_STACK_PROBE"
18491   "call\t__alloca"
18492   [(set_attr "type" "multi")
18493    (set_attr "length" "5")])
18494
18495 (define_expand "allocate_stack_worker_rex64_postreload"
18496   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18497                                     UNSPECV_STACK_PROBE)
18498               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18499               (clobber (match_dup 0))
18500               (clobber (reg:CC FLAGS_REG))])]
18501   ""
18502   "")
18503
18504 (define_expand "allocate_stack"
18505   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18506                    (minus:SI (reg:SI SP_REG)
18507                              (match_operand:SI 1 "general_operand" "")))
18508               (clobber (reg:CC FLAGS_REG))])
18509    (parallel [(set (reg:SI SP_REG)
18510                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18511               (clobber (reg:CC FLAGS_REG))])]
18512   "TARGET_STACK_PROBE"
18513 {
18514 #ifdef CHECK_STACK_LIMIT
18515   if (GET_CODE (operands[1]) == CONST_INT
18516       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18517     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18518                            operands[1]));
18519   else 
18520 #endif
18521     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18522                                                             operands[1])));
18523
18524   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18525   DONE;
18526 })
18527
18528 (define_expand "builtin_setjmp_receiver"
18529   [(label_ref (match_operand 0 "" ""))]
18530   "!TARGET_64BIT && flag_pic"
18531 {
18532   emit_insn (gen_set_got (pic_offset_table_rtx));
18533   DONE;
18534 })
18535 \f
18536 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18537
18538 (define_split
18539   [(set (match_operand 0 "register_operand" "")
18540         (match_operator 3 "promotable_binary_operator"
18541            [(match_operand 1 "register_operand" "")
18542             (match_operand 2 "aligned_operand" "")]))
18543    (clobber (reg:CC FLAGS_REG))]
18544   "! TARGET_PARTIAL_REG_STALL && reload_completed
18545    && ((GET_MODE (operands[0]) == HImode 
18546         && ((!optimize_size && !TARGET_FAST_PREFIX)
18547             || GET_CODE (operands[2]) != CONST_INT
18548             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18549        || (GET_MODE (operands[0]) == QImode 
18550            && (TARGET_PROMOTE_QImode || optimize_size)))"
18551   [(parallel [(set (match_dup 0)
18552                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18553               (clobber (reg:CC FLAGS_REG))])]
18554   "operands[0] = gen_lowpart (SImode, operands[0]);
18555    operands[1] = gen_lowpart (SImode, operands[1]);
18556    if (GET_CODE (operands[3]) != ASHIFT)
18557      operands[2] = gen_lowpart (SImode, operands[2]);
18558    PUT_MODE (operands[3], SImode);")
18559
18560 ; Promote the QImode tests, as i386 has encoding of the AND
18561 ; instruction with 32-bit sign-extended immediate and thus the
18562 ; instruction size is unchanged, except in the %eax case for
18563 ; which it is increased by one byte, hence the ! optimize_size.
18564 (define_split
18565   [(set (match_operand 0 "flags_reg_operand" "")
18566         (match_operator 2 "compare_operator"
18567           [(and (match_operand 3 "aligned_operand" "")
18568                 (match_operand 4 "const_int_operand" ""))
18569            (const_int 0)]))
18570    (set (match_operand 1 "register_operand" "")
18571         (and (match_dup 3) (match_dup 4)))]
18572   "! TARGET_PARTIAL_REG_STALL && reload_completed
18573    /* Ensure that the operand will remain sign-extended immediate.  */
18574    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18575    && ! optimize_size
18576    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18577        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18578   [(parallel [(set (match_dup 0)
18579                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18580                                     (const_int 0)]))
18581               (set (match_dup 1)
18582                    (and:SI (match_dup 3) (match_dup 4)))])]
18583 {
18584   operands[4]
18585     = gen_int_mode (INTVAL (operands[4])
18586                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18587   operands[1] = gen_lowpart (SImode, operands[1]);
18588   operands[3] = gen_lowpart (SImode, operands[3]);
18589 })
18590
18591 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18592 ; the TEST instruction with 32-bit sign-extended immediate and thus
18593 ; the instruction size would at least double, which is not what we
18594 ; want even with ! optimize_size.
18595 (define_split
18596   [(set (match_operand 0 "flags_reg_operand" "")
18597         (match_operator 1 "compare_operator"
18598           [(and (match_operand:HI 2 "aligned_operand" "")
18599                 (match_operand:HI 3 "const_int_operand" ""))
18600            (const_int 0)]))]
18601   "! TARGET_PARTIAL_REG_STALL && reload_completed
18602    /* Ensure that the operand will remain sign-extended immediate.  */
18603    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18604    && ! TARGET_FAST_PREFIX
18605    && ! optimize_size"
18606   [(set (match_dup 0)
18607         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18608                          (const_int 0)]))]
18609 {
18610   operands[3]
18611     = gen_int_mode (INTVAL (operands[3])
18612                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18613   operands[2] = gen_lowpart (SImode, operands[2]);
18614 })
18615
18616 (define_split
18617   [(set (match_operand 0 "register_operand" "")
18618         (neg (match_operand 1 "register_operand" "")))
18619    (clobber (reg:CC FLAGS_REG))]
18620   "! TARGET_PARTIAL_REG_STALL && reload_completed
18621    && (GET_MODE (operands[0]) == HImode
18622        || (GET_MODE (operands[0]) == QImode 
18623            && (TARGET_PROMOTE_QImode || optimize_size)))"
18624   [(parallel [(set (match_dup 0)
18625                    (neg:SI (match_dup 1)))
18626               (clobber (reg:CC FLAGS_REG))])]
18627   "operands[0] = gen_lowpart (SImode, operands[0]);
18628    operands[1] = gen_lowpart (SImode, operands[1]);")
18629
18630 (define_split
18631   [(set (match_operand 0 "register_operand" "")
18632         (not (match_operand 1 "register_operand" "")))]
18633   "! TARGET_PARTIAL_REG_STALL && reload_completed
18634    && (GET_MODE (operands[0]) == HImode
18635        || (GET_MODE (operands[0]) == QImode 
18636            && (TARGET_PROMOTE_QImode || optimize_size)))"
18637   [(set (match_dup 0)
18638         (not:SI (match_dup 1)))]
18639   "operands[0] = gen_lowpart (SImode, operands[0]);
18640    operands[1] = gen_lowpart (SImode, operands[1]);")
18641
18642 (define_split 
18643   [(set (match_operand 0 "register_operand" "")
18644         (if_then_else (match_operator 1 "comparison_operator" 
18645                                 [(reg FLAGS_REG) (const_int 0)])
18646                       (match_operand 2 "register_operand" "")
18647                       (match_operand 3 "register_operand" "")))]
18648   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18649    && (GET_MODE (operands[0]) == HImode
18650        || (GET_MODE (operands[0]) == QImode 
18651            && (TARGET_PROMOTE_QImode || optimize_size)))"
18652   [(set (match_dup 0)
18653         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18654   "operands[0] = gen_lowpart (SImode, operands[0]);
18655    operands[2] = gen_lowpart (SImode, operands[2]);
18656    operands[3] = gen_lowpart (SImode, operands[3]);")
18657                         
18658 \f
18659 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18660 ;; transform a complex memory operation into two memory to register operations.
18661
18662 ;; Don't push memory operands
18663 (define_peephole2
18664   [(set (match_operand:SI 0 "push_operand" "")
18665         (match_operand:SI 1 "memory_operand" ""))
18666    (match_scratch:SI 2 "r")]
18667   "! optimize_size && ! TARGET_PUSH_MEMORY"
18668   [(set (match_dup 2) (match_dup 1))
18669    (set (match_dup 0) (match_dup 2))]
18670   "")
18671
18672 (define_peephole2
18673   [(set (match_operand:DI 0 "push_operand" "")
18674         (match_operand:DI 1 "memory_operand" ""))
18675    (match_scratch:DI 2 "r")]
18676   "! optimize_size && ! TARGET_PUSH_MEMORY"
18677   [(set (match_dup 2) (match_dup 1))
18678    (set (match_dup 0) (match_dup 2))]
18679   "")
18680
18681 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18682 ;; SImode pushes.
18683 (define_peephole2
18684   [(set (match_operand:SF 0 "push_operand" "")
18685         (match_operand:SF 1 "memory_operand" ""))
18686    (match_scratch:SF 2 "r")]
18687   "! optimize_size && ! TARGET_PUSH_MEMORY"
18688   [(set (match_dup 2) (match_dup 1))
18689    (set (match_dup 0) (match_dup 2))]
18690   "")
18691
18692 (define_peephole2
18693   [(set (match_operand:HI 0 "push_operand" "")
18694         (match_operand:HI 1 "memory_operand" ""))
18695    (match_scratch:HI 2 "r")]
18696   "! optimize_size && ! TARGET_PUSH_MEMORY"
18697   [(set (match_dup 2) (match_dup 1))
18698    (set (match_dup 0) (match_dup 2))]
18699   "")
18700
18701 (define_peephole2
18702   [(set (match_operand:QI 0 "push_operand" "")
18703         (match_operand:QI 1 "memory_operand" ""))
18704    (match_scratch:QI 2 "q")]
18705   "! optimize_size && ! TARGET_PUSH_MEMORY"
18706   [(set (match_dup 2) (match_dup 1))
18707    (set (match_dup 0) (match_dup 2))]
18708   "")
18709
18710 ;; Don't move an immediate directly to memory when the instruction
18711 ;; gets too big.
18712 (define_peephole2
18713   [(match_scratch:SI 1 "r")
18714    (set (match_operand:SI 0 "memory_operand" "")
18715         (const_int 0))]
18716   "! optimize_size
18717    && ! TARGET_USE_MOV0
18718    && TARGET_SPLIT_LONG_MOVES
18719    && get_attr_length (insn) >= ix86_cost->large_insn
18720    && peep2_regno_dead_p (0, FLAGS_REG)"
18721   [(parallel [(set (match_dup 1) (const_int 0))
18722               (clobber (reg:CC FLAGS_REG))])
18723    (set (match_dup 0) (match_dup 1))]
18724   "")
18725
18726 (define_peephole2
18727   [(match_scratch:HI 1 "r")
18728    (set (match_operand:HI 0 "memory_operand" "")
18729         (const_int 0))]
18730   "! optimize_size
18731    && ! TARGET_USE_MOV0
18732    && TARGET_SPLIT_LONG_MOVES
18733    && get_attr_length (insn) >= ix86_cost->large_insn
18734    && peep2_regno_dead_p (0, FLAGS_REG)"
18735   [(parallel [(set (match_dup 2) (const_int 0))
18736               (clobber (reg:CC FLAGS_REG))])
18737    (set (match_dup 0) (match_dup 1))]
18738   "operands[2] = gen_lowpart (SImode, operands[1]);")
18739
18740 (define_peephole2
18741   [(match_scratch:QI 1 "q")
18742    (set (match_operand:QI 0 "memory_operand" "")
18743         (const_int 0))]
18744   "! optimize_size
18745    && ! TARGET_USE_MOV0
18746    && TARGET_SPLIT_LONG_MOVES
18747    && get_attr_length (insn) >= ix86_cost->large_insn
18748    && peep2_regno_dead_p (0, FLAGS_REG)"
18749   [(parallel [(set (match_dup 2) (const_int 0))
18750               (clobber (reg:CC FLAGS_REG))])
18751    (set (match_dup 0) (match_dup 1))]
18752   "operands[2] = gen_lowpart (SImode, operands[1]);")
18753
18754 (define_peephole2
18755   [(match_scratch:SI 2 "r")
18756    (set (match_operand:SI 0 "memory_operand" "")
18757         (match_operand:SI 1 "immediate_operand" ""))]
18758   "! optimize_size
18759    && get_attr_length (insn) >= ix86_cost->large_insn
18760    && TARGET_SPLIT_LONG_MOVES"
18761   [(set (match_dup 2) (match_dup 1))
18762    (set (match_dup 0) (match_dup 2))]
18763   "")
18764
18765 (define_peephole2
18766   [(match_scratch:HI 2 "r")
18767    (set (match_operand:HI 0 "memory_operand" "")
18768         (match_operand:HI 1 "immediate_operand" ""))]
18769   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18770   && TARGET_SPLIT_LONG_MOVES"
18771   [(set (match_dup 2) (match_dup 1))
18772    (set (match_dup 0) (match_dup 2))]
18773   "")
18774
18775 (define_peephole2
18776   [(match_scratch:QI 2 "q")
18777    (set (match_operand:QI 0 "memory_operand" "")
18778         (match_operand:QI 1 "immediate_operand" ""))]
18779   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18780   && TARGET_SPLIT_LONG_MOVES"
18781   [(set (match_dup 2) (match_dup 1))
18782    (set (match_dup 0) (match_dup 2))]
18783   "")
18784
18785 ;; Don't compare memory with zero, load and use a test instead.
18786 (define_peephole2
18787   [(set (match_operand 0 "flags_reg_operand" "")
18788         (match_operator 1 "compare_operator"
18789           [(match_operand:SI 2 "memory_operand" "")
18790            (const_int 0)]))
18791    (match_scratch:SI 3 "r")]
18792   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18793   [(set (match_dup 3) (match_dup 2))
18794    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18795   "")
18796
18797 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18798 ;; Don't split NOTs with a displacement operand, because resulting XOR
18799 ;; will not be pairable anyway.
18800 ;;
18801 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18802 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18803 ;; so this split helps here as well.
18804 ;;
18805 ;; Note: Can't do this as a regular split because we can't get proper
18806 ;; lifetime information then.
18807
18808 (define_peephole2
18809   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18810         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18811   "!optimize_size
18812    && peep2_regno_dead_p (0, FLAGS_REG)
18813    && ((TARGET_PENTIUM 
18814         && (GET_CODE (operands[0]) != MEM
18815             || !memory_displacement_operand (operands[0], SImode)))
18816        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18817   [(parallel [(set (match_dup 0)
18818                    (xor:SI (match_dup 1) (const_int -1)))
18819               (clobber (reg:CC FLAGS_REG))])]
18820   "")
18821
18822 (define_peephole2
18823   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18824         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18825   "!optimize_size
18826    && peep2_regno_dead_p (0, FLAGS_REG)
18827    && ((TARGET_PENTIUM 
18828         && (GET_CODE (operands[0]) != MEM
18829             || !memory_displacement_operand (operands[0], HImode)))
18830        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18831   [(parallel [(set (match_dup 0)
18832                    (xor:HI (match_dup 1) (const_int -1)))
18833               (clobber (reg:CC FLAGS_REG))])]
18834   "")
18835
18836 (define_peephole2
18837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18838         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18839   "!optimize_size
18840    && peep2_regno_dead_p (0, FLAGS_REG)
18841    && ((TARGET_PENTIUM 
18842         && (GET_CODE (operands[0]) != MEM
18843             || !memory_displacement_operand (operands[0], QImode)))
18844        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18845   [(parallel [(set (match_dup 0)
18846                    (xor:QI (match_dup 1) (const_int -1)))
18847               (clobber (reg:CC FLAGS_REG))])]
18848   "")
18849
18850 ;; Non pairable "test imm, reg" instructions can be translated to
18851 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18852 ;; byte opcode instead of two, have a short form for byte operands),
18853 ;; so do it for other CPUs as well.  Given that the value was dead,
18854 ;; this should not create any new dependencies.  Pass on the sub-word
18855 ;; versions if we're concerned about partial register stalls.
18856
18857 (define_peephole2
18858   [(set (match_operand 0 "flags_reg_operand" "")
18859         (match_operator 1 "compare_operator"
18860           [(and:SI (match_operand:SI 2 "register_operand" "")
18861                    (match_operand:SI 3 "immediate_operand" ""))
18862            (const_int 0)]))]
18863   "ix86_match_ccmode (insn, CCNOmode)
18864    && (true_regnum (operands[2]) != 0
18865        || (GET_CODE (operands[3]) == CONST_INT
18866            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18867    && peep2_reg_dead_p (1, operands[2])"
18868   [(parallel
18869      [(set (match_dup 0)
18870            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18871                             (const_int 0)]))
18872       (set (match_dup 2)
18873            (and:SI (match_dup 2) (match_dup 3)))])]
18874   "")
18875
18876 ;; We don't need to handle HImode case, because it will be promoted to SImode
18877 ;; on ! TARGET_PARTIAL_REG_STALL
18878
18879 (define_peephole2
18880   [(set (match_operand 0 "flags_reg_operand" "")
18881         (match_operator 1 "compare_operator"
18882           [(and:QI (match_operand:QI 2 "register_operand" "")
18883                    (match_operand:QI 3 "immediate_operand" ""))
18884            (const_int 0)]))]
18885   "! TARGET_PARTIAL_REG_STALL
18886    && ix86_match_ccmode (insn, CCNOmode)
18887    && true_regnum (operands[2]) != 0
18888    && peep2_reg_dead_p (1, operands[2])"
18889   [(parallel
18890      [(set (match_dup 0)
18891            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18892                             (const_int 0)]))
18893       (set (match_dup 2)
18894            (and:QI (match_dup 2) (match_dup 3)))])]
18895   "")
18896
18897 (define_peephole2
18898   [(set (match_operand 0 "flags_reg_operand" "")
18899         (match_operator 1 "compare_operator"
18900           [(and:SI
18901              (zero_extract:SI
18902                (match_operand 2 "ext_register_operand" "")
18903                (const_int 8)
18904                (const_int 8))
18905              (match_operand 3 "const_int_operand" ""))
18906            (const_int 0)]))]
18907   "! TARGET_PARTIAL_REG_STALL
18908    && ix86_match_ccmode (insn, CCNOmode)
18909    && true_regnum (operands[2]) != 0
18910    && peep2_reg_dead_p (1, operands[2])"
18911   [(parallel [(set (match_dup 0)
18912                    (match_op_dup 1
18913                      [(and:SI
18914                         (zero_extract:SI
18915                           (match_dup 2)
18916                           (const_int 8)
18917                           (const_int 8))
18918                         (match_dup 3))
18919                       (const_int 0)]))
18920               (set (zero_extract:SI (match_dup 2)
18921                                     (const_int 8)
18922                                     (const_int 8))
18923                    (and:SI 
18924                      (zero_extract:SI
18925                        (match_dup 2)
18926                        (const_int 8)
18927                        (const_int 8))
18928                      (match_dup 3)))])]
18929   "")
18930
18931 ;; Don't do logical operations with memory inputs.
18932 (define_peephole2
18933   [(match_scratch:SI 2 "r")
18934    (parallel [(set (match_operand:SI 0 "register_operand" "")
18935                    (match_operator:SI 3 "arith_or_logical_operator"
18936                      [(match_dup 0)
18937                       (match_operand:SI 1 "memory_operand" "")]))
18938               (clobber (reg:CC FLAGS_REG))])]
18939   "! optimize_size && ! TARGET_READ_MODIFY"
18940   [(set (match_dup 2) (match_dup 1))
18941    (parallel [(set (match_dup 0)
18942                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18943               (clobber (reg:CC FLAGS_REG))])]
18944   "")
18945
18946 (define_peephole2
18947   [(match_scratch:SI 2 "r")
18948    (parallel [(set (match_operand:SI 0 "register_operand" "")
18949                    (match_operator:SI 3 "arith_or_logical_operator"
18950                      [(match_operand:SI 1 "memory_operand" "")
18951                       (match_dup 0)]))
18952               (clobber (reg:CC FLAGS_REG))])]
18953   "! optimize_size && ! TARGET_READ_MODIFY"
18954   [(set (match_dup 2) (match_dup 1))
18955    (parallel [(set (match_dup 0)
18956                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18957               (clobber (reg:CC FLAGS_REG))])]
18958   "")
18959
18960 ; Don't do logical operations with memory outputs
18961 ;
18962 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18963 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18964 ; the same decoder scheduling characteristics as the original.
18965
18966 (define_peephole2
18967   [(match_scratch:SI 2 "r")
18968    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18969                    (match_operator:SI 3 "arith_or_logical_operator"
18970                      [(match_dup 0)
18971                       (match_operand:SI 1 "nonmemory_operand" "")]))
18972               (clobber (reg:CC FLAGS_REG))])]
18973   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18974   [(set (match_dup 2) (match_dup 0))
18975    (parallel [(set (match_dup 2)
18976                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18977               (clobber (reg:CC FLAGS_REG))])
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18980
18981 (define_peephole2
18982   [(match_scratch:SI 2 "r")
18983    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18984                    (match_operator:SI 3 "arith_or_logical_operator"
18985                      [(match_operand:SI 1 "nonmemory_operand" "")
18986                       (match_dup 0)]))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18989   [(set (match_dup 2) (match_dup 0))
18990    (parallel [(set (match_dup 2)
18991                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18992               (clobber (reg:CC FLAGS_REG))])
18993    (set (match_dup 0) (match_dup 2))]
18994   "")
18995
18996 ;; Attempt to always use XOR for zeroing registers.
18997 (define_peephole2
18998   [(set (match_operand 0 "register_operand" "")
18999         (const_int 0))]
19000   "(GET_MODE (operands[0]) == QImode
19001     || GET_MODE (operands[0]) == HImode
19002     || GET_MODE (operands[0]) == SImode
19003     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19004    && (! TARGET_USE_MOV0 || optimize_size)
19005    && peep2_regno_dead_p (0, FLAGS_REG)"
19006   [(parallel [(set (match_dup 0) (const_int 0))
19007               (clobber (reg:CC FLAGS_REG))])]
19008   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19009                               operands[0]);")
19010
19011 (define_peephole2
19012   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19013         (const_int 0))]
19014   "(GET_MODE (operands[0]) == QImode
19015     || GET_MODE (operands[0]) == HImode)
19016    && (! TARGET_USE_MOV0 || optimize_size)
19017    && peep2_regno_dead_p (0, FLAGS_REG)"
19018   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19019               (clobber (reg:CC FLAGS_REG))])])
19020
19021 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19022 (define_peephole2
19023   [(set (match_operand 0 "register_operand" "")
19024         (const_int -1))]
19025   "(GET_MODE (operands[0]) == HImode
19026     || GET_MODE (operands[0]) == SImode 
19027     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19028    && (optimize_size || TARGET_PENTIUM)
19029    && peep2_regno_dead_p (0, FLAGS_REG)"
19030   [(parallel [(set (match_dup 0) (const_int -1))
19031               (clobber (reg:CC FLAGS_REG))])]
19032   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19033                               operands[0]);")
19034
19035 ;; Attempt to convert simple leas to adds. These can be created by
19036 ;; move expanders.
19037 (define_peephole2
19038   [(set (match_operand:SI 0 "register_operand" "")
19039         (plus:SI (match_dup 0)
19040                  (match_operand:SI 1 "nonmemory_operand" "")))]
19041   "peep2_regno_dead_p (0, FLAGS_REG)"
19042   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19043               (clobber (reg:CC FLAGS_REG))])]
19044   "")
19045
19046 (define_peephole2
19047   [(set (match_operand:SI 0 "register_operand" "")
19048         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19049                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19050   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19051   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19052               (clobber (reg:CC FLAGS_REG))])]
19053   "operands[2] = gen_lowpart (SImode, operands[2]);")
19054
19055 (define_peephole2
19056   [(set (match_operand:DI 0 "register_operand" "")
19057         (plus:DI (match_dup 0)
19058                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19059   "peep2_regno_dead_p (0, FLAGS_REG)"
19060   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19061               (clobber (reg:CC FLAGS_REG))])]
19062   "")
19063
19064 (define_peephole2
19065   [(set (match_operand:SI 0 "register_operand" "")
19066         (mult:SI (match_dup 0)
19067                  (match_operand:SI 1 "const_int_operand" "")))]
19068   "exact_log2 (INTVAL (operands[1])) >= 0
19069    && peep2_regno_dead_p (0, FLAGS_REG)"
19070   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19071               (clobber (reg:CC FLAGS_REG))])]
19072   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19073
19074 (define_peephole2
19075   [(set (match_operand:DI 0 "register_operand" "")
19076         (mult:DI (match_dup 0)
19077                  (match_operand:DI 1 "const_int_operand" "")))]
19078   "exact_log2 (INTVAL (operands[1])) >= 0
19079    && peep2_regno_dead_p (0, FLAGS_REG)"
19080   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19081               (clobber (reg:CC FLAGS_REG))])]
19082   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19083
19084 (define_peephole2
19085   [(set (match_operand:SI 0 "register_operand" "")
19086         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19087                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19088   "exact_log2 (INTVAL (operands[2])) >= 0
19089    && REGNO (operands[0]) == REGNO (operands[1])
19090    && peep2_regno_dead_p (0, FLAGS_REG)"
19091   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19092               (clobber (reg:CC FLAGS_REG))])]
19093   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19094
19095 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19096 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19097 ;; many CPUs it is also faster, since special hardware to avoid esp
19098 ;; dependencies is present.
19099
19100 ;; While some of these conversions may be done using splitters, we use peepholes
19101 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19102
19103 ;; Convert prologue esp subtractions to push.
19104 ;; We need register to push.  In order to keep verify_flow_info happy we have
19105 ;; two choices
19106 ;; - use scratch and clobber it in order to avoid dependencies
19107 ;; - use already live register
19108 ;; We can't use the second way right now, since there is no reliable way how to
19109 ;; verify that given register is live.  First choice will also most likely in
19110 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19111 ;; call clobbered registers are dead.  We may want to use base pointer as an
19112 ;; alternative when no register is available later.
19113
19114 (define_peephole2
19115   [(match_scratch:SI 0 "r")
19116    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19117               (clobber (reg:CC FLAGS_REG))
19118               (clobber (mem:BLK (scratch)))])]
19119   "optimize_size || !TARGET_SUB_ESP_4"
19120   [(clobber (match_dup 0))
19121    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19122               (clobber (mem:BLK (scratch)))])])
19123
19124 (define_peephole2
19125   [(match_scratch:SI 0 "r")
19126    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19127               (clobber (reg:CC FLAGS_REG))
19128               (clobber (mem:BLK (scratch)))])]
19129   "optimize_size || !TARGET_SUB_ESP_8"
19130   [(clobber (match_dup 0))
19131    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19132    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19133               (clobber (mem:BLK (scratch)))])])
19134
19135 ;; Convert esp subtractions to push.
19136 (define_peephole2
19137   [(match_scratch:SI 0 "r")
19138    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19139               (clobber (reg:CC FLAGS_REG))])]
19140   "optimize_size || !TARGET_SUB_ESP_4"
19141   [(clobber (match_dup 0))
19142    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19143
19144 (define_peephole2
19145   [(match_scratch:SI 0 "r")
19146    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19147               (clobber (reg:CC FLAGS_REG))])]
19148   "optimize_size || !TARGET_SUB_ESP_8"
19149   [(clobber (match_dup 0))
19150    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19151    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19152
19153 ;; Convert epilogue deallocator to pop.
19154 (define_peephole2
19155   [(match_scratch:SI 0 "r")
19156    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19157               (clobber (reg:CC FLAGS_REG))
19158               (clobber (mem:BLK (scratch)))])]
19159   "optimize_size || !TARGET_ADD_ESP_4"
19160   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19161               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19162               (clobber (mem:BLK (scratch)))])]
19163   "")
19164
19165 ;; Two pops case is tricky, since pop causes dependency on destination register.
19166 ;; We use two registers if available.
19167 (define_peephole2
19168   [(match_scratch:SI 0 "r")
19169    (match_scratch:SI 1 "r")
19170    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19171               (clobber (reg:CC FLAGS_REG))
19172               (clobber (mem:BLK (scratch)))])]
19173   "optimize_size || !TARGET_ADD_ESP_8"
19174   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19175               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19176               (clobber (mem:BLK (scratch)))])
19177    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19178               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19179   "")
19180
19181 (define_peephole2
19182   [(match_scratch:SI 0 "r")
19183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19184               (clobber (reg:CC FLAGS_REG))
19185               (clobber (mem:BLK (scratch)))])]
19186   "optimize_size"
19187   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19189               (clobber (mem:BLK (scratch)))])
19190    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19191               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19192   "")
19193
19194 ;; Convert esp additions to pop.
19195 (define_peephole2
19196   [(match_scratch:SI 0 "r")
19197    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19198               (clobber (reg:CC FLAGS_REG))])]
19199   ""
19200   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19201               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19202   "")
19203
19204 ;; Two pops case is tricky, since pop causes dependency on destination register.
19205 ;; We use two registers if available.
19206 (define_peephole2
19207   [(match_scratch:SI 0 "r")
19208    (match_scratch:SI 1 "r")
19209    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19210               (clobber (reg:CC FLAGS_REG))])]
19211   ""
19212   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19213               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19214    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19215               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19216   "")
19217
19218 (define_peephole2
19219   [(match_scratch:SI 0 "r")
19220    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19221               (clobber (reg:CC FLAGS_REG))])]
19222   "optimize_size"
19223   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19224               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19225    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19226               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19227   "")
19228 \f
19229 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19230 ;; required and register dies.  Similarly for 128 to plus -128.
19231 (define_peephole2
19232   [(set (match_operand 0 "flags_reg_operand" "")
19233         (match_operator 1 "compare_operator"
19234           [(match_operand 2 "register_operand" "")
19235            (match_operand 3 "const_int_operand" "")]))]
19236   "(INTVAL (operands[3]) == -1
19237     || INTVAL (operands[3]) == 1
19238     || INTVAL (operands[3]) == 128)
19239    && ix86_match_ccmode (insn, CCGCmode)
19240    && peep2_reg_dead_p (1, operands[2])"
19241   [(parallel [(set (match_dup 0)
19242                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19243               (clobber (match_dup 2))])]
19244   "")
19245 \f
19246 (define_peephole2
19247   [(match_scratch:DI 0 "r")
19248    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19249               (clobber (reg:CC FLAGS_REG))
19250               (clobber (mem:BLK (scratch)))])]
19251   "optimize_size || !TARGET_SUB_ESP_4"
19252   [(clobber (match_dup 0))
19253    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19254               (clobber (mem:BLK (scratch)))])])
19255
19256 (define_peephole2
19257   [(match_scratch:DI 0 "r")
19258    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19259               (clobber (reg:CC FLAGS_REG))
19260               (clobber (mem:BLK (scratch)))])]
19261   "optimize_size || !TARGET_SUB_ESP_8"
19262   [(clobber (match_dup 0))
19263    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19264    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19265               (clobber (mem:BLK (scratch)))])])
19266
19267 ;; Convert esp subtractions to push.
19268 (define_peephole2
19269   [(match_scratch:DI 0 "r")
19270    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19271               (clobber (reg:CC FLAGS_REG))])]
19272   "optimize_size || !TARGET_SUB_ESP_4"
19273   [(clobber (match_dup 0))
19274    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19275
19276 (define_peephole2
19277   [(match_scratch:DI 0 "r")
19278    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19279               (clobber (reg:CC FLAGS_REG))])]
19280   "optimize_size || !TARGET_SUB_ESP_8"
19281   [(clobber (match_dup 0))
19282    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19283    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19284
19285 ;; Convert epilogue deallocator to pop.
19286 (define_peephole2
19287   [(match_scratch:DI 0 "r")
19288    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19289               (clobber (reg:CC FLAGS_REG))
19290               (clobber (mem:BLK (scratch)))])]
19291   "optimize_size || !TARGET_ADD_ESP_4"
19292   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19293               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19294               (clobber (mem:BLK (scratch)))])]
19295   "")
19296
19297 ;; Two pops case is tricky, since pop causes dependency on destination register.
19298 ;; We use two registers if available.
19299 (define_peephole2
19300   [(match_scratch:DI 0 "r")
19301    (match_scratch:DI 1 "r")
19302    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19303               (clobber (reg:CC FLAGS_REG))
19304               (clobber (mem:BLK (scratch)))])]
19305   "optimize_size || !TARGET_ADD_ESP_8"
19306   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19307               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19308               (clobber (mem:BLK (scratch)))])
19309    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19310               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19311   "")
19312
19313 (define_peephole2
19314   [(match_scratch:DI 0 "r")
19315    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19316               (clobber (reg:CC FLAGS_REG))
19317               (clobber (mem:BLK (scratch)))])]
19318   "optimize_size"
19319   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19321               (clobber (mem:BLK (scratch)))])
19322    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19323               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19324   "")
19325
19326 ;; Convert esp additions to pop.
19327 (define_peephole2
19328   [(match_scratch:DI 0 "r")
19329    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19330               (clobber (reg:CC FLAGS_REG))])]
19331   ""
19332   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19334   "")
19335
19336 ;; Two pops case is tricky, since pop causes dependency on destination register.
19337 ;; We use two registers if available.
19338 (define_peephole2
19339   [(match_scratch:DI 0 "r")
19340    (match_scratch:DI 1 "r")
19341    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19342               (clobber (reg:CC FLAGS_REG))])]
19343   ""
19344   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19345               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19346    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19347               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19348   "")
19349
19350 (define_peephole2
19351   [(match_scratch:DI 0 "r")
19352    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19353               (clobber (reg:CC FLAGS_REG))])]
19354   "optimize_size"
19355   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19356               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19357    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19358               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19359   "")
19360 \f
19361 ;; Convert imul by three, five and nine into lea
19362 (define_peephole2
19363   [(parallel
19364     [(set (match_operand:SI 0 "register_operand" "")
19365           (mult:SI (match_operand:SI 1 "register_operand" "")
19366                    (match_operand:SI 2 "const_int_operand" "")))
19367      (clobber (reg:CC FLAGS_REG))])]
19368   "INTVAL (operands[2]) == 3
19369    || INTVAL (operands[2]) == 5
19370    || INTVAL (operands[2]) == 9"
19371   [(set (match_dup 0)
19372         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19373                  (match_dup 1)))]
19374   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19375
19376 (define_peephole2
19377   [(parallel
19378     [(set (match_operand:SI 0 "register_operand" "")
19379           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19380                    (match_operand:SI 2 "const_int_operand" "")))
19381      (clobber (reg:CC FLAGS_REG))])]
19382   "!optimize_size 
19383    && (INTVAL (operands[2]) == 3
19384        || INTVAL (operands[2]) == 5
19385        || INTVAL (operands[2]) == 9)"
19386   [(set (match_dup 0) (match_dup 1))
19387    (set (match_dup 0)
19388         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19389                  (match_dup 0)))]
19390   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19391
19392 (define_peephole2
19393   [(parallel
19394     [(set (match_operand:DI 0 "register_operand" "")
19395           (mult:DI (match_operand:DI 1 "register_operand" "")
19396                    (match_operand:DI 2 "const_int_operand" "")))
19397      (clobber (reg:CC FLAGS_REG))])]
19398   "TARGET_64BIT
19399    && (INTVAL (operands[2]) == 3
19400        || INTVAL (operands[2]) == 5
19401        || INTVAL (operands[2]) == 9)"
19402   [(set (match_dup 0)
19403         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19404                  (match_dup 1)))]
19405   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19406
19407 (define_peephole2
19408   [(parallel
19409     [(set (match_operand:DI 0 "register_operand" "")
19410           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19411                    (match_operand:DI 2 "const_int_operand" "")))
19412      (clobber (reg:CC FLAGS_REG))])]
19413   "TARGET_64BIT
19414    && !optimize_size 
19415    && (INTVAL (operands[2]) == 3
19416        || INTVAL (operands[2]) == 5
19417        || INTVAL (operands[2]) == 9)"
19418   [(set (match_dup 0) (match_dup 1))
19419    (set (match_dup 0)
19420         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19421                  (match_dup 0)))]
19422   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19423
19424 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19425 ;; imul $32bit_imm, reg, reg is direct decoded.
19426 (define_peephole2
19427   [(match_scratch:DI 3 "r")
19428    (parallel [(set (match_operand:DI 0 "register_operand" "")
19429                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19430                             (match_operand:DI 2 "immediate_operand" "")))
19431               (clobber (reg:CC FLAGS_REG))])]
19432   "TARGET_K8 && !optimize_size
19433    && (GET_CODE (operands[2]) != CONST_INT
19434        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19435   [(set (match_dup 3) (match_dup 1))
19436    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19437               (clobber (reg:CC FLAGS_REG))])]
19438 "")
19439
19440 (define_peephole2
19441   [(match_scratch:SI 3 "r")
19442    (parallel [(set (match_operand:SI 0 "register_operand" "")
19443                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19444                             (match_operand:SI 2 "immediate_operand" "")))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   "TARGET_K8 && !optimize_size
19447    && (GET_CODE (operands[2]) != CONST_INT
19448        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19449   [(set (match_dup 3) (match_dup 1))
19450    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19451               (clobber (reg:CC FLAGS_REG))])]
19452 "")
19453
19454 (define_peephole2
19455   [(match_scratch:SI 3 "r")
19456    (parallel [(set (match_operand:DI 0 "register_operand" "")
19457                    (zero_extend:DI
19458                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19459                               (match_operand:SI 2 "immediate_operand" ""))))
19460               (clobber (reg:CC FLAGS_REG))])]
19461   "TARGET_K8 && !optimize_size
19462    && (GET_CODE (operands[2]) != CONST_INT
19463        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19464   [(set (match_dup 3) (match_dup 1))
19465    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19466               (clobber (reg:CC FLAGS_REG))])]
19467 "")
19468
19469 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19470 ;; Convert it into imul reg, reg
19471 ;; It would be better to force assembler to encode instruction using long
19472 ;; immediate, but there is apparently no way to do so.
19473 (define_peephole2
19474   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19475                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19476                             (match_operand:DI 2 "const_int_operand" "")))
19477               (clobber (reg:CC FLAGS_REG))])
19478    (match_scratch:DI 3 "r")]
19479   "TARGET_K8 && !optimize_size
19480    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19481   [(set (match_dup 3) (match_dup 2))
19482    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19483               (clobber (reg:CC FLAGS_REG))])]
19484 {
19485   if (!rtx_equal_p (operands[0], operands[1]))
19486     emit_move_insn (operands[0], operands[1]);
19487 })
19488
19489 (define_peephole2
19490   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19491                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19492                             (match_operand:SI 2 "const_int_operand" "")))
19493               (clobber (reg:CC FLAGS_REG))])
19494    (match_scratch:SI 3 "r")]
19495   "TARGET_K8 && !optimize_size
19496    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19497   [(set (match_dup 3) (match_dup 2))
19498    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19499               (clobber (reg:CC FLAGS_REG))])]
19500 {
19501   if (!rtx_equal_p (operands[0], operands[1]))
19502     emit_move_insn (operands[0], operands[1]);
19503 })
19504
19505 (define_peephole2
19506   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19507                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19508                             (match_operand:HI 2 "immediate_operand" "")))
19509               (clobber (reg:CC FLAGS_REG))])
19510    (match_scratch:HI 3 "r")]
19511   "TARGET_K8 && !optimize_size"
19512   [(set (match_dup 3) (match_dup 2))
19513    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19514               (clobber (reg:CC FLAGS_REG))])]
19515 {
19516   if (!rtx_equal_p (operands[0], operands[1]))
19517     emit_move_insn (operands[0], operands[1]);
19518 })
19519 \f
19520 ;; Call-value patterns last so that the wildcard operand does not
19521 ;; disrupt insn-recog's switch tables.
19522
19523 (define_insn "*call_value_pop_0"
19524   [(set (match_operand 0 "" "")
19525         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19526               (match_operand:SI 2 "" "")))
19527    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19528                             (match_operand:SI 3 "immediate_operand" "")))]
19529   "!TARGET_64BIT"
19530 {
19531   if (SIBLING_CALL_P (insn))
19532     return "jmp\t%P1";
19533   else
19534     return "call\t%P1";
19535 }
19536   [(set_attr "type" "callv")])
19537
19538 (define_insn "*call_value_pop_1"
19539   [(set (match_operand 0 "" "")
19540         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19541               (match_operand:SI 2 "" "")))
19542    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19543                             (match_operand:SI 3 "immediate_operand" "i")))]
19544   "!TARGET_64BIT"
19545 {
19546   if (constant_call_address_operand (operands[1], Pmode))
19547     {
19548       if (SIBLING_CALL_P (insn))
19549         return "jmp\t%P1";
19550       else
19551         return "call\t%P1";
19552     }
19553   if (SIBLING_CALL_P (insn))
19554     return "jmp\t%A1";
19555   else
19556     return "call\t%A1";
19557 }
19558   [(set_attr "type" "callv")])
19559
19560 (define_insn "*call_value_0"
19561   [(set (match_operand 0 "" "")
19562         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19563               (match_operand:SI 2 "" "")))]
19564   "!TARGET_64BIT"
19565 {
19566   if (SIBLING_CALL_P (insn))
19567     return "jmp\t%P1";
19568   else
19569     return "call\t%P1";
19570 }
19571   [(set_attr "type" "callv")])
19572
19573 (define_insn "*call_value_0_rex64"
19574   [(set (match_operand 0 "" "")
19575         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19576               (match_operand:DI 2 "const_int_operand" "")))]
19577   "TARGET_64BIT"
19578 {
19579   if (SIBLING_CALL_P (insn))
19580     return "jmp\t%P1";
19581   else
19582     return "call\t%P1";
19583 }
19584   [(set_attr "type" "callv")])
19585
19586 (define_insn "*call_value_1"
19587   [(set (match_operand 0 "" "")
19588         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19589               (match_operand:SI 2 "" "")))]
19590   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19591 {
19592   if (constant_call_address_operand (operands[1], Pmode))
19593     return "call\t%P1";
19594   return "call\t%A1";
19595 }
19596   [(set_attr "type" "callv")])
19597
19598 (define_insn "*sibcall_value_1"
19599   [(set (match_operand 0 "" "")
19600         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19601               (match_operand:SI 2 "" "")))]
19602   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19603 {
19604   if (constant_call_address_operand (operands[1], Pmode))
19605     return "jmp\t%P1";
19606   return "jmp\t%A1";
19607 }
19608   [(set_attr "type" "callv")])
19609
19610 (define_insn "*call_value_1_rex64"
19611   [(set (match_operand 0 "" "")
19612         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19613               (match_operand:DI 2 "" "")))]
19614   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19615 {
19616   if (constant_call_address_operand (operands[1], Pmode))
19617     return "call\t%P1";
19618   return "call\t%A1";
19619 }
19620   [(set_attr "type" "callv")])
19621
19622 (define_insn "*sibcall_value_1_rex64"
19623   [(set (match_operand 0 "" "")
19624         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19625               (match_operand:DI 2 "" "")))]
19626   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19627   "jmp\t%P1"
19628   [(set_attr "type" "callv")])
19629
19630 (define_insn "*sibcall_value_1_rex64_v"
19631   [(set (match_operand 0 "" "")
19632         (call (mem:QI (reg:DI 40))
19633               (match_operand:DI 1 "" "")))]
19634   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19635   "jmp\t*%%r11"
19636   [(set_attr "type" "callv")])
19637 \f
19638 (define_insn "trap"
19639   [(trap_if (const_int 1) (const_int 5))]
19640   ""
19641   "int\t$5")
19642
19643 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19644 ;;; for the sake of bounds checking.  By emitting bounds checks as
19645 ;;; conditional traps rather than as conditional jumps around
19646 ;;; unconditional traps we avoid introducing spurious basic-block
19647 ;;; boundaries and facilitate elimination of redundant checks.  In
19648 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19649 ;;; interrupt 5.
19650 ;;; 
19651 ;;; FIXME: Static branch prediction rules for ix86 are such that
19652 ;;; forward conditional branches predict as untaken.  As implemented
19653 ;;; below, pseudo conditional traps violate that rule.  We should use
19654 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19655 ;;; section loaded at the end of the text segment and branch forward
19656 ;;; there on bounds-failure, and then jump back immediately (in case
19657 ;;; the system chooses to ignore bounds violations, or to report
19658 ;;; violations and continue execution).
19659
19660 (define_expand "conditional_trap"
19661   [(trap_if (match_operator 0 "comparison_operator"
19662              [(match_dup 2) (const_int 0)])
19663             (match_operand 1 "const_int_operand" ""))]
19664   ""
19665 {
19666   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19667                               ix86_expand_compare (GET_CODE (operands[0]),
19668                                                    NULL, NULL),
19669                               operands[1]));
19670   DONE;
19671 })
19672
19673 (define_insn "*conditional_trap_1"
19674   [(trap_if (match_operator 0 "comparison_operator"
19675              [(reg FLAGS_REG) (const_int 0)])
19676             (match_operand 1 "const_int_operand" ""))]
19677   ""
19678 {
19679   operands[2] = gen_label_rtx ();
19680   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19681   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19682                              CODE_LABEL_NUMBER (operands[2]));
19683   RET;
19684 })
19685
19686         ;; Pentium III SIMD instructions.
19687
19688 ;; Moves for SSE/MMX regs.
19689
19690 (define_expand "movv4sf"
19691   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19692         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19693   "TARGET_SSE"
19694 {
19695   ix86_expand_vector_move (V4SFmode, operands);
19696   DONE;
19697 })
19698
19699 (define_insn "*movv4sf_internal"
19700   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19701         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19702   "TARGET_SSE"
19703   "@
19704     xorps\t%0, %0
19705     movaps\t{%1, %0|%0, %1}
19706     movaps\t{%1, %0|%0, %1}"
19707   [(set_attr "type" "ssemov")
19708    (set_attr "mode" "V4SF")])
19709
19710 (define_split
19711   [(set (match_operand:V4SF 0 "register_operand" "")
19712         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19713   "TARGET_SSE && reload_completed"
19714   [(set (match_dup 0)
19715         (vec_merge:V4SF
19716          (vec_duplicate:V4SF (match_dup 1))
19717          (match_dup 2)
19718          (const_int 1)))]
19719 {
19720   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19721   operands[2] = CONST0_RTX (V4SFmode);
19722 })
19723
19724 (define_expand "movv2df"
19725   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19726         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19727   "TARGET_SSE"
19728 {
19729   ix86_expand_vector_move (V2DFmode, operands);
19730   DONE;
19731 })
19732
19733 (define_insn "*movv2df_internal"
19734   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19735         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19736   "TARGET_SSE
19737    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19738 {
19739   switch (which_alternative)
19740     {
19741     case 0:
19742       if (get_attr_mode (insn) == MODE_V4SF)
19743         return "xorps\t%0, %0";
19744       else
19745         return "xorpd\t%0, %0";
19746     case 1:
19747     case 2:
19748       if (get_attr_mode (insn) == MODE_V4SF)
19749         return "movaps\t{%1, %0|%0, %1}";
19750       else
19751         return "movapd\t{%1, %0|%0, %1}";
19752     default:
19753       abort ();
19754     }
19755 }
19756   [(set_attr "type" "ssemov")
19757    (set (attr "mode")
19758         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19759                  (const_string "V4SF")
19760                (eq_attr "alternative" "0,1")
19761                  (if_then_else
19762                    (ne (symbol_ref "optimize_size")
19763                        (const_int 0))
19764                    (const_string "V4SF")
19765                    (const_string "V2DF"))
19766                (eq_attr "alternative" "2")
19767                  (if_then_else
19768                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19769                             (const_int 0))
19770                         (ne (symbol_ref "optimize_size")
19771                             (const_int 0)))
19772                    (const_string "V4SF")
19773                    (const_string "V2DF"))]
19774                (const_string "V2DF")))])
19775
19776 (define_split
19777   [(set (match_operand:V2DF 0 "register_operand" "")
19778         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19779   "TARGET_SSE2 && reload_completed"
19780   [(set (match_dup 0)
19781         (vec_merge:V2DF
19782          (vec_duplicate:V2DF (match_dup 1))
19783          (match_dup 2)
19784          (const_int 1)))]
19785 {
19786   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19787   operands[2] = CONST0_RTX (V2DFmode);
19788 })
19789
19790 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19791 ;; special-cased for TARGET_64BIT.
19792 (define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
19793
19794 (define_expand "mov<mode>"
19795   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
19796         (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
19797   "TARGET_SSE"
19798 {
19799   ix86_expand_vector_move (<MODE>mode, operands);
19800   DONE;
19801 })
19802
19803 (define_insn "*mov<mode>_internal"
19804   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
19805         (match_operand:SSEMODEI 1 "vector_move_operand"  "C ,xm,x"))]
19806   "TARGET_SSE
19807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19808 {
19809   switch (which_alternative)
19810     {
19811     case 0:
19812       if (get_attr_mode (insn) == MODE_V4SF)
19813         return "xorps\t%0, %0";
19814       else
19815         return "pxor\t%0, %0";
19816     case 1:
19817     case 2:
19818       if (get_attr_mode (insn) == MODE_V4SF)
19819         return "movaps\t{%1, %0|%0, %1}";
19820       else
19821         return "movdqa\t{%1, %0|%0, %1}";
19822     default:
19823       abort ();
19824     }
19825 }
19826   [(set_attr "type" "ssemov")
19827    (set (attr "mode")
19828         (cond [(eq_attr "alternative" "0,1")
19829                  (if_then_else
19830                    (ne (symbol_ref "optimize_size")
19831                        (const_int 0))
19832                    (const_string "V4SF")
19833                    (const_string "TI"))
19834                (eq_attr "alternative" "2")
19835                  (if_then_else
19836                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19837                             (const_int 0))
19838                         (ne (symbol_ref "optimize_size")
19839                             (const_int 0)))
19840                    (const_string "V4SF")
19841                    (const_string "TI"))]
19842                (const_string "TI")))])
19843
19844 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19845 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
19846
19847 (define_expand "mov<mode>"
19848   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
19849         (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
19850   "TARGET_MMX"
19851 {
19852   ix86_expand_vector_move (<MODE>mode, operands);
19853   DONE;
19854 })
19855
19856 (define_insn "*mov<mode>_internal"
19857   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19858                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19859         (match_operand:MMXMODEI 1 "vector_move_operand"
19860                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19861   "TARGET_MMX
19862    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19863   "@
19864     pxor\t%0, %0
19865     movq\t{%1, %0|%0, %1}
19866     movq\t{%1, %0|%0, %1}
19867     movdq2q\t{%1, %0|%0, %1}
19868     movq2dq\t{%1, %0|%0, %1}
19869     pxor\t%0, %0
19870     movq\t{%1, %0|%0, %1}
19871     movq\t{%1, %0|%0, %1}"
19872   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19873    (set_attr "mode" "DI")])
19874
19875 (define_expand "movv2sf"
19876   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19877         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19878   "TARGET_MMX"
19879 {
19880   ix86_expand_vector_move (V2SFmode, operands);
19881   DONE;
19882 })
19883
19884 (define_insn "*movv2sf_internal"
19885   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19886                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19887         (match_operand:V2SF 1 "vector_move_operand"
19888                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19889   "TARGET_MMX
19890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19891   "@
19892     pxor\t%0, %0
19893     movq\t{%1, %0|%0, %1}
19894     movq\t{%1, %0|%0, %1}
19895     movdq2q\t{%1, %0|%0, %1}
19896     movq2dq\t{%1, %0|%0, %1}
19897     xorps\t%0, %0
19898     movlps\t{%1, %0|%0, %1}
19899     movlps\t{%1, %0|%0, %1}"
19900   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19901    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19902
19903 (define_expand "movti"
19904   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19905         (match_operand:TI 1 "nonimmediate_operand" ""))]
19906   "TARGET_SSE || TARGET_64BIT"
19907 {
19908   if (TARGET_64BIT)
19909     ix86_expand_move (TImode, operands);
19910   else
19911     ix86_expand_vector_move (TImode, operands);
19912   DONE;
19913 })
19914
19915 (define_insn "*movti_internal"
19916   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19917         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19918   "TARGET_SSE && !TARGET_64BIT
19919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19920 {
19921   switch (which_alternative)
19922     {
19923     case 0:
19924       if (get_attr_mode (insn) == MODE_V4SF)
19925         return "xorps\t%0, %0";
19926       else
19927         return "pxor\t%0, %0";
19928     case 1:
19929     case 2:
19930       if (get_attr_mode (insn) == MODE_V4SF)
19931         return "movaps\t{%1, %0|%0, %1}";
19932       else
19933         return "movdqa\t{%1, %0|%0, %1}";
19934     default:
19935       abort ();
19936     }
19937 }
19938   [(set_attr "type" "ssemov,ssemov,ssemov")
19939    (set (attr "mode")
19940         (cond [(eq_attr "alternative" "0,1")
19941                  (if_then_else
19942                    (ne (symbol_ref "optimize_size")
19943                        (const_int 0))
19944                    (const_string "V4SF")
19945                    (const_string "TI"))
19946                (eq_attr "alternative" "2")
19947                  (if_then_else
19948                    (ne (symbol_ref "optimize_size")
19949                        (const_int 0))
19950                    (const_string "V4SF")
19951                    (const_string "TI"))]
19952                (const_string "TI")))])
19953
19954 (define_insn "*movti_rex64"
19955   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19956         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19957   "TARGET_64BIT
19958    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19959 {
19960   switch (which_alternative)
19961     {
19962     case 0:
19963     case 1:
19964       return "#";
19965     case 2:
19966       if (get_attr_mode (insn) == MODE_V4SF)
19967         return "xorps\t%0, %0";
19968       else
19969         return "pxor\t%0, %0";
19970     case 3:
19971     case 4:
19972       if (get_attr_mode (insn) == MODE_V4SF)
19973         return "movaps\t{%1, %0|%0, %1}";
19974       else
19975         return "movdqa\t{%1, %0|%0, %1}";
19976     default:
19977       abort ();
19978     }
19979 }
19980   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19981    (set (attr "mode")
19982         (cond [(eq_attr "alternative" "2,3")
19983                  (if_then_else
19984                    (ne (symbol_ref "optimize_size")
19985                        (const_int 0))
19986                    (const_string "V4SF")
19987                    (const_string "TI"))
19988                (eq_attr "alternative" "4")
19989                  (if_then_else
19990                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19991                             (const_int 0))
19992                         (ne (symbol_ref "optimize_size")
19993                             (const_int 0)))
19994                    (const_string "V4SF")
19995                    (const_string "TI"))]
19996                (const_string "DI")))])
19997
19998 (define_expand "movtf"
19999   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20000         (match_operand:TF 1 "nonimmediate_operand" ""))]
20001   "TARGET_64BIT"
20002 {
20003   ix86_expand_move (TFmode, operands);
20004   DONE;
20005 })
20006
20007 (define_insn "*movtf_internal"
20008   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20009         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20010   "TARGET_64BIT
20011    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20012 {
20013   switch (which_alternative)
20014     {
20015     case 0:
20016     case 1:
20017       return "#";
20018     case 2:
20019       if (get_attr_mode (insn) == MODE_V4SF)
20020         return "xorps\t%0, %0";
20021       else
20022         return "pxor\t%0, %0";
20023     case 3:
20024     case 4:
20025       if (get_attr_mode (insn) == MODE_V4SF)
20026         return "movaps\t{%1, %0|%0, %1}";
20027       else
20028         return "movdqa\t{%1, %0|%0, %1}";
20029     default:
20030       abort ();
20031     }
20032 }
20033   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20034    (set (attr "mode")
20035         (cond [(eq_attr "alternative" "2,3")
20036                  (if_then_else
20037                    (ne (symbol_ref "optimize_size")
20038                        (const_int 0))
20039                    (const_string "V4SF")
20040                    (const_string "TI"))
20041                (eq_attr "alternative" "4")
20042                  (if_then_else
20043                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20044                             (const_int 0))
20045                         (ne (symbol_ref "optimize_size")
20046                             (const_int 0)))
20047                    (const_string "V4SF")
20048                    (const_string "TI"))]
20049                (const_string "DI")))])
20050
20051 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20052
20053 (define_insn "*push<mode>"
20054   [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20055         (match_operand:SSEPUSH 1 "register_operand" "x"))]
20056   "TARGET_SSE"
20057   "#")
20058
20059 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20060
20061 (define_insn "*push<mode>"
20062   [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20063         (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20064   "TARGET_MMX"
20065   "#")
20066
20067 (define_split
20068   [(set (match_operand 0 "push_operand" "")
20069         (match_operand 1 "register_operand" ""))]
20070   "!TARGET_64BIT && reload_completed
20071    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20072   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20073    (set (match_dup 2) (match_dup 1))]
20074   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20075                                  stack_pointer_rtx);
20076    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20077
20078 (define_split
20079   [(set (match_operand 0 "push_operand" "")
20080         (match_operand 1 "register_operand" ""))]
20081   "TARGET_64BIT && reload_completed
20082    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20083   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20084    (set (match_dup 2) (match_dup 1))]
20085   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20086                                  stack_pointer_rtx);
20087    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20088
20089
20090 (define_split
20091   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20092         (match_operand:TI 1 "general_operand" ""))]
20093   "reload_completed && !SSE_REG_P (operands[0])
20094    && !SSE_REG_P (operands[1])"
20095   [(const_int 0)]
20096   "ix86_split_long_move (operands); DONE;")
20097
20098 (define_split
20099   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20100         (match_operand:TF 1 "general_operand" ""))]
20101   "reload_completed && !SSE_REG_P (operands[0])
20102    && !SSE_REG_P (operands[1])"
20103   [(const_int 0)]
20104   "ix86_split_long_move (operands); DONE;")
20105
20106 ;; All 16-byte vector modes handled by SSE
20107 (define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
20108
20109 (define_expand "movmisalign<mode>"
20110   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
20111         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
20112   "TARGET_SSE"
20113 {
20114   ix86_expand_vector_move_misalign (<MODE>mode, operands);
20115   DONE;
20116 })
20117
20118 ;; All 8-byte vector modes handled by MMX
20119 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
20120
20121 (define_expand "movmisalign<mode>"
20122   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
20123         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
20124   "TARGET_MMX"
20125 {
20126   ix86_expand_vector_move (<MODE>mode, operands);
20127   DONE;
20128 })
20129
20130 ;; These two patterns are useful for specifying exactly whether to use
20131 ;; movaps or movups
20132 (define_expand "sse_movaps"
20133   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20134         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20135                      UNSPEC_MOVA))]
20136   "TARGET_SSE"
20137 {
20138   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20139     {
20140       rtx tmp = gen_reg_rtx (V4SFmode);
20141       emit_insn (gen_sse_movaps (tmp, operands[1]));
20142       emit_move_insn (operands[0], tmp);
20143       DONE;
20144     }
20145 })
20146
20147 (define_insn "*sse_movaps_1"
20148   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20149         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20150                      UNSPEC_MOVA))]
20151   "TARGET_SSE
20152    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20153   "movaps\t{%1, %0|%0, %1}"
20154   [(set_attr "type" "ssemov,ssemov")
20155    (set_attr "mode" "V4SF")])
20156
20157 (define_expand "sse_movups"
20158   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20159         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20160                      UNSPEC_MOVU))]
20161   "TARGET_SSE"
20162 {
20163   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20164     {
20165       rtx tmp = gen_reg_rtx (V4SFmode);
20166       emit_insn (gen_sse_movups (tmp, operands[1]));
20167       emit_move_insn (operands[0], tmp);
20168       DONE;
20169     }
20170 })
20171
20172 (define_insn "*sse_movups_1"
20173   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20174         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20175                      UNSPEC_MOVU))]
20176   "TARGET_SSE
20177    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20178   "movups\t{%1, %0|%0, %1}"
20179   [(set_attr "type" "ssecvt,ssecvt")
20180    (set_attr "mode" "V4SF")])
20181
20182 ;; SSE Strange Moves.
20183
20184 (define_insn "sse_movmskps"
20185   [(set (match_operand:SI 0 "register_operand" "=r")
20186         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20187                    UNSPEC_MOVMSK))]
20188   "TARGET_SSE"
20189   "movmskps\t{%1, %0|%0, %1}"
20190   [(set_attr "type" "ssecvt")
20191    (set_attr "mode" "V4SF")])
20192
20193 (define_insn "mmx_pmovmskb"
20194   [(set (match_operand:SI 0 "register_operand" "=r")
20195         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20196                    UNSPEC_MOVMSK))]
20197   "TARGET_SSE || TARGET_3DNOW_A"
20198   "pmovmskb\t{%1, %0|%0, %1}"
20199   [(set_attr "type" "ssecvt")
20200    (set_attr "mode" "V4SF")])
20201
20202
20203 (define_insn "mmx_maskmovq"
20204   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20205         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20206                       (match_operand:V8QI 2 "register_operand" "y")]
20207                      UNSPEC_MASKMOV))]
20208   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20209   ;; @@@ check ordering of operands in intel/nonintel syntax
20210   "maskmovq\t{%2, %1|%1, %2}"
20211   [(set_attr "type" "mmxcvt")
20212    (set_attr "mode" "DI")])
20213
20214 (define_insn "mmx_maskmovq_rex"
20215   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20216         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20217                       (match_operand:V8QI 2 "register_operand" "y")]
20218                      UNSPEC_MASKMOV))]
20219   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20220   ;; @@@ check ordering of operands in intel/nonintel syntax
20221   "maskmovq\t{%2, %1|%1, %2}"
20222   [(set_attr "type" "mmxcvt")
20223    (set_attr "mode" "DI")])
20224
20225 (define_insn "sse_movntv4sf"
20226   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20227         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20228                      UNSPEC_MOVNT))]
20229   "TARGET_SSE"
20230   "movntps\t{%1, %0|%0, %1}"
20231   [(set_attr "type" "ssemov")
20232    (set_attr "mode" "V4SF")])
20233
20234 (define_insn "sse_movntdi"
20235   [(set (match_operand:DI 0 "memory_operand" "=m")
20236         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20237                    UNSPEC_MOVNT))]
20238   "TARGET_SSE || TARGET_3DNOW_A"
20239   "movntq\t{%1, %0|%0, %1}"
20240   [(set_attr "type" "mmxmov")
20241    (set_attr "mode" "DI")])
20242
20243 (define_insn "sse_movhlps"
20244   [(set (match_operand:V4SF 0 "register_operand" "=x")
20245         (vec_merge:V4SF
20246          (match_operand:V4SF 1 "register_operand" "0")
20247          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20248                           (parallel [(const_int 2)
20249                                      (const_int 3)
20250                                      (const_int 0)
20251                                      (const_int 1)]))
20252          (const_int 3)))]
20253   "TARGET_SSE"
20254   "movhlps\t{%2, %0|%0, %2}"
20255   [(set_attr "type" "ssecvt")
20256    (set_attr "mode" "V4SF")])
20257
20258 (define_insn "sse_movlhps"
20259   [(set (match_operand:V4SF 0 "register_operand" "=x")
20260         (vec_merge:V4SF
20261          (match_operand:V4SF 1 "register_operand" "0")
20262          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20263                           (parallel [(const_int 2)
20264                                      (const_int 3)
20265                                      (const_int 0)
20266                                      (const_int 1)]))
20267          (const_int 12)))]
20268   "TARGET_SSE"
20269   "movlhps\t{%2, %0|%0, %2}"
20270   [(set_attr "type" "ssecvt")
20271    (set_attr "mode" "V4SF")])
20272
20273 (define_insn "sse_movhps"
20274   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20275         (vec_merge:V4SF
20276          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20277          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20278          (const_int 12)))]
20279   "TARGET_SSE
20280    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20281   "movhps\t{%2, %0|%0, %2}"
20282   [(set_attr "type" "ssecvt")
20283    (set_attr "mode" "V4SF")])
20284
20285 (define_insn "sse_movlps"
20286   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20287         (vec_merge:V4SF
20288          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20289          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20290          (const_int 3)))]
20291   "TARGET_SSE
20292    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20293   "movlps\t{%2, %0|%0, %2}"
20294   [(set_attr "type" "ssecvt")
20295    (set_attr "mode" "V4SF")])
20296
20297 (define_expand "sse_loadss"
20298   [(match_operand:V4SF 0 "register_operand" "")
20299    (match_operand:SF 1 "memory_operand" "")]
20300   "TARGET_SSE"
20301 {
20302   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20303                                CONST0_RTX (V4SFmode)));
20304   DONE;
20305 })
20306
20307 (define_insn "sse_loadss_1"
20308   [(set (match_operand:V4SF 0 "register_operand" "=x")
20309         (vec_merge:V4SF
20310          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20311          (match_operand:V4SF 2 "const0_operand" "X")
20312          (const_int 1)))]
20313   "TARGET_SSE"
20314   "movss\t{%1, %0|%0, %1}"
20315   [(set_attr "type" "ssemov")
20316    (set_attr "mode" "SF")])
20317
20318 (define_insn "sse_movss"
20319   [(set (match_operand:V4SF 0 "register_operand" "=x")
20320         (vec_merge:V4SF
20321          (match_operand:V4SF 1 "register_operand" "0")
20322          (match_operand:V4SF 2 "register_operand" "x")
20323          (const_int 14)))]
20324   "TARGET_SSE"
20325   "movss\t{%2, %0|%0, %2}"
20326   [(set_attr "type" "ssemov")
20327    (set_attr "mode" "SF")])
20328
20329 (define_insn "sse_storess"
20330   [(set (match_operand:SF 0 "memory_operand" "=m")
20331         (vec_select:SF
20332          (match_operand:V4SF 1 "register_operand" "x")
20333          (parallel [(const_int 0)])))]
20334   "TARGET_SSE"
20335   "movss\t{%1, %0|%0, %1}"
20336   [(set_attr "type" "ssemov")
20337    (set_attr "mode" "SF")])
20338
20339 (define_insn "sse_shufps"
20340   [(set (match_operand:V4SF 0 "register_operand" "=x")
20341         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20342                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20343                       (match_operand:SI 3 "immediate_operand" "i")]
20344                      UNSPEC_SHUFFLE))]
20345   "TARGET_SSE"
20346   ;; @@@ check operand order for intel/nonintel syntax
20347   "shufps\t{%3, %2, %0|%0, %2, %3}"
20348   [(set_attr "type" "ssecvt")
20349    (set_attr "mode" "V4SF")])
20350
20351
20352 ;; SSE arithmetic
20353
20354 (define_insn "addv4sf3"
20355   [(set (match_operand:V4SF 0 "register_operand" "=x")
20356         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20357                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20358   "TARGET_SSE"
20359   "addps\t{%2, %0|%0, %2}"
20360   [(set_attr "type" "sseadd")
20361    (set_attr "mode" "V4SF")])
20362
20363 (define_insn "vmaddv4sf3"
20364   [(set (match_operand:V4SF 0 "register_operand" "=x")
20365         (vec_merge:V4SF
20366          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20367                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20368          (match_dup 1)
20369          (const_int 1)))]
20370   "TARGET_SSE"
20371   "addss\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "sseadd")
20373    (set_attr "mode" "SF")])
20374
20375 (define_insn "subv4sf3"
20376   [(set (match_operand:V4SF 0 "register_operand" "=x")
20377         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20378                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20379   "TARGET_SSE"
20380   "subps\t{%2, %0|%0, %2}"
20381   [(set_attr "type" "sseadd")
20382    (set_attr "mode" "V4SF")])
20383
20384 (define_insn "vmsubv4sf3"
20385   [(set (match_operand:V4SF 0 "register_operand" "=x")
20386         (vec_merge:V4SF
20387          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20388                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20389          (match_dup 1)
20390          (const_int 1)))]
20391   "TARGET_SSE"
20392   "subss\t{%2, %0|%0, %2}"
20393   [(set_attr "type" "sseadd")
20394    (set_attr "mode" "SF")])
20395
20396 ;; ??? Should probably be done by generic code instead.
20397 (define_expand "negv4sf2"
20398   [(set (match_operand:V4SF 0 "register_operand" "")
20399         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20400                   (match_dup 2)))]
20401   "TARGET_SSE"
20402 {
20403   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20404   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20405   operands[2] = force_reg (V4SFmode, vm0);
20406 })
20407
20408 (define_insn "mulv4sf3"
20409   [(set (match_operand:V4SF 0 "register_operand" "=x")
20410         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20411                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20412   "TARGET_SSE"
20413   "mulps\t{%2, %0|%0, %2}"
20414   [(set_attr "type" "ssemul")
20415    (set_attr "mode" "V4SF")])
20416
20417 (define_insn "vmmulv4sf3"
20418   [(set (match_operand:V4SF 0 "register_operand" "=x")
20419         (vec_merge:V4SF
20420          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20421                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20422          (match_dup 1)
20423          (const_int 1)))]
20424   "TARGET_SSE"
20425   "mulss\t{%2, %0|%0, %2}"
20426   [(set_attr "type" "ssemul")
20427    (set_attr "mode" "SF")])
20428
20429 (define_insn "divv4sf3"
20430   [(set (match_operand:V4SF 0 "register_operand" "=x")
20431         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20432                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20433   "TARGET_SSE"
20434   "divps\t{%2, %0|%0, %2}"
20435   [(set_attr "type" "ssediv")
20436    (set_attr "mode" "V4SF")])
20437
20438 (define_insn "vmdivv4sf3"
20439   [(set (match_operand:V4SF 0 "register_operand" "=x")
20440         (vec_merge:V4SF
20441          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20442                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20443          (match_dup 1)
20444          (const_int 1)))]
20445   "TARGET_SSE"
20446   "divss\t{%2, %0|%0, %2}"
20447   [(set_attr "type" "ssediv")
20448    (set_attr "mode" "SF")])
20449
20450
20451 ;; SSE square root/reciprocal
20452
20453 (define_insn "rcpv4sf2"
20454   [(set (match_operand:V4SF 0 "register_operand" "=x")
20455         (unspec:V4SF
20456          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20457   "TARGET_SSE"
20458   "rcpps\t{%1, %0|%0, %1}"
20459   [(set_attr "type" "sse")
20460    (set_attr "mode" "V4SF")])
20461
20462 (define_insn "vmrcpv4sf2"
20463   [(set (match_operand:V4SF 0 "register_operand" "=x")
20464         (vec_merge:V4SF
20465          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20466                       UNSPEC_RCP)
20467          (match_operand:V4SF 2 "register_operand" "0")
20468          (const_int 1)))]
20469   "TARGET_SSE"
20470   "rcpss\t{%1, %0|%0, %1}"
20471   [(set_attr "type" "sse")
20472    (set_attr "mode" "SF")])
20473
20474 (define_insn "rsqrtv4sf2"
20475   [(set (match_operand:V4SF 0 "register_operand" "=x")
20476         (unspec:V4SF
20477          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20478   "TARGET_SSE"
20479   "rsqrtps\t{%1, %0|%0, %1}"
20480   [(set_attr "type" "sse")
20481    (set_attr "mode" "V4SF")])
20482
20483 (define_insn "vmrsqrtv4sf2"
20484   [(set (match_operand:V4SF 0 "register_operand" "=x")
20485         (vec_merge:V4SF
20486          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20487                       UNSPEC_RSQRT)
20488          (match_operand:V4SF 2 "register_operand" "0")
20489          (const_int 1)))]
20490   "TARGET_SSE"
20491   "rsqrtss\t{%1, %0|%0, %1}"
20492   [(set_attr "type" "sse")
20493    (set_attr "mode" "SF")])
20494
20495 (define_insn "sqrtv4sf2"
20496   [(set (match_operand:V4SF 0 "register_operand" "=x")
20497         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20498   "TARGET_SSE"
20499   "sqrtps\t{%1, %0|%0, %1}"
20500   [(set_attr "type" "sse")
20501    (set_attr "mode" "V4SF")])
20502
20503 (define_insn "vmsqrtv4sf2"
20504   [(set (match_operand:V4SF 0 "register_operand" "=x")
20505         (vec_merge:V4SF
20506          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20507          (match_operand:V4SF 2 "register_operand" "0")
20508          (const_int 1)))]
20509   "TARGET_SSE"
20510   "sqrtss\t{%1, %0|%0, %1}"
20511   [(set_attr "type" "sse")
20512    (set_attr "mode" "SF")])
20513
20514 ;; SSE logical operations.
20515
20516 ;; SSE defines logical operations on floating point values.  This brings
20517 ;; interesting challenge to RTL representation where logicals are only valid
20518 ;; on integral types.  We deal with this by representing the floating point
20519 ;; logical as logical on arguments casted to TImode as this is what hardware
20520 ;; really does.  Unfortunately hardware requires the type information to be
20521 ;; present and thus we must avoid subregs from being simplified and eliminated
20522 ;; in later compilation phases.
20523 ;;
20524 ;; We have following variants from each instruction:
20525 ;; sse_andsf3 - the operation taking V4SF vector operands
20526 ;;              and doing TImode cast on them
20527 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20528 ;;                      TImode, since backend insist on eliminating casts
20529 ;;                      on memory operands
20530 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20531 ;;                   We cannot accept memory operand here as instruction reads
20532 ;;                   whole scalar.  This is generated only post reload by GCC
20533 ;;                   scalar float operations that expands to logicals (fabs)
20534 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20535 ;;                   memory operand.  Eventually combine can be able
20536 ;;                   to synthesize these using splitter.
20537 ;; sse2_anddf3, *sse2_anddf3_memory
20538 ;;              
20539 ;; 
20540 ;; These are not called andti3 etc. because we really really don't want
20541 ;; the compiler to widen DImode ands to TImode ands and then try to move
20542 ;; into DImode subregs of SSE registers, and them together, and move out
20543 ;; of DImode subregs again!
20544 ;; SSE1 single precision floating point logical operation
20545 (define_expand "sse_andv4sf3"
20546   [(set (match_operand:V4SF 0 "register_operand" "")
20547         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20548                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20549   "TARGET_SSE"
20550   "")
20551
20552 (define_insn "*sse_andv4sf3"
20553   [(set (match_operand:V4SF 0 "register_operand" "=x")
20554         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20555                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20556   "TARGET_SSE
20557    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20558   "andps\t{%2, %0|%0, %2}"
20559   [(set_attr "type" "sselog")
20560    (set_attr "mode" "V4SF")])
20561
20562 (define_expand "sse_nandv4sf3"
20563   [(set (match_operand:V4SF 0 "register_operand" "")
20564         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20565                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20566   "TARGET_SSE"
20567   "")
20568
20569 (define_insn "*sse_nandv4sf3"
20570   [(set (match_operand:V4SF 0 "register_operand" "=x")
20571         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20572                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20573   "TARGET_SSE"
20574   "andnps\t{%2, %0|%0, %2}"
20575   [(set_attr "type" "sselog")
20576    (set_attr "mode" "V4SF")])
20577
20578 (define_expand "sse_iorv4sf3"
20579   [(set (match_operand:V4SF 0 "register_operand" "")
20580         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20581                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20582   "TARGET_SSE"
20583   "")
20584
20585 (define_insn "*sse_iorv4sf3"
20586   [(set (match_operand:V4SF 0 "register_operand" "=x")
20587         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20588                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20589   "TARGET_SSE
20590    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20591   "orps\t{%2, %0|%0, %2}"
20592   [(set_attr "type" "sselog")
20593    (set_attr "mode" "V4SF")])
20594
20595 (define_expand "sse_xorv4sf3"
20596   [(set (match_operand:V4SF 0 "register_operand" "")
20597         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20598                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20599   "TARGET_SSE"
20600   "")
20601
20602 (define_insn "*sse_xorv4sf3"
20603   [(set (match_operand:V4SF 0 "register_operand" "=x")
20604         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20605                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20606   "TARGET_SSE
20607    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20608   "xorps\t{%2, %0|%0, %2}"
20609   [(set_attr "type" "sselog")
20610    (set_attr "mode" "V4SF")])
20611
20612 ;; SSE2 double precision floating point logical operation
20613
20614 (define_expand "sse2_andv2df3"
20615   [(set (match_operand:V2DF 0 "register_operand" "")
20616         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20617                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20618   "TARGET_SSE2"
20619   "")
20620
20621 (define_insn "*sse2_andv2df3"
20622   [(set (match_operand:V2DF 0 "register_operand" "=x")
20623         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20624                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20625   "TARGET_SSE2
20626    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20627   "andpd\t{%2, %0|%0, %2}"
20628   [(set_attr "type" "sselog")
20629    (set_attr "mode" "V2DF")])
20630
20631 (define_expand "sse2_nandv2df3"
20632   [(set (match_operand:V2DF 0 "register_operand" "")
20633         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20634                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20635   "TARGET_SSE2"
20636   "")
20637
20638 (define_insn "*sse2_nandv2df3"
20639   [(set (match_operand:V2DF 0 "register_operand" "=x")
20640         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20641                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20642   "TARGET_SSE2"
20643   "andnpd\t{%2, %0|%0, %2}"
20644   [(set_attr "type" "sselog")
20645    (set_attr "mode" "V2DF")])
20646
20647 (define_expand "sse2_iorv2df3"
20648   [(set (match_operand:V2DF 0 "register_operand" "")
20649         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20650                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20651   "TARGET_SSE2"
20652   "")
20653
20654 (define_insn "*sse2_iorv2df3"
20655   [(set (match_operand:V2DF 0 "register_operand" "=x")
20656         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20657                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20658   "TARGET_SSE2
20659    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20660   "orpd\t{%2, %0|%0, %2}"
20661   [(set_attr "type" "sselog")
20662    (set_attr "mode" "V2DF")])
20663
20664 (define_expand "sse2_xorv2df3"
20665   [(set (match_operand:V2DF 0 "register_operand" "")
20666         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20667                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20668   "TARGET_SSE2"
20669   "")
20670
20671 (define_insn "*sse2_xorv2df3"
20672   [(set (match_operand:V2DF 0 "register_operand" "=x")
20673         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20674                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20675   "TARGET_SSE2
20676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20677   "xorpd\t{%2, %0|%0, %2}"
20678   [(set_attr "type" "sselog")
20679    (set_attr "mode" "V2DF")])
20680
20681 ;; SSE2 integral logicals.  These patterns must always come after floating
20682 ;; point ones since we don't want compiler to use integer opcodes on floating
20683 ;; point SSE values to avoid matching of subregs in the match_operand.
20684 (define_insn "*sse2_andti3"
20685   [(set (match_operand:TI 0 "register_operand" "=x")
20686         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20687                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20688   "TARGET_SSE2
20689    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20690   "pand\t{%2, %0|%0, %2}"
20691   [(set_attr "type" "sselog")
20692    (set_attr "mode" "TI")])
20693
20694 (define_insn "sse2_andv2di3"
20695   [(set (match_operand:V2DI 0 "register_operand" "=x")
20696         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20697                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20698   "TARGET_SSE2
20699    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20700   "pand\t{%2, %0|%0, %2}"
20701   [(set_attr "type" "sselog")
20702    (set_attr "mode" "TI")])
20703
20704 (define_insn "*sse2_nandti3"
20705   [(set (match_operand:TI 0 "register_operand" "=x")
20706         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20707                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20708   "TARGET_SSE2"
20709   "pandn\t{%2, %0|%0, %2}"
20710   [(set_attr "type" "sselog")
20711    (set_attr "mode" "TI")])
20712
20713 (define_insn "sse2_nandv2di3"
20714   [(set (match_operand:V2DI 0 "register_operand" "=x")
20715         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20716                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20717   "TARGET_SSE2
20718    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20719   "pandn\t{%2, %0|%0, %2}"
20720   [(set_attr "type" "sselog")
20721    (set_attr "mode" "TI")])
20722
20723 (define_insn "*sse2_iorti3"
20724   [(set (match_operand:TI 0 "register_operand" "=x")
20725         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20726                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20727   "TARGET_SSE2
20728    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20729   "por\t{%2, %0|%0, %2}"
20730   [(set_attr "type" "sselog")
20731    (set_attr "mode" "TI")])
20732
20733 (define_insn "sse2_iorv2di3"
20734   [(set (match_operand:V2DI 0 "register_operand" "=x")
20735         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20736                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20737   "TARGET_SSE2
20738    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20739   "por\t{%2, %0|%0, %2}"
20740   [(set_attr "type" "sselog")
20741    (set_attr "mode" "TI")])
20742
20743 (define_insn "*sse2_xorti3"
20744   [(set (match_operand:TI 0 "register_operand" "=x")
20745         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20746                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20747   "TARGET_SSE2
20748    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20749   "pxor\t{%2, %0|%0, %2}"
20750   [(set_attr "type" "sselog")
20751    (set_attr "mode" "TI")])
20752
20753 (define_insn "sse2_xorv2di3"
20754   [(set (match_operand:V2DI 0 "register_operand" "=x")
20755         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20756                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20757   "TARGET_SSE2
20758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20759   "pxor\t{%2, %0|%0, %2}"
20760   [(set_attr "type" "sselog")
20761    (set_attr "mode" "TI")])
20762
20763 ;; Use xor, but don't show input operands so they aren't live before
20764 ;; this insn.
20765 (define_insn "sse_clrv4sf"
20766   [(set (match_operand:V4SF 0 "register_operand" "=x")
20767         (match_operand:V4SF 1 "const0_operand" "X"))]
20768   "TARGET_SSE"
20769 {
20770   if (get_attr_mode (insn) == MODE_TI)
20771     return "pxor\t{%0, %0|%0, %0}";
20772   else
20773     return "xorps\t{%0, %0|%0, %0}";
20774 }
20775   [(set_attr "type" "sselog")
20776    (set_attr "memory" "none")
20777    (set (attr "mode")
20778         (if_then_else
20779            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20780                          (const_int 0))
20781                      (ne (symbol_ref "TARGET_SSE2")
20782                          (const_int 0)))
20783                 (eq (symbol_ref "optimize_size")
20784                     (const_int 0)))
20785          (const_string "TI")
20786          (const_string "V4SF")))])
20787
20788 ;; Use xor, but don't show input operands so they aren't live before
20789 ;; this insn.
20790 (define_insn "sse_clrv2df"
20791   [(set (match_operand:V2DF 0 "register_operand" "=x")
20792         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20793   "TARGET_SSE2"
20794   "xorpd\t{%0, %0|%0, %0}"
20795   [(set_attr "type" "sselog")
20796    (set_attr "memory" "none")
20797    (set_attr "mode" "V4SF")])
20798
20799 ;; SSE mask-generating compares
20800
20801 (define_insn "maskcmpv4sf3"
20802   [(set (match_operand:V4SI 0 "register_operand" "=x")
20803         (match_operator:V4SI 3 "sse_comparison_operator"
20804                 [(match_operand:V4SF 1 "register_operand" "0")
20805                  (match_operand:V4SF 2 "register_operand" "x")]))]
20806   "TARGET_SSE"
20807   "cmp%D3ps\t{%2, %0|%0, %2}"
20808   [(set_attr "type" "ssecmp")
20809    (set_attr "mode" "V4SF")])
20810
20811 (define_insn "maskncmpv4sf3"
20812   [(set (match_operand:V4SI 0 "register_operand" "=x")
20813         (not:V4SI
20814          (match_operator:V4SI 3 "sse_comparison_operator"
20815                 [(match_operand:V4SF 1 "register_operand" "0")
20816                  (match_operand:V4SF 2 "register_operand" "x")])))]
20817   "TARGET_SSE"
20818 {
20819   if (GET_CODE (operands[3]) == UNORDERED)
20820     return "cmpordps\t{%2, %0|%0, %2}";
20821   else
20822     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20823 }
20824   [(set_attr "type" "ssecmp")
20825    (set_attr "mode" "V4SF")])
20826
20827 (define_insn "vmmaskcmpv4sf3"
20828   [(set (match_operand:V4SI 0 "register_operand" "=x")
20829         (vec_merge:V4SI
20830          (match_operator:V4SI 3 "sse_comparison_operator"
20831                 [(match_operand:V4SF 1 "register_operand" "0")
20832                  (match_operand:V4SF 2 "register_operand" "x")])
20833          (subreg:V4SI (match_dup 1) 0)
20834          (const_int 1)))]
20835   "TARGET_SSE"
20836   "cmp%D3ss\t{%2, %0|%0, %2}"
20837   [(set_attr "type" "ssecmp")
20838    (set_attr "mode" "SF")])
20839
20840 (define_insn "vmmaskncmpv4sf3"
20841   [(set (match_operand:V4SI 0 "register_operand" "=x")
20842         (vec_merge:V4SI
20843          (not:V4SI
20844           (match_operator:V4SI 3 "sse_comparison_operator"
20845                 [(match_operand:V4SF 1 "register_operand" "0")
20846                  (match_operand:V4SF 2 "register_operand" "x")]))
20847          (subreg:V4SI (match_dup 1) 0)
20848          (const_int 1)))]
20849   "TARGET_SSE"
20850 {
20851   if (GET_CODE (operands[3]) == UNORDERED)
20852     return "cmpordss\t{%2, %0|%0, %2}";
20853   else
20854     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20855 }
20856   [(set_attr "type" "ssecmp")
20857    (set_attr "mode" "SF")])
20858
20859 (define_insn "sse_comi"
20860   [(set (reg:CCFP FLAGS_REG)
20861         (compare:CCFP (vec_select:SF
20862                        (match_operand:V4SF 0 "register_operand" "x")
20863                        (parallel [(const_int 0)]))
20864                       (vec_select:SF
20865                        (match_operand:V4SF 1 "register_operand" "x")
20866                        (parallel [(const_int 0)]))))]
20867   "TARGET_SSE"
20868   "comiss\t{%1, %0|%0, %1}"
20869   [(set_attr "type" "ssecomi")
20870    (set_attr "mode" "SF")])
20871
20872 (define_insn "sse_ucomi"
20873   [(set (reg:CCFPU FLAGS_REG)
20874         (compare:CCFPU (vec_select:SF
20875                         (match_operand:V4SF 0 "register_operand" "x")
20876                         (parallel [(const_int 0)]))
20877                        (vec_select:SF
20878                         (match_operand:V4SF 1 "register_operand" "x")
20879                         (parallel [(const_int 0)]))))]
20880   "TARGET_SSE"
20881   "ucomiss\t{%1, %0|%0, %1}"
20882   [(set_attr "type" "ssecomi")
20883    (set_attr "mode" "SF")])
20884
20885
20886 ;; SSE unpack
20887
20888 (define_insn "sse_unpckhps"
20889   [(set (match_operand:V4SF 0 "register_operand" "=x")
20890         (vec_merge:V4SF
20891          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20892                           (parallel [(const_int 2)
20893                                      (const_int 0)
20894                                      (const_int 3)
20895                                      (const_int 1)]))
20896          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20897                           (parallel [(const_int 0)
20898                                      (const_int 2)
20899                                      (const_int 1)
20900                                      (const_int 3)]))
20901          (const_int 5)))]
20902   "TARGET_SSE"
20903   "unpckhps\t{%2, %0|%0, %2}"
20904   [(set_attr "type" "ssecvt")
20905    (set_attr "mode" "V4SF")])
20906
20907 (define_insn "sse_unpcklps"
20908   [(set (match_operand:V4SF 0 "register_operand" "=x")
20909         (vec_merge:V4SF
20910          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20911                           (parallel [(const_int 0)
20912                                      (const_int 2)
20913                                      (const_int 1)
20914                                      (const_int 3)]))
20915          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20916                           (parallel [(const_int 2)
20917                                      (const_int 0)
20918                                      (const_int 3)
20919                                      (const_int 1)]))
20920          (const_int 5)))]
20921   "TARGET_SSE"
20922   "unpcklps\t{%2, %0|%0, %2}"
20923   [(set_attr "type" "ssecvt")
20924    (set_attr "mode" "V4SF")])
20925
20926
20927 ;; SSE min/max
20928
20929 (define_insn "smaxv4sf3"
20930   [(set (match_operand:V4SF 0 "register_operand" "=x")
20931         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20932                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20933   "TARGET_SSE"
20934   "maxps\t{%2, %0|%0, %2}"
20935   [(set_attr "type" "sse")
20936    (set_attr "mode" "V4SF")])
20937
20938 (define_insn "vmsmaxv4sf3"
20939   [(set (match_operand:V4SF 0 "register_operand" "=x")
20940         (vec_merge:V4SF
20941          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20942                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20943          (match_dup 1)
20944          (const_int 1)))]
20945   "TARGET_SSE"
20946   "maxss\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "sse")
20948    (set_attr "mode" "SF")])
20949
20950 (define_insn "sminv4sf3"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20953                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20954   "TARGET_SSE"
20955   "minps\t{%2, %0|%0, %2}"
20956   [(set_attr "type" "sse")
20957    (set_attr "mode" "V4SF")])
20958
20959 (define_insn "vmsminv4sf3"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (vec_merge:V4SF
20962          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20963                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20964          (match_dup 1)
20965          (const_int 1)))]
20966   "TARGET_SSE"
20967   "minss\t{%2, %0|%0, %2}"
20968   [(set_attr "type" "sse")
20969    (set_attr "mode" "SF")])
20970
20971 ;; SSE <-> integer/MMX conversions
20972
20973 (define_insn "cvtpi2ps"
20974   [(set (match_operand:V4SF 0 "register_operand" "=x")
20975         (vec_merge:V4SF
20976          (match_operand:V4SF 1 "register_operand" "0")
20977          (vec_duplicate:V4SF
20978           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20979          (const_int 12)))]
20980   "TARGET_SSE"
20981   "cvtpi2ps\t{%2, %0|%0, %2}"
20982   [(set_attr "type" "ssecvt")
20983    (set_attr "mode" "V4SF")])
20984
20985 (define_insn "cvtps2pi"
20986   [(set (match_operand:V2SI 0 "register_operand" "=y")
20987         (vec_select:V2SI
20988          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20989          (parallel [(const_int 0) (const_int 1)])))]
20990   "TARGET_SSE"
20991   "cvtps2pi\t{%1, %0|%0, %1}"
20992   [(set_attr "type" "ssecvt")
20993    (set_attr "mode" "V4SF")])
20994
20995 (define_insn "cvttps2pi"
20996   [(set (match_operand:V2SI 0 "register_operand" "=y")
20997         (vec_select:V2SI
20998          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20999                       UNSPEC_FIX)
21000          (parallel [(const_int 0) (const_int 1)])))]
21001   "TARGET_SSE"
21002   "cvttps2pi\t{%1, %0|%0, %1}"
21003   [(set_attr "type" "ssecvt")
21004    (set_attr "mode" "SF")])
21005
21006 (define_insn "cvtsi2ss"
21007   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21008         (vec_merge:V4SF
21009          (match_operand:V4SF 1 "register_operand" "0,0")
21010          (vec_duplicate:V4SF
21011           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21012          (const_int 14)))]
21013   "TARGET_SSE"
21014   "cvtsi2ss\t{%2, %0|%0, %2}"
21015   [(set_attr "type" "sseicvt")
21016    (set_attr "athlon_decode" "vector,double")
21017    (set_attr "mode" "SF")])
21018
21019 (define_insn "cvtsi2ssq"
21020   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21021         (vec_merge:V4SF
21022          (match_operand:V4SF 1 "register_operand" "0,0")
21023          (vec_duplicate:V4SF
21024           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21025          (const_int 14)))]
21026   "TARGET_SSE && TARGET_64BIT"
21027   "cvtsi2ssq\t{%2, %0|%0, %2}"
21028   [(set_attr "type" "sseicvt")
21029    (set_attr "athlon_decode" "vector,double")
21030    (set_attr "mode" "SF")])
21031
21032 (define_insn "cvtss2si"
21033   [(set (match_operand:SI 0 "register_operand" "=r,r")
21034         (vec_select:SI
21035          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21036          (parallel [(const_int 0)])))]
21037   "TARGET_SSE"
21038   "cvtss2si\t{%1, %0|%0, %1}"
21039   [(set_attr "type" "sseicvt")
21040    (set_attr "athlon_decode" "double,vector")
21041    (set_attr "mode" "SI")])
21042
21043 (define_insn "cvtss2siq"
21044   [(set (match_operand:DI 0 "register_operand" "=r,r")
21045         (vec_select:DI
21046          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21047          (parallel [(const_int 0)])))]
21048   "TARGET_SSE"
21049   "cvtss2siq\t{%1, %0|%0, %1}"
21050   [(set_attr "type" "sseicvt")
21051    (set_attr "athlon_decode" "double,vector")
21052    (set_attr "mode" "DI")])
21053
21054 (define_insn "cvttss2si"
21055   [(set (match_operand:SI 0 "register_operand" "=r,r")
21056         (vec_select:SI
21057          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21058                       UNSPEC_FIX)
21059          (parallel [(const_int 0)])))]
21060   "TARGET_SSE"
21061   "cvttss2si\t{%1, %0|%0, %1}"
21062   [(set_attr "type" "sseicvt")
21063    (set_attr "mode" "SF")
21064    (set_attr "athlon_decode" "double,vector")])
21065
21066 (define_insn "cvttss2siq"
21067   [(set (match_operand:DI 0 "register_operand" "=r,r")
21068         (vec_select:DI
21069          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21070                       UNSPEC_FIX)
21071          (parallel [(const_int 0)])))]
21072   "TARGET_SSE && TARGET_64BIT"
21073   "cvttss2siq\t{%1, %0|%0, %1}"
21074   [(set_attr "type" "sseicvt")
21075    (set_attr "mode" "SF")
21076    (set_attr "athlon_decode" "double,vector")])
21077
21078
21079 ;; MMX insns
21080
21081 ;; MMX arithmetic
21082
21083 (define_insn "addv8qi3"
21084   [(set (match_operand:V8QI 0 "register_operand" "=y")
21085         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21086                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21087   "TARGET_MMX"
21088   "paddb\t{%2, %0|%0, %2}"
21089   [(set_attr "type" "mmxadd")
21090    (set_attr "mode" "DI")])
21091
21092 (define_insn "addv4hi3"
21093   [(set (match_operand:V4HI 0 "register_operand" "=y")
21094         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21095                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21096   "TARGET_MMX"
21097   "paddw\t{%2, %0|%0, %2}"
21098   [(set_attr "type" "mmxadd")
21099    (set_attr "mode" "DI")])
21100
21101 (define_insn "addv2si3"
21102   [(set (match_operand:V2SI 0 "register_operand" "=y")
21103         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21104                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21105   "TARGET_MMX"
21106   "paddd\t{%2, %0|%0, %2}"
21107   [(set_attr "type" "mmxadd")
21108    (set_attr "mode" "DI")])
21109
21110 (define_insn "mmx_adddi3"
21111   [(set (match_operand:DI 0 "register_operand" "=y")
21112         (unspec:DI
21113          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21114                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21115          UNSPEC_NOP))]
21116   "TARGET_MMX"
21117   "paddq\t{%2, %0|%0, %2}"
21118   [(set_attr "type" "mmxadd")
21119    (set_attr "mode" "DI")])
21120
21121 (define_insn "ssaddv8qi3"
21122   [(set (match_operand:V8QI 0 "register_operand" "=y")
21123         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21124                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21125   "TARGET_MMX"
21126   "paddsb\t{%2, %0|%0, %2}"
21127   [(set_attr "type" "mmxadd")
21128    (set_attr "mode" "DI")])
21129
21130 (define_insn "ssaddv4hi3"
21131   [(set (match_operand:V4HI 0 "register_operand" "=y")
21132         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21133                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21134   "TARGET_MMX"
21135   "paddsw\t{%2, %0|%0, %2}"
21136   [(set_attr "type" "mmxadd")
21137    (set_attr "mode" "DI")])
21138
21139 (define_insn "usaddv8qi3"
21140   [(set (match_operand:V8QI 0 "register_operand" "=y")
21141         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21142                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21143   "TARGET_MMX"
21144   "paddusb\t{%2, %0|%0, %2}"
21145   [(set_attr "type" "mmxadd")
21146    (set_attr "mode" "DI")])
21147
21148 (define_insn "usaddv4hi3"
21149   [(set (match_operand:V4HI 0 "register_operand" "=y")
21150         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21151                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21152   "TARGET_MMX"
21153   "paddusw\t{%2, %0|%0, %2}"
21154   [(set_attr "type" "mmxadd")
21155    (set_attr "mode" "DI")])
21156
21157 (define_insn "subv8qi3"
21158   [(set (match_operand:V8QI 0 "register_operand" "=y")
21159         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21160                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21161   "TARGET_MMX"
21162   "psubb\t{%2, %0|%0, %2}"
21163   [(set_attr "type" "mmxadd")
21164    (set_attr "mode" "DI")])
21165
21166 (define_insn "subv4hi3"
21167   [(set (match_operand:V4HI 0 "register_operand" "=y")
21168         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21169                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21170   "TARGET_MMX"
21171   "psubw\t{%2, %0|%0, %2}"
21172   [(set_attr "type" "mmxadd")
21173    (set_attr "mode" "DI")])
21174
21175 (define_insn "subv2si3"
21176   [(set (match_operand:V2SI 0 "register_operand" "=y")
21177         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21178                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21179   "TARGET_MMX"
21180   "psubd\t{%2, %0|%0, %2}"
21181   [(set_attr "type" "mmxadd")
21182    (set_attr "mode" "DI")])
21183
21184 (define_insn "mmx_subdi3"
21185   [(set (match_operand:DI 0 "register_operand" "=y")
21186         (unspec:DI
21187          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21188                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21189          UNSPEC_NOP))]
21190   "TARGET_MMX"
21191   "psubq\t{%2, %0|%0, %2}"
21192   [(set_attr "type" "mmxadd")
21193    (set_attr "mode" "DI")])
21194
21195 (define_insn "sssubv8qi3"
21196   [(set (match_operand:V8QI 0 "register_operand" "=y")
21197         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21198                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21199   "TARGET_MMX"
21200   "psubsb\t{%2, %0|%0, %2}"
21201   [(set_attr "type" "mmxadd")
21202    (set_attr "mode" "DI")])
21203
21204 (define_insn "sssubv4hi3"
21205   [(set (match_operand:V4HI 0 "register_operand" "=y")
21206         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21207                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21208   "TARGET_MMX"
21209   "psubsw\t{%2, %0|%0, %2}"
21210   [(set_attr "type" "mmxadd")
21211    (set_attr "mode" "DI")])
21212
21213 (define_insn "ussubv8qi3"
21214   [(set (match_operand:V8QI 0 "register_operand" "=y")
21215         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21216                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21217   "TARGET_MMX"
21218   "psubusb\t{%2, %0|%0, %2}"
21219   [(set_attr "type" "mmxadd")
21220    (set_attr "mode" "DI")])
21221
21222 (define_insn "ussubv4hi3"
21223   [(set (match_operand:V4HI 0 "register_operand" "=y")
21224         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21225                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21226   "TARGET_MMX"
21227   "psubusw\t{%2, %0|%0, %2}"
21228   [(set_attr "type" "mmxadd")
21229    (set_attr "mode" "DI")])
21230
21231 (define_insn "mulv4hi3"
21232   [(set (match_operand:V4HI 0 "register_operand" "=y")
21233         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21234                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21235   "TARGET_MMX"
21236   "pmullw\t{%2, %0|%0, %2}"
21237   [(set_attr "type" "mmxmul")
21238    (set_attr "mode" "DI")])
21239
21240 (define_insn "smulv4hi3_highpart"
21241   [(set (match_operand:V4HI 0 "register_operand" "=y")
21242         (truncate:V4HI
21243          (lshiftrt:V4SI
21244           (mult:V4SI (sign_extend:V4SI
21245                       (match_operand:V4HI 1 "register_operand" "0"))
21246                      (sign_extend:V4SI
21247                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21248           (const_int 16))))]
21249   "TARGET_MMX"
21250   "pmulhw\t{%2, %0|%0, %2}"
21251   [(set_attr "type" "mmxmul")
21252    (set_attr "mode" "DI")])
21253
21254 (define_insn "umulv4hi3_highpart"
21255   [(set (match_operand:V4HI 0 "register_operand" "=y")
21256         (truncate:V4HI
21257          (lshiftrt:V4SI
21258           (mult:V4SI (zero_extend:V4SI
21259                       (match_operand:V4HI 1 "register_operand" "0"))
21260                      (zero_extend:V4SI
21261                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21262           (const_int 16))))]
21263   "TARGET_SSE || TARGET_3DNOW_A"
21264   "pmulhuw\t{%2, %0|%0, %2}"
21265   [(set_attr "type" "mmxmul")
21266    (set_attr "mode" "DI")])
21267
21268 (define_insn "mmx_pmaddwd"
21269   [(set (match_operand:V2SI 0 "register_operand" "=y")
21270         (plus:V2SI
21271          (mult:V2SI
21272           (sign_extend:V2SI
21273            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21274                             (parallel [(const_int 0) (const_int 2)])))
21275           (sign_extend:V2SI
21276            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21277                             (parallel [(const_int 0) (const_int 2)]))))
21278          (mult:V2SI
21279           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21280                                              (parallel [(const_int 1)
21281                                                         (const_int 3)])))
21282           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21283                                              (parallel [(const_int 1)
21284                                                         (const_int 3)]))))))]
21285   "TARGET_MMX"
21286   "pmaddwd\t{%2, %0|%0, %2}"
21287   [(set_attr "type" "mmxmul")
21288    (set_attr "mode" "DI")])
21289
21290
21291 ;; MMX logical operations
21292 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21293 ;; normal code that also wants to use the FPU from getting broken.
21294 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21295 (define_insn "mmx_iordi3"
21296   [(set (match_operand:DI 0 "register_operand" "=y")
21297         (unspec:DI
21298          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21299                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21300          UNSPEC_NOP))]
21301   "TARGET_MMX"
21302   "por\t{%2, %0|%0, %2}"
21303   [(set_attr "type" "mmxadd")
21304    (set_attr "mode" "DI")])
21305
21306 (define_insn "mmx_xordi3"
21307   [(set (match_operand:DI 0 "register_operand" "=y")
21308         (unspec:DI
21309          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21310                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21311          UNSPEC_NOP))]
21312   "TARGET_MMX"
21313   "pxor\t{%2, %0|%0, %2}"
21314   [(set_attr "type" "mmxadd")
21315    (set_attr "mode" "DI")
21316    (set_attr "memory" "none")])
21317
21318 ;; Same as pxor, but don't show input operands so that we don't think
21319 ;; they are live.
21320 (define_insn "mmx_clrdi"
21321   [(set (match_operand:DI 0 "register_operand" "=y")
21322         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21323   "TARGET_MMX"
21324   "pxor\t{%0, %0|%0, %0}"
21325   [(set_attr "type" "mmxadd")
21326    (set_attr "mode" "DI")
21327    (set_attr "memory" "none")])
21328
21329 (define_insn "mmx_anddi3"
21330   [(set (match_operand:DI 0 "register_operand" "=y")
21331         (unspec:DI
21332          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21333                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21334          UNSPEC_NOP))]
21335   "TARGET_MMX"
21336   "pand\t{%2, %0|%0, %2}"
21337   [(set_attr "type" "mmxadd")
21338    (set_attr "mode" "DI")])
21339
21340 (define_insn "mmx_nanddi3"
21341   [(set (match_operand:DI 0 "register_operand" "=y")
21342         (unspec:DI
21343          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21344                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21345          UNSPEC_NOP))]
21346   "TARGET_MMX"
21347   "pandn\t{%2, %0|%0, %2}"
21348   [(set_attr "type" "mmxadd")
21349    (set_attr "mode" "DI")])
21350
21351
21352 ;; MMX unsigned averages/sum of absolute differences
21353
21354 (define_insn "mmx_uavgv8qi3"
21355   [(set (match_operand:V8QI 0 "register_operand" "=y")
21356         (ashiftrt:V8QI
21357          (plus:V8QI (plus:V8QI
21358                      (match_operand:V8QI 1 "register_operand" "0")
21359                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21360                     (const_vector:V8QI [(const_int 1)
21361                                         (const_int 1)
21362                                         (const_int 1)
21363                                         (const_int 1)
21364                                         (const_int 1)
21365                                         (const_int 1)
21366                                         (const_int 1)
21367                                         (const_int 1)]))
21368          (const_int 1)))]
21369   "TARGET_SSE || TARGET_3DNOW_A"
21370   "pavgb\t{%2, %0|%0, %2}"
21371   [(set_attr "type" "mmxshft")
21372    (set_attr "mode" "DI")])
21373
21374 (define_insn "mmx_uavgv4hi3"
21375   [(set (match_operand:V4HI 0 "register_operand" "=y")
21376         (ashiftrt:V4HI
21377          (plus:V4HI (plus:V4HI
21378                      (match_operand:V4HI 1 "register_operand" "0")
21379                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21380                     (const_vector:V4HI [(const_int 1)
21381                                         (const_int 1)
21382                                         (const_int 1)
21383                                         (const_int 1)]))
21384          (const_int 1)))]
21385   "TARGET_SSE || TARGET_3DNOW_A"
21386   "pavgw\t{%2, %0|%0, %2}"
21387   [(set_attr "type" "mmxshft")
21388    (set_attr "mode" "DI")])
21389
21390 (define_insn "mmx_psadbw"
21391   [(set (match_operand:DI 0 "register_operand" "=y")
21392         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21393                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21394                    UNSPEC_PSADBW))]
21395   "TARGET_SSE || TARGET_3DNOW_A"
21396   "psadbw\t{%2, %0|%0, %2}"
21397   [(set_attr "type" "mmxshft")
21398    (set_attr "mode" "DI")])
21399
21400
21401 ;; MMX insert/extract/shuffle
21402
21403 (define_insn "mmx_pinsrw"
21404   [(set (match_operand:V4HI 0 "register_operand" "=y")
21405         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21406                         (vec_duplicate:V4HI
21407                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21408                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21409   "TARGET_SSE || TARGET_3DNOW_A"
21410   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21411   [(set_attr "type" "mmxcvt")
21412    (set_attr "mode" "DI")])
21413
21414 (define_insn "mmx_pextrw"
21415   [(set (match_operand:SI 0 "register_operand" "=r")
21416         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21417                                        (parallel
21418                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21419   "TARGET_SSE || TARGET_3DNOW_A"
21420   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21421   [(set_attr "type" "mmxcvt")
21422    (set_attr "mode" "DI")])
21423
21424 (define_insn "mmx_pshufw"
21425   [(set (match_operand:V4HI 0 "register_operand" "=y")
21426         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21427                       (match_operand:SI 2 "immediate_operand" "i")]
21428                      UNSPEC_SHUFFLE))]
21429   "TARGET_SSE || TARGET_3DNOW_A"
21430   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21431   [(set_attr "type" "mmxcvt")
21432    (set_attr "mode" "DI")])
21433
21434
21435 ;; MMX mask-generating comparisons
21436
21437 (define_insn "eqv8qi3"
21438   [(set (match_operand:V8QI 0 "register_operand" "=y")
21439         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21440                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21441   "TARGET_MMX"
21442   "pcmpeqb\t{%2, %0|%0, %2}"
21443   [(set_attr "type" "mmxcmp")
21444    (set_attr "mode" "DI")])
21445
21446 (define_insn "eqv4hi3"
21447   [(set (match_operand:V4HI 0 "register_operand" "=y")
21448         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21449                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21450   "TARGET_MMX"
21451   "pcmpeqw\t{%2, %0|%0, %2}"
21452   [(set_attr "type" "mmxcmp")
21453    (set_attr "mode" "DI")])
21454
21455 (define_insn "eqv2si3"
21456   [(set (match_operand:V2SI 0 "register_operand" "=y")
21457         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21458                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21459   "TARGET_MMX"
21460   "pcmpeqd\t{%2, %0|%0, %2}"
21461   [(set_attr "type" "mmxcmp")
21462    (set_attr "mode" "DI")])
21463
21464 (define_insn "gtv8qi3"
21465   [(set (match_operand:V8QI 0 "register_operand" "=y")
21466         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21467                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21468   "TARGET_MMX"
21469   "pcmpgtb\t{%2, %0|%0, %2}"
21470   [(set_attr "type" "mmxcmp")
21471    (set_attr "mode" "DI")])
21472
21473 (define_insn "gtv4hi3"
21474   [(set (match_operand:V4HI 0 "register_operand" "=y")
21475         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21476                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21477   "TARGET_MMX"
21478   "pcmpgtw\t{%2, %0|%0, %2}"
21479   [(set_attr "type" "mmxcmp")
21480    (set_attr "mode" "DI")])
21481
21482 (define_insn "gtv2si3"
21483   [(set (match_operand:V2SI 0 "register_operand" "=y")
21484         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21485                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21486   "TARGET_MMX"
21487   "pcmpgtd\t{%2, %0|%0, %2}"
21488   [(set_attr "type" "mmxcmp")
21489    (set_attr "mode" "DI")])
21490
21491
21492 ;; MMX max/min insns
21493
21494 (define_insn "umaxv8qi3"
21495   [(set (match_operand:V8QI 0 "register_operand" "=y")
21496         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21497                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21498   "TARGET_SSE || TARGET_3DNOW_A"
21499   "pmaxub\t{%2, %0|%0, %2}"
21500   [(set_attr "type" "mmxadd")
21501    (set_attr "mode" "DI")])
21502
21503 (define_insn "smaxv4hi3"
21504   [(set (match_operand:V4HI 0 "register_operand" "=y")
21505         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21506                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21507   "TARGET_SSE || TARGET_3DNOW_A"
21508   "pmaxsw\t{%2, %0|%0, %2}"
21509   [(set_attr "type" "mmxadd")
21510    (set_attr "mode" "DI")])
21511
21512 (define_insn "uminv8qi3"
21513   [(set (match_operand:V8QI 0 "register_operand" "=y")
21514         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21515                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21516   "TARGET_SSE || TARGET_3DNOW_A"
21517   "pminub\t{%2, %0|%0, %2}"
21518   [(set_attr "type" "mmxadd")
21519    (set_attr "mode" "DI")])
21520
21521 (define_insn "sminv4hi3"
21522   [(set (match_operand:V4HI 0 "register_operand" "=y")
21523         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21524                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21525   "TARGET_SSE || TARGET_3DNOW_A"
21526   "pminsw\t{%2, %0|%0, %2}"
21527   [(set_attr "type" "mmxadd")
21528    (set_attr "mode" "DI")])
21529
21530
21531 ;; MMX shifts
21532
21533 (define_insn "ashrv4hi3"
21534   [(set (match_operand:V4HI 0 "register_operand" "=y")
21535         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21536                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21537   "TARGET_MMX"
21538   "psraw\t{%2, %0|%0, %2}"
21539   [(set_attr "type" "mmxshft")
21540    (set_attr "mode" "DI")])
21541
21542 (define_insn "ashrv2si3"
21543   [(set (match_operand:V2SI 0 "register_operand" "=y")
21544         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21545                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21546   "TARGET_MMX"
21547   "psrad\t{%2, %0|%0, %2}"
21548   [(set_attr "type" "mmxshft")
21549    (set_attr "mode" "DI")])
21550
21551 (define_insn "lshrv4hi3"
21552   [(set (match_operand:V4HI 0 "register_operand" "=y")
21553         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21554                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21555   "TARGET_MMX"
21556   "psrlw\t{%2, %0|%0, %2}"
21557   [(set_attr "type" "mmxshft")
21558    (set_attr "mode" "DI")])
21559
21560 (define_insn "lshrv2si3"
21561   [(set (match_operand:V2SI 0 "register_operand" "=y")
21562         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21563                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21564   "TARGET_MMX"
21565   "psrld\t{%2, %0|%0, %2}"
21566   [(set_attr "type" "mmxshft")
21567    (set_attr "mode" "DI")])
21568
21569 ;; See logical MMX insns.
21570 (define_insn "mmx_lshrdi3"
21571   [(set (match_operand:DI 0 "register_operand" "=y")
21572         (unspec:DI
21573           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21574                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21575           UNSPEC_NOP))]
21576   "TARGET_MMX"
21577   "psrlq\t{%2, %0|%0, %2}"
21578   [(set_attr "type" "mmxshft")
21579    (set_attr "mode" "DI")])
21580
21581 (define_insn "ashlv4hi3"
21582   [(set (match_operand:V4HI 0 "register_operand" "=y")
21583         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21584                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21585   "TARGET_MMX"
21586   "psllw\t{%2, %0|%0, %2}"
21587   [(set_attr "type" "mmxshft")
21588    (set_attr "mode" "DI")])
21589
21590 (define_insn "ashlv2si3"
21591   [(set (match_operand:V2SI 0 "register_operand" "=y")
21592         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21593                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21594   "TARGET_MMX"
21595   "pslld\t{%2, %0|%0, %2}"
21596   [(set_attr "type" "mmxshft")
21597    (set_attr "mode" "DI")])
21598
21599 ;; See logical MMX insns.
21600 (define_insn "mmx_ashldi3"
21601   [(set (match_operand:DI 0 "register_operand" "=y")
21602         (unspec:DI
21603          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21604                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21605          UNSPEC_NOP))]
21606   "TARGET_MMX"
21607   "psllq\t{%2, %0|%0, %2}"
21608   [(set_attr "type" "mmxshft")
21609    (set_attr "mode" "DI")])
21610
21611
21612 ;; MMX pack/unpack insns.
21613
21614 (define_insn "mmx_packsswb"
21615   [(set (match_operand:V8QI 0 "register_operand" "=y")
21616         (vec_concat:V8QI
21617          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21618          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21619   "TARGET_MMX"
21620   "packsswb\t{%2, %0|%0, %2}"
21621   [(set_attr "type" "mmxshft")
21622    (set_attr "mode" "DI")])
21623
21624 (define_insn "mmx_packssdw"
21625   [(set (match_operand:V4HI 0 "register_operand" "=y")
21626         (vec_concat:V4HI
21627          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21628          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21629   "TARGET_MMX"
21630   "packssdw\t{%2, %0|%0, %2}"
21631   [(set_attr "type" "mmxshft")
21632    (set_attr "mode" "DI")])
21633
21634 (define_insn "mmx_packuswb"
21635   [(set (match_operand:V8QI 0 "register_operand" "=y")
21636         (vec_concat:V8QI
21637          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21638          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21639   "TARGET_MMX"
21640   "packuswb\t{%2, %0|%0, %2}"
21641   [(set_attr "type" "mmxshft")
21642    (set_attr "mode" "DI")])
21643
21644 (define_insn "mmx_punpckhbw"
21645   [(set (match_operand:V8QI 0 "register_operand" "=y")
21646         (vec_merge:V8QI
21647          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21648                           (parallel [(const_int 4)
21649                                      (const_int 0)
21650                                      (const_int 5)
21651                                      (const_int 1)
21652                                      (const_int 6)
21653                                      (const_int 2)
21654                                      (const_int 7)
21655                                      (const_int 3)]))
21656          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21657                           (parallel [(const_int 0)
21658                                      (const_int 4)
21659                                      (const_int 1)
21660                                      (const_int 5)
21661                                      (const_int 2)
21662                                      (const_int 6)
21663                                      (const_int 3)
21664                                      (const_int 7)]))
21665          (const_int 85)))]
21666   "TARGET_MMX"
21667   "punpckhbw\t{%2, %0|%0, %2}"
21668   [(set_attr "type" "mmxcvt")
21669    (set_attr "mode" "DI")])
21670
21671 (define_insn "mmx_punpckhwd"
21672   [(set (match_operand:V4HI 0 "register_operand" "=y")
21673         (vec_merge:V4HI
21674          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21675                           (parallel [(const_int 0)
21676                                      (const_int 2)
21677                                      (const_int 1)
21678                                      (const_int 3)]))
21679          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21680                           (parallel [(const_int 2)
21681                                      (const_int 0)
21682                                      (const_int 3)
21683                                      (const_int 1)]))
21684          (const_int 5)))]
21685   "TARGET_MMX"
21686   "punpckhwd\t{%2, %0|%0, %2}"
21687   [(set_attr "type" "mmxcvt")
21688    (set_attr "mode" "DI")])
21689
21690 (define_insn "mmx_punpckhdq"
21691   [(set (match_operand:V2SI 0 "register_operand" "=y")
21692         (vec_merge:V2SI
21693          (match_operand:V2SI 1 "register_operand" "0")
21694          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21695                           (parallel [(const_int 1)
21696                                      (const_int 0)]))
21697          (const_int 1)))]
21698   "TARGET_MMX"
21699   "punpckhdq\t{%2, %0|%0, %2}"
21700   [(set_attr "type" "mmxcvt")
21701    (set_attr "mode" "DI")])
21702
21703 (define_insn "mmx_punpcklbw"
21704   [(set (match_operand:V8QI 0 "register_operand" "=y")
21705         (vec_merge:V8QI
21706          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21707                           (parallel [(const_int 0)
21708                                      (const_int 4)
21709                                      (const_int 1)
21710                                      (const_int 5)
21711                                      (const_int 2)
21712                                      (const_int 6)
21713                                      (const_int 3)
21714                                      (const_int 7)]))
21715          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21716                           (parallel [(const_int 4)
21717                                      (const_int 0)
21718                                      (const_int 5)
21719                                      (const_int 1)
21720                                      (const_int 6)
21721                                      (const_int 2)
21722                                      (const_int 7)
21723                                      (const_int 3)]))
21724          (const_int 85)))]
21725   "TARGET_MMX"
21726   "punpcklbw\t{%2, %0|%0, %2}"
21727   [(set_attr "type" "mmxcvt")
21728    (set_attr "mode" "DI")])
21729
21730 (define_insn "mmx_punpcklwd"
21731   [(set (match_operand:V4HI 0 "register_operand" "=y")
21732         (vec_merge:V4HI
21733          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21734                           (parallel [(const_int 2)
21735                                      (const_int 0)
21736                                      (const_int 3)
21737                                      (const_int 1)]))
21738          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21739                           (parallel [(const_int 0)
21740                                      (const_int 2)
21741                                      (const_int 1)
21742                                      (const_int 3)]))
21743          (const_int 5)))]
21744   "TARGET_MMX"
21745   "punpcklwd\t{%2, %0|%0, %2}"
21746   [(set_attr "type" "mmxcvt")
21747    (set_attr "mode" "DI")])
21748
21749 (define_insn "mmx_punpckldq"
21750   [(set (match_operand:V2SI 0 "register_operand" "=y")
21751         (vec_merge:V2SI
21752          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21753                            (parallel [(const_int 1)
21754                                       (const_int 0)]))
21755          (match_operand:V2SI 2 "register_operand" "y")
21756          (const_int 1)))]
21757   "TARGET_MMX"
21758   "punpckldq\t{%2, %0|%0, %2}"
21759   [(set_attr "type" "mmxcvt")
21760    (set_attr "mode" "DI")])
21761
21762
21763 ;; Miscellaneous stuff
21764
21765 (define_insn "emms"
21766   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21767    (clobber (reg:XF 8))
21768    (clobber (reg:XF 9))
21769    (clobber (reg:XF 10))
21770    (clobber (reg:XF 11))
21771    (clobber (reg:XF 12))
21772    (clobber (reg:XF 13))
21773    (clobber (reg:XF 14))
21774    (clobber (reg:XF 15))
21775    (clobber (reg:DI 29))
21776    (clobber (reg:DI 30))
21777    (clobber (reg:DI 31))
21778    (clobber (reg:DI 32))
21779    (clobber (reg:DI 33))
21780    (clobber (reg:DI 34))
21781    (clobber (reg:DI 35))
21782    (clobber (reg:DI 36))]
21783   "TARGET_MMX"
21784   "emms"
21785   [(set_attr "type" "mmx")
21786    (set_attr "memory" "unknown")])
21787
21788 (define_insn "ldmxcsr"
21789   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21790                     UNSPECV_LDMXCSR)]
21791   "TARGET_SSE"
21792   "ldmxcsr\t%0"
21793   [(set_attr "type" "sse")
21794    (set_attr "memory" "load")])
21795
21796 (define_insn "stmxcsr"
21797   [(set (match_operand:SI 0 "memory_operand" "=m")
21798         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21799   "TARGET_SSE"
21800   "stmxcsr\t%0"
21801   [(set_attr "type" "sse")
21802    (set_attr "memory" "store")])
21803
21804 (define_expand "sfence"
21805   [(set (match_dup 0)
21806         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21807   "TARGET_SSE || TARGET_3DNOW_A"
21808 {
21809   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21810   MEM_VOLATILE_P (operands[0]) = 1;
21811 })
21812
21813 (define_insn "*sfence_insn"
21814   [(set (match_operand:BLK 0 "" "")
21815         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21816   "TARGET_SSE || TARGET_3DNOW_A"
21817   "sfence"
21818   [(set_attr "type" "sse")
21819    (set_attr "memory" "unknown")])
21820
21821 (define_expand "sse_prologue_save"
21822   [(parallel [(set (match_operand:BLK 0 "" "")
21823                    (unspec:BLK [(reg:DI 21)
21824                                 (reg:DI 22)
21825                                 (reg:DI 23)
21826                                 (reg:DI 24)
21827                                 (reg:DI 25)
21828                                 (reg:DI 26)
21829                                 (reg:DI 27)
21830                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21831               (use (match_operand:DI 1 "register_operand" ""))
21832               (use (match_operand:DI 2 "immediate_operand" ""))
21833               (use (label_ref:DI (match_operand 3 "" "")))])]
21834   "TARGET_64BIT"
21835   "")
21836
21837 (define_insn "*sse_prologue_save_insn"
21838   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21839                           (match_operand:DI 4 "const_int_operand" "n")))
21840         (unspec:BLK [(reg:DI 21)
21841                      (reg:DI 22)
21842                      (reg:DI 23)
21843                      (reg:DI 24)
21844                      (reg:DI 25)
21845                      (reg:DI 26)
21846                      (reg:DI 27)
21847                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21848    (use (match_operand:DI 1 "register_operand" "r"))
21849    (use (match_operand:DI 2 "const_int_operand" "i"))
21850    (use (label_ref:DI (match_operand 3 "" "X")))]
21851   "TARGET_64BIT
21852    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21853    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21854   "*
21855 {
21856   int i;
21857   operands[0] = gen_rtx_MEM (Pmode,
21858                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21859   output_asm_insn (\"jmp\\t%A1\", operands);
21860   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21861     {
21862       operands[4] = adjust_address (operands[0], DImode, i*16);
21863       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21864       PUT_MODE (operands[4], TImode);
21865       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21866         output_asm_insn (\"rex\", operands);
21867       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21868     }
21869   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21870                              CODE_LABEL_NUMBER (operands[3]));
21871   RET;
21872 }
21873   "
21874   [(set_attr "type" "other")
21875    (set_attr "length_immediate" "0")
21876    (set_attr "length_address" "0")
21877    (set_attr "length" "135")
21878    (set_attr "memory" "store")
21879    (set_attr "modrm" "0")
21880    (set_attr "mode" "DI")])
21881
21882 ;; 3Dnow! instructions
21883
21884 (define_insn "addv2sf3"
21885   [(set (match_operand:V2SF 0 "register_operand" "=y")
21886         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21887                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21888   "TARGET_3DNOW"
21889   "pfadd\\t{%2, %0|%0, %2}"
21890   [(set_attr "type" "mmxadd")
21891    (set_attr "mode" "V2SF")])
21892
21893 (define_insn "subv2sf3"
21894   [(set (match_operand:V2SF 0 "register_operand" "=y")
21895         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21896                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21897   "TARGET_3DNOW"
21898   "pfsub\\t{%2, %0|%0, %2}"
21899   [(set_attr "type" "mmxadd")
21900    (set_attr "mode" "V2SF")])
21901
21902 (define_insn "subrv2sf3"
21903   [(set (match_operand:V2SF 0 "register_operand" "=y")
21904         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21905                     (match_operand:V2SF 1 "register_operand" "0")))]
21906   "TARGET_3DNOW"
21907   "pfsubr\\t{%2, %0|%0, %2}"
21908   [(set_attr "type" "mmxadd")
21909    (set_attr "mode" "V2SF")])
21910
21911 (define_insn "gtv2sf3"
21912   [(set (match_operand:V2SI 0 "register_operand" "=y")
21913         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21914                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21915   "TARGET_3DNOW"
21916   "pfcmpgt\\t{%2, %0|%0, %2}"
21917   [(set_attr "type" "mmxcmp")
21918    (set_attr "mode" "V2SF")])
21919
21920 (define_insn "gev2sf3"
21921   [(set (match_operand:V2SI 0 "register_operand" "=y")
21922         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21923                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21924   "TARGET_3DNOW"
21925   "pfcmpge\\t{%2, %0|%0, %2}"
21926   [(set_attr "type" "mmxcmp")
21927    (set_attr "mode" "V2SF")])
21928
21929 (define_insn "eqv2sf3"
21930   [(set (match_operand:V2SI 0 "register_operand" "=y")
21931         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21932                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21933   "TARGET_3DNOW"
21934   "pfcmpeq\\t{%2, %0|%0, %2}"
21935   [(set_attr "type" "mmxcmp")
21936    (set_attr "mode" "V2SF")])
21937
21938 (define_insn "pfmaxv2sf3"
21939   [(set (match_operand:V2SF 0 "register_operand" "=y")
21940         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21941                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21942   "TARGET_3DNOW"
21943   "pfmax\\t{%2, %0|%0, %2}"
21944   [(set_attr "type" "mmxadd")
21945    (set_attr "mode" "V2SF")])
21946
21947 (define_insn "pfminv2sf3"
21948   [(set (match_operand:V2SF 0 "register_operand" "=y")
21949         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21950                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21951   "TARGET_3DNOW"
21952   "pfmin\\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "mmxadd")
21954    (set_attr "mode" "V2SF")])
21955
21956 (define_insn "mulv2sf3"
21957   [(set (match_operand:V2SF 0 "register_operand" "=y")
21958         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21959                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21960   "TARGET_3DNOW"
21961   "pfmul\\t{%2, %0|%0, %2}"
21962   [(set_attr "type" "mmxmul")
21963    (set_attr "mode" "V2SF")])
21964
21965 (define_insn "femms"
21966   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21967    (clobber (reg:XF 8))
21968    (clobber (reg:XF 9))
21969    (clobber (reg:XF 10))
21970    (clobber (reg:XF 11))
21971    (clobber (reg:XF 12))
21972    (clobber (reg:XF 13))
21973    (clobber (reg:XF 14))
21974    (clobber (reg:XF 15))
21975    (clobber (reg:DI 29))
21976    (clobber (reg:DI 30))
21977    (clobber (reg:DI 31))
21978    (clobber (reg:DI 32))
21979    (clobber (reg:DI 33))
21980    (clobber (reg:DI 34))
21981    (clobber (reg:DI 35))
21982    (clobber (reg:DI 36))]
21983   "TARGET_3DNOW"
21984   "femms"
21985   [(set_attr "type" "mmx")
21986    (set_attr "memory" "none")]) 
21987
21988 (define_insn "pf2id"
21989   [(set (match_operand:V2SI 0 "register_operand" "=y")
21990         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21991   "TARGET_3DNOW"
21992   "pf2id\\t{%1, %0|%0, %1}"
21993   [(set_attr "type" "mmxcvt")
21994    (set_attr "mode" "V2SF")])
21995
21996 (define_insn "pf2iw"
21997   [(set (match_operand:V2SI 0 "register_operand" "=y")
21998         (sign_extend:V2SI
21999            (ss_truncate:V2HI
22000               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22001   "TARGET_3DNOW_A"
22002   "pf2iw\\t{%1, %0|%0, %1}"
22003   [(set_attr "type" "mmxcvt")
22004    (set_attr "mode" "V2SF")])
22005
22006 (define_insn "pfacc"
22007   [(set (match_operand:V2SF 0 "register_operand" "=y")
22008         (vec_concat:V2SF
22009            (plus:SF
22010               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22011                              (parallel [(const_int  0)]))
22012               (vec_select:SF (match_dup 1)
22013                              (parallel [(const_int 1)])))
22014            (plus:SF
22015               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22016                              (parallel [(const_int  0)]))
22017               (vec_select:SF (match_dup 2)
22018                              (parallel [(const_int 1)])))))]
22019   "TARGET_3DNOW"
22020   "pfacc\\t{%2, %0|%0, %2}"
22021   [(set_attr "type" "mmxadd")
22022    (set_attr "mode" "V2SF")])
22023
22024 (define_insn "pfnacc"
22025   [(set (match_operand:V2SF 0 "register_operand" "=y")
22026         (vec_concat:V2SF
22027            (minus:SF
22028               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22029                              (parallel [(const_int 0)]))
22030               (vec_select:SF (match_dup 1)
22031                              (parallel [(const_int 1)])))
22032            (minus:SF
22033               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22034                              (parallel [(const_int  0)]))
22035               (vec_select:SF (match_dup 2)
22036                              (parallel [(const_int 1)])))))]
22037   "TARGET_3DNOW_A"
22038   "pfnacc\\t{%2, %0|%0, %2}"
22039   [(set_attr "type" "mmxadd")
22040    (set_attr "mode" "V2SF")])
22041
22042 (define_insn "pfpnacc"
22043   [(set (match_operand:V2SF 0 "register_operand" "=y")
22044         (vec_concat:V2SF
22045            (minus:SF
22046               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22047                              (parallel [(const_int 0)]))
22048               (vec_select:SF (match_dup 1)
22049                              (parallel [(const_int 1)])))
22050            (plus:SF
22051               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22052                              (parallel [(const_int 0)]))
22053               (vec_select:SF (match_dup 2)
22054                              (parallel [(const_int 1)])))))]
22055   "TARGET_3DNOW_A"
22056   "pfpnacc\\t{%2, %0|%0, %2}"
22057   [(set_attr "type" "mmxadd")
22058    (set_attr "mode" "V2SF")])
22059
22060 (define_insn "pi2fw"
22061   [(set (match_operand:V2SF 0 "register_operand" "=y")
22062         (float:V2SF
22063            (vec_concat:V2SI
22064               (sign_extend:SI
22065                  (truncate:HI
22066                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22067                                    (parallel [(const_int 0)]))))
22068               (sign_extend:SI
22069                  (truncate:HI
22070                     (vec_select:SI (match_dup 1)
22071                                    (parallel [(const_int  1)])))))))]
22072   "TARGET_3DNOW_A"
22073   "pi2fw\\t{%1, %0|%0, %1}"
22074   [(set_attr "type" "mmxcvt")
22075    (set_attr "mode" "V2SF")])
22076
22077 (define_insn "floatv2si2"
22078   [(set (match_operand:V2SF 0 "register_operand" "=y")
22079         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22080   "TARGET_3DNOW"
22081   "pi2fd\\t{%1, %0|%0, %1}"
22082   [(set_attr "type" "mmxcvt")
22083    (set_attr "mode" "V2SF")])
22084
22085 ;; This insn is identical to pavgb in operation, but the opcode is
22086 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22087
22088 (define_insn "pavgusb"
22089  [(set (match_operand:V8QI 0 "register_operand" "=y")
22090        (unspec:V8QI
22091           [(match_operand:V8QI 1 "register_operand" "0")
22092            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22093           UNSPEC_PAVGUSB))]
22094   "TARGET_3DNOW"
22095   "pavgusb\\t{%2, %0|%0, %2}"
22096   [(set_attr "type" "mmxshft")
22097    (set_attr "mode" "TI")])
22098
22099 ;; 3DNow reciprocal and sqrt
22100  
22101 (define_insn "pfrcpv2sf2"
22102   [(set (match_operand:V2SF 0 "register_operand" "=y")
22103         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22104         UNSPEC_PFRCP))]
22105   "TARGET_3DNOW"
22106   "pfrcp\\t{%1, %0|%0, %1}"
22107   [(set_attr "type" "mmx")
22108    (set_attr "mode" "TI")])
22109
22110 (define_insn "pfrcpit1v2sf3"
22111   [(set (match_operand:V2SF 0 "register_operand" "=y")
22112         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22113                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22114                      UNSPEC_PFRCPIT1))]
22115   "TARGET_3DNOW"
22116   "pfrcpit1\\t{%2, %0|%0, %2}"
22117   [(set_attr "type" "mmx")
22118    (set_attr "mode" "TI")])
22119
22120 (define_insn "pfrcpit2v2sf3"
22121   [(set (match_operand:V2SF 0 "register_operand" "=y")
22122         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22123                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22124                      UNSPEC_PFRCPIT2))]
22125   "TARGET_3DNOW"
22126   "pfrcpit2\\t{%2, %0|%0, %2}"
22127   [(set_attr "type" "mmx")
22128    (set_attr "mode" "TI")])
22129
22130 (define_insn "pfrsqrtv2sf2"
22131   [(set (match_operand:V2SF 0 "register_operand" "=y")
22132         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22133                      UNSPEC_PFRSQRT))]
22134   "TARGET_3DNOW"
22135   "pfrsqrt\\t{%1, %0|%0, %1}"
22136   [(set_attr "type" "mmx")
22137    (set_attr "mode" "TI")])
22138                 
22139 (define_insn "pfrsqit1v2sf3"
22140   [(set (match_operand:V2SF 0 "register_operand" "=y")
22141         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22142                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22143                      UNSPEC_PFRSQIT1))]
22144   "TARGET_3DNOW"
22145   "pfrsqit1\\t{%2, %0|%0, %2}"
22146   [(set_attr "type" "mmx")
22147    (set_attr "mode" "TI")])
22148
22149 (define_insn "pmulhrwv4hi3"
22150   [(set (match_operand:V4HI 0 "register_operand" "=y")
22151         (truncate:V4HI
22152            (lshiftrt:V4SI
22153               (plus:V4SI
22154                  (mult:V4SI
22155                     (sign_extend:V4SI
22156                        (match_operand:V4HI 1 "register_operand" "0"))
22157                     (sign_extend:V4SI
22158                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22159                  (const_vector:V4SI [(const_int 32768)
22160                                      (const_int 32768)
22161                                      (const_int 32768)
22162                                      (const_int 32768)]))
22163               (const_int 16))))]
22164   "TARGET_3DNOW"
22165   "pmulhrw\\t{%2, %0|%0, %2}"
22166   [(set_attr "type" "mmxmul")
22167    (set_attr "mode" "TI")])
22168
22169 (define_insn "pswapdv2si2"
22170   [(set (match_operand:V2SI 0 "register_operand" "=y")
22171         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22172                          (parallel [(const_int 1) (const_int 0)])))]
22173   "TARGET_3DNOW_A"
22174   "pswapd\\t{%1, %0|%0, %1}"
22175   [(set_attr "type" "mmxcvt")
22176    (set_attr "mode" "TI")])
22177
22178 (define_insn "pswapdv2sf2"
22179   [(set (match_operand:V2SF 0 "register_operand" "=y")
22180         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22181                          (parallel [(const_int 1) (const_int 0)])))]
22182   "TARGET_3DNOW_A"
22183   "pswapd\\t{%1, %0|%0, %1}"
22184   [(set_attr "type" "mmxcvt")
22185    (set_attr "mode" "TI")])
22186
22187 (define_expand "prefetch"
22188   [(prefetch (match_operand 0 "address_operand" "")
22189              (match_operand:SI 1 "const_int_operand" "")
22190              (match_operand:SI 2 "const_int_operand" ""))]
22191   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22192 {
22193   int rw = INTVAL (operands[1]);
22194   int locality = INTVAL (operands[2]);
22195
22196   if (rw != 0 && rw != 1)
22197     abort ();
22198   if (locality < 0 || locality > 3)
22199     abort ();
22200   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22201     abort ();
22202
22203   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22204      suported by SSE counterpart or the SSE prefetch is not available
22205      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22206      of locality.  */
22207   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22208     operands[2] = GEN_INT (3);
22209   else
22210     operands[1] = const0_rtx;
22211 })
22212
22213 (define_insn "*prefetch_sse"
22214   [(prefetch (match_operand:SI 0 "address_operand" "p")
22215              (const_int 0)
22216              (match_operand:SI 1 "const_int_operand" ""))]
22217   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22218 {
22219   static const char * const patterns[4] = {
22220    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22221   };
22222
22223   int locality = INTVAL (operands[1]);
22224   if (locality < 0 || locality > 3)
22225     abort ();
22226
22227   return patterns[locality];  
22228 }
22229   [(set_attr "type" "sse")
22230    (set_attr "memory" "none")])
22231
22232 (define_insn "*prefetch_sse_rex"
22233   [(prefetch (match_operand:DI 0 "address_operand" "p")
22234              (const_int 0)
22235              (match_operand:SI 1 "const_int_operand" ""))]
22236   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22237 {
22238   static const char * const patterns[4] = {
22239    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22240   };
22241
22242   int locality = INTVAL (operands[1]);
22243   if (locality < 0 || locality > 3)
22244     abort ();
22245
22246   return patterns[locality];  
22247 }
22248   [(set_attr "type" "sse")
22249    (set_attr "memory" "none")])
22250
22251 (define_insn "*prefetch_3dnow"
22252   [(prefetch (match_operand:SI 0 "address_operand" "p")
22253              (match_operand:SI 1 "const_int_operand" "n")
22254              (const_int 3))]
22255   "TARGET_3DNOW && !TARGET_64BIT"
22256 {
22257   if (INTVAL (operands[1]) == 0)
22258     return "prefetch\t%a0";
22259   else
22260     return "prefetchw\t%a0";
22261 }
22262   [(set_attr "type" "mmx")
22263    (set_attr "memory" "none")])
22264
22265 (define_insn "*prefetch_3dnow_rex"
22266   [(prefetch (match_operand:DI 0 "address_operand" "p")
22267              (match_operand:SI 1 "const_int_operand" "n")
22268              (const_int 3))]
22269   "TARGET_3DNOW && TARGET_64BIT"
22270 {
22271   if (INTVAL (operands[1]) == 0)
22272     return "prefetch\t%a0";
22273   else
22274     return "prefetchw\t%a0";
22275 }
22276   [(set_attr "type" "mmx")
22277    (set_attr "memory" "none")])
22278
22279 ;; SSE2 support
22280
22281 (define_insn "addv2df3"
22282   [(set (match_operand:V2DF 0 "register_operand" "=x")
22283         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22284                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22285   "TARGET_SSE2"
22286   "addpd\t{%2, %0|%0, %2}"
22287   [(set_attr "type" "sseadd")
22288    (set_attr "mode" "V2DF")])
22289
22290 (define_insn "vmaddv2df3"
22291   [(set (match_operand:V2DF 0 "register_operand" "=x")
22292         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22293                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22294                         (match_dup 1)
22295                         (const_int 1)))]
22296   "TARGET_SSE2"
22297   "addsd\t{%2, %0|%0, %2}"
22298   [(set_attr "type" "sseadd")
22299    (set_attr "mode" "DF")])
22300
22301 (define_insn "subv2df3"
22302   [(set (match_operand:V2DF 0 "register_operand" "=x")
22303         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22304                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22305   "TARGET_SSE2"
22306   "subpd\t{%2, %0|%0, %2}"
22307   [(set_attr "type" "sseadd")
22308    (set_attr "mode" "V2DF")])
22309
22310 (define_insn "vmsubv2df3"
22311   [(set (match_operand:V2DF 0 "register_operand" "=x")
22312         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22313                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22314                         (match_dup 1)
22315                         (const_int 1)))]
22316   "TARGET_SSE2"
22317   "subsd\t{%2, %0|%0, %2}"
22318   [(set_attr "type" "sseadd")
22319    (set_attr "mode" "DF")])
22320
22321 (define_insn "mulv2df3"
22322   [(set (match_operand:V2DF 0 "register_operand" "=x")
22323         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22324                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22325   "TARGET_SSE2"
22326   "mulpd\t{%2, %0|%0, %2}"
22327   [(set_attr "type" "ssemul")
22328    (set_attr "mode" "V2DF")])
22329
22330 (define_insn "vmmulv2df3"
22331   [(set (match_operand:V2DF 0 "register_operand" "=x")
22332         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22333                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22334                         (match_dup 1)
22335                         (const_int 1)))]
22336   "TARGET_SSE2"
22337   "mulsd\t{%2, %0|%0, %2}"
22338   [(set_attr "type" "ssemul")
22339    (set_attr "mode" "DF")])
22340
22341 (define_insn "divv2df3"
22342   [(set (match_operand:V2DF 0 "register_operand" "=x")
22343         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22344                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22345   "TARGET_SSE2"
22346   "divpd\t{%2, %0|%0, %2}"
22347   [(set_attr "type" "ssediv")
22348    (set_attr "mode" "V2DF")])
22349
22350 (define_insn "vmdivv2df3"
22351   [(set (match_operand:V2DF 0 "register_operand" "=x")
22352         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22353                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22354                         (match_dup 1)
22355                         (const_int 1)))]
22356   "TARGET_SSE2"
22357   "divsd\t{%2, %0|%0, %2}"
22358   [(set_attr "type" "ssediv")
22359    (set_attr "mode" "DF")])
22360
22361 ;; SSE min/max
22362
22363 (define_insn "smaxv2df3"
22364   [(set (match_operand:V2DF 0 "register_operand" "=x")
22365         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22366                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22367   "TARGET_SSE2"
22368   "maxpd\t{%2, %0|%0, %2}"
22369   [(set_attr "type" "sseadd")
22370    (set_attr "mode" "V2DF")])
22371
22372 (define_insn "vmsmaxv2df3"
22373   [(set (match_operand:V2DF 0 "register_operand" "=x")
22374         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22375                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22376                         (match_dup 1)
22377                         (const_int 1)))]
22378   "TARGET_SSE2"
22379   "maxsd\t{%2, %0|%0, %2}"
22380   [(set_attr "type" "sseadd")
22381    (set_attr "mode" "DF")])
22382
22383 (define_insn "sminv2df3"
22384   [(set (match_operand:V2DF 0 "register_operand" "=x")
22385         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22386                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22387   "TARGET_SSE2"
22388   "minpd\t{%2, %0|%0, %2}"
22389   [(set_attr "type" "sseadd")
22390    (set_attr "mode" "V2DF")])
22391
22392 (define_insn "vmsminv2df3"
22393   [(set (match_operand:V2DF 0 "register_operand" "=x")
22394         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22395                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22396                         (match_dup 1)
22397                         (const_int 1)))]
22398   "TARGET_SSE2"
22399   "minsd\t{%2, %0|%0, %2}"
22400   [(set_attr "type" "sseadd")
22401    (set_attr "mode" "DF")])
22402 ;; SSE2 square root.  There doesn't appear to be an extension for the
22403 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22404
22405 (define_insn "sqrtv2df2"
22406   [(set (match_operand:V2DF 0 "register_operand" "=x")
22407         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22408   "TARGET_SSE2"
22409   "sqrtpd\t{%1, %0|%0, %1}"
22410   [(set_attr "type" "sse")
22411    (set_attr "mode" "V2DF")])
22412
22413 (define_insn "vmsqrtv2df2"
22414   [(set (match_operand:V2DF 0 "register_operand" "=x")
22415         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22416                         (match_operand:V2DF 2 "register_operand" "0")
22417                         (const_int 1)))]
22418   "TARGET_SSE2"
22419   "sqrtsd\t{%1, %0|%0, %1}"
22420   [(set_attr "type" "sse")
22421    (set_attr "mode" "SF")])
22422
22423 ;; SSE mask-generating compares
22424
22425 (define_insn "maskcmpv2df3"
22426   [(set (match_operand:V2DI 0 "register_operand" "=x")
22427         (match_operator:V2DI 3 "sse_comparison_operator"
22428                              [(match_operand:V2DF 1 "register_operand" "0")
22429                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22430   "TARGET_SSE2"
22431   "cmp%D3pd\t{%2, %0|%0, %2}"
22432   [(set_attr "type" "ssecmp")
22433    (set_attr "mode" "V2DF")])
22434
22435 (define_insn "maskncmpv2df3"
22436   [(set (match_operand:V2DI 0 "register_operand" "=x")
22437         (not:V2DI
22438          (match_operator:V2DI 3 "sse_comparison_operator"
22439                               [(match_operand:V2DF 1 "register_operand" "0")
22440                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22441   "TARGET_SSE2"
22442 {
22443   if (GET_CODE (operands[3]) == UNORDERED)
22444     return "cmpordps\t{%2, %0|%0, %2}";
22445   else
22446     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22447 }
22448   [(set_attr "type" "ssecmp")
22449    (set_attr "mode" "V2DF")])
22450
22451 (define_insn "vmmaskcmpv2df3"
22452   [(set (match_operand:V2DI 0 "register_operand" "=x")
22453         (vec_merge:V2DI
22454          (match_operator:V2DI 3 "sse_comparison_operator"
22455                               [(match_operand:V2DF 1 "register_operand" "0")
22456                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22457          (subreg:V2DI (match_dup 1) 0)
22458          (const_int 1)))]
22459   "TARGET_SSE2"
22460   "cmp%D3sd\t{%2, %0|%0, %2}"
22461   [(set_attr "type" "ssecmp")
22462    (set_attr "mode" "DF")])
22463
22464 (define_insn "vmmaskncmpv2df3"
22465   [(set (match_operand:V2DI 0 "register_operand" "=x")
22466         (vec_merge:V2DI
22467          (not:V2DI
22468           (match_operator:V2DI 3 "sse_comparison_operator"
22469                                [(match_operand:V2DF 1 "register_operand" "0")
22470                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22471          (subreg:V2DI (match_dup 1) 0)
22472          (const_int 1)))]
22473   "TARGET_SSE2"
22474 {
22475   if (GET_CODE (operands[3]) == UNORDERED)
22476     return "cmpordsd\t{%2, %0|%0, %2}";
22477   else
22478     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22479 }
22480   [(set_attr "type" "ssecmp")
22481    (set_attr "mode" "DF")])
22482
22483 (define_insn "sse2_comi"
22484   [(set (reg:CCFP FLAGS_REG)
22485         (compare:CCFP (vec_select:DF
22486                        (match_operand:V2DF 0 "register_operand" "x")
22487                        (parallel [(const_int 0)]))
22488                       (vec_select:DF
22489                        (match_operand:V2DF 1 "register_operand" "x")
22490                        (parallel [(const_int 0)]))))]
22491   "TARGET_SSE2"
22492   "comisd\t{%1, %0|%0, %1}"
22493   [(set_attr "type" "ssecomi")
22494    (set_attr "mode" "DF")])
22495
22496 (define_insn "sse2_ucomi"
22497   [(set (reg:CCFPU FLAGS_REG)
22498         (compare:CCFPU (vec_select:DF
22499                          (match_operand:V2DF 0 "register_operand" "x")
22500                          (parallel [(const_int 0)]))
22501                         (vec_select:DF
22502                          (match_operand:V2DF 1 "register_operand" "x")
22503                          (parallel [(const_int 0)]))))]
22504   "TARGET_SSE2"
22505   "ucomisd\t{%1, %0|%0, %1}"
22506   [(set_attr "type" "ssecomi")
22507    (set_attr "mode" "DF")])
22508
22509 ;; SSE Strange Moves.
22510
22511 (define_insn "sse2_movmskpd"
22512   [(set (match_operand:SI 0 "register_operand" "=r")
22513         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22514                    UNSPEC_MOVMSK))]
22515   "TARGET_SSE2"
22516   "movmskpd\t{%1, %0|%0, %1}"
22517   [(set_attr "type" "ssecvt")
22518    (set_attr "mode" "V2DF")])
22519
22520 (define_insn "sse2_pmovmskb"
22521   [(set (match_operand:SI 0 "register_operand" "=r")
22522         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22523                    UNSPEC_MOVMSK))]
22524   "TARGET_SSE2"
22525   "pmovmskb\t{%1, %0|%0, %1}"
22526   [(set_attr "type" "ssecvt")
22527    (set_attr "mode" "V2DF")])
22528
22529 (define_insn "sse2_maskmovdqu"
22530   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22531         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22532                        (match_operand:V16QI 2 "register_operand" "x")]
22533                       UNSPEC_MASKMOV))]
22534   "TARGET_SSE2"
22535   ;; @@@ check ordering of operands in intel/nonintel syntax
22536   "maskmovdqu\t{%2, %1|%1, %2}"
22537   [(set_attr "type" "ssecvt")
22538    (set_attr "mode" "TI")])
22539
22540 (define_insn "sse2_maskmovdqu_rex64"
22541   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22542         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22543                        (match_operand:V16QI 2 "register_operand" "x")]
22544                       UNSPEC_MASKMOV))]
22545   "TARGET_SSE2"
22546   ;; @@@ check ordering of operands in intel/nonintel syntax
22547   "maskmovdqu\t{%2, %1|%1, %2}"
22548   [(set_attr "type" "ssecvt")
22549    (set_attr "mode" "TI")])
22550
22551 (define_insn "sse2_movntv2df"
22552   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22553         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22554                      UNSPEC_MOVNT))]
22555   "TARGET_SSE2"
22556   "movntpd\t{%1, %0|%0, %1}"
22557   [(set_attr "type" "ssecvt")
22558    (set_attr "mode" "V2DF")])
22559
22560 (define_insn "sse2_movntv2di"
22561   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22562         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22563                      UNSPEC_MOVNT))]
22564   "TARGET_SSE2"
22565   "movntdq\t{%1, %0|%0, %1}"
22566   [(set_attr "type" "ssecvt")
22567    (set_attr "mode" "TI")])
22568
22569 (define_insn "sse2_movntsi"
22570   [(set (match_operand:SI 0 "memory_operand" "=m")
22571         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22572                    UNSPEC_MOVNT))]
22573   "TARGET_SSE2"
22574   "movnti\t{%1, %0|%0, %1}"
22575   [(set_attr "type" "ssecvt")
22576    (set_attr "mode" "V2DF")])
22577
22578 ;; SSE <-> integer/MMX conversions
22579
22580 ;; Conversions between SI and SF
22581
22582 (define_insn "cvtdq2ps"
22583   [(set (match_operand:V4SF 0 "register_operand" "=x")
22584         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22585   "TARGET_SSE2"
22586   "cvtdq2ps\t{%1, %0|%0, %1}"
22587   [(set_attr "type" "ssecvt")
22588    (set_attr "mode" "V2DF")])
22589
22590 (define_insn "cvtps2dq"
22591   [(set (match_operand:V4SI 0 "register_operand" "=x")
22592         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22593   "TARGET_SSE2"
22594   "cvtps2dq\t{%1, %0|%0, %1}"
22595   [(set_attr "type" "ssecvt")
22596    (set_attr "mode" "TI")])
22597
22598 (define_insn "cvttps2dq"
22599   [(set (match_operand:V4SI 0 "register_operand" "=x")
22600         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22601                      UNSPEC_FIX))]
22602   "TARGET_SSE2"
22603   "cvttps2dq\t{%1, %0|%0, %1}"
22604   [(set_attr "type" "ssecvt")
22605    (set_attr "mode" "TI")])
22606
22607 ;; Conversions between SI and DF
22608
22609 (define_insn "cvtdq2pd"
22610   [(set (match_operand:V2DF 0 "register_operand" "=x")
22611         (float:V2DF (vec_select:V2SI
22612                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22613                      (parallel
22614                       [(const_int 0)
22615                        (const_int 1)]))))]
22616   "TARGET_SSE2"
22617   "cvtdq2pd\t{%1, %0|%0, %1}"
22618   [(set_attr "type" "ssecvt")
22619    (set_attr "mode" "V2DF")])
22620
22621 (define_insn "cvtpd2dq"
22622   [(set (match_operand:V4SI 0 "register_operand" "=x")
22623         (vec_concat:V4SI
22624          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22625          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22626   "TARGET_SSE2"
22627   "cvtpd2dq\t{%1, %0|%0, %1}"
22628   [(set_attr "type" "ssecvt")
22629    (set_attr "mode" "TI")])
22630
22631 (define_insn "cvttpd2dq"
22632   [(set (match_operand:V4SI 0 "register_operand" "=x")
22633         (vec_concat:V4SI
22634          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22635                       UNSPEC_FIX)
22636          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22637   "TARGET_SSE2"
22638   "cvttpd2dq\t{%1, %0|%0, %1}"
22639   [(set_attr "type" "ssecvt")
22640    (set_attr "mode" "TI")])
22641
22642 (define_insn "cvtpd2pi"
22643   [(set (match_operand:V2SI 0 "register_operand" "=y")
22644         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22645   "TARGET_SSE2"
22646   "cvtpd2pi\t{%1, %0|%0, %1}"
22647   [(set_attr "type" "ssecvt")
22648    (set_attr "mode" "TI")])
22649
22650 (define_insn "cvttpd2pi"
22651   [(set (match_operand:V2SI 0 "register_operand" "=y")
22652         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22653                      UNSPEC_FIX))]
22654   "TARGET_SSE2"
22655   "cvttpd2pi\t{%1, %0|%0, %1}"
22656   [(set_attr "type" "ssecvt")
22657    (set_attr "mode" "TI")])
22658
22659 (define_insn "cvtpi2pd"
22660   [(set (match_operand:V2DF 0 "register_operand" "=x")
22661         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22662   "TARGET_SSE2"
22663   "cvtpi2pd\t{%1, %0|%0, %1}"
22664   [(set_attr "type" "ssecvt")
22665    (set_attr "mode" "TI")])
22666
22667 ;; Conversions between SI and DF
22668
22669 (define_insn "cvtsd2si"
22670   [(set (match_operand:SI 0 "register_operand" "=r,r")
22671         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22672                                (parallel [(const_int 0)]))))]
22673   "TARGET_SSE2"
22674   "cvtsd2si\t{%1, %0|%0, %1}"
22675   [(set_attr "type" "sseicvt")
22676    (set_attr "athlon_decode" "double,vector")
22677    (set_attr "mode" "SI")])
22678
22679 (define_insn "cvtsd2siq"
22680   [(set (match_operand:DI 0 "register_operand" "=r,r")
22681         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22682                                (parallel [(const_int 0)]))))]
22683   "TARGET_SSE2 && TARGET_64BIT"
22684   "cvtsd2siq\t{%1, %0|%0, %1}"
22685   [(set_attr "type" "sseicvt")
22686    (set_attr "athlon_decode" "double,vector")
22687    (set_attr "mode" "DI")])
22688
22689 (define_insn "cvttsd2si"
22690   [(set (match_operand:SI 0 "register_operand" "=r,r")
22691         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22692                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22693   "TARGET_SSE2"
22694   "cvttsd2si\t{%1, %0|%0, %1}"
22695   [(set_attr "type" "sseicvt")
22696    (set_attr "mode" "SI")
22697    (set_attr "athlon_decode" "double,vector")])
22698
22699 (define_insn "cvttsd2siq"
22700   [(set (match_operand:DI 0 "register_operand" "=r,r")
22701         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22702                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22703   "TARGET_SSE2 && TARGET_64BIT"
22704   "cvttsd2siq\t{%1, %0|%0, %1}"
22705   [(set_attr "type" "sseicvt")
22706    (set_attr "mode" "DI")
22707    (set_attr "athlon_decode" "double,vector")])
22708
22709 (define_insn "cvtsi2sd"
22710   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22711         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22712                         (vec_duplicate:V2DF
22713                           (float:DF
22714                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22715                         (const_int 2)))]
22716   "TARGET_SSE2"
22717   "cvtsi2sd\t{%2, %0|%0, %2}"
22718   [(set_attr "type" "sseicvt")
22719    (set_attr "mode" "DF")
22720    (set_attr "athlon_decode" "double,direct")])
22721
22722 (define_insn "cvtsi2sdq"
22723   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22724         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22725                         (vec_duplicate:V2DF
22726                           (float:DF
22727                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22728                         (const_int 2)))]
22729   "TARGET_SSE2 && TARGET_64BIT"
22730   "cvtsi2sdq\t{%2, %0|%0, %2}"
22731   [(set_attr "type" "sseicvt")
22732    (set_attr "mode" "DF")
22733    (set_attr "athlon_decode" "double,direct")])
22734
22735 ;; Conversions between SF and DF
22736
22737 (define_insn "cvtsd2ss"
22738   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22739         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22740                         (vec_duplicate:V4SF
22741                           (float_truncate:V2SF
22742                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22743                         (const_int 14)))]
22744   "TARGET_SSE2"
22745   "cvtsd2ss\t{%2, %0|%0, %2}"
22746   [(set_attr "type" "ssecvt")
22747    (set_attr "athlon_decode" "vector,double")
22748    (set_attr "mode" "SF")])
22749
22750 (define_insn "cvtss2sd"
22751   [(set (match_operand:V2DF 0 "register_operand" "=x")
22752         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22753                         (float_extend:V2DF
22754                           (vec_select:V2SF
22755                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22756                             (parallel [(const_int 0)
22757                                        (const_int 1)])))
22758                         (const_int 2)))]
22759   "TARGET_SSE2"
22760   "cvtss2sd\t{%2, %0|%0, %2}"
22761   [(set_attr "type" "ssecvt")
22762    (set_attr "mode" "DF")])
22763
22764 (define_insn "cvtpd2ps"
22765   [(set (match_operand:V4SF 0 "register_operand" "=x")
22766         (subreg:V4SF
22767           (vec_concat:V4SI
22768             (subreg:V2SI (float_truncate:V2SF
22769                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22770             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22771   "TARGET_SSE2"
22772   "cvtpd2ps\t{%1, %0|%0, %1}"
22773   [(set_attr "type" "ssecvt")
22774    (set_attr "mode" "V4SF")])
22775
22776 (define_insn "cvtps2pd"
22777   [(set (match_operand:V2DF 0 "register_operand" "=x")
22778         (float_extend:V2DF
22779           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22780                            (parallel [(const_int 0)
22781                                       (const_int 1)]))))]
22782   "TARGET_SSE2"
22783   "cvtps2pd\t{%1, %0|%0, %1}"
22784   [(set_attr "type" "ssecvt")
22785    (set_attr "mode" "V2DF")])
22786
22787 ;; SSE2 variants of MMX insns
22788
22789 ;; MMX arithmetic
22790
22791 (define_insn "addv16qi3"
22792   [(set (match_operand:V16QI 0 "register_operand" "=x")
22793         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22794                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22795   "TARGET_SSE2"
22796   "paddb\t{%2, %0|%0, %2}"
22797   [(set_attr "type" "sseiadd")
22798    (set_attr "mode" "TI")])
22799
22800 (define_insn "addv8hi3"
22801   [(set (match_operand:V8HI 0 "register_operand" "=x")
22802         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22803                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22804   "TARGET_SSE2"
22805   "paddw\t{%2, %0|%0, %2}"
22806   [(set_attr "type" "sseiadd")
22807    (set_attr "mode" "TI")])
22808
22809 (define_insn "addv4si3"
22810   [(set (match_operand:V4SI 0 "register_operand" "=x")
22811         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22812                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22813   "TARGET_SSE2"
22814   "paddd\t{%2, %0|%0, %2}"
22815   [(set_attr "type" "sseiadd")
22816    (set_attr "mode" "TI")])
22817
22818 (define_insn "addv2di3"
22819   [(set (match_operand:V2DI 0 "register_operand" "=x")
22820         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22821                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22822   "TARGET_SSE2"
22823   "paddq\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "sseiadd")
22825    (set_attr "mode" "TI")])
22826
22827 (define_insn "ssaddv16qi3"
22828   [(set (match_operand:V16QI 0 "register_operand" "=x")
22829         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22830                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22831   "TARGET_SSE2"
22832   "paddsb\t{%2, %0|%0, %2}"
22833   [(set_attr "type" "sseiadd")
22834    (set_attr "mode" "TI")])
22835
22836 (define_insn "ssaddv8hi3"
22837   [(set (match_operand:V8HI 0 "register_operand" "=x")
22838         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22839                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22840   "TARGET_SSE2"
22841   "paddsw\t{%2, %0|%0, %2}"
22842   [(set_attr "type" "sseiadd")
22843    (set_attr "mode" "TI")])
22844
22845 (define_insn "usaddv16qi3"
22846   [(set (match_operand:V16QI 0 "register_operand" "=x")
22847         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22848                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22849   "TARGET_SSE2"
22850   "paddusb\t{%2, %0|%0, %2}"
22851   [(set_attr "type" "sseiadd")
22852    (set_attr "mode" "TI")])
22853
22854 (define_insn "usaddv8hi3"
22855   [(set (match_operand:V8HI 0 "register_operand" "=x")
22856         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22857                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22858   "TARGET_SSE2"
22859   "paddusw\t{%2, %0|%0, %2}"
22860   [(set_attr "type" "sseiadd")
22861    (set_attr "mode" "TI")])
22862
22863 (define_insn "subv16qi3"
22864   [(set (match_operand:V16QI 0 "register_operand" "=x")
22865         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22866                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22867   "TARGET_SSE2"
22868   "psubb\t{%2, %0|%0, %2}"
22869   [(set_attr "type" "sseiadd")
22870    (set_attr "mode" "TI")])
22871
22872 (define_insn "subv8hi3"
22873   [(set (match_operand:V8HI 0 "register_operand" "=x")
22874         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22875                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22876   "TARGET_SSE2"
22877   "psubw\t{%2, %0|%0, %2}"
22878   [(set_attr "type" "sseiadd")
22879    (set_attr "mode" "TI")])
22880
22881 (define_insn "subv4si3"
22882   [(set (match_operand:V4SI 0 "register_operand" "=x")
22883         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22884                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22885   "TARGET_SSE2"
22886   "psubd\t{%2, %0|%0, %2}"
22887   [(set_attr "type" "sseiadd")
22888    (set_attr "mode" "TI")])
22889
22890 (define_insn "subv2di3"
22891   [(set (match_operand:V2DI 0 "register_operand" "=x")
22892         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22893                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22894   "TARGET_SSE2"
22895   "psubq\t{%2, %0|%0, %2}"
22896   [(set_attr "type" "sseiadd")
22897    (set_attr "mode" "TI")])
22898
22899 (define_insn "sssubv16qi3"
22900   [(set (match_operand:V16QI 0 "register_operand" "=x")
22901         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22902                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22903   "TARGET_SSE2"
22904   "psubsb\t{%2, %0|%0, %2}"
22905   [(set_attr "type" "sseiadd")
22906    (set_attr "mode" "TI")])
22907
22908 (define_insn "sssubv8hi3"
22909   [(set (match_operand:V8HI 0 "register_operand" "=x")
22910         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22911                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22912   "TARGET_SSE2"
22913   "psubsw\t{%2, %0|%0, %2}"
22914   [(set_attr "type" "sseiadd")
22915    (set_attr "mode" "TI")])
22916
22917 (define_insn "ussubv16qi3"
22918   [(set (match_operand:V16QI 0 "register_operand" "=x")
22919         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22920                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22921   "TARGET_SSE2"
22922   "psubusb\t{%2, %0|%0, %2}"
22923   [(set_attr "type" "sseiadd")
22924    (set_attr "mode" "TI")])
22925
22926 (define_insn "ussubv8hi3"
22927   [(set (match_operand:V8HI 0 "register_operand" "=x")
22928         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22929                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22930   "TARGET_SSE2"
22931   "psubusw\t{%2, %0|%0, %2}"
22932   [(set_attr "type" "sseiadd")
22933    (set_attr "mode" "TI")])
22934
22935 (define_insn "mulv8hi3"
22936   [(set (match_operand:V8HI 0 "register_operand" "=x")
22937         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22938                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22939   "TARGET_SSE2"
22940   "pmullw\t{%2, %0|%0, %2}"
22941   [(set_attr "type" "sseimul")
22942    (set_attr "mode" "TI")])
22943
22944 (define_insn "smulv8hi3_highpart"
22945   [(set (match_operand:V8HI 0 "register_operand" "=x")
22946         (truncate:V8HI
22947          (lshiftrt:V8SI
22948           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22949                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22950           (const_int 16))))]
22951   "TARGET_SSE2"
22952   "pmulhw\t{%2, %0|%0, %2}"
22953   [(set_attr "type" "sseimul")
22954    (set_attr "mode" "TI")])
22955
22956 (define_insn "umulv8hi3_highpart"
22957   [(set (match_operand:V8HI 0 "register_operand" "=x")
22958         (truncate:V8HI
22959          (lshiftrt:V8SI
22960           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22961                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22962           (const_int 16))))]
22963   "TARGET_SSE2"
22964   "pmulhuw\t{%2, %0|%0, %2}"
22965   [(set_attr "type" "sseimul")
22966    (set_attr "mode" "TI")])
22967
22968 (define_insn "sse2_umulsidi3"
22969   [(set (match_operand:DI 0 "register_operand" "=y")
22970         (mult:DI (zero_extend:DI (vec_select:SI
22971                                   (match_operand:V2SI 1 "register_operand" "0")
22972                                   (parallel [(const_int 0)])))
22973                  (zero_extend:DI (vec_select:SI
22974                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22975                                   (parallel [(const_int 0)])))))]
22976   "TARGET_SSE2"
22977   "pmuludq\t{%2, %0|%0, %2}"
22978   [(set_attr "type" "mmxmul")
22979    (set_attr "mode" "DI")])
22980
22981 (define_insn "sse2_umulv2siv2di3"
22982   [(set (match_operand:V2DI 0 "register_operand" "=x")
22983         (mult:V2DI (zero_extend:V2DI
22984                      (vec_select:V2SI
22985                        (match_operand:V4SI 1 "register_operand" "0")
22986                        (parallel [(const_int 0) (const_int 2)])))
22987                    (zero_extend:V2DI
22988                      (vec_select:V2SI
22989                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22990                        (parallel [(const_int 0) (const_int 2)])))))]
22991   "TARGET_SSE2"
22992   "pmuludq\t{%2, %0|%0, %2}"
22993   [(set_attr "type" "sseimul")
22994    (set_attr "mode" "TI")])
22995
22996 (define_insn "sse2_pmaddwd"
22997   [(set (match_operand:V4SI 0 "register_operand" "=x")
22998         (plus:V4SI
22999          (mult:V4SI
23000           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23001                                              (parallel [(const_int 0)
23002                                                         (const_int 2)
23003                                                         (const_int 4)
23004                                                         (const_int 6)])))
23005           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23006                                              (parallel [(const_int 0)
23007                                                         (const_int 2)
23008                                                         (const_int 4)
23009                                                         (const_int 6)]))))
23010          (mult:V4SI
23011           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23012                                              (parallel [(const_int 1)
23013                                                         (const_int 3)
23014                                                         (const_int 5)
23015                                                         (const_int 7)])))
23016           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23017                                              (parallel [(const_int 1)
23018                                                         (const_int 3)
23019                                                         (const_int 5)
23020                                                         (const_int 7)]))))))]
23021   "TARGET_SSE2"
23022   "pmaddwd\t{%2, %0|%0, %2}"
23023   [(set_attr "type" "sseiadd")
23024    (set_attr "mode" "TI")])
23025
23026 ;; Same as pxor, but don't show input operands so that we don't think
23027 ;; they are live.
23028 (define_insn "sse2_clrti"
23029   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23030   "TARGET_SSE2"
23031 {
23032   if (get_attr_mode (insn) == MODE_TI)
23033     return "pxor\t%0, %0";
23034   else
23035     return "xorps\t%0, %0";
23036 }
23037   [(set_attr "type" "ssemov")
23038    (set_attr "memory" "none")
23039    (set (attr "mode")
23040               (if_then_else
23041                 (ne (symbol_ref "optimize_size")
23042                     (const_int 0))
23043                 (const_string "V4SF")
23044                 (const_string "TI")))])
23045
23046 ;; MMX unsigned averages/sum of absolute differences
23047
23048 (define_insn "sse2_uavgv16qi3"
23049   [(set (match_operand:V16QI 0 "register_operand" "=x")
23050         (ashiftrt:V16QI
23051          (plus:V16QI (plus:V16QI
23052                      (match_operand:V16QI 1 "register_operand" "0")
23053                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23054                      (const_vector:V16QI [(const_int 1) (const_int 1)
23055                                           (const_int 1) (const_int 1)
23056                                           (const_int 1) (const_int 1)
23057                                           (const_int 1) (const_int 1)
23058                                           (const_int 1) (const_int 1)
23059                                           (const_int 1) (const_int 1)
23060                                           (const_int 1) (const_int 1)
23061                                           (const_int 1) (const_int 1)]))
23062          (const_int 1)))]
23063   "TARGET_SSE2"
23064   "pavgb\t{%2, %0|%0, %2}"
23065   [(set_attr "type" "sseiadd")
23066    (set_attr "mode" "TI")])
23067
23068 (define_insn "sse2_uavgv8hi3"
23069   [(set (match_operand:V8HI 0 "register_operand" "=x")
23070         (ashiftrt:V8HI
23071          (plus:V8HI (plus:V8HI
23072                      (match_operand:V8HI 1 "register_operand" "0")
23073                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23074                     (const_vector:V8HI [(const_int 1) (const_int 1)
23075                                         (const_int 1) (const_int 1)
23076                                         (const_int 1) (const_int 1)
23077                                         (const_int 1) (const_int 1)]))
23078          (const_int 1)))]
23079   "TARGET_SSE2"
23080   "pavgw\t{%2, %0|%0, %2}"
23081   [(set_attr "type" "sseiadd")
23082    (set_attr "mode" "TI")])
23083
23084 ;; @@@ this isn't the right representation.
23085 (define_insn "sse2_psadbw"
23086   [(set (match_operand:V2DI 0 "register_operand" "=x")
23087         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23088                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23089                      UNSPEC_PSADBW))]
23090   "TARGET_SSE2"
23091   "psadbw\t{%2, %0|%0, %2}"
23092   [(set_attr "type" "sseiadd")
23093    (set_attr "mode" "TI")])
23094
23095
23096 ;; MMX insert/extract/shuffle
23097
23098 (define_insn "sse2_pinsrw"
23099   [(set (match_operand:V8HI 0 "register_operand" "=x")
23100         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23101                         (vec_duplicate:V8HI
23102                          (truncate:HI
23103                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23104                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23105   "TARGET_SSE2"
23106   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23107   [(set_attr "type" "ssecvt")
23108    (set_attr "mode" "TI")])
23109
23110 (define_insn "sse2_pextrw"
23111   [(set (match_operand:SI 0 "register_operand" "=r")
23112         (zero_extend:SI
23113           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23114                          (parallel
23115                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23116   "TARGET_SSE2"
23117   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23118   [(set_attr "type" "ssecvt")
23119    (set_attr "mode" "TI")])
23120
23121 (define_insn "sse2_pshufd"
23122   [(set (match_operand:V4SI 0 "register_operand" "=x")
23123         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23124                       (match_operand:SI 2 "immediate_operand" "i")]
23125                      UNSPEC_SHUFFLE))]
23126   "TARGET_SSE2"
23127   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23128   [(set_attr "type" "ssecvt")
23129    (set_attr "mode" "TI")])
23130
23131 (define_insn "sse2_pshuflw"
23132   [(set (match_operand:V8HI 0 "register_operand" "=x")
23133         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23134                       (match_operand:SI 2 "immediate_operand" "i")]
23135                      UNSPEC_PSHUFLW))]
23136   "TARGET_SSE2"
23137   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23138   [(set_attr "type" "ssecvt")
23139    (set_attr "mode" "TI")])
23140
23141 (define_insn "sse2_pshufhw"
23142   [(set (match_operand:V8HI 0 "register_operand" "=x")
23143         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23144                       (match_operand:SI 2 "immediate_operand" "i")]
23145                      UNSPEC_PSHUFHW))]
23146   "TARGET_SSE2"
23147   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23148   [(set_attr "type" "ssecvt")
23149    (set_attr "mode" "TI")])
23150
23151 ;; MMX mask-generating comparisons
23152
23153 (define_insn "eqv16qi3"
23154   [(set (match_operand:V16QI 0 "register_operand" "=x")
23155         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23156                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23157   "TARGET_SSE2"
23158   "pcmpeqb\t{%2, %0|%0, %2}"
23159   [(set_attr "type" "ssecmp")
23160    (set_attr "mode" "TI")])
23161
23162 (define_insn "eqv8hi3"
23163   [(set (match_operand:V8HI 0 "register_operand" "=x")
23164         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23165                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23166   "TARGET_SSE2"
23167   "pcmpeqw\t{%2, %0|%0, %2}"
23168   [(set_attr "type" "ssecmp")
23169    (set_attr "mode" "TI")])
23170
23171 (define_insn "eqv4si3"
23172   [(set (match_operand:V4SI 0 "register_operand" "=x")
23173         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23174                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23175   "TARGET_SSE2"
23176   "pcmpeqd\t{%2, %0|%0, %2}"
23177   [(set_attr "type" "ssecmp")
23178    (set_attr "mode" "TI")])
23179
23180 (define_insn "gtv16qi3"
23181   [(set (match_operand:V16QI 0 "register_operand" "=x")
23182         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23183                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23184   "TARGET_SSE2"
23185   "pcmpgtb\t{%2, %0|%0, %2}"
23186   [(set_attr "type" "ssecmp")
23187    (set_attr "mode" "TI")])
23188
23189 (define_insn "gtv8hi3"
23190   [(set (match_operand:V8HI 0 "register_operand" "=x")
23191         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23192                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23193   "TARGET_SSE2"
23194   "pcmpgtw\t{%2, %0|%0, %2}"
23195   [(set_attr "type" "ssecmp")
23196    (set_attr "mode" "TI")])
23197
23198 (define_insn "gtv4si3"
23199   [(set (match_operand:V4SI 0 "register_operand" "=x")
23200         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23201                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23202   "TARGET_SSE2"
23203   "pcmpgtd\t{%2, %0|%0, %2}"
23204   [(set_attr "type" "ssecmp")
23205    (set_attr "mode" "TI")])
23206
23207
23208 ;; MMX max/min insns
23209
23210 (define_insn "umaxv16qi3"
23211   [(set (match_operand:V16QI 0 "register_operand" "=x")
23212         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23213                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23214   "TARGET_SSE2"
23215   "pmaxub\t{%2, %0|%0, %2}"
23216   [(set_attr "type" "sseiadd")
23217    (set_attr "mode" "TI")])
23218
23219 (define_insn "smaxv8hi3"
23220   [(set (match_operand:V8HI 0 "register_operand" "=x")
23221         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23222                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23223   "TARGET_SSE2"
23224   "pmaxsw\t{%2, %0|%0, %2}"
23225   [(set_attr "type" "sseiadd")
23226    (set_attr "mode" "TI")])
23227
23228 (define_insn "uminv16qi3"
23229   [(set (match_operand:V16QI 0 "register_operand" "=x")
23230         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23231                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23232   "TARGET_SSE2"
23233   "pminub\t{%2, %0|%0, %2}"
23234   [(set_attr "type" "sseiadd")
23235    (set_attr "mode" "TI")])
23236
23237 (define_insn "sminv8hi3"
23238   [(set (match_operand:V8HI 0 "register_operand" "=x")
23239         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23240                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23241   "TARGET_SSE2"
23242   "pminsw\t{%2, %0|%0, %2}"
23243   [(set_attr "type" "sseiadd")
23244    (set_attr "mode" "TI")])
23245
23246
23247 ;; MMX shifts
23248
23249 (define_insn "ashrv8hi3"
23250   [(set (match_operand:V8HI 0 "register_operand" "=x")
23251         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23252                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23253   "TARGET_SSE2"
23254   "psraw\t{%2, %0|%0, %2}"
23255   [(set_attr "type" "sseishft")
23256    (set_attr "mode" "TI")])
23257
23258 (define_insn "ashrv4si3"
23259   [(set (match_operand:V4SI 0 "register_operand" "=x")
23260         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23261                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23262   "TARGET_SSE2"
23263   "psrad\t{%2, %0|%0, %2}"
23264   [(set_attr "type" "sseishft")
23265    (set_attr "mode" "TI")])
23266
23267 (define_insn "lshrv8hi3"
23268   [(set (match_operand:V8HI 0 "register_operand" "=x")
23269         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23270                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23271   "TARGET_SSE2"
23272   "psrlw\t{%2, %0|%0, %2}"
23273   [(set_attr "type" "sseishft")
23274    (set_attr "mode" "TI")])
23275
23276 (define_insn "lshrv4si3"
23277   [(set (match_operand:V4SI 0 "register_operand" "=x")
23278         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23279                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23280   "TARGET_SSE2"
23281   "psrld\t{%2, %0|%0, %2}"
23282   [(set_attr "type" "sseishft")
23283    (set_attr "mode" "TI")])
23284
23285 (define_insn "lshrv2di3"
23286   [(set (match_operand:V2DI 0 "register_operand" "=x")
23287         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23288                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23289   "TARGET_SSE2"
23290   "psrlq\t{%2, %0|%0, %2}"
23291   [(set_attr "type" "sseishft")
23292    (set_attr "mode" "TI")])
23293
23294 (define_insn "ashlv8hi3"
23295   [(set (match_operand:V8HI 0 "register_operand" "=x")
23296         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23297                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23298   "TARGET_SSE2"
23299   "psllw\t{%2, %0|%0, %2}"
23300   [(set_attr "type" "sseishft")
23301    (set_attr "mode" "TI")])
23302
23303 (define_insn "ashlv4si3"
23304   [(set (match_operand:V4SI 0 "register_operand" "=x")
23305         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23306                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23307   "TARGET_SSE2"
23308   "pslld\t{%2, %0|%0, %2}"
23309   [(set_attr "type" "sseishft")
23310    (set_attr "mode" "TI")])
23311
23312 (define_insn "ashlv2di3"
23313   [(set (match_operand:V2DI 0 "register_operand" "=x")
23314         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23315                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23316   "TARGET_SSE2"
23317   "psllq\t{%2, %0|%0, %2}"
23318   [(set_attr "type" "sseishft")
23319    (set_attr "mode" "TI")])
23320
23321 (define_insn "ashrv8hi3_ti"
23322   [(set (match_operand:V8HI 0 "register_operand" "=x")
23323         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23324                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23325   "TARGET_SSE2"
23326   "psraw\t{%2, %0|%0, %2}"
23327   [(set_attr "type" "sseishft")
23328    (set_attr "mode" "TI")])
23329
23330 (define_insn "ashrv4si3_ti"
23331   [(set (match_operand:V4SI 0 "register_operand" "=x")
23332         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23333                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23334   "TARGET_SSE2"
23335   "psrad\t{%2, %0|%0, %2}"
23336   [(set_attr "type" "sseishft")
23337    (set_attr "mode" "TI")])
23338
23339 (define_insn "lshrv8hi3_ti"
23340   [(set (match_operand:V8HI 0 "register_operand" "=x")
23341         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23342                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23343   "TARGET_SSE2"
23344   "psrlw\t{%2, %0|%0, %2}"
23345   [(set_attr "type" "sseishft")
23346    (set_attr "mode" "TI")])
23347
23348 (define_insn "lshrv4si3_ti"
23349   [(set (match_operand:V4SI 0 "register_operand" "=x")
23350         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23351                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23352   "TARGET_SSE2"
23353   "psrld\t{%2, %0|%0, %2}"
23354   [(set_attr "type" "sseishft")
23355    (set_attr "mode" "TI")])
23356
23357 (define_insn "lshrv2di3_ti"
23358   [(set (match_operand:V2DI 0 "register_operand" "=x")
23359         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23360                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23361   "TARGET_SSE2"
23362   "psrlq\t{%2, %0|%0, %2}"
23363   [(set_attr "type" "sseishft")
23364    (set_attr "mode" "TI")])
23365
23366 (define_insn "ashlv8hi3_ti"
23367   [(set (match_operand:V8HI 0 "register_operand" "=x")
23368         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23369                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23370   "TARGET_SSE2"
23371   "psllw\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseishft")
23373    (set_attr "mode" "TI")])
23374
23375 (define_insn "ashlv4si3_ti"
23376   [(set (match_operand:V4SI 0 "register_operand" "=x")
23377         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23378                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23379   "TARGET_SSE2"
23380   "pslld\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseishft")
23382    (set_attr "mode" "TI")])
23383
23384 (define_insn "ashlv2di3_ti"
23385   [(set (match_operand:V2DI 0 "register_operand" "=x")
23386         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23387                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23388   "TARGET_SSE2"
23389   "psllq\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseishft")
23391    (set_attr "mode" "TI")])
23392
23393 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23394 ;; we wouldn't need here it since we never generate TImode arithmetic.
23395
23396 ;; There has to be some kind of prize for the weirdest new instruction...
23397 (define_insn "sse2_ashlti3"
23398   [(set (match_operand:TI 0 "register_operand" "=x")
23399         (unspec:TI
23400          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23401                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23402                                (const_int 8)))] UNSPEC_NOP))]
23403   "TARGET_SSE2"
23404   "pslldq\t{%2, %0|%0, %2}"
23405   [(set_attr "type" "sseishft")
23406    (set_attr "mode" "TI")])
23407
23408 (define_insn "sse2_lshrti3"
23409   [(set (match_operand:TI 0 "register_operand" "=x")
23410         (unspec:TI
23411          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23412                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23413                                 (const_int 8)))] UNSPEC_NOP))]
23414   "TARGET_SSE2"
23415   "psrldq\t{%2, %0|%0, %2}"
23416   [(set_attr "type" "sseishft")
23417    (set_attr "mode" "TI")])
23418
23419 ;; SSE unpack
23420
23421 (define_insn "sse2_unpckhpd"
23422   [(set (match_operand:V2DF 0 "register_operand" "=x")
23423         (vec_concat:V2DF
23424          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23425                         (parallel [(const_int 1)]))
23426          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23427                         (parallel [(const_int 1)]))))]
23428   "TARGET_SSE2"
23429   "unpckhpd\t{%2, %0|%0, %2}"
23430   [(set_attr "type" "ssecvt")
23431    (set_attr "mode" "V2DF")])
23432
23433 (define_insn "sse2_unpcklpd"
23434   [(set (match_operand:V2DF 0 "register_operand" "=x")
23435         (vec_concat:V2DF
23436          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23437                         (parallel [(const_int 0)]))
23438          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23439                         (parallel [(const_int 0)]))))]
23440   "TARGET_SSE2"
23441   "unpcklpd\t{%2, %0|%0, %2}"
23442   [(set_attr "type" "ssecvt")
23443    (set_attr "mode" "V2DF")])
23444
23445 ;; MMX pack/unpack insns.
23446
23447 (define_insn "sse2_packsswb"
23448   [(set (match_operand:V16QI 0 "register_operand" "=x")
23449         (vec_concat:V16QI
23450          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23451          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23452   "TARGET_SSE2"
23453   "packsswb\t{%2, %0|%0, %2}"
23454   [(set_attr "type" "ssecvt")
23455    (set_attr "mode" "TI")])
23456
23457 (define_insn "sse2_packssdw"
23458   [(set (match_operand:V8HI 0 "register_operand" "=x")
23459         (vec_concat:V8HI
23460          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23461          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23462   "TARGET_SSE2"
23463   "packssdw\t{%2, %0|%0, %2}"
23464   [(set_attr "type" "ssecvt")
23465    (set_attr "mode" "TI")])
23466
23467 (define_insn "sse2_packuswb"
23468   [(set (match_operand:V16QI 0 "register_operand" "=x")
23469         (vec_concat:V16QI
23470          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23471          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23472   "TARGET_SSE2"
23473   "packuswb\t{%2, %0|%0, %2}"
23474   [(set_attr "type" "ssecvt")
23475    (set_attr "mode" "TI")])
23476
23477 (define_insn "sse2_punpckhbw"
23478   [(set (match_operand:V16QI 0 "register_operand" "=x")
23479         (vec_merge:V16QI
23480          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23481                            (parallel [(const_int 8) (const_int 0)
23482                                       (const_int 9) (const_int 1)
23483                                       (const_int 10) (const_int 2)
23484                                       (const_int 11) (const_int 3)
23485                                       (const_int 12) (const_int 4)
23486                                       (const_int 13) (const_int 5)
23487                                       (const_int 14) (const_int 6)
23488                                       (const_int 15) (const_int 7)]))
23489          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23490                            (parallel [(const_int 0) (const_int 8)
23491                                       (const_int 1) (const_int 9)
23492                                       (const_int 2) (const_int 10)
23493                                       (const_int 3) (const_int 11)
23494                                       (const_int 4) (const_int 12)
23495                                       (const_int 5) (const_int 13)
23496                                       (const_int 6) (const_int 14)
23497                                       (const_int 7) (const_int 15)]))
23498          (const_int 21845)))]
23499   "TARGET_SSE2"
23500   "punpckhbw\t{%2, %0|%0, %2}"
23501   [(set_attr "type" "ssecvt")
23502    (set_attr "mode" "TI")])
23503
23504 (define_insn "sse2_punpckhwd"
23505   [(set (match_operand:V8HI 0 "register_operand" "=x")
23506         (vec_merge:V8HI
23507          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23508                           (parallel [(const_int 4) (const_int 0)
23509                                      (const_int 5) (const_int 1)
23510                                      (const_int 6) (const_int 2)
23511                                      (const_int 7) (const_int 3)]))
23512          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23513                           (parallel [(const_int 0) (const_int 4)
23514                                      (const_int 1) (const_int 5)
23515                                      (const_int 2) (const_int 6)
23516                                      (const_int 3) (const_int 7)]))
23517          (const_int 85)))]
23518   "TARGET_SSE2"
23519   "punpckhwd\t{%2, %0|%0, %2}"
23520   [(set_attr "type" "ssecvt")
23521    (set_attr "mode" "TI")])
23522
23523 (define_insn "sse2_punpckhdq"
23524   [(set (match_operand:V4SI 0 "register_operand" "=x")
23525         (vec_merge:V4SI
23526          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23527                           (parallel [(const_int 2) (const_int 0)
23528                                      (const_int 3) (const_int 1)]))
23529          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23530                           (parallel [(const_int 0) (const_int 2)
23531                                      (const_int 1) (const_int 3)]))
23532          (const_int 5)))]
23533   "TARGET_SSE2"
23534   "punpckhdq\t{%2, %0|%0, %2}"
23535   [(set_attr "type" "ssecvt")
23536    (set_attr "mode" "TI")])
23537
23538 (define_insn "sse2_punpcklbw"
23539   [(set (match_operand:V16QI 0 "register_operand" "=x")
23540         (vec_merge:V16QI
23541          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23542                            (parallel [(const_int 0) (const_int 8)
23543                                       (const_int 1) (const_int 9)
23544                                       (const_int 2) (const_int 10)
23545                                       (const_int 3) (const_int 11)
23546                                       (const_int 4) (const_int 12)
23547                                       (const_int 5) (const_int 13)
23548                                       (const_int 6) (const_int 14)
23549                                       (const_int 7) (const_int 15)]))
23550          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23551                            (parallel [(const_int 8) (const_int 0)
23552                                       (const_int 9) (const_int 1)
23553                                       (const_int 10) (const_int 2)
23554                                       (const_int 11) (const_int 3)
23555                                       (const_int 12) (const_int 4)
23556                                       (const_int 13) (const_int 5)
23557                                       (const_int 14) (const_int 6)
23558                                       (const_int 15) (const_int 7)]))
23559          (const_int 21845)))]
23560   "TARGET_SSE2"
23561   "punpcklbw\t{%2, %0|%0, %2}"
23562   [(set_attr "type" "ssecvt")
23563    (set_attr "mode" "TI")])
23564
23565 (define_insn "sse2_punpcklwd"
23566   [(set (match_operand:V8HI 0 "register_operand" "=x")
23567         (vec_merge:V8HI
23568          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23569                           (parallel [(const_int 0) (const_int 4)
23570                                      (const_int 1) (const_int 5)
23571                                      (const_int 2) (const_int 6)
23572                                      (const_int 3) (const_int 7)]))
23573          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23574                           (parallel [(const_int 4) (const_int 0)
23575                                      (const_int 5) (const_int 1)
23576                                      (const_int 6) (const_int 2)
23577                                      (const_int 7) (const_int 3)]))
23578          (const_int 85)))]
23579   "TARGET_SSE2"
23580   "punpcklwd\t{%2, %0|%0, %2}"
23581   [(set_attr "type" "ssecvt")
23582    (set_attr "mode" "TI")])
23583
23584 (define_insn "sse2_punpckldq"
23585   [(set (match_operand:V4SI 0 "register_operand" "=x")
23586         (vec_merge:V4SI
23587          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23588                           (parallel [(const_int 0) (const_int 2)
23589                                      (const_int 1) (const_int 3)]))
23590          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23591                           (parallel [(const_int 2) (const_int 0)
23592                                      (const_int 3) (const_int 1)]))
23593          (const_int 5)))]
23594   "TARGET_SSE2"
23595   "punpckldq\t{%2, %0|%0, %2}"
23596   [(set_attr "type" "ssecvt")
23597    (set_attr "mode" "TI")])
23598
23599 (define_insn "sse2_punpcklqdq"
23600   [(set (match_operand:V2DI 0 "register_operand" "=x")
23601         (vec_merge:V2DI
23602          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23603                           (parallel [(const_int 1)
23604                                      (const_int 0)]))
23605          (match_operand:V2DI 1 "register_operand" "0")
23606          (const_int 1)))]
23607   "TARGET_SSE2"
23608   "punpcklqdq\t{%2, %0|%0, %2}"
23609   [(set_attr "type" "ssecvt")
23610    (set_attr "mode" "TI")])
23611
23612 (define_insn "sse2_punpckhqdq"
23613   [(set (match_operand:V2DI 0 "register_operand" "=x")
23614         (vec_merge:V2DI
23615          (match_operand:V2DI 1 "register_operand" "0")
23616          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23617                           (parallel [(const_int 1)
23618                                      (const_int 0)]))
23619          (const_int 1)))]
23620   "TARGET_SSE2"
23621   "punpckhqdq\t{%2, %0|%0, %2}"
23622   [(set_attr "type" "ssecvt")
23623    (set_attr "mode" "TI")])
23624
23625 ;; SSE2 moves
23626
23627 (define_insn "sse2_movapd"
23628   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23629         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23630                      UNSPEC_MOVA))]
23631   "TARGET_SSE2
23632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23633   "movapd\t{%1, %0|%0, %1}"
23634   [(set_attr "type" "ssemov")
23635    (set_attr "mode" "V2DF")])
23636
23637 (define_insn "sse2_movupd"
23638   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23639         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23640                      UNSPEC_MOVU))]
23641   "TARGET_SSE2
23642    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23643   "movupd\t{%1, %0|%0, %1}"
23644   [(set_attr "type" "ssecvt")
23645    (set_attr "mode" "V2DF")])
23646
23647 (define_insn "sse2_movdqa"
23648   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23649         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23650                        UNSPEC_MOVA))]
23651   "TARGET_SSE2
23652    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23653   "movdqa\t{%1, %0|%0, %1}"
23654   [(set_attr "type" "ssemov")
23655    (set_attr "mode" "TI")])
23656
23657 (define_insn "sse2_movdqu"
23658   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23659         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23660                        UNSPEC_MOVU))]
23661   "TARGET_SSE2
23662    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23663   "movdqu\t{%1, %0|%0, %1}"
23664   [(set_attr "type" "ssecvt")
23665    (set_attr "mode" "TI")])
23666
23667 (define_insn "sse2_movdq2q"
23668   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23669         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23670                        (parallel [(const_int 0)])))]
23671   "TARGET_SSE2 && !TARGET_64BIT"
23672   "@
23673    movq\t{%1, %0|%0, %1}
23674    movdq2q\t{%1, %0|%0, %1}"
23675   [(set_attr "type" "ssecvt")
23676    (set_attr "mode" "TI")])
23677
23678 (define_insn "sse2_movdq2q_rex64"
23679   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23680         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23681                        (parallel [(const_int 0)])))]
23682   "TARGET_SSE2 && TARGET_64BIT"
23683   "@
23684    movq\t{%1, %0|%0, %1}
23685    movdq2q\t{%1, %0|%0, %1}
23686    movd\t{%1, %0|%0, %1}"
23687   [(set_attr "type" "ssecvt")
23688    (set_attr "mode" "TI")])
23689
23690 (define_insn "sse2_movq2dq"
23691   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23692         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23693                          (const_int 0)))]
23694   "TARGET_SSE2 && !TARGET_64BIT"
23695   "@
23696    movq\t{%1, %0|%0, %1}
23697    movq2dq\t{%1, %0|%0, %1}"
23698   [(set_attr "type" "ssecvt,ssemov")
23699    (set_attr "mode" "TI")])
23700
23701 (define_insn "sse2_movq2dq_rex64"
23702   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23703         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23704                          (const_int 0)))]
23705   "TARGET_SSE2 && TARGET_64BIT"
23706   "@
23707    movq\t{%1, %0|%0, %1}
23708    movq2dq\t{%1, %0|%0, %1}
23709    movd\t{%1, %0|%0, %1}"
23710   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23711    (set_attr "mode" "TI")])
23712
23713 (define_insn "sse2_movq"
23714   [(set (match_operand:V2DI 0 "register_operand" "=x")
23715         (vec_concat:V2DI (vec_select:DI
23716                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23717                           (parallel [(const_int 0)]))
23718                          (const_int 0)))]
23719   "TARGET_SSE2"
23720   "movq\t{%1, %0|%0, %1}"
23721   [(set_attr "type" "ssemov")
23722    (set_attr "mode" "TI")])
23723
23724 (define_insn "sse2_loadd"
23725   [(set (match_operand:V4SI 0 "register_operand" "=x")
23726         (vec_merge:V4SI
23727          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23728          (const_vector:V4SI [(const_int 0)
23729                              (const_int 0)
23730                              (const_int 0)
23731                              (const_int 0)])
23732          (const_int 1)))]
23733   "TARGET_SSE2"
23734   "movd\t{%1, %0|%0, %1}"
23735   [(set_attr "type" "ssemov")
23736    (set_attr "mode" "TI")])
23737
23738 (define_insn "sse2_stored"
23739   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23740         (vec_select:SI
23741          (match_operand:V4SI 1 "register_operand" "x")
23742          (parallel [(const_int 0)])))]
23743   "TARGET_SSE2"
23744   "movd\t{%1, %0|%0, %1}"
23745   [(set_attr "type" "ssemov")
23746    (set_attr "mode" "TI")])
23747
23748 ;; Store the high double of the source vector into the double destination.
23749 (define_insn "sse2_storehpd"
23750   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,Y,Y")
23751         (vec_select:DF
23752           (match_operand:V2DF 1 "nonimmediate_operand" " Y,0,o")
23753           (parallel [(const_int 1)])))]
23754   "TARGET_SSE2"
23755   "@
23756    movhpd\t{%1, %0|%0, %1}
23757    unpckhpd\t%0, %0
23758    #"
23759   [(set_attr "type" "ssecvt")
23760    (set_attr "mode" "V2DF")])
23761
23762 (define_split
23763   [(set (match_operand:DF 0 "register_operand" "")
23764         (vec_select:DF
23765           (match_operand:V2DF 1 "memory_operand" "")
23766           (parallel [(const_int 1)])))]
23767   "TARGET_SSE2 && reload_completed"
23768   [(const_int 0)]
23769 {
23770   emit_move_insn (operands[0], adjust_address (operands[1], DFmode, 8));
23771   DONE;
23772 })
23773
23774 ;; Load the high double of the target vector from the source scalar.
23775 (define_insn "sse2_loadhpd"
23776   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,o")
23777         (vec_concat:V2DF
23778           (vec_select:DF
23779             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23780             (parallel [(const_int 0)]))
23781           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")))]
23782   "TARGET_SSE2"
23783   "@
23784    movhpd\t{%2, %0|%0, %2}
23785    unpcklpd\t{%2, %0|%0, %2}
23786    #"
23787   [(set_attr "type" "ssecvt")
23788    (set_attr "mode" "V2DF")])
23789
23790 (define_split
23791   [(set (match_operand:V2DF 0 "memory_operand" "")
23792         (vec_concat:V2DF
23793           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
23794           (match_operand:DF 1 "register_operand" "")))]
23795   "TARGET_SSE2 && reload_completed"
23796   [(const_int 0)]
23797 {
23798   emit_move_insn (adjust_address (operands[0], DFmode, 8), operands[1]);
23799   DONE;
23800 })
23801
23802 ;; Store the low double of the source vector into the double destination.
23803 (define_expand "sse2_storelpd"
23804   [(set (match_operand:DF 0 "nonimmediate_operand" "")
23805         (vec_select:DF
23806           (match_operand:V2DF 1 "nonimmediate_operand" "")
23807           (parallel [(const_int 1)])))]
23808   "TARGET_SSE2"
23809 {
23810   operands[1] = gen_lowpart (DFmode, operands[1]);
23811   emit_move_insn (operands[0], operands[1]);
23812   DONE;
23813 })
23814
23815 ;; Load the load double of the target vector from the source scalar.
23816 (define_insn "sse2_loadlpd"
23817   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,m")
23818         (vec_concat:V2DF
23819           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")
23820           (vec_select:DF
23821             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23822             (parallel [(const_int 1)]))))]
23823   "TARGET_SSE2"
23824   "@
23825    movlpd\t{%2, %0|%0, %2}
23826    movsd\t{%2, %0|%0, %2}
23827    movlpd\t{%2, %0|%0, %2}"
23828   [(set_attr "type" "ssecvt")
23829    (set_attr "mode" "V2DF")])
23830
23831 ;; Merge the low part of the source vector into the low part of the target.
23832 (define_insn "sse2_movsd"
23833   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,m")
23834         (vec_merge:V2DF
23835          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23836          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,Y")
23837          (const_int 2)))]
23838   "TARGET_SSE2"
23839   "@movsd\t{%2, %0|%0, %2}
23840     movlpd\t{%2, %0|%0, %2}
23841     movlpd\t{%2, %0|%0, %2}"
23842   [(set_attr "type" "ssecvt")
23843    (set_attr "mode" "DF,V2DF,V2DF")])
23844
23845 (define_expand "sse2_loadsd"
23846   [(match_operand:V2DF 0 "register_operand" "")
23847    (match_operand:DF 1 "memory_operand" "")]
23848   "TARGET_SSE2"
23849 {
23850   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23851                                 CONST0_RTX (V2DFmode)));
23852   DONE;
23853 })
23854
23855 (define_insn "sse2_loadsd_1"
23856   [(set (match_operand:V2DF 0 "register_operand" "=x")
23857         (vec_merge:V2DF
23858          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23859          (match_operand:V2DF 2 "const0_operand" "X")
23860          (const_int 1)))]
23861   "TARGET_SSE2"
23862   "movsd\t{%1, %0|%0, %1}"
23863   [(set_attr "type" "ssecvt")
23864    (set_attr "mode" "DF")])
23865
23866 (define_insn "sse2_storesd"
23867   [(set (match_operand:DF 0 "memory_operand" "=m")
23868         (vec_select:DF
23869          (match_operand:V2DF 1 "register_operand" "x")
23870          (parallel [(const_int 0)])))]
23871   "TARGET_SSE2"
23872   "movsd\t{%1, %0|%0, %1}"
23873   [(set_attr "type" "ssecvt")
23874    (set_attr "mode" "DF")])
23875
23876 (define_insn "sse2_shufpd"
23877   [(set (match_operand:V2DF 0 "register_operand" "=x")
23878         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23879                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23880                       (match_operand:SI 3 "immediate_operand" "i")]
23881                      UNSPEC_SHUFFLE))]
23882   "TARGET_SSE2"
23883   ;; @@@ check operand order for intel/nonintel syntax
23884   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23885   [(set_attr "type" "ssecvt")
23886    (set_attr "mode" "V2DF")])
23887
23888 (define_insn "sse2_clflush"
23889   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23890                     UNSPECV_CLFLUSH)]
23891   "TARGET_SSE2"
23892   "clflush\t%a0"
23893   [(set_attr "type" "sse")
23894    (set_attr "memory" "unknown")])
23895
23896 (define_expand "sse2_mfence"
23897   [(set (match_dup 0)
23898         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23899   "TARGET_SSE2"
23900 {
23901   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23902   MEM_VOLATILE_P (operands[0]) = 1;
23903 })
23904
23905 (define_insn "*mfence_insn"
23906   [(set (match_operand:BLK 0 "" "")
23907         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23908   "TARGET_SSE2"
23909   "mfence"
23910   [(set_attr "type" "sse")
23911    (set_attr "memory" "unknown")])
23912
23913 (define_expand "sse2_lfence"
23914   [(set (match_dup 0)
23915         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23916   "TARGET_SSE2"
23917 {
23918   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23919   MEM_VOLATILE_P (operands[0]) = 1;
23920 })
23921
23922 (define_insn "*lfence_insn"
23923   [(set (match_operand:BLK 0 "" "")
23924         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23925   "TARGET_SSE2"
23926   "lfence"
23927   [(set_attr "type" "sse")
23928    (set_attr "memory" "unknown")])
23929
23930 ;; SSE3
23931
23932 (define_insn "mwait"
23933   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23934                      (match_operand:SI 1 "register_operand" "c")]
23935                     UNSPECV_MWAIT)]
23936   "TARGET_SSE3"
23937   "mwait\t%0, %1"
23938   [(set_attr "length" "3")])
23939
23940 (define_insn "monitor"
23941   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23942                      (match_operand:SI 1 "register_operand" "c")
23943                      (match_operand:SI 2 "register_operand" "d")]
23944                     UNSPECV_MONITOR)]
23945   "TARGET_SSE3"
23946   "monitor\t%0, %1, %2"
23947   [(set_attr "length" "3")])
23948
23949 ;; SSE3 arithmetic
23950
23951 (define_insn "addsubv4sf3"
23952   [(set (match_operand:V4SF 0 "register_operand" "=x")
23953         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23954                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23955                      UNSPEC_ADDSUB))]
23956   "TARGET_SSE3"
23957   "addsubps\t{%2, %0|%0, %2}"
23958   [(set_attr "type" "sseadd")
23959    (set_attr "mode" "V4SF")])
23960
23961 (define_insn "addsubv2df3"
23962   [(set (match_operand:V2DF 0 "register_operand" "=x")
23963         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23964                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23965                      UNSPEC_ADDSUB))]
23966   "TARGET_SSE3"
23967   "addsubpd\t{%2, %0|%0, %2}"
23968   [(set_attr "type" "sseadd")
23969    (set_attr "mode" "V2DF")])
23970
23971 (define_insn "haddv4sf3"
23972   [(set (match_operand:V4SF 0 "register_operand" "=x")
23973         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23974                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23975                      UNSPEC_HADD))]
23976   "TARGET_SSE3"
23977   "haddps\t{%2, %0|%0, %2}"
23978   [(set_attr "type" "sseadd")
23979    (set_attr "mode" "V4SF")])
23980
23981 (define_insn "haddv2df3"
23982   [(set (match_operand:V2DF 0 "register_operand" "=x")
23983         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23984                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23985                      UNSPEC_HADD))]
23986   "TARGET_SSE3"
23987   "haddpd\t{%2, %0|%0, %2}"
23988   [(set_attr "type" "sseadd")
23989    (set_attr "mode" "V2DF")])
23990
23991 (define_insn "hsubv4sf3"
23992   [(set (match_operand:V4SF 0 "register_operand" "=x")
23993         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23994                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23995                      UNSPEC_HSUB))]
23996   "TARGET_SSE3"
23997   "hsubps\t{%2, %0|%0, %2}"
23998   [(set_attr "type" "sseadd")
23999    (set_attr "mode" "V4SF")])
24000
24001 (define_insn "hsubv2df3"
24002   [(set (match_operand:V2DF 0 "register_operand" "=x")
24003         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24004                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24005                      UNSPEC_HSUB))]
24006   "TARGET_SSE3"
24007   "hsubpd\t{%2, %0|%0, %2}"
24008   [(set_attr "type" "sseadd")
24009    (set_attr "mode" "V2DF")])
24010
24011 (define_insn "movshdup"
24012   [(set (match_operand:V4SF 0 "register_operand" "=x")
24013         (unspec:V4SF
24014          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24015   "TARGET_SSE3"
24016   "movshdup\t{%1, %0|%0, %1}"
24017   [(set_attr "type" "sse")
24018    (set_attr "mode" "V4SF")])
24019
24020 (define_insn "movsldup"
24021   [(set (match_operand:V4SF 0 "register_operand" "=x")
24022         (unspec:V4SF
24023          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24024   "TARGET_SSE3"
24025   "movsldup\t{%1, %0|%0, %1}"
24026   [(set_attr "type" "sse")
24027    (set_attr "mode" "V4SF")])
24028
24029 (define_insn "lddqu"
24030   [(set (match_operand:V16QI 0 "register_operand" "=x")
24031         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24032                        UNSPEC_LDQQU))]
24033   "TARGET_SSE3"
24034   "lddqu\t{%1, %0|%0, %1}"
24035   [(set_attr "type" "ssecvt")
24036    (set_attr "mode" "TI")])
24037
24038 (define_insn "loadddup"
24039   [(set (match_operand:V2DF 0 "register_operand" "=x")
24040         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24041   "TARGET_SSE3"
24042   "movddup\t{%1, %0|%0, %1}"
24043   [(set_attr "type" "ssecvt")
24044    (set_attr "mode" "DF")])
24045
24046 (define_insn "movddup"
24047   [(set (match_operand:V2DF 0 "register_operand" "=x")
24048         (vec_duplicate:V2DF
24049          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24050                         (parallel [(const_int 0)]))))]
24051   "TARGET_SSE3"
24052   "movddup\t{%1, %0|%0, %1}"
24053   [(set_attr "type" "ssecvt")
24054    (set_attr "mode" "DF")])