OSDN Git Service

* Makefile.in (insn-preds.o): Depend on REGS_H.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg 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" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1136
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1141
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1144
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1150 }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1175
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1183
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1189 }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "mode" "SI")
1244    (set_attr "modrm" "0")])
1245
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1251
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1261
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1270
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1275 {
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1288 }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1321
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1338
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1352
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "TARGET_PARTIAL_REG_STALL"
1359   "xchg{w}\t%1, %0"
1360   [(set_attr "type" "imov")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "mode" "HI")
1363    (set_attr "modrm" "0")])
1364
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "! TARGET_PARTIAL_REG_STALL"
1371   "xchg{l}\t%k1, %k0"
1372   [(set_attr "type" "imov")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "mode" "SI")
1375    (set_attr "modrm" "0")])
1376
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1381 {
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1385 })
1386
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1395
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1406
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1412
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1416
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1426
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1435
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1442 ;;
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450 {
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1463 }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1,2")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1,2")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1503
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1509 {
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1512
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1522 })
1523
1524 (define_insn "*swapqi"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   ""
1530   "xchg{b}\t%1, %0"
1531   [(set_attr "type" "imov")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "mode" "QI")
1534    (set_attr "modrm" "0")])
1535
1536 (define_expand "movstrictqi"
1537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538         (match_operand:QI 1 "general_operand" ""))]
1539   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1540 {
1541   /* Don't generate memory->memory moves, go through a register.  */
1542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543     operands[1] = force_reg (QImode, operands[1]);
1544 })
1545
1546 (define_insn "*movstrictqi_1"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548         (match_operand:QI 1 "general_operand" "*qn,m"))]
1549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551   "mov{b}\t{%1, %0|%0, %1}"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "QI")])
1554
1555 (define_insn "*movstrictqi_xor"
1556   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557         (match_operand:QI 1 "const0_operand" "i"))
1558    (clobber (reg:CC FLAGS_REG))]
1559   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560   "xor{b}\t{%0, %0|%0, %0}"
1561   [(set_attr "type" "alu1")
1562    (set_attr "mode" "QI")
1563    (set_attr "length_immediate" "0")])
1564
1565 (define_insn "*movsi_extv_1"
1566   [(set (match_operand:SI 0 "register_operand" "=R")
1567         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568                          (const_int 8)
1569                          (const_int 8)))]
1570   ""
1571   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572   [(set_attr "type" "imovx")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "*movhi_extv_1"
1576   [(set (match_operand:HI 0 "register_operand" "=R")
1577         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movqi_extv_1"
1586   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   "!TARGET_64BIT"
1591 {
1592   switch (get_attr_type (insn))
1593     {
1594     case TYPE_IMOVX:
1595       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596     default:
1597       return "mov{b}\t{%h1, %0|%0, %h1}";
1598     }
1599 }
1600   [(set (attr "type")
1601      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603                              (ne (symbol_ref "TARGET_MOVX")
1604                                  (const_int 0))))
1605         (const_string "imovx")
1606         (const_string "imov")))
1607    (set (attr "mode")
1608      (if_then_else (eq_attr "type" "imovx")
1609         (const_string "SI")
1610         (const_string "QI")))])
1611
1612 (define_insn "*movqi_extv_1_rex64"
1613   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "TARGET_64BIT"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1626 }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{b}\t{%1, %P0|%P0, %1}
1648    mov{b}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "QI")])
1655
1656 (define_insn "*movabsqi_2_rex64"
1657   [(set (match_operand:QI 0 "register_operand" "=a,r")
1658         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{b}\t{%P1, %0|%0, %P1}
1662    mov{b}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "QI")])
1669
1670 (define_insn "*movsi_extzv_1"
1671   [(set (match_operand:SI 0 "register_operand" "=R")
1672         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673                          (const_int 8)
1674                          (const_int 8)))]
1675   ""
1676   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677   [(set_attr "type" "imovx")
1678    (set_attr "mode" "SI")])
1679
1680 (define_insn "*movqi_extzv_2"
1681   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683                                     (const_int 8)
1684                                     (const_int 8)) 0))]
1685   "!TARGET_64BIT"
1686 {
1687   switch (get_attr_type (insn))
1688     {
1689     case TYPE_IMOVX:
1690       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691     default:
1692       return "mov{b}\t{%h1, %0|%0, %h1}";
1693     }
1694 }
1695   [(set (attr "type")
1696      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698                              (ne (symbol_ref "TARGET_MOVX")
1699                                  (const_int 0))))
1700         (const_string "imovx")
1701         (const_string "imov")))
1702    (set (attr "mode")
1703      (if_then_else (eq_attr "type" "imovx")
1704         (const_string "SI")
1705         (const_string "QI")))])
1706
1707 (define_insn "*movqi_extzv_2_rex64"
1708   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "TARGET_64BIT"
1713 {
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1721 }
1722   [(set (attr "type")
1723      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724                         (ne (symbol_ref "TARGET_MOVX")
1725                             (const_int 0)))
1726         (const_string "imovx")
1727         (const_string "imov")))
1728    (set (attr "mode")
1729      (if_then_else (eq_attr "type" "imovx")
1730         (const_string "SI")
1731         (const_string "QI")))])
1732
1733 (define_insn "movsi_insv_1"
1734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735                          (const_int 8)
1736                          (const_int 8))
1737         (match_operand:SI 1 "general_operand" "Qmn"))]
1738   "!TARGET_64BIT"
1739   "mov{b}\t{%b1, %h0|%h0, %b1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "QI")])
1742
1743 (define_insn "movdi_insv_1_rex64"
1744   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748   "TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1752
1753 (define_insn "*movqi_insv_2"
1754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758                      (const_int 8)))]
1759   ""
1760   "mov{b}\t{%h1, %h0|%h0, %h1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1763
1764 (define_expand "movdi"
1765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766         (match_operand:DI 1 "general_operand" ""))]
1767   ""
1768   "ix86_expand_move (DImode, operands); DONE;")
1769
1770 (define_insn "*pushdi"
1771   [(set (match_operand:DI 0 "push_operand" "=<")
1772         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773   "!TARGET_64BIT"
1774   "#")
1775
1776 (define_insn "pushdi2_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779   "TARGET_64BIT"
1780   "@
1781    push{q}\t%1
1782    #"
1783   [(set_attr "type" "push,multi")
1784    (set_attr "mode" "DI")])
1785
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it.  In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791   [(match_scratch:DI 2 "r")
1792    (set (match_operand:DI 0 "push_operand" "")
1793         (match_operand:DI 1 "immediate_operand" ""))]
1794   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795    && !x86_64_immediate_operand (operands[1], DImode)"
1796   [(set (match_dup 2) (match_dup 1))
1797    (set (match_dup 0) (match_dup 2))]
1798   "")
1799
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804   [(set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808   [(set (match_dup 0) (match_dup 1))
1809    (set (match_dup 2) (match_dup 3))]
1810   "split_di (operands + 1, 1, operands + 2, operands + 3);
1811    operands[1] = gen_lowpart (DImode, operands[2]);
1812    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813                                                     GEN_INT (4)));
1814   ")
1815
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand" "")
1818         (match_operand:DI 1 "immediate_operand" ""))]
1819   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820    && !symbolic_operand (operands[1], DImode)
1821    && !x86_64_immediate_operand (operands[1], DImode)"
1822   [(set (match_dup 0) (match_dup 1))
1823    (set (match_dup 2) (match_dup 3))]
1824   "split_di (operands + 1, 1, operands + 2, operands + 3);
1825    operands[1] = gen_lowpart (DImode, operands[2]);
1826    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827                                                     GEN_INT (4)));
1828   ")
1829
1830 (define_insn "*pushdi2_prologue_rex64"
1831   [(set (match_operand:DI 0 "push_operand" "=<")
1832         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833    (clobber (mem:BLK (scratch)))]
1834   "TARGET_64BIT"
1835   "push{q}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1838
1839 (define_insn "*popdi1_epilogue_rex64"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841         (mem:DI (reg:DI SP_REG)))
1842    (set (reg:DI SP_REG)
1843         (plus:DI (reg:DI SP_REG) (const_int 8)))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "pop{q}\t%0"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "popdi1"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1859
1860 (define_insn "*movdi_xor_rex64"
1861   [(set (match_operand:DI 0 "register_operand" "=r")
1862         (match_operand:DI 1 "const0_operand" "i"))
1863    (clobber (reg:CC FLAGS_REG))]
1864   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865    && reload_completed"
1866   "xor{l}\t{%k0, %k0|%k0, %k0}"
1867   [(set_attr "type" "alu1")
1868    (set_attr "mode" "SI")
1869    (set_attr "length_immediate" "0")])
1870
1871 (define_insn "*movdi_or_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const_int_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876    && reload_completed
1877    && operands[1] == constm1_rtx"
1878 {
1879   operands[1] = constm1_rtx;
1880   return "or{q}\t{%1, %0|%0, %1}";
1881 }
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "DI")
1884    (set_attr "length_immediate" "1")])
1885
1886 (define_insn "*movdi_2"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889   "!TARGET_64BIT
1890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891   "@
1892    #
1893    #
1894    movq\t{%1, %0|%0, %1}
1895    movq\t{%1, %0|%0, %1}
1896    movq\t{%1, %0|%0, %1}
1897    movdqa\t{%1, %0|%0, %1}
1898    movq\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1901
1902 (define_split
1903   [(set (match_operand:DI 0 "push_operand" "")
1904         (match_operand:DI 1 "general_operand" ""))]
1905   "!TARGET_64BIT && reload_completed
1906    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907   [(const_int 0)]
1908   "ix86_split_long_move (operands); DONE;")
1909
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913         (match_operand:DI 1 "general_operand" ""))]
1914   "!TARGET_64BIT && reload_completed
1915    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917   [(const_int 0)]
1918   "ix86_split_long_move (operands); DONE;")
1919
1920 (define_insn "*movdi_1_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923   "TARGET_64BIT
1924    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 {
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (which_alternative == 11)
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934     case TYPE_SSEMOV:
1935       if (get_attr_mode (insn) == MODE_TI)
1936           return "movdqa\t{%1, %0|%0, %1}";
1937       /* FALLTHRU */
1938     case TYPE_MMXMOV:
1939       /* Moves from and into integer register is done using movd opcode with
1940          REX prefix.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942           return "movd\t{%1, %0|%0, %1}";
1943       return "movq\t{%1, %0|%0, %1}";
1944     case TYPE_MULTI:
1945       return "#";
1946     case TYPE_LEA:
1947       return "lea{q}\t{%a1, %0|%0, %a1}";
1948     default:
1949       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950         abort ();
1951       if (get_attr_mode (insn) == MODE_SI)
1952         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953       else if (which_alternative == 2)
1954         return "movabs{q}\t{%1, %0|%0, %1}";
1955       else
1956         return "mov{q}\t{%1, %0|%0, %1}";
1957     }
1958 }
1959   [(set (attr "type")
1960      (cond [(eq_attr "alternative" "5,6,7")
1961               (const_string "mmxmov")
1962             (eq_attr "alternative" "8,9,10")
1963               (const_string "ssemov")
1964             (eq_attr "alternative" "11,12")
1965               (const_string "ssecvt")
1966             (eq_attr "alternative" "4")
1967               (const_string "multi")
1968             (and (ne (symbol_ref "flag_pic") (const_int 0))
1969                  (match_operand:DI 1 "symbolic_operand" ""))
1970               (const_string "lea")
1971            ]
1972            (const_string "imov")))
1973    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1976
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980   "TARGET_64BIT
1981    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_MULTI:
1993       return "#";
1994     case TYPE_LEA:
1995       return "lea{q}\t{%a1, %0|%0, %a1}";
1996     default:
1997       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998         abort ();
1999       if (get_attr_mode (insn) == MODE_SI)
2000         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001       else if (which_alternative == 2)
2002         return "movabs{q}\t{%1, %0|%0, %1}";
2003       else
2004         return "mov{q}\t{%1, %0|%0, %1}";
2005     }
2006 }
2007   [(set (attr "type")
2008      (cond [(eq_attr "alternative" "5,6,7")
2009               (const_string "mmxmov")
2010             (eq_attr "alternative" "8,9,10")
2011               (const_string "ssemov")
2012             (eq_attr "alternative" "4")
2013               (const_string "multi")
2014             (and (ne (symbol_ref "flag_pic") (const_int 0))
2015                  (match_operand:DI 1 "symbolic_operand" ""))
2016               (const_string "lea")
2017            ]
2018            (const_string "imov")))
2019    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{q}\t{%1, %P0|%P0, %1}
2032    mov{q}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "DI")])
2039
2040 (define_insn "*movabsdi_2_rex64"
2041   [(set (match_operand:DI 0 "register_operand" "=a,r")
2042         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{q}\t{%P1, %0|%0, %P1}
2046    mov{q}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "DI")])
2053
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it.  In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058   [(match_scratch:DI 2 "r")
2059    (set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 1))
2064    (set (match_dup 0) (match_dup 2))]
2065   "")
2066
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075   [(set (match_dup 2) (match_dup 3))
2076    (set (match_dup 4) (match_dup 5))]
2077   "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083    && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_insn "*swapdi_rex64"
2090   [(set (match_operand:DI 0 "register_operand" "+r")
2091         (match_operand:DI 1 "register_operand" "+r"))
2092    (set (match_dup 1)
2093         (match_dup 0))]
2094   "TARGET_64BIT"
2095   "xchg{q}\t%1, %0"
2096   [(set_attr "type" "imov")
2097    (set_attr "pent_pair" "np")
2098    (set_attr "athlon_decode" "vector")
2099    (set_attr "mode" "DI")
2100    (set_attr "modrm" "0")])
2101
2102   
2103 (define_expand "movsf"
2104   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105         (match_operand:SF 1 "general_operand" ""))]
2106   ""
2107   "ix86_expand_move (SFmode, operands); DONE;")
2108
2109 (define_insn "*pushsf"
2110   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112   "!TARGET_64BIT"
2113 {
2114   switch (which_alternative)
2115     {
2116     case 1:
2117       return "push{l}\t%1";
2118
2119     default:
2120       /* This insn should be already split before reg-stack.  */
2121       abort ();
2122     }
2123 }
2124   [(set_attr "type" "multi,push,multi")
2125    (set_attr "mode" "SF,SI,SF")])
2126
2127 (define_insn "*pushsf_rex64"
2128   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130   "TARGET_64BIT"
2131 {
2132   switch (which_alternative)
2133     {
2134     case 1:
2135       return "push{q}\t%q1";
2136
2137     default:
2138       /* This insn should be already split before reg-stack.  */
2139       abort ();
2140     }
2141 }
2142   [(set_attr "type" "multi,push,multi")
2143    (set_attr "mode" "SF,DI,SF")])
2144
2145 (define_split
2146   [(set (match_operand:SF 0 "push_operand" "")
2147         (match_operand:SF 1 "memory_operand" ""))]
2148   "reload_completed
2149    && GET_CODE (operands[1]) == MEM
2150    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152   [(set (match_dup 0)
2153         (match_dup 1))]
2154   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159   [(set (match_operand:SF 0 "push_operand" "")
2160         (match_operand:SF 1 "any_fp_register_operand" ""))]
2161   "!TARGET_64BIT"
2162   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2164
2165 (define_split
2166   [(set (match_operand:SF 0 "push_operand" "")
2167         (match_operand:SF 1 "any_fp_register_operand" ""))]
2168   "TARGET_64BIT"
2169   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2171
2172 (define_insn "*movsf_1"
2173   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2174         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177    && (reload_in_progress || reload_completed
2178        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179        || GET_CODE (operands[1]) != CONST_DOUBLE
2180        || memory_operand (operands[0], SFmode))" 
2181 {
2182   switch (which_alternative)
2183     {
2184     case 0:
2185       return output_387_reg_move (insn, operands);
2186
2187     case 1:
2188       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189         return "fstp%z0\t%y0";
2190       else
2191         return "fst%z0\t%y0";
2192
2193     case 2:
2194       return standard_80387_constant_opcode (operands[1]);
2195
2196     case 3:
2197     case 4:
2198       return "mov{l}\t{%1, %0|%0, %1}";
2199     case 5:
2200       if (get_attr_mode (insn) == MODE_TI)
2201         return "pxor\t%0, %0";
2202       else
2203         return "xorps\t%0, %0";
2204     case 6:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movss\t{%1, %0|%0, %1}";
2209     case 7:
2210     case 8:
2211       return "movss\t{%1, %0|%0, %1}";
2212
2213     case 9:
2214     case 10:
2215       return "movd\t{%1, %0|%0, %1}";
2216
2217     case 11:
2218       return "movq\t{%1, %0|%0, %1}";
2219
2220     default:
2221       abort();
2222     }
2223 }
2224   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225    (set (attr "mode")
2226         (cond [(eq_attr "alternative" "3,4,9,10")
2227                  (const_string "SI")
2228                (eq_attr "alternative" "5")
2229                  (if_then_else
2230                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231                                  (const_int 0))
2232                              (ne (symbol_ref "TARGET_SSE2")
2233                                  (const_int 0)))
2234                         (eq (symbol_ref "optimize_size")
2235                             (const_int 0)))
2236                    (const_string "TI")
2237                    (const_string "V4SF"))
2238                /* For architectures resolving dependencies on
2239                   whole SSE registers use APS move to break dependency
2240                   chains, otherwise use short move to avoid extra work. 
2241
2242                   Do the same for architectures resolving dependencies on
2243                   the parts.  While in DF mode it is better to always handle
2244                   just register parts, the SF mode is different due to lack
2245                   of instructions to load just part of the register.  It is
2246                   better to maintain the whole registers in single format
2247                   to avoid problems on using packed logical operations.  */
2248                (eq_attr "alternative" "6")
2249                  (if_then_else
2250                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251                             (const_int 0))
2252                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253                             (const_int 0)))
2254                    (const_string "V4SF")
2255                    (const_string "SF"))
2256                (eq_attr "alternative" "11")
2257                  (const_string "DI")]
2258                (const_string "SF")))])
2259
2260 (define_insn "*movsf_1_nointerunit"
2261   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2262         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2269 {
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2274
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2280
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2283
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2300
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2304
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2307
2308     default:
2309       abort();
2310     }
2311 }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2329
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "register_operand" "+f")
2350         (match_operand:SF 1 "register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || !TARGET_SSE"
2354 {
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2359 }
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2381 }
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2404
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2412
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429    && (reload_in_progress || reload_completed
2430        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431        || GET_CODE (operands[1]) != CONST_DOUBLE
2432        || memory_operand (operands[0], DFmode))" 
2433 {
2434   switch (which_alternative)
2435     {
2436     case 0:
2437       return output_387_reg_move (insn, operands);
2438
2439     case 1:
2440       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441         return "fstp%z0\t%y0";
2442       else
2443         return "fst%z0\t%y0";
2444
2445     case 2:
2446       return standard_80387_constant_opcode (operands[1]);
2447
2448     case 3:
2449     case 4:
2450       return "#";
2451     case 5:
2452       switch (get_attr_mode (insn))
2453         {
2454         case MODE_V4SF:
2455           return "xorps\t%0, %0";
2456         case MODE_V2DF:
2457           return "xorpd\t%0, %0";
2458         case MODE_TI:
2459           return "pxor\t%0, %0";
2460         default:
2461           abort ();
2462         }
2463     case 6:
2464       switch (get_attr_mode (insn))
2465         {
2466         case MODE_V4SF:
2467           return "movaps\t{%1, %0|%0, %1}";
2468         case MODE_V2DF:
2469           return "movapd\t{%1, %0|%0, %1}";
2470         case MODE_DF:
2471           return "movsd\t{%1, %0|%0, %1}";
2472         default:
2473           abort ();
2474         }
2475     case 7:
2476       if (get_attr_mode (insn) == MODE_V2DF)
2477         return "movlpd\t{%1, %0|%0, %1}";
2478       else
2479         return "movsd\t{%1, %0|%0, %1}";
2480     case 8:
2481       return "movsd\t{%1, %0|%0, %1}";
2482
2483     default:
2484       abort();
2485     }
2486 }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "3,4")
2490                  (const_string "SI")
2491                /* xorps is one byte shorter.  */
2492                (eq_attr "alternative" "5")
2493                  (cond [(ne (symbol_ref "optimize_size")
2494                             (const_int 0))
2495                           (const_string "V4SF")
2496                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497                             (const_int 0))
2498                           (const_string "TI")]
2499                        (const_string "V2DF"))
2500                /* For architectures resolving dependencies on
2501                   whole SSE registers use APD move to break dependency
2502                   chains, otherwise use short move to avoid extra work.
2503
2504                   movaps encodes one byte shorter.  */
2505                (eq_attr "alternative" "6")
2506                  (cond
2507                   [(ne (symbol_ref "optimize_size")
2508                        (const_int 0))
2509                      (const_string "V4SF")
2510                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511                        (const_int 0))
2512                      (const_string "V2DF")]
2513                    (const_string "DF"))
2514                /* For architectures resolving dependencies on register
2515                   parts we may avoid extra work to zero out upper part
2516                   of register.  */
2517                (eq_attr "alternative" "7")
2518                  (if_then_else
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520                        (const_int 0))
2521                    (const_string "V2DF")
2522                    (const_string "DF"))]
2523                (const_string "DF")))])
2524
2525 (define_insn "*movdf_integer"
2526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530    && (reload_in_progress || reload_completed
2531        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532        || GET_CODE (operands[1]) != CONST_DOUBLE
2533        || memory_operand (operands[0], DFmode))" 
2534 {
2535   switch (which_alternative)
2536     {
2537     case 0:
2538       return output_387_reg_move (insn, operands);
2539
2540     case 1:
2541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542         return "fstp%z0\t%y0";
2543       else
2544         return "fst%z0\t%y0";
2545
2546     case 2:
2547       return standard_80387_constant_opcode (operands[1]);
2548
2549     case 3:
2550     case 4:
2551       return "#";
2552
2553     case 5:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "xorps\t%0, %0";
2558         case MODE_V2DF:
2559           return "xorpd\t%0, %0";
2560         case MODE_TI:
2561           return "pxor\t%0, %0";
2562         default:
2563           abort ();
2564         }
2565     case 6:
2566       switch (get_attr_mode (insn))
2567         {
2568         case MODE_V4SF:
2569           return "movaps\t{%1, %0|%0, %1}";
2570         case MODE_V2DF:
2571           return "movapd\t{%1, %0|%0, %1}";
2572         case MODE_DF:
2573           return "movsd\t{%1, %0|%0, %1}";
2574         default:
2575           abort ();
2576         }
2577     case 7:
2578       if (get_attr_mode (insn) == MODE_V2DF)
2579         return "movlpd\t{%1, %0|%0, %1}";
2580       else
2581         return "movsd\t{%1, %0|%0, %1}";
2582     case 8:
2583       return "movsd\t{%1, %0|%0, %1}";
2584
2585     default:
2586       abort();
2587     }
2588 }
2589   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590    (set (attr "mode")
2591         (cond [(eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593                /* xorps is one byte shorter.  */
2594                (eq_attr "alternative" "5")
2595                  (cond [(ne (symbol_ref "optimize_size")
2596                             (const_int 0))
2597                           (const_string "V4SF")
2598                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599                             (const_int 0))
2600                           (const_string "TI")]
2601                        (const_string "V2DF"))
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.  
2605
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                   [(ne (symbol_ref "optimize_size")
2610                        (const_int 0))
2611                      (const_string "V4SF")
2612                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                        (const_int 0))
2614                      (const_string "V2DF")]
2615                    (const_string "DF"))
2616                /* For architectures resolving dependencies on register
2617                   parts we may avoid extra work to zero out upper part
2618                   of register.  */
2619                (eq_attr "alternative" "7")
2620                  (if_then_else
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622                        (const_int 0))
2623                    (const_string "V2DF")
2624                    (const_string "DF"))]
2625                (const_string "DF")))])
2626
2627 (define_split
2628   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629         (match_operand:DF 1 "general_operand" ""))]
2630   "reload_completed
2631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632    && ! (ANY_FP_REG_P (operands[0]) || 
2633          (GET_CODE (operands[0]) == SUBREG
2634           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635    && ! (ANY_FP_REG_P (operands[1]) || 
2636          (GET_CODE (operands[1]) == SUBREG
2637           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638   [(const_int 0)]
2639   "ix86_split_long_move (operands); DONE;")
2640
2641 (define_insn "*swapdf"
2642   [(set (match_operand:DF 0 "register_operand" "+f")
2643         (match_operand:DF 1 "register_operand" "+f"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "reload_completed || !TARGET_SSE2"
2647 {
2648   if (STACK_TOP_P (operands[0]))
2649     return "fxch\t%1";
2650   else
2651     return "fxch\t%0";
2652 }
2653   [(set_attr "type" "fxch")
2654    (set_attr "mode" "DF")])
2655
2656 (define_expand "movxf"
2657   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658         (match_operand:XF 1 "general_operand" ""))]
2659   ""
2660   "ix86_expand_move (XFmode, operands); DONE;")
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;;  handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_size"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   abort ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_insn "*pushxf_integer"
2681   [(set (match_operand:XF 0 "push_operand" "=<,<")
2682         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683   "!optimize_size"
2684 {
2685   /* This insn should be already split before reg-stack.  */
2686   abort ();
2687 }
2688   [(set_attr "type" "multi")
2689    (set_attr "mode" "XF,SI")])
2690
2691 (define_split
2692   [(set (match_operand 0 "push_operand" "")
2693         (match_operand 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_MODE (operands[0]) == XFmode
2696        || GET_MODE (operands[0]) == DFmode)
2697    && !ANY_FP_REG_P (operands[1])"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2700
2701 (define_split
2702   [(set (match_operand:XF 0 "push_operand" "")
2703         (match_operand:XF 1 "any_fp_register_operand" ""))]
2704   "!TARGET_64BIT"
2705   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2708
2709 (define_split
2710   [(set (match_operand:XF 0 "push_operand" "")
2711         (match_operand:XF 1 "any_fp_register_operand" ""))]
2712   "TARGET_64BIT"
2713   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2716
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721   "optimize_size
2722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723    && (reload_in_progress || reload_completed
2724        || GET_CODE (operands[1]) != CONST_DOUBLE
2725        || memory_operand (operands[0], XFmode))" 
2726 {
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       return output_387_reg_move (insn, operands);
2731
2732     case 1:
2733       /* There is no non-popping store to memory for XFmode.  So if
2734          we need one, follow the store with a load.  */
2735       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736         return "fstp%z0\t%y0\;fld%z0\t%y0";
2737       else
2738         return "fstp%z0\t%y0";
2739
2740     case 2:
2741       return standard_80387_constant_opcode (operands[1]);
2742
2743     case 3: case 4:
2744       return "#";
2745     }
2746   abort();
2747 }
2748   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749    (set_attr "mode" "XF,XF,XF,SI,SI")])
2750
2751 (define_insn "*movxf_integer"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754   "!optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2772
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2775
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2780 }
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_split
2785   [(set (match_operand 0 "nonimmediate_operand" "")
2786         (match_operand 1 "general_operand" ""))]
2787   "reload_completed
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && GET_MODE (operands[0]) == XFmode
2790    && ! (ANY_FP_REG_P (operands[0]) || 
2791          (GET_CODE (operands[0]) == SUBREG
2792           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793    && ! (ANY_FP_REG_P (operands[1]) || 
2794          (GET_CODE (operands[1]) == SUBREG
2795           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798
2799 (define_split
2800   [(set (match_operand 0 "register_operand" "")
2801         (match_operand 1 "memory_operand" ""))]
2802   "reload_completed
2803    && GET_CODE (operands[1]) == MEM
2804    && (GET_MODE (operands[0]) == XFmode
2805        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808   [(set (match_dup 0) (match_dup 1))]
2809 {
2810   rtx c = get_pool_constant (XEXP (operands[1], 0));
2811   rtx r = operands[0];
2812
2813   if (GET_CODE (r) == SUBREG)
2814     r = SUBREG_REG (r);
2815
2816   if (SSE_REG_P (r))
2817     {
2818       if (!standard_sse_constant_p (c))
2819         FAIL;
2820     }
2821   else if (FP_REG_P (r))
2822     {
2823       if (!standard_80387_constant_p (c))
2824         FAIL;
2825     }
2826   else if (MMX_REG_P (r))
2827     FAIL;
2828
2829   operands[1] = c;
2830 })
2831
2832 (define_insn "swapxf"
2833   [(set (match_operand:XF 0 "register_operand" "+f")
2834         (match_operand:XF 1 "register_operand" "+f"))
2835    (set (match_dup 1)
2836         (match_dup 0))]
2837   ""
2838 {
2839   if (STACK_TOP_P (operands[0]))
2840     return "fxch\t%1";
2841   else
2842     return "fxch\t%0";
2843 }
2844   [(set_attr "type" "fxch")
2845    (set_attr "mode" "XF")])
2846 \f
2847 ;; Zero extension instructions
2848
2849 (define_expand "zero_extendhisi2"
2850   [(set (match_operand:SI 0 "register_operand" "")
2851      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852   ""
2853 {
2854   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855     {
2856       operands[1] = force_reg (HImode, operands[1]);
2857       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858       DONE;
2859     }
2860 })
2861
2862 (define_insn "zero_extendhisi2_and"
2863   [(set (match_operand:SI 0 "register_operand" "=r")
2864      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865    (clobber (reg:CC FLAGS_REG))]
2866   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867   "#"
2868   [(set_attr "type" "alu1")
2869    (set_attr "mode" "SI")])
2870
2871 (define_split
2872   [(set (match_operand:SI 0 "register_operand" "")
2873         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877               (clobber (reg:CC FLAGS_REG))])]
2878   "")
2879
2880 (define_insn "*zero_extendhisi2_movzwl"
2881   [(set (match_operand:SI 0 "register_operand" "=r")
2882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884   "movz{wl|x}\t{%1, %0|%0, %1}"
2885   [(set_attr "type" "imovx")
2886    (set_attr "mode" "SI")])
2887
2888 (define_expand "zero_extendqihi2"
2889   [(parallel
2890     [(set (match_operand:HI 0 "register_operand" "")
2891        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892      (clobber (reg:CC FLAGS_REG))])]
2893   ""
2894   "")
2895
2896 (define_insn "*zero_extendqihi2_and"
2897   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899    (clobber (reg:CC FLAGS_REG))]
2900   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901   "#"
2902   [(set_attr "type" "alu1")
2903    (set_attr "mode" "HI")])
2904
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910   "#"
2911   [(set_attr "type" "imovx,alu1")
2912    (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw"
2915   [(set (match_operand:HI 0 "register_operand" "=r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918   "movz{bw|x}\t{%1, %0|%0, %1}"
2919   [(set_attr "type" "imovx")
2920    (set_attr "mode" "HI")])
2921
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924   [(set (match_operand:HI 0 "register_operand" "")
2925         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926    (clobber (reg:CC FLAGS_REG))]
2927   "reload_completed 
2928    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930   [(set (match_operand:HI 0 "register_operand" "")
2931         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2932
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936   [(set (match_operand:HI 0 "register_operand" "")
2937         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed
2940    && ANY_QI_REG_P (operands[0])
2941    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943   [(set (match_dup 0) (const_int 0))
2944    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945   "operands[2] = gen_lowpart (QImode, operands[0]);")
2946
2947 ;; Rest is handled by single and.
2948 (define_split
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951    (clobber (reg:CC FLAGS_REG))]
2952   "reload_completed
2953    && true_regnum (operands[0]) == true_regnum (operands[1])"
2954   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955               (clobber (reg:CC FLAGS_REG))])]
2956   "")
2957
2958 (define_expand "zero_extendqisi2"
2959   [(parallel
2960     [(set (match_operand:SI 0 "register_operand" "")
2961        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962      (clobber (reg:CC FLAGS_REG))])]
2963   ""
2964   "")
2965
2966 (define_insn "*zero_extendqisi2_and"
2967   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969    (clobber (reg:CC FLAGS_REG))]
2970   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971   "#"
2972   [(set_attr "type" "alu1")
2973    (set_attr "mode" "SI")])
2974
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,r")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "#"
2981   [(set_attr "type" "imovx,alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw"
2985   [(set (match_operand:SI 0 "register_operand" "=r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988   "movz{bl|x}\t{%1, %0|%0, %1}"
2989   [(set_attr "type" "imovx")
2990    (set_attr "mode" "SI")])
2991
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994   [(set (match_operand:SI 0 "register_operand" "")
2995         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996    (clobber (reg:CC FLAGS_REG))]
2997   "reload_completed 
2998    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000   [(set (match_dup 0)
3001         (zero_extend:SI (match_dup 1)))])
3002
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006   [(set (match_operand:SI 0 "register_operand" "")
3007         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && ANY_QI_REG_P (operands[0])
3011    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014   [(set (match_dup 0) (const_int 0))
3015    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016   "operands[2] = gen_lowpart (QImode, operands[0]);")
3017
3018 ;; Rest is handled by single and.
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed
3024    && true_regnum (operands[0]) == true_regnum (operands[1])"
3025   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026               (clobber (reg:CC FLAGS_REG))])]
3027   "")
3028
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033   ""
3034   "if (!TARGET_64BIT)
3035      {
3036        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037        DONE;
3038      }
3039   ")
3040
3041 (define_insn "zero_extendsidi2_32"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046   "@
3047    #
3048    #
3049    #
3050    movd\t{%1, %0|%0, %1}
3051    movd\t{%1, %0|%0, %1}"
3052   [(set_attr "mode" "SI,SI,SI,DI,TI")
3053    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055 (define_insn "*zero_extendsidi2_32_1"
3056   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060   "@
3061    #
3062    #
3063    #
3064    movd\t{%1, %0|%0, %1}
3065    movd\t{%1, %0|%0, %1}"
3066   [(set_attr "mode" "SI,SI,SI,DI,TI")
3067    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3068
3069 (define_insn "zero_extendsidi2_rex64"
3070   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073   "@
3074    mov\t{%k1, %k0|%k0, %k1}
3075    #
3076    movd\t{%1, %0|%0, %1}
3077    movd\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079    (set_attr "mode" "SI,DI,DI,TI")])
3080
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085   "@
3086    mov\t{%k1, %k0|%k0, %k1}
3087    #
3088    movd\t{%1, %0|%0, %1}
3089    movd\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091    (set_attr "mode" "SI,DI,SI,SI")])
3092
3093 (define_split
3094   [(set (match_operand:DI 0 "memory_operand" "")
3095      (zero_extend:DI (match_dup 0)))]
3096   "TARGET_64BIT"
3097   [(set (match_dup 4) (const_int 0))]
3098   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
3100 (define_split 
3101   [(set (match_operand:DI 0 "register_operand" "")
3102         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_64BIT && reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split 
3110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115   [(set (match_dup 3) (match_dup 1))
3116    (set (match_dup 4) (const_int 0))]
3117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3118
3119 (define_insn "zero_extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122   "TARGET_64BIT"
3123   "@
3124    movz{wl|x}\t{%1, %k0|%k0, %1}
3125    movz{wq|x}\t{%1, %0|%0, %1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI,DI")])
3128
3129 (define_insn "zero_extendqidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r,r")
3131      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132   "TARGET_64BIT"
3133   "@
3134    movz{bl|x}\t{%1, %k0|%k0, %1}
3135    movz{bq|x}\t{%1, %0|%0, %1}"
3136   [(set_attr "type" "imovx")
3137    (set_attr "mode" "SI,DI")])
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_expand "extendsidi2"
3142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144               (clobber (reg:CC FLAGS_REG))
3145               (clobber (match_scratch:SI 2 ""))])]
3146   ""
3147 {
3148   if (TARGET_64BIT)
3149     {
3150       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151       DONE;
3152     }
3153 })
3154
3155 (define_insn "*extendsidi2_1"
3156   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158    (clobber (reg:CC FLAGS_REG))
3159    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160   "!TARGET_64BIT"
3161   "#")
3162
3163 (define_insn "extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    {cltq|cdqe}
3169    movs{lq|x}\t{%1,%0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "DI")
3172    (set_attr "prefix_0f" "0")
3173    (set_attr "modrm" "0,1")])
3174
3175 (define_insn "extendhidi2"
3176   [(set (match_operand:DI 0 "register_operand" "=r")
3177         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178   "TARGET_64BIT"
3179   "movs{wq|x}\t{%1,%0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "DI")])
3182
3183 (define_insn "extendqidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r")
3185         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186   "TARGET_64BIT"
3187   "movs{bq|x}\t{%1,%0|%0, %1}"
3188    [(set_attr "type" "imovx")
3189     (set_attr "mode" "DI")])
3190
3191 ;; Extend to memory case when source register does die.
3192 (define_split 
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_operand:SI 2 "register_operand" ""))]
3197   "(reload_completed
3198     && dead_or_set_p (insn, operands[1])
3199     && !reg_mentioned_p (operands[1], operands[0]))"
3200   [(set (match_dup 3) (match_dup 1))
3201    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202               (clobber (reg:CC FLAGS_REG))])
3203    (set (match_dup 4) (match_dup 1))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 ;; Extend to memory case when source register does not die.
3207 (define_split 
3208   [(set (match_operand:DI 0 "memory_operand" "")
3209         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210    (clobber (reg:CC FLAGS_REG))
3211    (clobber (match_operand:SI 2 "register_operand" ""))]
3212   "reload_completed"
3213   [(const_int 0)]
3214 {
3215   split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217   emit_move_insn (operands[3], operands[1]);
3218
3219   /* Generate a cltd if possible and doing so it profitable.  */
3220   if (true_regnum (operands[1]) == 0
3221       && true_regnum (operands[2]) == 1
3222       && (optimize_size || TARGET_USE_CLTD))
3223     {
3224       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225     }
3226   else
3227     {
3228       emit_move_insn (operands[2], operands[1]);
3229       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230     }
3231   emit_move_insn (operands[4], operands[2]);
3232   DONE;
3233 })
3234
3235 ;; Extend to register case.  Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split 
3238   [(set (match_operand:DI 0 "register_operand" "")
3239         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))
3241    (clobber (match_scratch:SI 2 ""))]
3242   "reload_completed"
3243   [(const_int 0)]
3244 {
3245   split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248     emit_move_insn (operands[3], operands[1]);
3249
3250   /* Generate a cltd if possible and doing so it profitable.  */
3251   if (true_regnum (operands[3]) == 0
3252       && (optimize_size || TARGET_USE_CLTD))
3253     {
3254       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255       DONE;
3256     }
3257
3258   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259     emit_move_insn (operands[4], operands[1]);
3260
3261   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262   DONE;
3263 })
3264
3265 (define_insn "extendhisi2"
3266   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268   ""
3269 {
3270   switch (get_attr_prefix_0f (insn))
3271     {
3272     case 0:
3273       return "{cwtl|cwde}";
3274     default:
3275       return "movs{wl|x}\t{%1,%0|%0, %1}";
3276     }
3277 }
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "SI")
3280    (set (attr "prefix_0f")
3281      ;; movsx is short decodable while cwtl is vector decoded.
3282      (if_then_else (and (eq_attr "cpu" "!k6")
3283                         (eq_attr "alternative" "0"))
3284         (const_string "0")
3285         (const_string "1")))
3286    (set (attr "modrm")
3287      (if_then_else (eq_attr "prefix_0f" "0")
3288         (const_string "0")
3289         (const_string "1")))])
3290
3291 (define_insn "*extendhisi2_zext"
3292   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293         (zero_extend:DI
3294           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295   "TARGET_64BIT"
3296 {
3297   switch (get_attr_prefix_0f (insn))
3298     {
3299     case 0:
3300       return "{cwtl|cwde}";
3301     default:
3302       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303     }
3304 }
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "SI")
3307    (set (attr "prefix_0f")
3308      ;; movsx is short decodable while cwtl is vector decoded.
3309      (if_then_else (and (eq_attr "cpu" "!k6")
3310                         (eq_attr "alternative" "0"))
3311         (const_string "0")
3312         (const_string "1")))
3313    (set (attr "modrm")
3314      (if_then_else (eq_attr "prefix_0f" "0")
3315         (const_string "0")
3316         (const_string "1")))])
3317
3318 (define_insn "extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321   ""
3322 {
3323   switch (get_attr_prefix_0f (insn))
3324     {
3325     case 0:
3326       return "{cbtw|cbw}";
3327     default:
3328       return "movs{bw|x}\t{%1,%0|%0, %1}";
3329     }
3330 }
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "HI")
3333    (set (attr "prefix_0f")
3334      ;; movsx is short decodable while cwtl is vector decoded.
3335      (if_then_else (and (eq_attr "cpu" "!k6")
3336                         (eq_attr "alternative" "0"))
3337         (const_string "0")
3338         (const_string "1")))
3339    (set (attr "modrm")
3340      (if_then_else (eq_attr "prefix_0f" "0")
3341         (const_string "0")
3342         (const_string "1")))])
3343
3344 (define_insn "extendqisi2"
3345   [(set (match_operand:SI 0 "register_operand" "=r")
3346         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   ""
3348   "movs{bl|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqisi2_zext"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (zero_extend:DI
3355           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356   "TARGET_64BIT"
3357   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3360 \f
3361 ;; Conversions between float and double.
3362
3363 ;; These are all no-ops in the model used for the 80387.  So just
3364 ;; emit moves.
3365
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3367 (define_insn "*dummy_extendsfdf2"
3368   [(set (match_operand:DF 0 "push_operand" "=<")
3369         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370   "0"
3371   "#")
3372
3373 (define_split
3374   [(set (match_operand:DF 0 "push_operand" "")
3375         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376   "!TARGET_64BIT"
3377   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3379
3380 (define_split
3381   [(set (match_operand:DF 0 "push_operand" "")
3382         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383   "TARGET_64BIT"
3384   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3386
3387 (define_insn "*dummy_extendsfxf2"
3388   [(set (match_operand:XF 0 "push_operand" "=<")
3389         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390   "0"
3391   "#")
3392
3393 (define_split
3394   [(set (match_operand:XF 0 "push_operand" "")
3395         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396   ""
3397   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3400
3401 (define_split
3402   [(set (match_operand:XF 0 "push_operand" "")
3403         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404   "TARGET_64BIT"
3405   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3408
3409 (define_split
3410   [(set (match_operand:XF 0 "push_operand" "")
3411         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412   ""
3413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3416
3417 (define_split
3418   [(set (match_operand:XF 0 "push_operand" "")
3419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420   "TARGET_64BIT"
3421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3424
3425 (define_expand "extendsfdf2"
3426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428   "TARGET_80387 || TARGET_SSE2"
3429 {
3430   /* ??? Needed for compress_float_constant since all fp constants
3431      are LEGITIMATE_CONSTANT_P.  */
3432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435     operands[1] = force_reg (SFmode, operands[1]);
3436 })
3437
3438 (define_insn "*extendsfdf2_1"
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441   "(TARGET_80387 || TARGET_SSE2)
3442    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3443 {
3444   switch (which_alternative)
3445     {
3446     case 0:
3447       return output_387_reg_move (insn, operands);
3448
3449     case 1:
3450       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451         return "fstp%z0\t%y0";
3452       else
3453         return "fst%z0\t%y0";
3454
3455     case 2:
3456       return "cvtss2sd\t{%1, %0|%0, %1}";
3457
3458     default:
3459       abort ();
3460     }
3461 }
3462   [(set_attr "type" "fmov,fmov,ssecvt")
3463    (set_attr "mode" "SF,XF,DF")])
3464
3465 (define_insn "*extendsfdf2_1_sse_only"
3466   [(set (match_operand:DF 0 "register_operand" "=Y")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468   "!TARGET_80387 && TARGET_SSE2
3469    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470   "cvtss2sd\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "ssecvt")
3472    (set_attr "mode" "DF")])
3473
3474 (define_expand "extendsfxf2"
3475   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477   "TARGET_80387"
3478 {
3479   /* ??? Needed for compress_float_constant since all fp constants
3480      are LEGITIMATE_CONSTANT_P.  */
3481   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484     operands[1] = force_reg (SFmode, operands[1]);
3485 })
3486
3487 (define_insn "*extendsfxf2_1"
3488   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490   "TARGET_80387
3491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3492 {
3493   switch (which_alternative)
3494     {
3495     case 0:
3496       return output_387_reg_move (insn, operands);
3497
3498     case 1:
3499       /* There is no non-popping store to memory for XFmode.  So if
3500          we need one, follow the store with a load.  */
3501       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503       else
3504         return "fstp%z0\t%y0";
3505
3506     default:
3507       abort ();
3508     }
3509 }
3510   [(set_attr "type" "fmov")
3511    (set_attr "mode" "SF,XF")])
3512
3513 (define_expand "extenddfxf2"
3514   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516   "TARGET_80387"
3517 {
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (DFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extenddfxf2_1"
3527   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529   "TARGET_80387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 1:
3538       /* There is no non-popping store to memory for XFmode.  So if
3539          we need one, follow the store with a load.  */
3540       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542       else
3543         return "fstp%z0\t%y0";
3544
3545     default:
3546       abort ();
3547     }
3548 }
3549   [(set_attr "type" "fmov")
3550    (set_attr "mode" "DF,XF")])
3551
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case.  Otherwise this is just like a simple move
3555 ;; insn.  So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3557
3558 (define_expand "truncdfsf2"
3559   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560                    (float_truncate:SF
3561                     (match_operand:DF 1 "register_operand" "")))
3562               (clobber (match_dup 2))])]
3563   "TARGET_80387 || TARGET_SSE2"
3564   "
3565    if (!TARGET_80387)
3566      {
3567         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568         DONE;
3569      }
3570    else if (flag_unsafe_math_optimizations)
3571      {
3572         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574         if (reg != operands[0])
3575           emit_move_insn (operands[0], reg);
3576         DONE;
3577      }
3578    else
3579      operands[2] = assign_386_stack_local (SFmode, 0);
3580 ")
3581
3582 (define_insn "truncdfsf2_noop"
3583   [(set (match_operand:SF 0 "register_operand" "=f")
3584         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585   "TARGET_80387 && flag_unsafe_math_optimizations"
3586 {
3587   return output_387_reg_move (insn, operands);
3588 }
3589   [(set_attr "type" "fmov")
3590    (set_attr "mode" "SF")])
3591
3592 (define_insn "*truncdfsf2_1"
3593   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594         (float_truncate:SF
3595          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597   "TARGET_80387 && !TARGET_SSE2"
3598 {
3599   switch (which_alternative)
3600     {
3601     case 0:
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fst%z0\t%y0";
3606     default:
3607       abort ();
3608     }
3609 }
3610   [(set_attr "type" "fmov,multi,multi,multi")
3611    (set_attr "mode" "SF,SF,SF,SF")])
3612
3613 (define_insn "*truncdfsf2_1_sse"
3614   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615         (float_truncate:SF
3616          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0";
3625       else
3626         return "fst%z0\t%y0";
3627     case 4:
3628       return "#";
3629     default:
3630       abort ();
3631     }
3632 }
3633   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634    (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     case 4:
3651       return "#";
3652     default:
3653       abort ();
3654     }
3655 }
3656   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657    (set_attr "mode" "SF,SF,SF,SF,DF")])
3658
3659 (define_insn "*truncdfsf2_2"
3660   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661         (float_truncate:SF
3662          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3665 {
3666   switch (which_alternative)
3667     {
3668     case 0:
3669     case 1:
3670       return "cvtsd2ss\t{%1, %0|%0, %1}";
3671     case 2:
3672       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673         return "fstp%z0\t%y0";
3674       else
3675         return "fst%z0\t%y0";
3676     default:
3677       abort ();
3678     }
3679 }
3680   [(set_attr "type" "ssecvt,ssecvt,fmov")
3681    (set_attr "athlon_decode" "vector,double,*")
3682    (set_attr "mode" "SF,SF,SF")])
3683
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686         (float_truncate:SF
3687          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690 {
3691   switch (which_alternative)
3692     {
3693     case 0:
3694       return "#";
3695     case 1:
3696       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697         return "fstp%z0\t%y0";
3698       else
3699         return "fst%z0\t%y0";
3700     default:
3701       abort ();
3702     }
3703 }
3704   [(set_attr "type" "ssecvt,fmov")
3705    (set_attr "mode" "DF,SF")])
3706
3707 (define_insn "*truncdfsf2_3"
3708   [(set (match_operand:SF 0 "memory_operand" "=m")
3709         (float_truncate:SF
3710          (match_operand:DF 1 "register_operand" "f")))]
3711   "TARGET_80387"
3712 {
3713   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714     return "fstp%z0\t%y0";
3715   else
3716     return "fst%z0\t%y0";
3717 }
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3720
3721 (define_insn "truncdfsf2_sse_only"
3722   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726   "cvtsd2ss\t{%1, %0|%0, %1}"
3727   [(set_attr "type" "ssecvt")
3728    (set_attr "athlon_decode" "vector,double")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732   [(set (match_operand:SF 0 "register_operand" "=&Y")
3733         (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736   "#"
3737   [(set_attr "type" "ssecvt")
3738    (set_attr "mode" "DF")])
3739
3740 (define_split
3741   [(set (match_operand:SF 0 "memory_operand" "")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "register_operand" "")))
3744    (clobber (match_operand:SF 2 "memory_operand" ""))]
3745   "TARGET_80387"
3746   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747   "")
3748
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752   [(set (match_operand:SF 0 "register_operand" "")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "nonimmediate_operand" "")))
3755    (clobber (match_operand 2 "" ""))]
3756   "TARGET_80387 && reload_completed
3757    && SSE_REG_P (operands[0])
3758    && !STACK_REG_P (operands[1])"
3759   [(const_int 0)]
3760 {
3761   rtx src, dest;
3762   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764   else
3765     {
3766       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768       /* simplify_gen_subreg refuses to widen memory references.  */
3769       if (GET_CODE (src) == SUBREG)
3770         alter_subreg (&src);
3771       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772         abort ();
3773       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774       emit_insn (gen_cvtsd2ss (dest, dest, src));
3775     }
3776   DONE;
3777 })
3778
3779 (define_split
3780   [(set (match_operand:SF 0 "register_operand" "")
3781         (float_truncate:SF
3782          (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 && reload_completed
3784    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785   [(const_int 0)]
3786 {
3787   rtx src, dest;
3788   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790   /* simplify_gen_subreg refuses to widen memory references.  */
3791   if (GET_CODE (src) == SUBREG)
3792     alter_subreg (&src);
3793   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794     abort ();
3795   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796   emit_insn (gen_cvtsd2ss (dest, dest, src));
3797   DONE;
3798 })
3799
3800 (define_split
3801   [(set (match_operand:SF 0 "register_operand" "")
3802         (float_truncate:SF
3803          (match_operand:DF 1 "fp_register_operand" "")))
3804    (clobber (match_operand:SF 2 "memory_operand" ""))]
3805   "TARGET_80387 && reload_completed"
3806   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807    (set (match_dup 0) (match_dup 2))]
3808   "")
3809
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816   "
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827   ")
3828
3829 (define_insn "truncxfsf2_noop"
3830   [(set (match_operand:SF 0 "register_operand" "=f")
3831         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832   "TARGET_80387 && flag_unsafe_math_optimizations"
3833 {
3834   return output_387_reg_move (insn, operands);
3835 }
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncxfsf2_1"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_80387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3856 }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_2"
3861   [(set (match_operand:SF 0 "memory_operand" "=m")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f")))]
3864   "TARGET_80387"
3865 {
3866   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867     return "fstp%z0\t%y0";
3868   else
3869     return "fst%z0\t%y0";
3870 }
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF")])
3873
3874 (define_split
3875   [(set (match_operand:SF 0 "memory_operand" "")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "")))
3878    (clobber (match_operand:SF 2 "memory_operand" ""))]
3879   "TARGET_80387"
3880   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881   "")
3882
3883 (define_split
3884   [(set (match_operand:SF 0 "register_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387 && reload_completed"
3889   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890    (set (match_dup 0) (match_dup 2))]
3891   "")
3892
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3899   "
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3910   ")
3911
3912 (define_insn "truncxfdf2_noop"
3913   [(set (match_operand:DF 0 "register_operand" "=f")
3914         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387 && flag_unsafe_math_optimizations"
3916 {
3917   return output_387_reg_move (insn, operands);
3918 }
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "DF")])
3921
3922 (define_insn "*truncxfdf2_1"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924         (float_truncate:DF
3925          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927   "TARGET_80387"
3928 {
3929   switch (which_alternative)
3930     {
3931     case 0:
3932       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933         return "fstp%z0\t%y0";
3934       else
3935         return "fst%z0\t%y0";
3936     default:
3937       abort();
3938     }
3939   abort ();
3940 }
3941   [(set_attr "type" "fmov,multi,multi,multi")
3942    (set_attr "mode" "DF")])
3943
3944 (define_insn "*truncxfdf2_2"
3945   [(set (match_operand:DF 0 "memory_operand" "=m")
3946         (float_truncate:DF
3947           (match_operand:XF 1 "register_operand" "f")))]
3948   "TARGET_80387"
3949 {
3950   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951     return "fstp%z0\t%y0";
3952   else
3953     return "fst%z0\t%y0";
3954 }
3955   [(set_attr "type" "fmov")
3956    (set_attr "mode" "DF")])
3957
3958 (define_split
3959   [(set (match_operand:DF 0 "memory_operand" "")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:DF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965   "")
3966
3967 (define_split
3968   [(set (match_operand:DF 0 "register_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387 && reload_completed"
3973   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974    (set (match_dup 0) (match_dup 2))]
3975   "")
3976
3977 \f
3978 ;; %%% Break up all these bad boys.
3979
3980 ;; Signed conversion to DImode.
3981
3982 (define_expand "fix_truncxfdi2"
3983   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3985               (clobber (reg:CC FLAGS_REG))])]
3986   "TARGET_80387"
3987   "")
3988
3989 (define_expand "fix_truncdfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3994 {
3995   if (TARGET_64BIT && TARGET_SSE2)
3996    {
3997      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999      if (out != operands[0])
4000         emit_move_insn (operands[0], out);
4001      DONE;
4002    }
4003 })
4004
4005 (define_expand "fix_truncsfdi2"
4006   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4008               (clobber (reg:CC FLAGS_REG))])] 
4009   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4010 {
4011   if (TARGET_SSE && TARGET_64BIT)
4012    {
4013      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015      if (out != operands[0])
4016         emit_move_insn (operands[0], out);
4017      DONE;
4018    }
4019 })
4020
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:DI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028    && !reload_completed && !reload_in_progress
4029    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030   "#"
4031   "&& 1"
4032   [(const_int 0)]
4033 {
4034   ix86_optimize_mode_switching = 1;
4035   operands[2] = assign_386_stack_local (HImode, 1);
4036   operands[3] = assign_386_stack_local (HImode, 2);
4037   if (memory_operand (operands[0], VOIDmode))
4038     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039                                        operands[2], operands[3]));
4040   else
4041     {
4042       operands[4] = assign_386_stack_local (DImode, 0);
4043       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044                                            operands[2], operands[3],
4045                                            operands[4]));
4046     }
4047   DONE;
4048 }
4049   [(set_attr "type" "fistp")
4050    (set_attr "i387_cw" "trunc")
4051    (set_attr "mode" "DI")])
4052
4053 (define_insn "fix_truncdi_nomemory"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055         (fix:DI (match_operand 1 "register_operand" "f,f")))
4056    (use (match_operand:HI 2 "memory_operand" "m,m"))
4057    (use (match_operand:HI 3 "memory_operand" "m,m"))
4058    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062   "#"
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_memory"
4068   [(set (match_operand:DI 0 "memory_operand" "=m")
4069         (fix:DI (match_operand 1 "register_operand" "f")))
4070    (use (match_operand:HI 2 "memory_operand" "m"))
4071    (use (match_operand:HI 3 "memory_operand" "m"))
4072    (clobber (match_scratch:DF 4 "=&1f"))]
4073   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075   "* return output_fix_trunc (insn, operands);"
4076   [(set_attr "type" "fistp")
4077    (set_attr "i387_cw" "trunc")
4078    (set_attr "mode" "DI")])
4079
4080 (define_split 
4081   [(set (match_operand:DI 0 "register_operand" "")
4082         (fix:DI (match_operand 1 "register_operand" "")))
4083    (use (match_operand:HI 2 "memory_operand" ""))
4084    (use (match_operand:HI 3 "memory_operand" ""))
4085    (clobber (match_operand:DI 4 "memory_operand" ""))
4086    (clobber (match_scratch 5 ""))]
4087   "reload_completed"
4088   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089               (use (match_dup 2))
4090               (use (match_dup 3))
4091               (clobber (match_dup 5))])
4092    (set (match_dup 0) (match_dup 4))]
4093   "")
4094
4095 (define_split 
4096   [(set (match_operand:DI 0 "memory_operand" "")
4097         (fix:DI (match_operand 1 "register_operand" "")))
4098    (use (match_operand:HI 2 "memory_operand" ""))
4099    (use (match_operand:HI 3 "memory_operand" ""))
4100    (clobber (match_operand:DI 4 "memory_operand" ""))
4101    (clobber (match_scratch 5 ""))]
4102   "reload_completed"
4103   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104               (use (match_dup 2))
4105               (use (match_dup 3))
4106               (clobber (match_dup 5))])]
4107   "")
4108
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111   [(set (match_operand:DI 0 "register_operand" "=r,r")
4112         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_64BIT && TARGET_SSE"
4114   "cvttss2si{q}\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "SF")
4117    (set_attr "athlon_decode" "double,vector")])
4118
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121   [(match_scratch:SF 2 "x")
4122    (set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124   "TARGET_K8 && !optimize_size"
4125   [(set (match_dup 2) (match_dup 1))
4126    (set (match_dup 0) (fix:DI (match_dup 2)))]
4127   "")
4128
4129 (define_insn "fix_truncdfdi_sse"
4130   [(set (match_operand:DI 0 "register_operand" "=r,r")
4131         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132   "TARGET_64BIT && TARGET_SSE2"
4133   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt,sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140   [(match_scratch:DF 2 "Y")
4141    (set (match_operand:DI 0 "register_operand" "")
4142         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143   "TARGET_K8 && !optimize_size"
4144   [(set (match_dup 2) (match_dup 1))
4145    (set (match_dup 0) (fix:DI (match_dup 2)))]
4146   "")
4147
4148 ;; Signed conversion to SImode.
4149
4150 (define_expand "fix_truncxfsi2"
4151   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))])]
4154   "TARGET_80387"
4155   "")
4156
4157 (define_expand "fix_truncdfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || TARGET_SSE2"
4162 {
4163   if (TARGET_SSE2)
4164    {
4165      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167      if (out != operands[0])
4168         emit_move_insn (operands[0], out);
4169      DONE;
4170    }
4171 })
4172
4173 (define_expand "fix_truncsfsi2"
4174   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4176               (clobber (reg:CC FLAGS_REG))])] 
4177   "TARGET_80387 || TARGET_SSE"
4178 {
4179   if (TARGET_SSE)
4180    {
4181      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183      if (out != operands[0])
4184         emit_move_insn (operands[0], out);
4185      DONE;
4186    }
4187 })
4188
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193         (fix:SI (match_operand 1 "register_operand" "f,f")))
4194    (clobber (reg:CC FLAGS_REG))]
4195   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !reload_completed && !reload_in_progress
4197    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198   "#"
4199   "&& 1"
4200   [(const_int 0)]
4201 {
4202   ix86_optimize_mode_switching = 1;
4203   operands[2] = assign_386_stack_local (HImode, 1);
4204   operands[3] = assign_386_stack_local (HImode, 2);
4205   if (memory_operand (operands[0], VOIDmode))
4206     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207                                        operands[2], operands[3]));
4208   else
4209     {
4210       operands[4] = assign_386_stack_local (SImode, 0);
4211       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212                                            operands[2], operands[3],
4213                                            operands[4]));
4214     }
4215   DONE;
4216 }
4217   [(set_attr "type" "fistp")
4218    (set_attr "i387_cw" "trunc")
4219    (set_attr "mode" "SI")])
4220
4221 (define_insn "fix_truncsi_nomemory"
4222   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:SI (match_operand 1 "register_operand" "f,f")))
4224    (use (match_operand:HI 2 "memory_operand" "m,m"))
4225    (use (match_operand:HI 3 "memory_operand" "m,m"))
4226    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229   "#"
4230   [(set_attr "type" "fistp")
4231    (set_attr "i387_cw" "trunc")
4232    (set_attr "mode" "SI")])
4233
4234 (define_insn "fix_truncsi_memory"
4235   [(set (match_operand:SI 0 "memory_operand" "=m")
4236         (fix:SI (match_operand 1 "register_operand" "f")))
4237    (use (match_operand:HI 2 "memory_operand" "m"))
4238    (use (match_operand:HI 3 "memory_operand" "m"))]
4239   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241   "* return output_fix_trunc (insn, operands);"
4242   [(set_attr "type" "fistp")
4243    (set_attr "i387_cw" "trunc")
4244    (set_attr "mode" "SI")])
4245
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248   [(set (match_operand:SI 0 "register_operand" "=r,r")
4249         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250   "TARGET_SSE"
4251   "cvttss2si\t{%1, %0|%0, %1}"
4252   [(set_attr "type" "sseicvt")
4253    (set_attr "mode" "DF")
4254    (set_attr "athlon_decode" "double,vector")])
4255
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258   [(match_scratch:SF 2 "x")
4259    (set (match_operand:SI 0 "register_operand" "")
4260         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261   "TARGET_K8 && !optimize_size"
4262   [(set (match_dup 2) (match_dup 1))
4263    (set (match_dup 0) (fix:SI (match_dup 2)))]
4264   "")
4265
4266 (define_insn "fix_truncdfsi_sse"
4267   [(set (match_operand:SI 0 "register_operand" "=r,r")
4268         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269   "TARGET_SSE2"
4270   "cvttsd2si\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "sseicvt")
4272    (set_attr "mode" "DF")
4273    (set_attr "athlon_decode" "double,vector")])
4274
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277   [(match_scratch:DF 2 "Y")
4278    (set (match_operand:SI 0 "register_operand" "")
4279         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280   "TARGET_K8 && !optimize_size"
4281   [(set (match_dup 2) (match_dup 1))
4282    (set (match_dup 0) (fix:SI (match_dup 2)))]
4283   "")
4284
4285 (define_split 
4286   [(set (match_operand:SI 0 "register_operand" "")
4287         (fix:SI (match_operand 1 "register_operand" "")))
4288    (use (match_operand:HI 2 "memory_operand" ""))
4289    (use (match_operand:HI 3 "memory_operand" ""))
4290    (clobber (match_operand:SI 4 "memory_operand" ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293               (use (match_dup 2))
4294               (use (match_dup 3))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4297
4298 (define_split 
4299   [(set (match_operand:SI 0 "memory_operand" "")
4300         (fix:SI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:SI 4 "memory_operand" ""))]
4304   "reload_completed"
4305   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306               (use (match_dup 2))
4307               (use (match_dup 3))])]
4308   "")
4309
4310 ;; Signed conversion to HImode.
4311
4312 (define_expand "fix_truncxfhi2"
4313   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])] 
4316   "TARGET_80387"
4317   "")
4318
4319 (define_expand "fix_truncdfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 && !TARGET_SSE2"
4324   "")
4325
4326 (define_expand "fix_truncsfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4329                (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE"
4331   "")
4332
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337         (fix:HI (match_operand 1 "register_operand" "f,f")))
4338    (clobber (reg:CC FLAGS_REG))]
4339   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !reload_completed && !reload_in_progress
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "#"
4343   "&& 1"
4344   [(const_int 0)]
4345 {
4346   ix86_optimize_mode_switching = 1;
4347   operands[2] = assign_386_stack_local (HImode, 1);
4348   operands[3] = assign_386_stack_local (HImode, 2);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351                                        operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (HImode, 0);
4355       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356                                            operands[2], operands[3],
4357                                            operands[4]));
4358     }
4359   DONE;
4360 }
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "HI")])
4364
4365 (define_insn "fix_trunchi_nomemory"
4366   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367         (fix:HI (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "HI")])
4389
4390 (define_split 
4391   [(set (match_operand:HI 0 "memory_operand" "")
4392         (fix:HI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:HI 4 "memory_operand" ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))])]
4400   "")
4401
4402 (define_split 
4403   [(set (match_operand:HI 0 "register_operand" "")
4404         (fix:HI (match_operand 1 "register_operand" "")))
4405    (use (match_operand:HI 2 "memory_operand" ""))
4406    (use (match_operand:HI 3 "memory_operand" ""))
4407    (clobber (match_operand:HI 4 "memory_operand" ""))]
4408   "reload_completed"
4409   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410               (use (match_dup 2))
4411               (use (match_dup 3))
4412               (clobber (match_dup 4))])
4413    (set (match_dup 0) (match_dup 4))]
4414   "")
4415
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4424
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4434 \f
4435 ;; Conversion between fixed point and floating point.
4436
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4439
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_SSE || TARGET_80387"
4444 {
4445   if (TARGET_SSE && TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4451 })
4452
4453 (define_insn "*floathisf2_1"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4456   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "fp_int_src" "true")])
4463
4464 (define_expand "floatsisf2"
4465   [(set (match_operand:SF 0 "register_operand" "")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467   "TARGET_SSE || TARGET_80387"
4468   "")
4469
4470 (define_insn "*floatsisf2_i387"
4471   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4474   "@
4475    fild%z1\t%1
4476    #
4477    cvtsi2ss\t{%1, %0|%0, %1}
4478    cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "*,*,vector,double")
4482    (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_sse"
4485   [(set (match_operand:SF 0 "register_operand" "=x,x")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487   "TARGET_SSE"
4488   "cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4500    && SSE_REG_P (operands[0])"
4501   [(const_int 0)]
4502 {
4503   rtx dest;
4504   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4505   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4506   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4507   DONE;
4508 })
4509
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4514   "")
4515
4516 (define_insn "*floatdisf2_i387_only"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4519   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4520   "@
4521    fild%z1\t%1
4522    #"
4523   [(set_attr "type" "fmov,multi")
4524    (set_attr "mode" "SF")
4525    (set_attr "fp_int_src" "true")])
4526
4527 (define_insn "*floatdisf2_i387"
4528   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4529         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4530   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4531   "@
4532    fild%z1\t%1
4533    #
4534    cvtsi2ss{q}\t{%1, %0|%0, %1}
4535    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "*,*,vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatdisf2_sse"
4542   [(set (match_operand:SF 0 "register_operand" "=x,x")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4544   "TARGET_64BIT && TARGET_SSE"
4545   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4546   [(set_attr "type" "sseicvt")
4547    (set_attr "mode" "SF")
4548    (set_attr "athlon_decode" "vector,double")
4549    (set_attr "fp_int_src" "true")])
4550
4551 ; Avoid possible reformatting penalty on the destination by first
4552 ; zeroing it out
4553 (define_split
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4557    && SSE_REG_P (operands[0])"
4558   [(const_int 0)]
4559 {
4560   rtx dest;
4561   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4562   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4563   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4564   DONE;
4565 })
4566
4567 (define_expand "floathidf2"
4568   [(set (match_operand:DF 0 "register_operand" "")
4569         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4570   "TARGET_SSE2 || TARGET_80387"
4571 {
4572   if (TARGET_SSE && TARGET_SSE_MATH)
4573     {
4574       emit_insn (gen_floatsidf2 (operands[0],
4575                                  convert_to_mode (SImode, operands[1], 0)));
4576       DONE;
4577     }
4578 })
4579
4580 (define_insn "*floathidf2_1"
4581   [(set (match_operand:DF 0 "register_operand" "=f,f")
4582         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4583   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4584   "@
4585    fild%z1\t%1
4586    #"
4587   [(set_attr "type" "fmov,multi")
4588    (set_attr "mode" "DF")
4589    (set_attr "fp_int_src" "true")])
4590
4591 (define_expand "floatsidf2"
4592   [(set (match_operand:DF 0 "register_operand" "")
4593         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4594   "TARGET_80387 || TARGET_SSE2"
4595   "")
4596
4597 (define_insn "*floatsidf2_i387"
4598   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4600   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4601   "@
4602    fild%z1\t%1
4603    #
4604    cvtsi2sd\t{%1, %0|%0, %1}
4605    cvtsi2sd\t{%1, %0|%0, %1}"
4606   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4607    (set_attr "mode" "DF")
4608    (set_attr "athlon_decode" "*,*,double,direct")
4609    (set_attr "fp_int_src" "true")])
4610
4611 (define_insn "*floatsidf2_sse"
4612   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4613         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4614   "TARGET_SSE2"
4615   "cvtsi2sd\t{%1, %0|%0, %1}"
4616   [(set_attr "type" "sseicvt")
4617    (set_attr "mode" "DF")
4618    (set_attr "athlon_decode" "double,direct")
4619    (set_attr "fp_int_src" "true")])
4620
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4625   "")
4626
4627 (define_insn "*floatdidf2_i387_only"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4630   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4631   "@
4632    fild%z1\t%1
4633    #"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "DF")
4636    (set_attr "fp_int_src" "true")])
4637
4638 (define_insn "*floatdidf2_i387"
4639   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4641   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4642   "@
4643    fild%z1\t%1
4644    #
4645    cvtsi2sd{q}\t{%1, %0|%0, %1}
4646    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "*,*,double,direct")
4650    (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatdidf2_sse"
4653   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4655   "TARGET_SSE2"
4656   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4657   [(set_attr "type" "sseicvt")
4658    (set_attr "mode" "DF")
4659    (set_attr "athlon_decode" "double,direct")
4660    (set_attr "fp_int_src" "true")])
4661
4662 (define_insn "floathixf2"
4663   [(set (match_operand:XF 0 "register_operand" "=f,f")
4664         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "XF")
4671    (set_attr "fp_int_src" "true")])
4672
4673 (define_insn "floatsixf2"
4674   [(set (match_operand:XF 0 "register_operand" "=f,f")
4675         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4676   "TARGET_80387"
4677   "@
4678    fild%z1\t%1
4679    #"
4680   [(set_attr "type" "fmov,multi")
4681    (set_attr "mode" "XF")
4682    (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "floatdixf2"
4685   [(set (match_operand:XF 0 "register_operand" "=f,f")
4686         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4687   "TARGET_80387"
4688   "@
4689    fild%z1\t%1
4690    #"
4691   [(set_attr "type" "fmov,multi")
4692    (set_attr "mode" "XF")
4693    (set_attr "fp_int_src" "true")])
4694
4695 ;; %%% Kill these when reload knows how to do it.
4696 (define_split
4697   [(set (match_operand 0 "fp_register_operand" "")
4698         (float (match_operand 1 "register_operand" "")))]
4699   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4700   [(const_int 0)]
4701 {
4702   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4703   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4704   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4705   ix86_free_from_memory (GET_MODE (operands[1]));
4706   DONE;
4707 })
4708
4709 (define_expand "floatunssisf2"
4710   [(use (match_operand:SF 0 "register_operand" ""))
4711    (use (match_operand:SI 1 "register_operand" ""))]
4712   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4713   "x86_emit_floatuns (operands); DONE;")
4714
4715 (define_expand "floatunsdisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:DI 1 "register_operand" ""))]
4718   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4719   "x86_emit_floatuns (operands); DONE;")
4720
4721 (define_expand "floatunsdidf2"
4722   [(use (match_operand:DF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4725   "x86_emit_floatuns (operands); DONE;")
4726 \f
4727 ;; SSE extract/set expanders
4728
4729 (define_expand "vec_setv2df"
4730   [(match_operand:V2DF 0 "register_operand" "")
4731    (match_operand:DF 1 "register_operand" "")
4732    (match_operand 2 "const_int_operand" "")]
4733   "TARGET_SSE2"
4734 {
4735   switch (INTVAL (operands[2]))
4736     {
4737     case 0:
4738       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4739                                  simplify_gen_subreg (V2DFmode, operands[1],
4740                                                       DFmode, 0)));
4741       break;
4742     case 1:
4743       {
4744         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4745
4746         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4747       }
4748       break;
4749     default:
4750       abort ();
4751     }
4752   DONE;
4753 })
4754
4755 (define_expand "vec_extractv2df"
4756   [(match_operand:DF 0 "register_operand" "")
4757    (match_operand:V2DF 1 "register_operand" "")
4758    (match_operand 2 "const_int_operand" "")]
4759   "TARGET_SSE2"
4760 {
4761   switch (INTVAL (operands[2]))
4762     {
4763     case 0:
4764       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4765       break;
4766     case 1:
4767       {
4768         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4769
4770         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4771       }
4772       break;
4773     default:
4774       abort ();
4775     }
4776   DONE;
4777 })
4778
4779 (define_expand "vec_initv2df"
4780   [(match_operand:V2DF 0 "register_operand" "")
4781    (match_operand 1 "" "")]
4782   "TARGET_SSE2"
4783 {
4784   ix86_expand_vector_init (operands[0], operands[1]);
4785   DONE;
4786 })
4787
4788 (define_expand "vec_setv4sf"
4789   [(match_operand:V4SF 0 "register_operand" "")
4790    (match_operand:SF 1 "register_operand" "")
4791    (match_operand 2 "const_int_operand" "")]
4792   "TARGET_SSE"
4793 {
4794   switch (INTVAL (operands[2]))
4795     {
4796     case 0:
4797       emit_insn (gen_sse_movss (operands[0], operands[0],
4798                                 simplify_gen_subreg (V4SFmode, operands[1],
4799                                                      SFmode, 0)));
4800       break;
4801     case 1:
4802       {
4803         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4804         rtx tmp = gen_reg_rtx (V4SFmode);
4805  
4806         emit_move_insn (tmp, operands[0]);
4807         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4808         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4809         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4810                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4811       }
4812       break;
4813     case 2:
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) + (0<<4) + (3<<6))));
4822       }
4823       break;
4824     case 3:
4825       {
4826         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4827         rtx tmp = gen_reg_rtx (V4SFmode);
4828
4829         emit_move_insn (tmp, operands[0]);
4830         emit_insn (gen_sse_movss (tmp, tmp, op1));
4831         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4832                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4833       }
4834       break;
4835     default:
4836       abort ();
4837     }
4838   DONE;
4839 })
4840
4841 (define_expand "vec_extractv4sf"
4842   [(match_operand:SF 0 "register_operand" "")
4843    (match_operand:V4SF 1 "register_operand" "")
4844    (match_operand 2 "const_int_operand" "")]
4845   "TARGET_SSE"
4846 {
4847   switch (INTVAL (operands[2]))
4848     {
4849     case 0:
4850       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4851       break;
4852     case 1:
4853       {
4854         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4855         rtx tmp = gen_reg_rtx (V4SFmode);
4856  
4857         emit_move_insn (tmp, operands[1]);
4858         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4859                                    const1_rtx));
4860       }
4861       break;
4862     case 2:
4863       {
4864         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4865         rtx tmp = gen_reg_rtx (V4SFmode);
4866  
4867         emit_move_insn (tmp, operands[1]);
4868         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4869       }
4870       break;
4871     case 3:
4872       {
4873         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4874         rtx tmp = gen_reg_rtx (V4SFmode);
4875  
4876         emit_move_insn (tmp, operands[1]);
4877         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4878                                    GEN_INT (3)));
4879       }
4880       break;
4881     default:
4882       abort ();
4883     }
4884   DONE;
4885 })
4886
4887 (define_expand "vec_initv4sf"
4888   [(match_operand:V4SF 0 "register_operand" "")
4889    (match_operand 1 "" "")]
4890   "TARGET_SSE"
4891 {
4892   ix86_expand_vector_init (operands[0], operands[1]);
4893   DONE;
4894 })
4895 \f
4896 ;; Add instructions
4897
4898 ;; %%% splits for addsidi3
4899 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4900 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4901 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4902
4903 (define_expand "adddi3"
4904   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4905         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4906                  (match_operand:DI 2 "x86_64_general_operand" "")))
4907    (clobber (reg:CC FLAGS_REG))]
4908   ""
4909   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4910
4911 (define_insn "*adddi3_1"
4912   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4913         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4914                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4917   "#")
4918
4919 (define_split
4920   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4921         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4922                  (match_operand:DI 2 "general_operand" "")))
4923    (clobber (reg:CC FLAGS_REG))]
4924   "!TARGET_64BIT && reload_completed"
4925   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4926                                           UNSPEC_ADD_CARRY))
4927               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4928    (parallel [(set (match_dup 3)
4929                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4930                                      (match_dup 4))
4931                             (match_dup 5)))
4932               (clobber (reg:CC FLAGS_REG))])]
4933   "split_di (operands+0, 1, operands+0, operands+3);
4934    split_di (operands+1, 1, operands+1, operands+4);
4935    split_di (operands+2, 1, operands+2, operands+5);")
4936
4937 (define_insn "adddi3_carry_rex64"
4938   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4939           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4940                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4941                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4942    (clobber (reg:CC FLAGS_REG))]
4943   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4944   "adc{q}\t{%2, %0|%0, %2}"
4945   [(set_attr "type" "alu")
4946    (set_attr "pent_pair" "pu")
4947    (set_attr "mode" "DI")])
4948
4949 (define_insn "*adddi3_cc_rex64"
4950   [(set (reg:CC FLAGS_REG)
4951         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4952                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4953                    UNSPEC_ADD_CARRY))
4954    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4955         (plus:DI (match_dup 1) (match_dup 2)))]
4956   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4957   "add{q}\t{%2, %0|%0, %2}"
4958   [(set_attr "type" "alu")
4959    (set_attr "mode" "DI")])
4960
4961 (define_insn "addqi3_carry"
4962   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4963           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4964                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4965                    (match_operand:QI 2 "general_operand" "qi,qm")))
4966    (clobber (reg:CC FLAGS_REG))]
4967   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4968   "adc{b}\t{%2, %0|%0, %2}"
4969   [(set_attr "type" "alu")
4970    (set_attr "pent_pair" "pu")
4971    (set_attr "mode" "QI")])
4972
4973 (define_insn "addhi3_carry"
4974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4975           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4976                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4977                    (match_operand:HI 2 "general_operand" "ri,rm")))
4978    (clobber (reg:CC FLAGS_REG))]
4979   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4980   "adc{w}\t{%2, %0|%0, %2}"
4981   [(set_attr "type" "alu")
4982    (set_attr "pent_pair" "pu")
4983    (set_attr "mode" "HI")])
4984
4985 (define_insn "addsi3_carry"
4986   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4987           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4988                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4989                    (match_operand:SI 2 "general_operand" "ri,rm")))
4990    (clobber (reg:CC FLAGS_REG))]
4991   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4992   "adc{l}\t{%2, %0|%0, %2}"
4993   [(set_attr "type" "alu")
4994    (set_attr "pent_pair" "pu")
4995    (set_attr "mode" "SI")])
4996
4997 (define_insn "*addsi3_carry_zext"
4998   [(set (match_operand:DI 0 "register_operand" "=r")
4999           (zero_extend:DI 
5000             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5001                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5002                      (match_operand:SI 2 "general_operand" "rim"))))
5003    (clobber (reg:CC FLAGS_REG))]
5004   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5005   "adc{l}\t{%2, %k0|%k0, %2}"
5006   [(set_attr "type" "alu")
5007    (set_attr "pent_pair" "pu")
5008    (set_attr "mode" "SI")])
5009
5010 (define_insn "*addsi3_cc"
5011   [(set (reg:CC FLAGS_REG)
5012         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5013                     (match_operand:SI 2 "general_operand" "ri,rm")]
5014                    UNSPEC_ADD_CARRY))
5015    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5016         (plus:SI (match_dup 1) (match_dup 2)))]
5017   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018   "add{l}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn "addqi3_cc"
5023   [(set (reg:CC FLAGS_REG)
5024         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5025                     (match_operand:QI 2 "general_operand" "qi,qm")]
5026                    UNSPEC_ADD_CARRY))
5027    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5028         (plus:QI (match_dup 1) (match_dup 2)))]
5029   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5030   "add{b}\t{%2, %0|%0, %2}"
5031   [(set_attr "type" "alu")
5032    (set_attr "mode" "QI")])
5033
5034 (define_expand "addsi3"
5035   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5036                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5037                             (match_operand:SI 2 "general_operand" "")))
5038               (clobber (reg:CC FLAGS_REG))])]
5039   ""
5040   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5041
5042 (define_insn "*lea_1"
5043   [(set (match_operand:SI 0 "register_operand" "=r")
5044         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5045   "!TARGET_64BIT"
5046   "lea{l}\t{%a1, %0|%0, %a1}"
5047   [(set_attr "type" "lea")
5048    (set_attr "mode" "SI")])
5049
5050 (define_insn "*lea_1_rex64"
5051   [(set (match_operand:SI 0 "register_operand" "=r")
5052         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5053   "TARGET_64BIT"
5054   "lea{l}\t{%a1, %0|%0, %a1}"
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5057
5058 (define_insn "*lea_1_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060         (zero_extend:DI
5061          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5062   "TARGET_64BIT"
5063   "lea{l}\t{%a1, %k0|%k0, %a1}"
5064   [(set_attr "type" "lea")
5065    (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_2_rex64"
5068   [(set (match_operand:DI 0 "register_operand" "=r")
5069         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5070   "TARGET_64BIT"
5071   "lea{q}\t{%a1, %0|%0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "DI")])
5074
5075 ;; The lea patterns for non-Pmodes needs to be matched by several
5076 ;; insns converted to real lea by splitters.
5077
5078 (define_insn_and_split "*lea_general_1"
5079   [(set (match_operand 0 "register_operand" "=r")
5080         (plus (plus (match_operand 1 "index_register_operand" "l")
5081                     (match_operand 2 "register_operand" "r"))
5082               (match_operand 3 "immediate_operand" "i")))]
5083   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5084     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5085    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5086    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5087    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5088    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5089        || GET_MODE (operands[3]) == VOIDmode)"
5090   "#"
5091   "&& reload_completed"
5092   [(const_int 0)]
5093 {
5094   rtx pat;
5095   operands[0] = gen_lowpart (SImode, operands[0]);
5096   operands[1] = gen_lowpart (Pmode, operands[1]);
5097   operands[2] = gen_lowpart (Pmode, operands[2]);
5098   operands[3] = gen_lowpart (Pmode, operands[3]);
5099   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5100                       operands[3]);
5101   if (Pmode != SImode)
5102     pat = gen_rtx_SUBREG (SImode, pat, 0);
5103   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5104   DONE;
5105 }
5106   [(set_attr "type" "lea")
5107    (set_attr "mode" "SI")])
5108
5109 (define_insn_and_split "*lea_general_1_zext"
5110   [(set (match_operand:DI 0 "register_operand" "=r")
5111         (zero_extend:DI
5112           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5113                             (match_operand:SI 2 "register_operand" "r"))
5114                    (match_operand:SI 3 "immediate_operand" "i"))))]
5115   "TARGET_64BIT"
5116   "#"
5117   "&& reload_completed"
5118   [(set (match_dup 0)
5119         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5120                                                      (match_dup 2))
5121                                             (match_dup 3)) 0)))]
5122 {
5123   operands[1] = gen_lowpart (Pmode, operands[1]);
5124   operands[2] = gen_lowpart (Pmode, operands[2]);
5125   operands[3] = gen_lowpart (Pmode, operands[3]);
5126 }
5127   [(set_attr "type" "lea")
5128    (set_attr "mode" "SI")])
5129
5130 (define_insn_and_split "*lea_general_2"
5131   [(set (match_operand 0 "register_operand" "=r")
5132         (plus (mult (match_operand 1 "index_register_operand" "l")
5133                     (match_operand 2 "const248_operand" "i"))
5134               (match_operand 3 "nonmemory_operand" "ri")))]
5135   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5136     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5137    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5138    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5139    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5140        || GET_MODE (operands[3]) == VOIDmode)"
5141   "#"
5142   "&& reload_completed"
5143   [(const_int 0)]
5144 {
5145   rtx pat;
5146   operands[0] = gen_lowpart (SImode, operands[0]);
5147   operands[1] = gen_lowpart (Pmode, operands[1]);
5148   operands[3] = gen_lowpart (Pmode, operands[3]);
5149   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5150                       operands[3]);
5151   if (Pmode != SImode)
5152     pat = gen_rtx_SUBREG (SImode, pat, 0);
5153   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5154   DONE;
5155 }
5156   [(set_attr "type" "lea")
5157    (set_attr "mode" "SI")])
5158
5159 (define_insn_and_split "*lea_general_2_zext"
5160   [(set (match_operand:DI 0 "register_operand" "=r")
5161         (zero_extend:DI
5162           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5163                             (match_operand:SI 2 "const248_operand" "n"))
5164                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5165   "TARGET_64BIT"
5166   "#"
5167   "&& reload_completed"
5168   [(set (match_dup 0)
5169         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5170                                                      (match_dup 2))
5171                                             (match_dup 3)) 0)))]
5172 {
5173   operands[1] = gen_lowpart (Pmode, operands[1]);
5174   operands[3] = gen_lowpart (Pmode, operands[3]);
5175 }
5176   [(set_attr "type" "lea")
5177    (set_attr "mode" "SI")])
5178
5179 (define_insn_and_split "*lea_general_3"
5180   [(set (match_operand 0 "register_operand" "=r")
5181         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5182                           (match_operand 2 "const248_operand" "i"))
5183                     (match_operand 3 "register_operand" "r"))
5184               (match_operand 4 "immediate_operand" "i")))]
5185   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5186     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5188    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5189    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5190   "#"
5191   "&& reload_completed"
5192   [(const_int 0)]
5193 {
5194   rtx pat;
5195   operands[0] = gen_lowpart (SImode, operands[0]);
5196   operands[1] = gen_lowpart (Pmode, operands[1]);
5197   operands[3] = gen_lowpart (Pmode, operands[3]);
5198   operands[4] = gen_lowpart (Pmode, operands[4]);
5199   pat = gen_rtx_PLUS (Pmode,
5200                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5201                                                          operands[2]),
5202                                     operands[3]),
5203                       operands[4]);
5204   if (Pmode != SImode)
5205     pat = gen_rtx_SUBREG (SImode, pat, 0);
5206   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5207   DONE;
5208 }
5209   [(set_attr "type" "lea")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn_and_split "*lea_general_3_zext"
5213   [(set (match_operand:DI 0 "register_operand" "=r")
5214         (zero_extend:DI
5215           (plus:SI (plus:SI (mult:SI
5216                               (match_operand:SI 1 "index_register_operand" "l")
5217                               (match_operand:SI 2 "const248_operand" "n"))
5218                             (match_operand:SI 3 "register_operand" "r"))
5219                    (match_operand:SI 4 "immediate_operand" "i"))))]
5220   "TARGET_64BIT"
5221   "#"
5222   "&& reload_completed"
5223   [(set (match_dup 0)
5224         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5225                                                               (match_dup 2))
5226                                                      (match_dup 3))
5227                                             (match_dup 4)) 0)))]
5228 {
5229   operands[1] = gen_lowpart (Pmode, operands[1]);
5230   operands[3] = gen_lowpart (Pmode, operands[3]);
5231   operands[4] = gen_lowpart (Pmode, operands[4]);
5232 }
5233   [(set_attr "type" "lea")
5234    (set_attr "mode" "SI")])
5235
5236 (define_insn "*adddi_1_rex64"
5237   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5238         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5239                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5240    (clobber (reg:CC FLAGS_REG))]
5241   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5242 {
5243   switch (get_attr_type (insn))
5244     {
5245     case TYPE_LEA:
5246       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5247       return "lea{q}\t{%a2, %0|%0, %a2}";
5248
5249     case TYPE_INCDEC:
5250       if (! rtx_equal_p (operands[0], operands[1]))
5251         abort ();
5252       if (operands[2] == const1_rtx)
5253         return "inc{q}\t%0";
5254       else if (operands[2] == constm1_rtx)
5255         return "dec{q}\t%0";
5256       else
5257         abort ();
5258
5259     default:
5260       if (! rtx_equal_p (operands[0], operands[1]))
5261         abort ();
5262
5263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5265       if (GET_CODE (operands[2]) == CONST_INT
5266           /* Avoid overflows.  */
5267           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5268           && (INTVAL (operands[2]) == 128
5269               || (INTVAL (operands[2]) < 0
5270                   && INTVAL (operands[2]) != -128)))
5271         {
5272           operands[2] = GEN_INT (-INTVAL (operands[2]));
5273           return "sub{q}\t{%2, %0|%0, %2}";
5274         }
5275       return "add{q}\t{%2, %0|%0, %2}";
5276     }
5277 }
5278   [(set (attr "type")
5279      (cond [(eq_attr "alternative" "2")
5280               (const_string "lea")
5281             ; Current assemblers are broken and do not allow @GOTOFF in
5282             ; ought but a memory context.
5283             (match_operand:DI 2 "pic_symbolic_operand" "")
5284               (const_string "lea")
5285             (match_operand:DI 2 "incdec_operand" "")
5286               (const_string "incdec")
5287            ]
5288            (const_string "alu")))
5289    (set_attr "mode" "DI")])
5290
5291 ;; Convert lea to the lea pattern to avoid flags dependency.
5292 (define_split
5293   [(set (match_operand:DI 0 "register_operand" "")
5294         (plus:DI (match_operand:DI 1 "register_operand" "")
5295                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5296    (clobber (reg:CC FLAGS_REG))]
5297   "TARGET_64BIT && reload_completed
5298    && true_regnum (operands[0]) != true_regnum (operands[1])"
5299   [(set (match_dup 0)
5300         (plus:DI (match_dup 1)
5301                  (match_dup 2)))]
5302   "")
5303
5304 (define_insn "*adddi_2_rex64"
5305   [(set (reg FLAGS_REG)
5306         (compare
5307           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5308                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5309           (const_int 0)))                       
5310    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5311         (plus:DI (match_dup 1) (match_dup 2)))]
5312   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5313    && ix86_binary_operator_ok (PLUS, DImode, operands)
5314    /* Current assemblers are broken and do not allow @GOTOFF in
5315       ought but a memory context.  */
5316    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5317 {
5318   switch (get_attr_type (insn))
5319     {
5320     case TYPE_INCDEC:
5321       if (! rtx_equal_p (operands[0], operands[1]))
5322         abort ();
5323       if (operands[2] == const1_rtx)
5324         return "inc{q}\t%0";
5325       else if (operands[2] == constm1_rtx)
5326         return "dec{q}\t%0";
5327       else
5328         abort ();
5329
5330     default:
5331       if (! rtx_equal_p (operands[0], operands[1]))
5332         abort ();
5333       /* ???? We ought to handle there the 32bit case too
5334          - do we need new constraint?  */
5335       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5336          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5337       if (GET_CODE (operands[2]) == CONST_INT
5338           /* Avoid overflows.  */
5339           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5340           && (INTVAL (operands[2]) == 128
5341               || (INTVAL (operands[2]) < 0
5342                   && INTVAL (operands[2]) != -128)))
5343         {
5344           operands[2] = GEN_INT (-INTVAL (operands[2]));
5345           return "sub{q}\t{%2, %0|%0, %2}";
5346         }
5347       return "add{q}\t{%2, %0|%0, %2}";
5348     }
5349 }
5350   [(set (attr "type")
5351      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5352         (const_string "incdec")
5353         (const_string "alu")))
5354    (set_attr "mode" "DI")])
5355
5356 (define_insn "*adddi_3_rex64"
5357   [(set (reg FLAGS_REG)
5358         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5359                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5360    (clobber (match_scratch:DI 0 "=r"))]
5361   "TARGET_64BIT
5362    && ix86_match_ccmode (insn, CCZmode)
5363    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5364    /* Current assemblers are broken and do not allow @GOTOFF in
5365       ought but a memory context.  */
5366    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5367 {
5368   switch (get_attr_type (insn))
5369     {
5370     case TYPE_INCDEC:
5371       if (! rtx_equal_p (operands[0], operands[1]))
5372         abort ();
5373       if (operands[2] == const1_rtx)
5374         return "inc{q}\t%0";
5375       else if (operands[2] == constm1_rtx)
5376         return "dec{q}\t%0";
5377       else
5378         abort ();
5379
5380     default:
5381       if (! rtx_equal_p (operands[0], operands[1]))
5382         abort ();
5383       /* ???? We ought to handle there the 32bit case too
5384          - do we need new constraint?  */
5385       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5386          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5387       if (GET_CODE (operands[2]) == CONST_INT
5388           /* Avoid overflows.  */
5389           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5390           && (INTVAL (operands[2]) == 128
5391               || (INTVAL (operands[2]) < 0
5392                   && INTVAL (operands[2]) != -128)))
5393         {
5394           operands[2] = GEN_INT (-INTVAL (operands[2]));
5395           return "sub{q}\t{%2, %0|%0, %2}";
5396         }
5397       return "add{q}\t{%2, %0|%0, %2}";
5398     }
5399 }
5400   [(set (attr "type")
5401      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5402         (const_string "incdec")
5403         (const_string "alu")))
5404    (set_attr "mode" "DI")])
5405
5406 ; For comparisons against 1, -1 and 128, we may generate better code
5407 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5408 ; is matched then.  We can't accept general immediate, because for
5409 ; case of overflows,  the result is messed up.
5410 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5411 ; when negated.
5412 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5413 ; only for comparisons not depending on it.
5414 (define_insn "*adddi_4_rex64"
5415   [(set (reg FLAGS_REG)
5416         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5417                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5418    (clobber (match_scratch:DI 0 "=rm"))]
5419   "TARGET_64BIT
5420    &&  ix86_match_ccmode (insn, CCGCmode)"
5421 {
5422   switch (get_attr_type (insn))
5423     {
5424     case TYPE_INCDEC:
5425       if (operands[2] == constm1_rtx)
5426         return "inc{q}\t%0";
5427       else if (operands[2] == const1_rtx)
5428         return "dec{q}\t%0";
5429       else
5430         abort();
5431
5432     default:
5433       if (! rtx_equal_p (operands[0], operands[1]))
5434         abort ();
5435       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5436          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5437       if ((INTVAL (operands[2]) == -128
5438            || (INTVAL (operands[2]) > 0
5439                && INTVAL (operands[2]) != 128))
5440           /* Avoid overflows.  */
5441           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5442         return "sub{q}\t{%2, %0|%0, %2}";
5443       operands[2] = GEN_INT (-INTVAL (operands[2]));
5444       return "add{q}\t{%2, %0|%0, %2}";
5445     }
5446 }
5447   [(set (attr "type")
5448      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5449         (const_string "incdec")
5450         (const_string "alu")))
5451    (set_attr "mode" "DI")])
5452
5453 (define_insn "*adddi_5_rex64"
5454   [(set (reg FLAGS_REG)
5455         (compare
5456           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5457                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5458           (const_int 0)))                       
5459    (clobber (match_scratch:DI 0 "=r"))]
5460   "TARGET_64BIT
5461    && ix86_match_ccmode (insn, CCGOCmode)
5462    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5463    /* Current assemblers are broken and do not allow @GOTOFF in
5464       ought but a memory context.  */
5465    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5466 {
5467   switch (get_attr_type (insn))
5468     {
5469     case TYPE_INCDEC:
5470       if (! rtx_equal_p (operands[0], operands[1]))
5471         abort ();
5472       if (operands[2] == const1_rtx)
5473         return "inc{q}\t%0";
5474       else if (operands[2] == constm1_rtx)
5475         return "dec{q}\t%0";
5476       else
5477         abort();
5478
5479     default:
5480       if (! rtx_equal_p (operands[0], operands[1]))
5481         abort ();
5482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5484       if (GET_CODE (operands[2]) == CONST_INT
5485           /* Avoid overflows.  */
5486           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5487           && (INTVAL (operands[2]) == 128
5488               || (INTVAL (operands[2]) < 0
5489                   && INTVAL (operands[2]) != -128)))
5490         {
5491           operands[2] = GEN_INT (-INTVAL (operands[2]));
5492           return "sub{q}\t{%2, %0|%0, %2}";
5493         }
5494       return "add{q}\t{%2, %0|%0, %2}";
5495     }
5496 }
5497   [(set (attr "type")
5498      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5499         (const_string "incdec")
5500         (const_string "alu")))
5501    (set_attr "mode" "DI")])
5502
5503
5504 (define_insn "*addsi_1"
5505   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5506         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5507                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5508    (clobber (reg:CC FLAGS_REG))]
5509   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_LEA:
5514       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5515       return "lea{l}\t{%a2, %0|%0, %a2}";
5516
5517     case TYPE_INCDEC:
5518       if (! rtx_equal_p (operands[0], operands[1]))
5519         abort ();
5520       if (operands[2] == const1_rtx)
5521         return "inc{l}\t%0";
5522       else if (operands[2] == constm1_rtx)
5523         return "dec{l}\t%0";
5524       else
5525         abort();
5526
5527     default:
5528       if (! rtx_equal_p (operands[0], operands[1]))
5529         abort ();
5530
5531       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5532          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5533       if (GET_CODE (operands[2]) == CONST_INT
5534           && (INTVAL (operands[2]) == 128
5535               || (INTVAL (operands[2]) < 0
5536                   && INTVAL (operands[2]) != -128)))
5537         {
5538           operands[2] = GEN_INT (-INTVAL (operands[2]));
5539           return "sub{l}\t{%2, %0|%0, %2}";
5540         }
5541       return "add{l}\t{%2, %0|%0, %2}";
5542     }
5543 }
5544   [(set (attr "type")
5545      (cond [(eq_attr "alternative" "2")
5546               (const_string "lea")
5547             ; Current assemblers are broken and do not allow @GOTOFF in
5548             ; ought but a memory context.
5549             (match_operand:SI 2 "pic_symbolic_operand" "")
5550               (const_string "lea")
5551             (match_operand:SI 2 "incdec_operand" "")
5552               (const_string "incdec")
5553            ]
5554            (const_string "alu")))
5555    (set_attr "mode" "SI")])
5556
5557 ;; Convert lea to the lea pattern to avoid flags dependency.
5558 (define_split
5559   [(set (match_operand 0 "register_operand" "")
5560         (plus (match_operand 1 "register_operand" "")
5561               (match_operand 2 "nonmemory_operand" "")))
5562    (clobber (reg:CC FLAGS_REG))]
5563   "reload_completed
5564    && true_regnum (operands[0]) != true_regnum (operands[1])"
5565   [(const_int 0)]
5566 {
5567   rtx pat;
5568   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5569      may confuse gen_lowpart.  */
5570   if (GET_MODE (operands[0]) != Pmode)
5571     {
5572       operands[1] = gen_lowpart (Pmode, operands[1]);
5573       operands[2] = gen_lowpart (Pmode, operands[2]);
5574     }
5575   operands[0] = gen_lowpart (SImode, operands[0]);
5576   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5577   if (Pmode != SImode)
5578     pat = gen_rtx_SUBREG (SImode, pat, 0);
5579   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5580   DONE;
5581 })
5582
5583 ;; It may seem that nonimmediate operand is proper one for operand 1.
5584 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5585 ;; we take care in ix86_binary_operator_ok to not allow two memory
5586 ;; operands so proper swapping will be done in reload.  This allow
5587 ;; patterns constructed from addsi_1 to match.
5588 (define_insn "addsi_1_zext"
5589   [(set (match_operand:DI 0 "register_operand" "=r,r")
5590         (zero_extend:DI
5591           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5592                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5593    (clobber (reg:CC FLAGS_REG))]
5594   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5595 {
5596   switch (get_attr_type (insn))
5597     {
5598     case TYPE_LEA:
5599       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5600       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5601
5602     case TYPE_INCDEC:
5603       if (operands[2] == const1_rtx)
5604         return "inc{l}\t%k0";
5605       else if (operands[2] == constm1_rtx)
5606         return "dec{l}\t%k0";
5607       else
5608         abort();
5609
5610     default:
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %k0|%k0, %2}";
5620         }
5621       return "add{l}\t{%2, %k0|%k0, %2}";
5622     }
5623 }
5624   [(set (attr "type")
5625      (cond [(eq_attr "alternative" "1")
5626               (const_string "lea")
5627             ; Current assemblers are broken and do not allow @GOTOFF in
5628             ; ought but a memory context.
5629             (match_operand:SI 2 "pic_symbolic_operand" "")
5630               (const_string "lea")
5631             (match_operand:SI 2 "incdec_operand" "")
5632               (const_string "incdec")
5633            ]
5634            (const_string "alu")))
5635    (set_attr "mode" "SI")])
5636
5637 ;; Convert lea to the lea pattern to avoid flags dependency.
5638 (define_split
5639   [(set (match_operand:DI 0 "register_operand" "")
5640         (zero_extend:DI
5641           (plus:SI (match_operand:SI 1 "register_operand" "")
5642                    (match_operand:SI 2 "nonmemory_operand" ""))))
5643    (clobber (reg:CC FLAGS_REG))]
5644   "TARGET_64BIT && reload_completed
5645    && true_regnum (operands[0]) != true_regnum (operands[1])"
5646   [(set (match_dup 0)
5647         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5648 {
5649   operands[1] = gen_lowpart (Pmode, operands[1]);
5650   operands[2] = gen_lowpart (Pmode, operands[2]);
5651 })
5652
5653 (define_insn "*addsi_2"
5654   [(set (reg FLAGS_REG)
5655         (compare
5656           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5657                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5658           (const_int 0)))                       
5659    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5660         (plus:SI (match_dup 1) (match_dup 2)))]
5661   "ix86_match_ccmode (insn, CCGOCmode)
5662    && ix86_binary_operator_ok (PLUS, SImode, operands)
5663    /* Current assemblers are broken and do not allow @GOTOFF in
5664       ought but a memory context.  */
5665    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5666 {
5667   switch (get_attr_type (insn))
5668     {
5669     case TYPE_INCDEC:
5670       if (! rtx_equal_p (operands[0], operands[1]))
5671         abort ();
5672       if (operands[2] == const1_rtx)
5673         return "inc{l}\t%0";
5674       else if (operands[2] == constm1_rtx)
5675         return "dec{l}\t%0";
5676       else
5677         abort();
5678
5679     default:
5680       if (! rtx_equal_p (operands[0], operands[1]))
5681         abort ();
5682       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5683          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5684       if (GET_CODE (operands[2]) == CONST_INT
5685           && (INTVAL (operands[2]) == 128
5686               || (INTVAL (operands[2]) < 0
5687                   && INTVAL (operands[2]) != -128)))
5688         {
5689           operands[2] = GEN_INT (-INTVAL (operands[2]));
5690           return "sub{l}\t{%2, %0|%0, %2}";
5691         }
5692       return "add{l}\t{%2, %0|%0, %2}";
5693     }
5694 }
5695   [(set (attr "type")
5696      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5697         (const_string "incdec")
5698         (const_string "alu")))
5699    (set_attr "mode" "SI")])
5700
5701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5702 (define_insn "*addsi_2_zext"
5703   [(set (reg FLAGS_REG)
5704         (compare
5705           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5706                    (match_operand:SI 2 "general_operand" "rmni"))
5707           (const_int 0)))                       
5708    (set (match_operand:DI 0 "register_operand" "=r")
5709         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5711    && ix86_binary_operator_ok (PLUS, SImode, operands)
5712    /* Current assemblers are broken and do not allow @GOTOFF in
5713       ought but a memory context.  */
5714    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715 {
5716   switch (get_attr_type (insn))
5717     {
5718     case TYPE_INCDEC:
5719       if (operands[2] == const1_rtx)
5720         return "inc{l}\t%k0";
5721       else if (operands[2] == constm1_rtx)
5722         return "dec{l}\t%k0";
5723       else
5724         abort();
5725
5726     default:
5727       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5728          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5729       if (GET_CODE (operands[2]) == CONST_INT
5730           && (INTVAL (operands[2]) == 128
5731               || (INTVAL (operands[2]) < 0
5732                   && INTVAL (operands[2]) != -128)))
5733         {
5734           operands[2] = GEN_INT (-INTVAL (operands[2]));
5735           return "sub{l}\t{%2, %k0|%k0, %2}";
5736         }
5737       return "add{l}\t{%2, %k0|%k0, %2}";
5738     }
5739 }
5740   [(set (attr "type")
5741      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5742         (const_string "incdec")
5743         (const_string "alu")))
5744    (set_attr "mode" "SI")])
5745
5746 (define_insn "*addsi_3"
5747   [(set (reg FLAGS_REG)
5748         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5749                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5750    (clobber (match_scratch:SI 0 "=r"))]
5751   "ix86_match_ccmode (insn, CCZmode)
5752    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5753    /* Current assemblers are broken and do not allow @GOTOFF in
5754       ought but a memory context.  */
5755    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5756 {
5757   switch (get_attr_type (insn))
5758     {
5759     case TYPE_INCDEC:
5760       if (! rtx_equal_p (operands[0], operands[1]))
5761         abort ();
5762       if (operands[2] == const1_rtx)
5763         return "inc{l}\t%0";
5764       else if (operands[2] == constm1_rtx)
5765         return "dec{l}\t%0";
5766       else
5767         abort();
5768
5769     default:
5770       if (! rtx_equal_p (operands[0], operands[1]))
5771         abort ();
5772       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5773          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5774       if (GET_CODE (operands[2]) == CONST_INT
5775           && (INTVAL (operands[2]) == 128
5776               || (INTVAL (operands[2]) < 0
5777                   && INTVAL (operands[2]) != -128)))
5778         {
5779           operands[2] = GEN_INT (-INTVAL (operands[2]));
5780           return "sub{l}\t{%2, %0|%0, %2}";
5781         }
5782       return "add{l}\t{%2, %0|%0, %2}";
5783     }
5784 }
5785   [(set (attr "type")
5786      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5787         (const_string "incdec")
5788         (const_string "alu")))
5789    (set_attr "mode" "SI")])
5790
5791 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5792 (define_insn "*addsi_3_zext"
5793   [(set (reg FLAGS_REG)
5794         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5795                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5796    (set (match_operand:DI 0 "register_operand" "=r")
5797         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5798   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5799    && ix86_binary_operator_ok (PLUS, SImode, operands)
5800    /* Current assemblers are broken and do not allow @GOTOFF in
5801       ought but a memory context.  */
5802    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5803 {
5804   switch (get_attr_type (insn))
5805     {
5806     case TYPE_INCDEC:
5807       if (operands[2] == const1_rtx)
5808         return "inc{l}\t%k0";
5809       else if (operands[2] == constm1_rtx)
5810         return "dec{l}\t%k0";
5811       else
5812         abort();
5813
5814     default:
5815       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5816          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5817       if (GET_CODE (operands[2]) == CONST_INT
5818           && (INTVAL (operands[2]) == 128
5819               || (INTVAL (operands[2]) < 0
5820                   && INTVAL (operands[2]) != -128)))
5821         {
5822           operands[2] = GEN_INT (-INTVAL (operands[2]));
5823           return "sub{l}\t{%2, %k0|%k0, %2}";
5824         }
5825       return "add{l}\t{%2, %k0|%k0, %2}";
5826     }
5827 }
5828   [(set (attr "type")
5829      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5830         (const_string "incdec")
5831         (const_string "alu")))
5832    (set_attr "mode" "SI")])
5833
5834 ; For comparisons against 1, -1 and 128, we may generate better code
5835 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5836 ; is matched then.  We can't accept general immediate, because for
5837 ; case of overflows,  the result is messed up.
5838 ; This pattern also don't hold of 0x80000000, since the value overflows
5839 ; when negated.
5840 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5841 ; only for comparisons not depending on it.
5842 (define_insn "*addsi_4"
5843   [(set (reg FLAGS_REG)
5844         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5845                  (match_operand:SI 2 "const_int_operand" "n")))
5846    (clobber (match_scratch:SI 0 "=rm"))]
5847   "ix86_match_ccmode (insn, CCGCmode)
5848    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5849 {
5850   switch (get_attr_type (insn))
5851     {
5852     case TYPE_INCDEC:
5853       if (operands[2] == constm1_rtx)
5854         return "inc{l}\t%0";
5855       else if (operands[2] == const1_rtx)
5856         return "dec{l}\t%0";
5857       else
5858         abort();
5859
5860     default:
5861       if (! rtx_equal_p (operands[0], operands[1]))
5862         abort ();
5863       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5864          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5865       if ((INTVAL (operands[2]) == -128
5866            || (INTVAL (operands[2]) > 0
5867                && INTVAL (operands[2]) != 128)))
5868         return "sub{l}\t{%2, %0|%0, %2}";
5869       operands[2] = GEN_INT (-INTVAL (operands[2]));
5870       return "add{l}\t{%2, %0|%0, %2}";
5871     }
5872 }
5873   [(set (attr "type")
5874      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875         (const_string "incdec")
5876         (const_string "alu")))
5877    (set_attr "mode" "SI")])
5878
5879 (define_insn "*addsi_5"
5880   [(set (reg FLAGS_REG)
5881         (compare
5882           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5883                    (match_operand:SI 2 "general_operand" "rmni"))
5884           (const_int 0)))                       
5885    (clobber (match_scratch:SI 0 "=r"))]
5886   "ix86_match_ccmode (insn, CCGOCmode)
5887    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5888    /* Current assemblers are broken and do not allow @GOTOFF in
5889       ought but a memory context.  */
5890    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5891 {
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (! rtx_equal_p (operands[0], operands[1]))
5896         abort ();
5897       if (operands[2] == const1_rtx)
5898         return "inc{l}\t%0";
5899       else if (operands[2] == constm1_rtx)
5900         return "dec{l}\t%0";
5901       else
5902         abort();
5903
5904     default:
5905       if (! rtx_equal_p (operands[0], operands[1]))
5906         abort ();
5907       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5908          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5909       if (GET_CODE (operands[2]) == CONST_INT
5910           && (INTVAL (operands[2]) == 128
5911               || (INTVAL (operands[2]) < 0
5912                   && INTVAL (operands[2]) != -128)))
5913         {
5914           operands[2] = GEN_INT (-INTVAL (operands[2]));
5915           return "sub{l}\t{%2, %0|%0, %2}";
5916         }
5917       return "add{l}\t{%2, %0|%0, %2}";
5918     }
5919 }
5920   [(set (attr "type")
5921      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5922         (const_string "incdec")
5923         (const_string "alu")))
5924    (set_attr "mode" "SI")])
5925
5926 (define_expand "addhi3"
5927   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5928                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5929                             (match_operand:HI 2 "general_operand" "")))
5930               (clobber (reg:CC FLAGS_REG))])]
5931   "TARGET_HIMODE_MATH"
5932   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5933
5934 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5935 ;; type optimizations enabled by define-splits.  This is not important
5936 ;; for PII, and in fact harmful because of partial register stalls.
5937
5938 (define_insn "*addhi_1_lea"
5939   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5940         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5941                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5942    (clobber (reg:CC FLAGS_REG))]
5943   "!TARGET_PARTIAL_REG_STALL
5944    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5945 {
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_LEA:
5949       return "#";
5950     case TYPE_INCDEC:
5951       if (operands[2] == const1_rtx)
5952         return "inc{w}\t%0";
5953       else if (operands[2] == constm1_rtx)
5954         return "dec{w}\t%0";
5955       abort();
5956
5957     default:
5958       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5959          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5960       if (GET_CODE (operands[2]) == CONST_INT
5961           && (INTVAL (operands[2]) == 128
5962               || (INTVAL (operands[2]) < 0
5963                   && INTVAL (operands[2]) != -128)))
5964         {
5965           operands[2] = GEN_INT (-INTVAL (operands[2]));
5966           return "sub{w}\t{%2, %0|%0, %2}";
5967         }
5968       return "add{w}\t{%2, %0|%0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (eq_attr "alternative" "2")
5973         (const_string "lea")
5974         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975            (const_string "incdec")
5976            (const_string "alu"))))
5977    (set_attr "mode" "HI,HI,SI")])
5978
5979 (define_insn "*addhi_1"
5980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5981         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5982                  (match_operand:HI 2 "general_operand" "ri,rm")))
5983    (clobber (reg:CC FLAGS_REG))]
5984   "TARGET_PARTIAL_REG_STALL
5985    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5986 {
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_INCDEC:
5990       if (operands[2] == const1_rtx)
5991         return "inc{w}\t%0";
5992       else if (operands[2] == constm1_rtx)
5993         return "dec{w}\t%0";
5994       abort();
5995
5996     default:
5997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5999       if (GET_CODE (operands[2]) == CONST_INT
6000           && (INTVAL (operands[2]) == 128
6001               || (INTVAL (operands[2]) < 0
6002                   && INTVAL (operands[2]) != -128)))
6003         {
6004           operands[2] = GEN_INT (-INTVAL (operands[2]));
6005           return "sub{w}\t{%2, %0|%0, %2}";
6006         }
6007       return "add{w}\t{%2, %0|%0, %2}";
6008     }
6009 }
6010   [(set (attr "type")
6011      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6012         (const_string "incdec")
6013         (const_string "alu")))
6014    (set_attr "mode" "HI")])
6015
6016 (define_insn "*addhi_2"
6017   [(set (reg FLAGS_REG)
6018         (compare
6019           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6020                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6021           (const_int 0)))                       
6022    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6023         (plus:HI (match_dup 1) (match_dup 2)))]
6024   "ix86_match_ccmode (insn, CCGOCmode)
6025    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6026 {
6027   switch (get_attr_type (insn))
6028     {
6029     case TYPE_INCDEC:
6030       if (operands[2] == const1_rtx)
6031         return "inc{w}\t%0";
6032       else if (operands[2] == constm1_rtx)
6033         return "dec{w}\t%0";
6034       abort();
6035
6036     default:
6037       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6038          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6039       if (GET_CODE (operands[2]) == CONST_INT
6040           && (INTVAL (operands[2]) == 128
6041               || (INTVAL (operands[2]) < 0
6042                   && INTVAL (operands[2]) != -128)))
6043         {
6044           operands[2] = GEN_INT (-INTVAL (operands[2]));
6045           return "sub{w}\t{%2, %0|%0, %2}";
6046         }
6047       return "add{w}\t{%2, %0|%0, %2}";
6048     }
6049 }
6050   [(set (attr "type")
6051      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6052         (const_string "incdec")
6053         (const_string "alu")))
6054    (set_attr "mode" "HI")])
6055
6056 (define_insn "*addhi_3"
6057   [(set (reg FLAGS_REG)
6058         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6059                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6060    (clobber (match_scratch:HI 0 "=r"))]
6061   "ix86_match_ccmode (insn, CCZmode)
6062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == const1_rtx)
6068         return "inc{w}\t%0";
6069       else if (operands[2] == constm1_rtx)
6070         return "dec{w}\t%0";
6071       abort();
6072
6073     default:
6074       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076       if (GET_CODE (operands[2]) == CONST_INT
6077           && (INTVAL (operands[2]) == 128
6078               || (INTVAL (operands[2]) < 0
6079                   && INTVAL (operands[2]) != -128)))
6080         {
6081           operands[2] = GEN_INT (-INTVAL (operands[2]));
6082           return "sub{w}\t{%2, %0|%0, %2}";
6083         }
6084       return "add{w}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set_attr "mode" "HI")])
6092
6093 ; See comments above addsi_3_imm for details.
6094 (define_insn "*addhi_4"
6095   [(set (reg FLAGS_REG)
6096         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6097                  (match_operand:HI 2 "const_int_operand" "n")))
6098    (clobber (match_scratch:HI 0 "=rm"))]
6099   "ix86_match_ccmode (insn, CCGCmode)
6100    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6101 {
6102   switch (get_attr_type (insn))
6103     {
6104     case TYPE_INCDEC:
6105       if (operands[2] == constm1_rtx)
6106         return "inc{w}\t%0";
6107       else if (operands[2] == const1_rtx)
6108         return "dec{w}\t%0";
6109       else
6110         abort();
6111
6112     default:
6113       if (! rtx_equal_p (operands[0], operands[1]))
6114         abort ();
6115       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6116          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6117       if ((INTVAL (operands[2]) == -128
6118            || (INTVAL (operands[2]) > 0
6119                && INTVAL (operands[2]) != 128)))
6120         return "sub{w}\t{%2, %0|%0, %2}";
6121       operands[2] = GEN_INT (-INTVAL (operands[2]));
6122       return "add{w}\t{%2, %0|%0, %2}";
6123     }
6124 }
6125   [(set (attr "type")
6126      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6127         (const_string "incdec")
6128         (const_string "alu")))
6129    (set_attr "mode" "SI")])
6130
6131
6132 (define_insn "*addhi_5"
6133   [(set (reg FLAGS_REG)
6134         (compare
6135           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6136                    (match_operand:HI 2 "general_operand" "rmni"))
6137           (const_int 0)))                       
6138    (clobber (match_scratch:HI 0 "=r"))]
6139   "ix86_match_ccmode (insn, CCGOCmode)
6140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6141 {
6142   switch (get_attr_type (insn))
6143     {
6144     case TYPE_INCDEC:
6145       if (operands[2] == const1_rtx)
6146         return "inc{w}\t%0";
6147       else if (operands[2] == constm1_rtx)
6148         return "dec{w}\t%0";
6149       abort();
6150
6151     default:
6152       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6154       if (GET_CODE (operands[2]) == CONST_INT
6155           && (INTVAL (operands[2]) == 128
6156               || (INTVAL (operands[2]) < 0
6157                   && INTVAL (operands[2]) != -128)))
6158         {
6159           operands[2] = GEN_INT (-INTVAL (operands[2]));
6160           return "sub{w}\t{%2, %0|%0, %2}";
6161         }
6162       return "add{w}\t{%2, %0|%0, %2}";
6163     }
6164 }
6165   [(set (attr "type")
6166      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6167         (const_string "incdec")
6168         (const_string "alu")))
6169    (set_attr "mode" "HI")])
6170
6171 (define_expand "addqi3"
6172   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6173                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6174                             (match_operand:QI 2 "general_operand" "")))
6175               (clobber (reg:CC FLAGS_REG))])]
6176   "TARGET_QIMODE_MATH"
6177   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6178
6179 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6180 (define_insn "*addqi_1_lea"
6181   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6182         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6183                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6184    (clobber (reg:CC FLAGS_REG))]
6185   "!TARGET_PARTIAL_REG_STALL
6186    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6187 {
6188   int widen = (which_alternative == 2);
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_LEA:
6192       return "#";
6193     case TYPE_INCDEC:
6194       if (operands[2] == const1_rtx)
6195         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6196       else if (operands[2] == constm1_rtx)
6197         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6198       abort();
6199
6200     default:
6201       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6203       if (GET_CODE (operands[2]) == CONST_INT
6204           && (INTVAL (operands[2]) == 128
6205               || (INTVAL (operands[2]) < 0
6206                   && INTVAL (operands[2]) != -128)))
6207         {
6208           operands[2] = GEN_INT (-INTVAL (operands[2]));
6209           if (widen)
6210             return "sub{l}\t{%2, %k0|%k0, %2}";
6211           else
6212             return "sub{b}\t{%2, %0|%0, %2}";
6213         }
6214       if (widen)
6215         return "add{l}\t{%k2, %k0|%k0, %k2}";
6216       else
6217         return "add{b}\t{%2, %0|%0, %2}";
6218     }
6219 }
6220   [(set (attr "type")
6221      (if_then_else (eq_attr "alternative" "3")
6222         (const_string "lea")
6223         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6224            (const_string "incdec")
6225            (const_string "alu"))))
6226    (set_attr "mode" "QI,QI,SI,SI")])
6227
6228 (define_insn "*addqi_1"
6229   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6230         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6231                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6232    (clobber (reg:CC FLAGS_REG))]
6233   "TARGET_PARTIAL_REG_STALL
6234    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6235 {
6236   int widen = (which_alternative == 2);
6237   switch (get_attr_type (insn))
6238     {
6239     case TYPE_INCDEC:
6240       if (operands[2] == const1_rtx)
6241         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6242       else if (operands[2] == constm1_rtx)
6243         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6244       abort();
6245
6246     default:
6247       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6248          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6249       if (GET_CODE (operands[2]) == CONST_INT
6250           && (INTVAL (operands[2]) == 128
6251               || (INTVAL (operands[2]) < 0
6252                   && INTVAL (operands[2]) != -128)))
6253         {
6254           operands[2] = GEN_INT (-INTVAL (operands[2]));
6255           if (widen)
6256             return "sub{l}\t{%2, %k0|%k0, %2}";
6257           else
6258             return "sub{b}\t{%2, %0|%0, %2}";
6259         }
6260       if (widen)
6261         return "add{l}\t{%k2, %k0|%k0, %k2}";
6262       else
6263         return "add{b}\t{%2, %0|%0, %2}";
6264     }
6265 }
6266   [(set (attr "type")
6267      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6268         (const_string "incdec")
6269         (const_string "alu")))
6270    (set_attr "mode" "QI,QI,SI")])
6271
6272 (define_insn "*addqi_1_slp"
6273   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6274         (plus:QI (match_dup 0)
6275                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6276    (clobber (reg:CC FLAGS_REG))]
6277   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6278    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6279 {
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[1] == const1_rtx)
6284         return "inc{b}\t%0";
6285       else if (operands[1] == constm1_rtx)
6286         return "dec{b}\t%0";
6287       abort();
6288
6289     default:
6290       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6291       if (GET_CODE (operands[1]) == CONST_INT
6292           && INTVAL (operands[1]) < 0)
6293         {
6294           operands[1] = GEN_INT (-INTVAL (operands[1]));
6295           return "sub{b}\t{%1, %0|%0, %1}";
6296         }
6297       return "add{b}\t{%1, %0|%0, %1}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu1")))
6304    (set_attr "mode" "QI")])
6305
6306 (define_insn "*addqi_2"
6307   [(set (reg FLAGS_REG)
6308         (compare
6309           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6310                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6311           (const_int 0)))
6312    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6313         (plus:QI (match_dup 1) (match_dup 2)))]
6314   "ix86_match_ccmode (insn, CCGOCmode)
6315    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6316 {
6317   switch (get_attr_type (insn))
6318     {
6319     case TYPE_INCDEC:
6320       if (operands[2] == const1_rtx)
6321         return "inc{b}\t%0";
6322       else if (operands[2] == constm1_rtx
6323                || (GET_CODE (operands[2]) == CONST_INT
6324                    && INTVAL (operands[2]) == 255))
6325         return "dec{b}\t%0";
6326       abort();
6327
6328     default:
6329       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6330       if (GET_CODE (operands[2]) == CONST_INT
6331           && INTVAL (operands[2]) < 0)
6332         {
6333           operands[2] = GEN_INT (-INTVAL (operands[2]));
6334           return "sub{b}\t{%2, %0|%0, %2}";
6335         }
6336       return "add{b}\t{%2, %0|%0, %2}";
6337     }
6338 }
6339   [(set (attr "type")
6340      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341         (const_string "incdec")
6342         (const_string "alu")))
6343    (set_attr "mode" "QI")])
6344
6345 (define_insn "*addqi_3"
6346   [(set (reg FLAGS_REG)
6347         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6348                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6349    (clobber (match_scratch:QI 0 "=q"))]
6350   "ix86_match_ccmode (insn, CCZmode)
6351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6352 {
6353   switch (get_attr_type (insn))
6354     {
6355     case TYPE_INCDEC:
6356       if (operands[2] == const1_rtx)
6357         return "inc{b}\t%0";
6358       else if (operands[2] == constm1_rtx
6359                || (GET_CODE (operands[2]) == CONST_INT
6360                    && INTVAL (operands[2]) == 255))
6361         return "dec{b}\t%0";
6362       abort();
6363
6364     default:
6365       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6366       if (GET_CODE (operands[2]) == CONST_INT
6367           && INTVAL (operands[2]) < 0)
6368         {
6369           operands[2] = GEN_INT (-INTVAL (operands[2]));
6370           return "sub{b}\t{%2, %0|%0, %2}";
6371         }
6372       return "add{b}\t{%2, %0|%0, %2}";
6373     }
6374 }
6375   [(set (attr "type")
6376      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6377         (const_string "incdec")
6378         (const_string "alu")))
6379    (set_attr "mode" "QI")])
6380
6381 ; See comments above addsi_3_imm for details.
6382 (define_insn "*addqi_4"
6383   [(set (reg FLAGS_REG)
6384         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6385                  (match_operand:QI 2 "const_int_operand" "n")))
6386    (clobber (match_scratch:QI 0 "=qm"))]
6387   "ix86_match_ccmode (insn, CCGCmode)
6388    && (INTVAL (operands[2]) & 0xff) != 0x80"
6389 {
6390   switch (get_attr_type (insn))
6391     {
6392     case TYPE_INCDEC:
6393       if (operands[2] == constm1_rtx
6394           || (GET_CODE (operands[2]) == CONST_INT
6395               && INTVAL (operands[2]) == 255))
6396         return "inc{b}\t%0";
6397       else if (operands[2] == const1_rtx)
6398         return "dec{b}\t%0";
6399       else
6400         abort();
6401
6402     default:
6403       if (! rtx_equal_p (operands[0], operands[1]))
6404         abort ();
6405       if (INTVAL (operands[2]) < 0)
6406         {
6407           operands[2] = GEN_INT (-INTVAL (operands[2]));
6408           return "add{b}\t{%2, %0|%0, %2}";
6409         }
6410       return "sub{b}\t{%2, %0|%0, %2}";
6411     }
6412 }
6413   [(set (attr "type")
6414      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6415         (const_string "incdec")
6416         (const_string "alu")))
6417    (set_attr "mode" "QI")])
6418
6419
6420 (define_insn "*addqi_5"
6421   [(set (reg FLAGS_REG)
6422         (compare
6423           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6424                    (match_operand:QI 2 "general_operand" "qmni"))
6425           (const_int 0)))
6426    (clobber (match_scratch:QI 0 "=q"))]
6427   "ix86_match_ccmode (insn, CCGOCmode)
6428    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6429 {
6430   switch (get_attr_type (insn))
6431     {
6432     case TYPE_INCDEC:
6433       if (operands[2] == const1_rtx)
6434         return "inc{b}\t%0";
6435       else if (operands[2] == constm1_rtx
6436                || (GET_CODE (operands[2]) == CONST_INT
6437                    && INTVAL (operands[2]) == 255))
6438         return "dec{b}\t%0";
6439       abort();
6440
6441     default:
6442       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6443       if (GET_CODE (operands[2]) == CONST_INT
6444           && INTVAL (operands[2]) < 0)
6445         {
6446           operands[2] = GEN_INT (-INTVAL (operands[2]));
6447           return "sub{b}\t{%2, %0|%0, %2}";
6448         }
6449       return "add{b}\t{%2, %0|%0, %2}";
6450     }
6451 }
6452   [(set (attr "type")
6453      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6454         (const_string "incdec")
6455         (const_string "alu")))
6456    (set_attr "mode" "QI")])
6457
6458
6459 (define_insn "addqi_ext_1"
6460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6461                          (const_int 8)
6462                          (const_int 8))
6463         (plus:SI
6464           (zero_extract:SI
6465             (match_operand 1 "ext_register_operand" "0")
6466             (const_int 8)
6467             (const_int 8))
6468           (match_operand:QI 2 "general_operand" "Qmn")))
6469    (clobber (reg:CC FLAGS_REG))]
6470   "!TARGET_64BIT"
6471 {
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_INCDEC:
6475       if (operands[2] == const1_rtx)
6476         return "inc{b}\t%h0";
6477       else if (operands[2] == constm1_rtx
6478                || (GET_CODE (operands[2]) == CONST_INT
6479                    && INTVAL (operands[2]) == 255))
6480         return "dec{b}\t%h0";
6481       abort();
6482
6483     default:
6484       return "add{b}\t{%2, %h0|%h0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6492
6493 (define_insn "*addqi_ext_1_rex64"
6494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6495                          (const_int 8)
6496                          (const_int 8))
6497         (plus:SI
6498           (zero_extract:SI
6499             (match_operand 1 "ext_register_operand" "0")
6500             (const_int 8)
6501             (const_int 8))
6502           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6503    (clobber (reg:CC FLAGS_REG))]
6504   "TARGET_64BIT"
6505 {
6506   switch (get_attr_type (insn))
6507     {
6508     case TYPE_INCDEC:
6509       if (operands[2] == const1_rtx)
6510         return "inc{b}\t%h0";
6511       else if (operands[2] == constm1_rtx
6512                || (GET_CODE (operands[2]) == CONST_INT
6513                    && INTVAL (operands[2]) == 255))
6514         return "dec{b}\t%h0";
6515       abort();
6516
6517     default:
6518       return "add{b}\t{%2, %h0|%h0, %2}";
6519     }
6520 }
6521   [(set (attr "type")
6522      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6523         (const_string "incdec")
6524         (const_string "alu")))
6525    (set_attr "mode" "QI")])
6526
6527 (define_insn "*addqi_ext_2"
6528   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6529                          (const_int 8)
6530                          (const_int 8))
6531         (plus:SI
6532           (zero_extract:SI
6533             (match_operand 1 "ext_register_operand" "%0")
6534             (const_int 8)
6535             (const_int 8))
6536           (zero_extract:SI
6537             (match_operand 2 "ext_register_operand" "Q")
6538             (const_int 8)
6539             (const_int 8))))
6540    (clobber (reg:CC FLAGS_REG))]
6541   ""
6542   "add{b}\t{%h2, %h0|%h0, %h2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "QI")])
6545
6546 ;; The patterns that match these are at the end of this file.
6547
6548 (define_expand "addxf3"
6549   [(set (match_operand:XF 0 "register_operand" "")
6550         (plus:XF (match_operand:XF 1 "register_operand" "")
6551                  (match_operand:XF 2 "register_operand" "")))]
6552   "TARGET_80387"
6553   "")
6554
6555 (define_expand "adddf3"
6556   [(set (match_operand:DF 0 "register_operand" "")
6557         (plus:DF (match_operand:DF 1 "register_operand" "")
6558                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6559   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6560   "")
6561
6562 (define_expand "addsf3"
6563   [(set (match_operand:SF 0 "register_operand" "")
6564         (plus:SF (match_operand:SF 1 "register_operand" "")
6565                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6566   "TARGET_80387 || TARGET_SSE_MATH"
6567   "")
6568 \f
6569 ;; Subtract instructions
6570
6571 ;; %%% splits for subsidi3
6572
6573 (define_expand "subdi3"
6574   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6575                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6576                              (match_operand:DI 2 "x86_64_general_operand" "")))
6577               (clobber (reg:CC FLAGS_REG))])]
6578   ""
6579   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6580
6581 (define_insn "*subdi3_1"
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587   "#")
6588
6589 (define_split
6590   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592                   (match_operand:DI 2 "general_operand" "")))
6593    (clobber (reg:CC FLAGS_REG))]
6594   "!TARGET_64BIT && reload_completed"
6595   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6596               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6597    (parallel [(set (match_dup 3)
6598                    (minus:SI (match_dup 4)
6599                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6600                                       (match_dup 5))))
6601               (clobber (reg:CC FLAGS_REG))])]
6602   "split_di (operands+0, 1, operands+0, operands+3);
6603    split_di (operands+1, 1, operands+1, operands+4);
6604    split_di (operands+2, 1, operands+2, operands+5);")
6605
6606 (define_insn "subdi3_carry_rex64"
6607   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6608           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
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   "sbb{q}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "pent_pair" "pu")
6616    (set_attr "mode" "DI")])
6617
6618 (define_insn "*subdi_1_rex64"
6619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6620         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6624   "sub{q}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "DI")])
6627
6628 (define_insn "*subdi_2_rex64"
6629   [(set (reg FLAGS_REG)
6630         (compare
6631           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6632                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6633           (const_int 0)))
6634    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635         (minus:DI (match_dup 1) (match_dup 2)))]
6636   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6637    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6638   "sub{q}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_3_rex63"
6643   [(set (reg FLAGS_REG)
6644         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6645                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6646    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:DI (match_dup 1) (match_dup 2)))]
6648   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6649    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "subqi3_carry"
6655   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6656           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6657             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6658                (match_operand:QI 2 "general_operand" "qi,qm"))))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6661   "sbb{b}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "pent_pair" "pu")
6664    (set_attr "mode" "QI")])
6665
6666 (define_insn "subhi3_carry"
6667   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6668           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6669             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6670                (match_operand:HI 2 "general_operand" "ri,rm"))))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6673   "sbb{w}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "pent_pair" "pu")
6676    (set_attr "mode" "HI")])
6677
6678 (define_insn "subsi3_carry"
6679   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6680           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6681             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6682                (match_operand:SI 2 "general_operand" "ri,rm"))))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sbb{l}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "pent_pair" "pu")
6688    (set_attr "mode" "SI")])
6689
6690 (define_insn "subsi3_carry_zext"
6691   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6692           (zero_extend:DI
6693             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6694               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6695                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6696    (clobber (reg:CC FLAGS_REG))]
6697   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698   "sbb{l}\t{%2, %k0|%k0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "pent_pair" "pu")
6701    (set_attr "mode" "SI")])
6702
6703 (define_expand "subsi3"
6704   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6705                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6706                              (match_operand:SI 2 "general_operand" "")))
6707               (clobber (reg:CC FLAGS_REG))])]
6708   ""
6709   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6710
6711 (define_insn "*subsi_1"
6712   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714                   (match_operand:SI 2 "general_operand" "ri,rm")))
6715    (clobber (reg:CC FLAGS_REG))]
6716   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6717   "sub{l}\t{%2, %0|%0, %2}"
6718   [(set_attr "type" "alu")
6719    (set_attr "mode" "SI")])
6720
6721 (define_insn "*subsi_1_zext"
6722   [(set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_operand:SI 1 "register_operand" "0")
6725                     (match_operand:SI 2 "general_operand" "rim"))))
6726    (clobber (reg:CC FLAGS_REG))]
6727   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %k0|%k0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "SI")])
6731
6732 (define_insn "*subsi_2"
6733   [(set (reg FLAGS_REG)
6734         (compare
6735           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6736                     (match_operand:SI 2 "general_operand" "ri,rm"))
6737           (const_int 0)))
6738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:SI (match_dup 1) (match_dup 2)))]
6740   "ix86_match_ccmode (insn, CCGOCmode)
6741    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742   "sub{l}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "alu")
6744    (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2_zext"
6747   [(set (reg FLAGS_REG)
6748         (compare
6749           (minus:SI (match_operand:SI 1 "register_operand" "0")
6750                     (match_operand:SI 2 "general_operand" "rim"))
6751           (const_int 0)))
6752    (set (match_operand:DI 0 "register_operand" "=r")
6753         (zero_extend:DI
6754           (minus:SI (match_dup 1)
6755                     (match_dup 2))))]
6756   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6757    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758   "sub{l}\t{%2, %k0|%k0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "SI")])
6761
6762 (define_insn "*subsi_3"
6763   [(set (reg FLAGS_REG)
6764         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6765                  (match_operand:SI 2 "general_operand" "ri,rm")))
6766    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6767         (minus:SI (match_dup 1) (match_dup 2)))]
6768   "ix86_match_ccmode (insn, CCmode)
6769    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770   "sub{l}\t{%2, %0|%0, %2}"
6771   [(set_attr "type" "alu")
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_3_zext"
6775   [(set (reg FLAGS_REG)
6776         (compare (match_operand:SI 1 "register_operand" "0")
6777                  (match_operand:SI 2 "general_operand" "rim")))
6778    (set (match_operand:DI 0 "register_operand" "=r")
6779         (zero_extend:DI
6780           (minus:SI (match_dup 1)
6781                     (match_dup 2))))]
6782   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{q}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "DI")])
6787
6788 (define_expand "subhi3"
6789   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6790                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6791                              (match_operand:HI 2 "general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_HIMODE_MATH"
6794   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6795
6796 (define_insn "*subhi_1"
6797   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6798         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:HI 2 "general_operand" "ri,rm")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6802   "sub{w}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "HI")])
6805
6806 (define_insn "*subhi_2"
6807   [(set (reg FLAGS_REG)
6808         (compare
6809           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6810                     (match_operand:HI 2 "general_operand" "ri,rm"))
6811           (const_int 0)))
6812    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6813         (minus:HI (match_dup 1) (match_dup 2)))]
6814   "ix86_match_ccmode (insn, CCGOCmode)
6815    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6816   "sub{w}\t{%2, %0|%0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "HI")])
6819
6820 (define_insn "*subhi_3"
6821   [(set (reg FLAGS_REG)
6822         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823                  (match_operand:HI 2 "general_operand" "ri,rm")))
6824    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825         (minus:HI (match_dup 1) (match_dup 2)))]
6826   "ix86_match_ccmode (insn, CCmode)
6827    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6828   "sub{w}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "HI")])
6831
6832 (define_expand "subqi3"
6833   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6834                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6835                              (match_operand:QI 2 "general_operand" "")))
6836               (clobber (reg:CC FLAGS_REG))])]
6837   "TARGET_QIMODE_MATH"
6838   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6839
6840 (define_insn "*subqi_1"
6841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6842         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6843                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6844    (clobber (reg:CC FLAGS_REG))]
6845   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6846   "sub{b}\t{%2, %0|%0, %2}"
6847   [(set_attr "type" "alu")
6848    (set_attr "mode" "QI")])
6849
6850 (define_insn "*subqi_1_slp"
6851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6852         (minus:QI (match_dup 0)
6853                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6854    (clobber (reg:CC FLAGS_REG))]
6855   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6856    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6857   "sub{b}\t{%1, %0|%0, %1}"
6858   [(set_attr "type" "alu1")
6859    (set_attr "mode" "QI")])
6860
6861 (define_insn "*subqi_2"
6862   [(set (reg FLAGS_REG)
6863         (compare
6864           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6865                     (match_operand:QI 2 "general_operand" "qi,qm"))
6866           (const_int 0)))
6867    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6868         (minus:HI (match_dup 1) (match_dup 2)))]
6869   "ix86_match_ccmode (insn, CCGOCmode)
6870    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6871   "sub{b}\t{%2, %0|%0, %2}"
6872   [(set_attr "type" "alu")
6873    (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_3"
6876   [(set (reg FLAGS_REG)
6877         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                  (match_operand:QI 2 "general_operand" "qi,qm")))
6879    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6880         (minus:HI (match_dup 1) (match_dup 2)))]
6881   "ix86_match_ccmode (insn, CCmode)
6882    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6883   "sub{b}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "QI")])
6886
6887 ;; The patterns that match these are at the end of this file.
6888
6889 (define_expand "subxf3"
6890   [(set (match_operand:XF 0 "register_operand" "")
6891         (minus:XF (match_operand:XF 1 "register_operand" "")
6892                   (match_operand:XF 2 "register_operand" "")))]
6893   "TARGET_80387"
6894   "")
6895
6896 (define_expand "subdf3"
6897   [(set (match_operand:DF 0 "register_operand" "")
6898         (minus:DF (match_operand:DF 1 "register_operand" "")
6899                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6900   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6901   "")
6902
6903 (define_expand "subsf3"
6904   [(set (match_operand:SF 0 "register_operand" "")
6905         (minus:SF (match_operand:SF 1 "register_operand" "")
6906                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6907   "TARGET_80387 || TARGET_SSE_MATH"
6908   "")
6909 \f
6910 ;; Multiply instructions
6911
6912 (define_expand "muldi3"
6913   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6914                    (mult:DI (match_operand:DI 1 "register_operand" "")
6915                             (match_operand:DI 2 "x86_64_general_operand" "")))
6916               (clobber (reg:CC FLAGS_REG))])]
6917   "TARGET_64BIT"
6918   "")
6919
6920 (define_insn "*muldi3_1_rex64"
6921   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6922         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6923                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_64BIT
6926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927   "@
6928    imul{q}\t{%2, %1, %0|%0, %1, %2}
6929    imul{q}\t{%2, %1, %0|%0, %1, %2}
6930    imul{q}\t{%2, %0|%0, %2}"
6931   [(set_attr "type" "imul")
6932    (set_attr "prefix_0f" "0,0,1")
6933    (set (attr "athlon_decode")
6934         (cond [(eq_attr "cpu" "athlon")
6935                   (const_string "vector")
6936                (eq_attr "alternative" "1")
6937                   (const_string "vector")
6938                (and (eq_attr "alternative" "2")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "DI")])
6943
6944 (define_expand "mulsi3"
6945   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6946                    (mult:SI (match_operand:SI 1 "register_operand" "")
6947                             (match_operand:SI 2 "general_operand" "")))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   ""
6950   "")
6951
6952 (define_insn "*mulsi3_1"
6953   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6954         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958   "@
6959    imul{l}\t{%2, %1, %0|%0, %1, %2}
6960    imul{l}\t{%2, %1, %0|%0, %1, %2}
6961    imul{l}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "imul")
6963    (set_attr "prefix_0f" "0,0,1")
6964    (set (attr "athlon_decode")
6965         (cond [(eq_attr "cpu" "athlon")
6966                   (const_string "vector")
6967                (eq_attr "alternative" "1")
6968                   (const_string "vector")
6969                (and (eq_attr "alternative" "2")
6970                     (match_operand 1 "memory_operand" ""))
6971                   (const_string "vector")]
6972               (const_string "direct")))
6973    (set_attr "mode" "SI")])
6974
6975 (define_insn "*mulsi3_1_zext"
6976   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6977         (zero_extend:DI
6978           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6979                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "TARGET_64BIT
6982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6983   "@
6984    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6986    imul{l}\t{%2, %k0|%k0, %2}"
6987   [(set_attr "type" "imul")
6988    (set_attr "prefix_0f" "0,0,1")
6989    (set (attr "athlon_decode")
6990         (cond [(eq_attr "cpu" "athlon")
6991                   (const_string "vector")
6992                (eq_attr "alternative" "1")
6993                   (const_string "vector")
6994                (and (eq_attr "alternative" "2")
6995                     (match_operand 1 "memory_operand" ""))
6996                   (const_string "vector")]
6997               (const_string "direct")))
6998    (set_attr "mode" "SI")])
6999
7000 (define_expand "mulhi3"
7001   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7002                    (mult:HI (match_operand:HI 1 "register_operand" "")
7003                             (match_operand:HI 2 "general_operand" "")))
7004               (clobber (reg:CC FLAGS_REG))])]
7005   "TARGET_HIMODE_MATH"
7006   "")
7007
7008 (define_insn "*mulhi3_1"
7009   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7010         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7011                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7014   "@
7015    imul{w}\t{%2, %1, %0|%0, %1, %2}
7016    imul{w}\t{%2, %1, %0|%0, %1, %2}
7017    imul{w}\t{%2, %0|%0, %2}"
7018   [(set_attr "type" "imul")
7019    (set_attr "prefix_0f" "0,0,1")
7020    (set (attr "athlon_decode")
7021         (cond [(eq_attr "cpu" "athlon")
7022                   (const_string "vector")
7023                (eq_attr "alternative" "1,2")
7024                   (const_string "vector")]
7025               (const_string "direct")))
7026    (set_attr "mode" "HI")])
7027
7028 (define_expand "mulqi3"
7029   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7030                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7031                             (match_operand:QI 2 "register_operand" "")))
7032               (clobber (reg:CC FLAGS_REG))])]
7033   "TARGET_QIMODE_MATH"
7034   "")
7035
7036 (define_insn "*mulqi3_1"
7037   [(set (match_operand:QI 0 "register_operand" "=a")
7038         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7039                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7040    (clobber (reg:CC FLAGS_REG))]
7041   "TARGET_QIMODE_MATH
7042    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043   "mul{b}\t%2"
7044   [(set_attr "type" "imul")
7045    (set_attr "length_immediate" "0")
7046    (set (attr "athlon_decode")
7047      (if_then_else (eq_attr "cpu" "athlon")
7048         (const_string "vector")
7049         (const_string "direct")))
7050    (set_attr "mode" "QI")])
7051
7052 (define_expand "umulqihi3"
7053   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054                    (mult:HI (zero_extend:HI
7055                               (match_operand:QI 1 "nonimmediate_operand" ""))
7056                             (zero_extend:HI
7057                               (match_operand:QI 2 "register_operand" ""))))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "TARGET_QIMODE_MATH"
7060   "")
7061
7062 (define_insn "*umulqihi3_1"
7063   [(set (match_operand:HI 0 "register_operand" "=a")
7064         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7065                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "TARGET_QIMODE_MATH
7068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069   "mul{b}\t%2"
7070   [(set_attr "type" "imul")
7071    (set_attr "length_immediate" "0")
7072    (set (attr "athlon_decode")
7073      (if_then_else (eq_attr "cpu" "athlon")
7074         (const_string "vector")
7075         (const_string "direct")))
7076    (set_attr "mode" "QI")])
7077
7078 (define_expand "mulqihi3"
7079   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7081                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*mulqihi3_insn"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "imul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "mode" "QI")])
7101
7102 (define_expand "umulditi3"
7103   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104                    (mult:TI (zero_extend:TI
7105                               (match_operand:DI 1 "nonimmediate_operand" ""))
7106                             (zero_extend:TI
7107                               (match_operand:DI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_64BIT"
7110   "")
7111
7112 (define_insn "*umulditi3_insn"
7113   [(set (match_operand:TI 0 "register_operand" "=A")
7114         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_64BIT
7118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119   "mul{q}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "double")))
7126    (set_attr "mode" "DI")])
7127
7128 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7129 (define_expand "umulsidi3"
7130   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7131                    (mult:DI (zero_extend:DI
7132                               (match_operand:SI 1 "nonimmediate_operand" ""))
7133                             (zero_extend:DI
7134                               (match_operand:SI 2 "register_operand" ""))))
7135               (clobber (reg:CC FLAGS_REG))])]
7136   "!TARGET_64BIT"
7137   "")
7138
7139 (define_insn "*umulsidi3_insn"
7140   [(set (match_operand:DI 0 "register_operand" "=A")
7141         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7142                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "!TARGET_64BIT
7145    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146   "mul{l}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "mode" "SI")])
7154
7155 (define_expand "mulditi3"
7156   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7157                    (mult:TI (sign_extend:TI
7158                               (match_operand:DI 1 "nonimmediate_operand" ""))
7159                             (sign_extend:TI
7160                               (match_operand:DI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*mulditi3_insn"
7166   [(set (match_operand:TI 0 "register_operand" "=A")
7167         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7168                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "TARGET_64BIT
7171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172   "imul{q}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "DI")])
7180
7181 (define_expand "mulsidi3"
7182   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183                    (mult:DI (sign_extend:DI
7184                               (match_operand:SI 1 "nonimmediate_operand" ""))
7185                             (sign_extend:DI
7186                               (match_operand:SI 2 "register_operand" ""))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "!TARGET_64BIT"
7189   "")
7190
7191 (define_insn "*mulsidi3_insn"
7192   [(set (match_operand:DI 0 "register_operand" "=A")
7193         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7194                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7195    (clobber (reg:CC FLAGS_REG))]
7196   "!TARGET_64BIT
7197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198   "imul{l}\t%2"
7199   [(set_attr "type" "imul")
7200    (set_attr "length_immediate" "0")
7201    (set (attr "athlon_decode")
7202      (if_then_else (eq_attr "cpu" "athlon")
7203         (const_string "vector")
7204         (const_string "double")))
7205    (set_attr "mode" "SI")])
7206
7207 (define_expand "umuldi3_highpart"
7208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209                    (truncate:DI
7210                      (lshiftrt:TI
7211                        (mult:TI (zero_extend:TI
7212                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7213                                 (zero_extend:TI
7214                                   (match_operand:DI 2 "register_operand" "")))
7215                        (const_int 64))))
7216               (clobber (match_scratch:DI 3 ""))
7217               (clobber (reg:CC FLAGS_REG))])]
7218   "TARGET_64BIT"
7219   "")
7220
7221 (define_insn "*umuldi3_highpart_rex64"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (truncate:DI
7224           (lshiftrt:TI
7225             (mult:TI (zero_extend:TI
7226                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7227                      (zero_extend:TI
7228                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7229             (const_int 64))))
7230    (clobber (match_scratch:DI 3 "=1"))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{q}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "DI")])
7242
7243 (define_expand "umulsi3_highpart"
7244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245                    (truncate:SI
7246                      (lshiftrt:DI
7247                        (mult:DI (zero_extend:DI
7248                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7249                                 (zero_extend:DI
7250                                   (match_operand:SI 2 "register_operand" "")))
7251                        (const_int 32))))
7252               (clobber (match_scratch:SI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   "")
7256
7257 (define_insn "*umulsi3_highpart_insn"
7258   [(set (match_operand:SI 0 "register_operand" "=d")
7259         (truncate:SI
7260           (lshiftrt:DI
7261             (mult:DI (zero_extend:DI
7262                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263                      (zero_extend:DI
7264                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269   "mul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "SI")])
7277
7278 (define_insn "*umulsi3_highpart_zext"
7279   [(set (match_operand:DI 0 "register_operand" "=d")
7280         (zero_extend:DI (truncate:SI
7281           (lshiftrt:DI
7282             (mult:DI (zero_extend:DI
7283                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284                      (zero_extend:DI
7285                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286             (const_int 32)))))
7287    (clobber (match_scratch:SI 3 "=1"))
7288    (clobber (reg:CC FLAGS_REG))]
7289   "TARGET_64BIT
7290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291   "mul{l}\t%2"
7292   [(set_attr "type" "imul")
7293    (set_attr "length_immediate" "0")
7294    (set (attr "athlon_decode")
7295      (if_then_else (eq_attr "cpu" "athlon")
7296         (const_string "vector")
7297         (const_string "double")))
7298    (set_attr "mode" "SI")])
7299
7300 (define_expand "smuldi3_highpart"
7301   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7302                    (truncate:DI
7303                      (lshiftrt:TI
7304                        (mult:TI (sign_extend:TI
7305                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7306                                 (sign_extend:TI
7307                                   (match_operand:DI 2 "register_operand" "")))
7308                        (const_int 64))))
7309               (clobber (match_scratch:DI 3 ""))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   "TARGET_64BIT"
7312   "")
7313
7314 (define_insn "*smuldi3_highpart_rex64"
7315   [(set (match_operand:DI 0 "register_operand" "=d")
7316         (truncate:DI
7317           (lshiftrt:TI
7318             (mult:TI (sign_extend:TI
7319                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7320                      (sign_extend:TI
7321                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7322             (const_int 64))))
7323    (clobber (match_scratch:DI 3 "=1"))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_64BIT
7326    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7327   "imul{q}\t%2"
7328   [(set_attr "type" "imul")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "DI")])
7334
7335 (define_expand "smulsi3_highpart"
7336   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7337                    (truncate:SI
7338                      (lshiftrt:DI
7339                        (mult:DI (sign_extend:DI
7340                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:DI
7342                                   (match_operand:SI 2 "register_operand" "")))
7343                        (const_int 32))))
7344               (clobber (match_scratch:SI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   ""
7347   "")
7348
7349 (define_insn "*smulsi3_highpart_insn"
7350   [(set (match_operand:SI 0 "register_operand" "=d")
7351         (truncate:SI
7352           (lshiftrt:DI
7353             (mult:DI (sign_extend:DI
7354                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:DI
7356                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7357             (const_int 32))))
7358    (clobber (match_scratch:SI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7361   "imul{l}\t%2"
7362   [(set_attr "type" "imul")
7363    (set (attr "athlon_decode")
7364      (if_then_else (eq_attr "cpu" "athlon")
7365         (const_string "vector")
7366         (const_string "double")))
7367    (set_attr "mode" "SI")])
7368
7369 (define_insn "*smulsi3_highpart_zext"
7370   [(set (match_operand:DI 0 "register_operand" "=d")
7371         (zero_extend:DI (truncate:SI
7372           (lshiftrt:DI
7373             (mult:DI (sign_extend:DI
7374                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7375                      (sign_extend:DI
7376                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7377             (const_int 32)))))
7378    (clobber (match_scratch:SI 3 "=1"))
7379    (clobber (reg:CC FLAGS_REG))]
7380   "TARGET_64BIT
7381    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7382   "imul{l}\t%2"
7383   [(set_attr "type" "imul")
7384    (set (attr "athlon_decode")
7385      (if_then_else (eq_attr "cpu" "athlon")
7386         (const_string "vector")
7387         (const_string "double")))
7388    (set_attr "mode" "SI")])
7389
7390 ;; The patterns that match these are at the end of this file.
7391
7392 (define_expand "mulxf3"
7393   [(set (match_operand:XF 0 "register_operand" "")
7394         (mult:XF (match_operand:XF 1 "register_operand" "")
7395                  (match_operand:XF 2 "register_operand" "")))]
7396   "TARGET_80387"
7397   "")
7398
7399 (define_expand "muldf3"
7400   [(set (match_operand:DF 0 "register_operand" "")
7401         (mult:DF (match_operand:DF 1 "register_operand" "")
7402                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7403   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7404   "")
7405
7406 (define_expand "mulsf3"
7407   [(set (match_operand:SF 0 "register_operand" "")
7408         (mult:SF (match_operand:SF 1 "register_operand" "")
7409                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7410   "TARGET_80387 || TARGET_SSE_MATH"
7411   "")
7412 \f
7413 ;; Divide instructions
7414
7415 (define_insn "divqi3"
7416   [(set (match_operand:QI 0 "register_operand" "=a")
7417         (div:QI (match_operand:HI 1 "register_operand" "0")
7418                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_QIMODE_MATH"
7421   "idiv{b}\t%2"
7422   [(set_attr "type" "idiv")
7423    (set_attr "mode" "QI")])
7424
7425 (define_insn "udivqi3"
7426   [(set (match_operand:QI 0 "register_operand" "=a")
7427         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7428                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "TARGET_QIMODE_MATH"
7431   "div{b}\t%2"
7432   [(set_attr "type" "idiv")
7433    (set_attr "mode" "QI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "divxf3"
7438   [(set (match_operand:XF 0 "register_operand" "")
7439         (div:XF (match_operand:XF 1 "register_operand" "")
7440                 (match_operand:XF 2 "register_operand" "")))]
7441   "TARGET_80387"
7442   "")
7443
7444 (define_expand "divdf3"
7445   [(set (match_operand:DF 0 "register_operand" "")
7446         (div:DF (match_operand:DF 1 "register_operand" "")
7447                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7448    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449    "")
7450  
7451 (define_expand "divsf3"
7452   [(set (match_operand:SF 0 "register_operand" "")
7453         (div:SF (match_operand:SF 1 "register_operand" "")
7454                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7455   "TARGET_80387 || TARGET_SSE_MATH"
7456   "")
7457 \f
7458 ;; Remainder instructions.
7459
7460 (define_expand "divmoddi4"
7461   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7462                    (div:DI (match_operand:DI 1 "register_operand" "")
7463                            (match_operand:DI 2 "nonimmediate_operand" "")))
7464               (set (match_operand:DI 3 "register_operand" "")
7465                    (mod:DI (match_dup 1) (match_dup 2)))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   "TARGET_64BIT"
7468   "")
7469
7470 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7471 ;; Penalize eax case slightly because it results in worse scheduling
7472 ;; of code.
7473 (define_insn "*divmoddi4_nocltd_rex64"
7474   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7475         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7476                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7477    (set (match_operand:DI 1 "register_operand" "=&d,&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 "*divmoddi4_cltd_rex64"
7485   [(set (match_operand:DI 0 "register_operand" "=a")
7486         (div:DI (match_operand:DI 2 "register_operand" "a")
7487                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7488    (set (match_operand:DI 1 "register_operand" "=&d")
7489         (mod:DI (match_dup 2) (match_dup 3)))
7490    (clobber (reg:CC FLAGS_REG))]
7491   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7492   "#"
7493   [(set_attr "type" "multi")])
7494
7495 (define_insn "*divmoddi_noext_rex64"
7496   [(set (match_operand:DI 0 "register_operand" "=a")
7497         (div:DI (match_operand:DI 1 "register_operand" "0")
7498                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499    (set (match_operand:DI 3 "register_operand" "=d")
7500         (mod:DI (match_dup 1) (match_dup 2)))
7501    (use (match_operand:DI 4 "register_operand" "3"))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "TARGET_64BIT"
7504   "idiv{q}\t%2"
7505   [(set_attr "type" "idiv")
7506    (set_attr "mode" "DI")])
7507
7508 (define_split
7509   [(set (match_operand:DI 0 "register_operand" "")
7510         (div:DI (match_operand:DI 1 "register_operand" "")
7511                 (match_operand:DI 2 "nonimmediate_operand" "")))
7512    (set (match_operand:DI 3 "register_operand" "")
7513         (mod:DI (match_dup 1) (match_dup 2)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && reload_completed"
7516   [(parallel [(set (match_dup 3)
7517                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7518               (clobber (reg:CC FLAGS_REG))])
7519    (parallel [(set (match_dup 0)
7520                    (div:DI (reg:DI 0) (match_dup 2)))
7521               (set (match_dup 3)
7522                    (mod:DI (reg:DI 0) (match_dup 2)))
7523               (use (match_dup 3))
7524               (clobber (reg:CC FLAGS_REG))])]
7525 {
7526   /* Avoid use of cltd in favor of a mov+shift.  */
7527   if (!TARGET_USE_CLTD && !optimize_size)
7528     {
7529       if (true_regnum (operands[1]))
7530         emit_move_insn (operands[0], operands[1]);
7531       else
7532         emit_move_insn (operands[3], operands[1]);
7533       operands[4] = operands[3];
7534     }
7535   else
7536     {
7537       if (true_regnum (operands[1]))
7538         abort();
7539       operands[4] = operands[1];
7540     }
7541 })
7542
7543
7544 (define_expand "divmodsi4"
7545   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7546                    (div:SI (match_operand:SI 1 "register_operand" "")
7547                            (match_operand:SI 2 "nonimmediate_operand" "")))
7548               (set (match_operand:SI 3 "register_operand" "")
7549                    (mod:SI (match_dup 1) (match_dup 2)))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   ""
7552   "")
7553
7554 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7555 ;; Penalize eax case slightly because it results in worse scheduling
7556 ;; of code.
7557 (define_insn "*divmodsi4_nocltd"
7558   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7559         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d,&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 "*divmodsi4_cltd"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 2 "register_operand" "a")
7571                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 1 "register_operand" "=&d")
7573         (mod:SI (match_dup 2) (match_dup 3)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "optimize_size || TARGET_USE_CLTD"
7576   "#"
7577   [(set_attr "type" "multi")])
7578
7579 (define_insn "*divmodsi_noext"
7580   [(set (match_operand:SI 0 "register_operand" "=a")
7581         (div:SI (match_operand:SI 1 "register_operand" "0")
7582                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7583    (set (match_operand:SI 3 "register_operand" "=d")
7584         (mod:SI (match_dup 1) (match_dup 2)))
7585    (use (match_operand:SI 4 "register_operand" "3"))
7586    (clobber (reg:CC FLAGS_REG))]
7587   ""
7588   "idiv{l}\t%2"
7589   [(set_attr "type" "idiv")
7590    (set_attr "mode" "SI")])
7591
7592 (define_split
7593   [(set (match_operand:SI 0 "register_operand" "")
7594         (div:SI (match_operand:SI 1 "register_operand" "")
7595                 (match_operand:SI 2 "nonimmediate_operand" "")))
7596    (set (match_operand:SI 3 "register_operand" "")
7597         (mod:SI (match_dup 1) (match_dup 2)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "reload_completed"
7600   [(parallel [(set (match_dup 3)
7601                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7602               (clobber (reg:CC FLAGS_REG))])
7603    (parallel [(set (match_dup 0)
7604                    (div:SI (reg:SI 0) (match_dup 2)))
7605               (set (match_dup 3)
7606                    (mod:SI (reg:SI 0) (match_dup 2)))
7607               (use (match_dup 3))
7608               (clobber (reg:CC FLAGS_REG))])]
7609 {
7610   /* Avoid use of cltd in favor of a mov+shift.  */
7611   if (!TARGET_USE_CLTD && !optimize_size)
7612     {
7613       if (true_regnum (operands[1]))
7614         emit_move_insn (operands[0], operands[1]);
7615       else
7616         emit_move_insn (operands[3], operands[1]);
7617       operands[4] = operands[3];
7618     }
7619   else
7620     {
7621       if (true_regnum (operands[1]))
7622         abort();
7623       operands[4] = operands[1];
7624     }
7625 })
7626 ;; %%% Split me.
7627 (define_insn "divmodhi4"
7628   [(set (match_operand:HI 0 "register_operand" "=a")
7629         (div:HI (match_operand:HI 1 "register_operand" "0")
7630                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7631    (set (match_operand:HI 3 "register_operand" "=&d")
7632         (mod:HI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "TARGET_HIMODE_MATH"
7635   "cwtd\;idiv{w}\t%2"
7636   [(set_attr "type" "multi")
7637    (set_attr "length_immediate" "0")
7638    (set_attr "mode" "SI")])
7639
7640 (define_insn "udivmoddi4"
7641   [(set (match_operand:DI 0 "register_operand" "=a")
7642         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7643                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:DI 3 "register_operand" "=&d")
7645         (umod:DI (match_dup 1) (match_dup 2)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   "TARGET_64BIT"
7648   "xor{q}\t%3, %3\;div{q}\t%2"
7649   [(set_attr "type" "multi")
7650    (set_attr "length_immediate" "0")
7651    (set_attr "mode" "DI")])
7652
7653 (define_insn "*udivmoddi4_noext"
7654   [(set (match_operand:DI 0 "register_operand" "=a")
7655         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:DI 3 "register_operand" "=d")
7658         (umod:DI (match_dup 1) (match_dup 2)))
7659    (use (match_dup 3))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT"
7662   "div{q}\t%2"
7663   [(set_attr "type" "idiv")
7664    (set_attr "mode" "DI")])
7665
7666 (define_split
7667   [(set (match_operand:DI 0 "register_operand" "")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "")
7669                  (match_operand:DI 2 "nonimmediate_operand" "")))
7670    (set (match_operand:DI 3 "register_operand" "")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT && reload_completed"
7674   [(set (match_dup 3) (const_int 0))
7675    (parallel [(set (match_dup 0)
7676                    (udiv:DI (match_dup 1) (match_dup 2)))
7677               (set (match_dup 3)
7678                    (umod:DI (match_dup 1) (match_dup 2)))
7679               (use (match_dup 3))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   "")
7682
7683 (define_insn "udivmodsi4"
7684   [(set (match_operand:SI 0 "register_operand" "=a")
7685         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7686                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7687    (set (match_operand:SI 3 "register_operand" "=&d")
7688         (umod:SI (match_dup 1) (match_dup 2)))
7689    (clobber (reg:CC FLAGS_REG))]
7690   ""
7691   "xor{l}\t%3, %3\;div{l}\t%2"
7692   [(set_attr "type" "multi")
7693    (set_attr "length_immediate" "0")
7694    (set_attr "mode" "SI")])
7695
7696 (define_insn "*udivmodsi4_noext"
7697   [(set (match_operand:SI 0 "register_operand" "=a")
7698         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700    (set (match_operand:SI 3 "register_operand" "=d")
7701         (umod:SI (match_dup 1) (match_dup 2)))
7702    (use (match_dup 3))
7703    (clobber (reg:CC FLAGS_REG))]
7704   ""
7705   "div{l}\t%2"
7706   [(set_attr "type" "idiv")
7707    (set_attr "mode" "SI")])
7708
7709 (define_split
7710   [(set (match_operand:SI 0 "register_operand" "")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "")
7712                  (match_operand:SI 2 "nonimmediate_operand" "")))
7713    (set (match_operand:SI 3 "register_operand" "")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "reload_completed"
7717   [(set (match_dup 3) (const_int 0))
7718    (parallel [(set (match_dup 0)
7719                    (udiv:SI (match_dup 1) (match_dup 2)))
7720               (set (match_dup 3)
7721                    (umod:SI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 3))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "")
7725
7726 (define_expand "udivmodhi4"
7727   [(set (match_dup 4) (const_int 0))
7728    (parallel [(set (match_operand:HI 0 "register_operand" "")
7729                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7730                             (match_operand:HI 2 "nonimmediate_operand" "")))
7731               (set (match_operand:HI 3 "register_operand" "")
7732                    (umod:HI (match_dup 1) (match_dup 2)))
7733               (use (match_dup 4))
7734               (clobber (reg:CC FLAGS_REG))])]
7735   "TARGET_HIMODE_MATH"
7736   "operands[4] = gen_reg_rtx (HImode);")
7737
7738 (define_insn "*udivmodhi_noext"
7739   [(set (match_operand:HI 0 "register_operand" "=a")
7740         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7741                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7742    (set (match_operand:HI 3 "register_operand" "=d")
7743         (umod:HI (match_dup 1) (match_dup 2)))
7744    (use (match_operand:HI 4 "register_operand" "3"))
7745    (clobber (reg:CC FLAGS_REG))]
7746   ""
7747   "div{w}\t%2"
7748   [(set_attr "type" "idiv")
7749    (set_attr "mode" "HI")])
7750
7751 ;; We cannot use div/idiv for double division, because it causes
7752 ;; "division by zero" on the overflow and that's not what we expect
7753 ;; from truncate.  Because true (non truncating) double division is
7754 ;; never generated, we can't create this insn anyway.
7755 ;
7756 ;(define_insn ""
7757 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7758 ;       (truncate:SI
7759 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7760 ;                  (zero_extend:DI
7761 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7762 ;   (set (match_operand:SI 3 "register_operand" "=d")
7763 ;       (truncate:SI
7764 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7765 ;   (clobber (reg:CC FLAGS_REG))]
7766 ;  ""
7767 ;  "div{l}\t{%2, %0|%0, %2}"
7768 ;  [(set_attr "type" "idiv")])
7769 \f
7770 ;;- Logical AND instructions
7771
7772 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7773 ;; Note that this excludes ah.
7774
7775 (define_insn "*testdi_1_rex64"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7779                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7780           (const_int 0)))]
7781   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7782    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7783   "@
7784    test{l}\t{%k1, %k0|%k0, %k1}
7785    test{l}\t{%k1, %k0|%k0, %k1}
7786    test{q}\t{%1, %0|%0, %1}
7787    test{q}\t{%1, %0|%0, %1}
7788    test{q}\t{%1, %0|%0, %1}"
7789   [(set_attr "type" "test")
7790    (set_attr "modrm" "0,1,0,1,1")
7791    (set_attr "mode" "SI,SI,DI,DI,DI")
7792    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7793
7794 (define_insn "testsi_1"
7795   [(set (reg FLAGS_REG)
7796         (compare
7797           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7798                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7799           (const_int 0)))]
7800   "ix86_match_ccmode (insn, CCNOmode)
7801    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7802   "test{l}\t{%1, %0|%0, %1}"
7803   [(set_attr "type" "test")
7804    (set_attr "modrm" "0,1,1")
7805    (set_attr "mode" "SI")
7806    (set_attr "pent_pair" "uv,np,uv")])
7807
7808 (define_expand "testsi_ccno_1"
7809   [(set (reg:CCNO FLAGS_REG)
7810         (compare:CCNO
7811           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7812                   (match_operand:SI 1 "nonmemory_operand" ""))
7813           (const_int 0)))]
7814   ""
7815   "")
7816
7817 (define_insn "*testhi_1"
7818   [(set (reg FLAGS_REG)
7819         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7820                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7821                  (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)
7823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824   "test{w}\t{%1, %0|%0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "modrm" "0,1,1")
7827    (set_attr "mode" "HI")
7828    (set_attr "pent_pair" "uv,np,uv")])
7829
7830 (define_expand "testqi_ccz_1"
7831   [(set (reg:CCZ FLAGS_REG)
7832         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7833                              (match_operand:QI 1 "nonmemory_operand" ""))
7834                  (const_int 0)))]
7835   ""
7836   "")
7837
7838 (define_insn "*testqi_1_maybe_si"
7839   [(set (reg FLAGS_REG)
7840         (compare
7841           (and:QI
7842             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7843             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7844           (const_int 0)))]
7845    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846     && ix86_match_ccmode (insn,
7847                          GET_CODE (operands[1]) == CONST_INT
7848                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7849 {
7850   if (which_alternative == 3)
7851     {
7852       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7853         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7854       return "test{l}\t{%1, %k0|%k0, %1}";
7855     }
7856   return "test{b}\t{%1, %0|%0, %1}";
7857 }
7858   [(set_attr "type" "test")
7859    (set_attr "modrm" "0,1,1,1")
7860    (set_attr "mode" "QI,QI,QI,SI")
7861    (set_attr "pent_pair" "uv,np,uv,np")])
7862
7863 (define_insn "*testqi_1"
7864   [(set (reg FLAGS_REG)
7865         (compare
7866           (and:QI
7867             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7868             (match_operand:QI 1 "general_operand" "n,n,qn"))
7869           (const_int 0)))]
7870   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7871    && ix86_match_ccmode (insn, CCNOmode)"
7872   "test{b}\t{%1, %0|%0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "modrm" "0,1,1")
7875    (set_attr "mode" "QI")
7876    (set_attr "pent_pair" "uv,np,uv")])
7877
7878 (define_expand "testqi_ext_ccno_0"
7879   [(set (reg:CCNO FLAGS_REG)
7880         (compare:CCNO
7881           (and:SI
7882             (zero_extract:SI
7883               (match_operand 0 "ext_register_operand" "")
7884               (const_int 8)
7885               (const_int 8))
7886             (match_operand 1 "const_int_operand" ""))
7887           (const_int 0)))]
7888   ""
7889   "")
7890
7891 (define_insn "*testqi_ext_0"
7892   [(set (reg FLAGS_REG)
7893         (compare
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "Q")
7897               (const_int 8)
7898               (const_int 8))
7899             (match_operand 1 "const_int_operand" "n"))
7900           (const_int 0)))]
7901   "ix86_match_ccmode (insn, CCNOmode)"
7902   "test{b}\t{%1, %h0|%h0, %1}"
7903   [(set_attr "type" "test")
7904    (set_attr "mode" "QI")
7905    (set_attr "length_immediate" "1")
7906    (set_attr "pent_pair" "np")])
7907
7908 (define_insn "*testqi_ext_1"
7909   [(set (reg FLAGS_REG)
7910         (compare
7911           (and:SI
7912             (zero_extract:SI
7913               (match_operand 0 "ext_register_operand" "Q")
7914               (const_int 8)
7915               (const_int 8))
7916             (zero_extend:SI
7917               (match_operand:QI 1 "general_operand" "Qm")))
7918           (const_int 0)))]
7919   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7921   "test{b}\t{%1, %h0|%h0, %1}"
7922   [(set_attr "type" "test")
7923    (set_attr "mode" "QI")])
7924
7925 (define_insn "*testqi_ext_1_rex64"
7926   [(set (reg FLAGS_REG)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (zero_extend:SI
7934               (match_operand:QI 1 "register_operand" "Q")))
7935           (const_int 0)))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7937   "test{b}\t{%1, %h0|%h0, %1}"
7938   [(set_attr "type" "test")
7939    (set_attr "mode" "QI")])
7940
7941 (define_insn "*testqi_ext_2"
7942   [(set (reg FLAGS_REG)
7943         (compare
7944           (and:SI
7945             (zero_extract:SI
7946               (match_operand 0 "ext_register_operand" "Q")
7947               (const_int 8)
7948               (const_int 8))
7949             (zero_extract:SI
7950               (match_operand 1 "ext_register_operand" "Q")
7951               (const_int 8)
7952               (const_int 8)))
7953           (const_int 0)))]
7954   "ix86_match_ccmode (insn, CCNOmode)"
7955   "test{b}\t{%h1, %h0|%h0, %h1}"
7956   [(set_attr "type" "test")
7957    (set_attr "mode" "QI")])
7958
7959 ;; Combine likes to form bit extractions for some tests.  Humor it.
7960 (define_insn "*testqi_ext_3"
7961   [(set (reg FLAGS_REG)
7962         (compare (zero_extract:SI
7963                    (match_operand 0 "nonimmediate_operand" "rm")
7964                    (match_operand:SI 1 "const_int_operand" "")
7965                    (match_operand:SI 2 "const_int_operand" ""))
7966                  (const_int 0)))]
7967   "ix86_match_ccmode (insn, CCNOmode)
7968    && (GET_MODE (operands[0]) == SImode
7969        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7970        || GET_MODE (operands[0]) == HImode
7971        || GET_MODE (operands[0]) == QImode)"
7972   "#")
7973
7974 (define_insn "*testqi_ext_3_rex64"
7975   [(set (reg FLAGS_REG)
7976         (compare (zero_extract:DI
7977                    (match_operand 0 "nonimmediate_operand" "rm")
7978                    (match_operand:DI 1 "const_int_operand" "")
7979                    (match_operand:DI 2 "const_int_operand" ""))
7980                  (const_int 0)))]
7981   "TARGET_64BIT
7982    && ix86_match_ccmode (insn, CCNOmode)
7983    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7984    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7985    /* Ensure that resulting mask is zero or sign extended operand.  */
7986    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7987        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7988            && INTVAL (operands[1]) > 32))
7989    && (GET_MODE (operands[0]) == SImode
7990        || GET_MODE (operands[0]) == DImode
7991        || GET_MODE (operands[0]) == HImode
7992        || GET_MODE (operands[0]) == QImode)"
7993   "#")
7994
7995 (define_split
7996   [(set (match_operand 0 "flags_reg_operand" "")
7997         (match_operator 1 "compare_operator"
7998           [(zero_extract
7999              (match_operand 2 "nonimmediate_operand" "")
8000              (match_operand 3 "const_int_operand" "")
8001              (match_operand 4 "const_int_operand" ""))
8002            (const_int 0)]))]
8003   "ix86_match_ccmode (insn, CCNOmode)"
8004   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8005 {
8006   rtx val = operands[2];
8007   HOST_WIDE_INT len = INTVAL (operands[3]);
8008   HOST_WIDE_INT pos = INTVAL (operands[4]);
8009   HOST_WIDE_INT mask;
8010   enum machine_mode mode, submode;
8011
8012   mode = GET_MODE (val);
8013   if (GET_CODE (val) == MEM)
8014     {
8015       /* ??? Combine likes to put non-volatile mem extractions in QImode
8016          no matter the size of the test.  So find a mode that works.  */
8017       if (! MEM_VOLATILE_P (val))
8018         {
8019           mode = smallest_mode_for_size (pos + len, MODE_INT);
8020           val = adjust_address (val, mode, 0);
8021         }
8022     }
8023   else if (GET_CODE (val) == SUBREG
8024            && (submode = GET_MODE (SUBREG_REG (val)),
8025                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8026            && pos + len <= GET_MODE_BITSIZE (submode))
8027     {
8028       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8029       mode = submode;
8030       val = SUBREG_REG (val);
8031     }
8032   else if (mode == HImode && pos + len <= 8)
8033     {
8034       /* Small HImode tests can be converted to QImode.  */
8035       mode = QImode;
8036       val = gen_lowpart (QImode, val);
8037     }
8038
8039   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8040   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8041
8042   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8043 })
8044
8045 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8046 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8047 ;; this is relatively important trick.
8048 ;; Do the conversion only post-reload to avoid limiting of the register class
8049 ;; to QI regs.
8050 (define_split
8051   [(set (match_operand 0 "flags_reg_operand" "")
8052         (match_operator 1 "compare_operator"
8053           [(and (match_operand 2 "register_operand" "")
8054                 (match_operand 3 "const_int_operand" ""))
8055            (const_int 0)]))]
8056    "reload_completed
8057     && QI_REG_P (operands[2])
8058     && GET_MODE (operands[2]) != QImode
8059     && ((ix86_match_ccmode (insn, CCZmode)
8060          && !(INTVAL (operands[3]) & ~(255 << 8)))
8061         || (ix86_match_ccmode (insn, CCNOmode)
8062             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8063   [(set (match_dup 0)
8064         (match_op_dup 1
8065           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8066                    (match_dup 3))
8067            (const_int 0)]))]
8068   "operands[2] = gen_lowpart (SImode, operands[2]);
8069    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8070
8071 (define_split
8072   [(set (match_operand 0 "flags_reg_operand" "")
8073         (match_operator 1 "compare_operator"
8074           [(and (match_operand 2 "nonimmediate_operand" "")
8075                 (match_operand 3 "const_int_operand" ""))
8076            (const_int 0)]))]
8077    "reload_completed
8078     && GET_MODE (operands[2]) != QImode
8079     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8080     && ((ix86_match_ccmode (insn, CCZmode)
8081          && !(INTVAL (operands[3]) & ~255))
8082         || (ix86_match_ccmode (insn, CCNOmode)
8083             && !(INTVAL (operands[3]) & ~127)))"
8084   [(set (match_dup 0)
8085         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8086                          (const_int 0)]))]
8087   "operands[2] = gen_lowpart (QImode, operands[2]);
8088    operands[3] = gen_lowpart (QImode, operands[3]);")
8089
8090
8091 ;; %%% This used to optimize known byte-wide and operations to memory,
8092 ;; and sometimes to QImode registers.  If this is considered useful,
8093 ;; it should be done with splitters.
8094
8095 (define_expand "anddi3"
8096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8097         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8098                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT"
8101   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102
8103 (define_insn "*anddi_1_rex64"
8104   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8105         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8106                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109 {
8110   switch (get_attr_type (insn))
8111     {
8112     case TYPE_IMOVX:
8113       {
8114         enum machine_mode mode;
8115
8116         if (GET_CODE (operands[2]) != CONST_INT)
8117           abort ();
8118         if (INTVAL (operands[2]) == 0xff)
8119           mode = QImode;
8120         else if (INTVAL (operands[2]) == 0xffff)
8121           mode = HImode;
8122         else
8123           abort ();
8124         
8125         operands[1] = gen_lowpart (mode, operands[1]);
8126         if (mode == QImode)
8127           return "movz{bq|x}\t{%1,%0|%0, %1}";
8128         else
8129           return "movz{wq|x}\t{%1,%0|%0, %1}";
8130       }
8131
8132     default:
8133       if (! rtx_equal_p (operands[0], operands[1]))
8134         abort ();
8135       if (get_attr_mode (insn) == MODE_SI)
8136         return "and{l}\t{%k2, %k0|%k0, %k2}";
8137       else
8138         return "and{q}\t{%2, %0|%0, %2}";
8139     }
8140 }
8141   [(set_attr "type" "alu,alu,alu,imovx")
8142    (set_attr "length_immediate" "*,*,*,0")
8143    (set_attr "mode" "SI,DI,DI,DI")])
8144
8145 (define_insn "*anddi_2"
8146   [(set (reg FLAGS_REG)
8147         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8148                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8149                  (const_int 0)))
8150    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8151         (and:DI (match_dup 1) (match_dup 2)))]
8152   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153    && ix86_binary_operator_ok (AND, DImode, operands)"
8154   "@
8155    and{l}\t{%k2, %k0|%k0, %k2}
8156    and{q}\t{%2, %0|%0, %2}
8157    and{q}\t{%2, %0|%0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI,DI,DI")])
8160
8161 (define_expand "andsi3"
8162   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8163         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8164                 (match_operand:SI 2 "general_operand" "")))
8165    (clobber (reg:CC FLAGS_REG))]
8166   ""
8167   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168
8169 (define_insn "*andsi_1"
8170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8171         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8172                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8173    (clobber (reg:CC FLAGS_REG))]
8174   "ix86_binary_operator_ok (AND, SImode, operands)"
8175 {
8176   switch (get_attr_type (insn))
8177     {
8178     case TYPE_IMOVX:
8179       {
8180         enum machine_mode mode;
8181
8182         if (GET_CODE (operands[2]) != CONST_INT)
8183           abort ();
8184         if (INTVAL (operands[2]) == 0xff)
8185           mode = QImode;
8186         else if (INTVAL (operands[2]) == 0xffff)
8187           mode = HImode;
8188         else
8189           abort ();
8190         
8191         operands[1] = gen_lowpart (mode, operands[1]);
8192         if (mode == QImode)
8193           return "movz{bl|x}\t{%1,%0|%0, %1}";
8194         else
8195           return "movz{wl|x}\t{%1,%0|%0, %1}";
8196       }
8197
8198     default:
8199       if (! rtx_equal_p (operands[0], operands[1]))
8200         abort ();
8201       return "and{l}\t{%2, %0|%0, %2}";
8202     }
8203 }
8204   [(set_attr "type" "alu,alu,imovx")
8205    (set_attr "length_immediate" "*,*,0")
8206    (set_attr "mode" "SI")])
8207
8208 (define_split
8209   [(set (match_operand 0 "register_operand" "")
8210         (and (match_dup 0)
8211              (const_int -65536)))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8214   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8215   "operands[1] = gen_lowpart (HImode, operands[0]);")
8216
8217 (define_split
8218   [(set (match_operand 0 "ext_register_operand" "")
8219         (and (match_dup 0)
8220              (const_int -256)))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8223   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224   "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227   [(set (match_operand 0 "ext_register_operand" "")
8228         (and (match_dup 0)
8229              (const_int -65281)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8232   [(parallel [(set (zero_extract:SI (match_dup 0)
8233                                     (const_int 8)
8234                                     (const_int 8))
8235                    (xor:SI 
8236                      (zero_extract:SI (match_dup 0)
8237                                       (const_int 8)
8238                                       (const_int 8))
8239                      (zero_extract:SI (match_dup 0)
8240                                       (const_int 8)
8241                                       (const_int 8))))
8242               (clobber (reg:CC FLAGS_REG))])]
8243   "operands[0] = gen_lowpart (SImode, operands[0]);")
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 (define_insn "*andsi_1_zext"
8247   [(set (match_operand:DI 0 "register_operand" "=r")
8248         (zero_extend:DI
8249           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250                   (match_operand:SI 2 "general_operand" "rim"))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8253   "and{l}\t{%2, %k0|%k0, %2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "mode" "SI")])
8256
8257 (define_insn "*andsi_2"
8258   [(set (reg FLAGS_REG)
8259         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8260                          (match_operand:SI 2 "general_operand" "rim,ri"))
8261                  (const_int 0)))
8262    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8263         (and:SI (match_dup 1) (match_dup 2)))]
8264   "ix86_match_ccmode (insn, CCNOmode)
8265    && ix86_binary_operator_ok (AND, SImode, operands)"
8266   "and{l}\t{%2, %0|%0, %2}"
8267   [(set_attr "type" "alu")
8268    (set_attr "mode" "SI")])
8269
8270 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8271 (define_insn "*andsi_2_zext"
8272   [(set (reg FLAGS_REG)
8273         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274                          (match_operand:SI 2 "general_operand" "rim"))
8275                  (const_int 0)))
8276    (set (match_operand:DI 0 "register_operand" "=r")
8277         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8278   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8279    && ix86_binary_operator_ok (AND, SImode, operands)"
8280   "and{l}\t{%2, %k0|%k0, %2}"
8281   [(set_attr "type" "alu")
8282    (set_attr "mode" "SI")])
8283
8284 (define_expand "andhi3"
8285   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8286         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8287                 (match_operand:HI 2 "general_operand" "")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "TARGET_HIMODE_MATH"
8290   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291
8292 (define_insn "*andhi_1"
8293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8294         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8295                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "ix86_binary_operator_ok (AND, HImode, operands)"
8298 {
8299   switch (get_attr_type (insn))
8300     {
8301     case TYPE_IMOVX:
8302       if (GET_CODE (operands[2]) != CONST_INT)
8303         abort ();
8304       if (INTVAL (operands[2]) == 0xff)
8305         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8306       abort ();
8307
8308     default:
8309       if (! rtx_equal_p (operands[0], operands[1]))
8310         abort ();
8311
8312       return "and{w}\t{%2, %0|%0, %2}";
8313     }
8314 }
8315   [(set_attr "type" "alu,alu,imovx")
8316    (set_attr "length_immediate" "*,*,0")
8317    (set_attr "mode" "HI,HI,SI")])
8318
8319 (define_insn "*andhi_2"
8320   [(set (reg FLAGS_REG)
8321         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8322                          (match_operand:HI 2 "general_operand" "rim,ri"))
8323                  (const_int 0)))
8324    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8325         (and:HI (match_dup 1) (match_dup 2)))]
8326   "ix86_match_ccmode (insn, CCNOmode)
8327    && ix86_binary_operator_ok (AND, HImode, operands)"
8328   "and{w}\t{%2, %0|%0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "mode" "HI")])
8331
8332 (define_expand "andqi3"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8335                 (match_operand:QI 2 "general_operand" "")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_QIMODE_MATH"
8338   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339
8340 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8341 (define_insn "*andqi_1"
8342   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8343         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8344                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "ix86_binary_operator_ok (AND, QImode, operands)"
8347   "@
8348    and{b}\t{%2, %0|%0, %2}
8349    and{b}\t{%2, %0|%0, %2}
8350    and{l}\t{%k2, %k0|%k0, %k2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "QI,QI,SI")])
8353
8354 (define_insn "*andqi_1_slp"
8355   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8356         (and:QI (match_dup 0)
8357                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8361   "and{b}\t{%1, %0|%0, %1}"
8362   [(set_attr "type" "alu1")
8363    (set_attr "mode" "QI")])
8364
8365 (define_insn "*andqi_2_maybe_si"
8366   [(set (reg FLAGS_REG)
8367         (compare (and:QI
8368                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8370                  (const_int 0)))
8371    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8372         (and:QI (match_dup 1) (match_dup 2)))]
8373   "ix86_binary_operator_ok (AND, QImode, operands)
8374    && ix86_match_ccmode (insn,
8375                          GET_CODE (operands[2]) == CONST_INT
8376                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8377 {
8378   if (which_alternative == 2)
8379     {
8380       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8381         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8382       return "and{l}\t{%2, %k0|%k0, %2}";
8383     }
8384   return "and{b}\t{%2, %0|%0, %2}";
8385 }
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_2"
8390   [(set (reg FLAGS_REG)
8391         (compare (and:QI
8392                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8393                    (match_operand:QI 2 "general_operand" "qim,qi"))
8394                  (const_int 0)))
8395    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8396         (and:QI (match_dup 1) (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)
8398    && ix86_binary_operator_ok (AND, QImode, operands)"
8399   "and{b}\t{%2, %0|%0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_2_slp"
8404   [(set (reg FLAGS_REG)
8405         (compare (and:QI
8406                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8407                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8408                  (const_int 0)))
8409    (set (strict_low_part (match_dup 0))
8410         (and:QI (match_dup 0) (match_dup 1)))]
8411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8412    && ix86_match_ccmode (insn, CCNOmode)
8413    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8414   "and{b}\t{%1, %0|%0, %1}"
8415   [(set_attr "type" "alu1")
8416    (set_attr "mode" "QI")])
8417
8418 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8419 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8420 ;; for a QImode operand, which of course failed.
8421
8422 (define_insn "andqi_ext_0"
8423   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424                          (const_int 8)
8425                          (const_int 8))
8426         (and:SI 
8427           (zero_extract:SI
8428             (match_operand 1 "ext_register_operand" "0")
8429             (const_int 8)
8430             (const_int 8))
8431           (match_operand 2 "const_int_operand" "n")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   ""
8434   "and{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "1")
8437    (set_attr "mode" "QI")])
8438
8439 ;; Generated by peephole translating test to and.  This shows up
8440 ;; often in fp comparisons.
8441
8442 (define_insn "*andqi_ext_0_cc"
8443   [(set (reg FLAGS_REG)
8444         (compare
8445           (and:SI
8446             (zero_extract:SI
8447               (match_operand 1 "ext_register_operand" "0")
8448               (const_int 8)
8449               (const_int 8))
8450             (match_operand 2 "const_int_operand" "n"))
8451           (const_int 0)))
8452    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453                          (const_int 8)
8454                          (const_int 8))
8455         (and:SI 
8456           (zero_extract:SI
8457             (match_dup 1)
8458             (const_int 8)
8459             (const_int 8))
8460           (match_dup 2)))]
8461   "ix86_match_ccmode (insn, CCNOmode)"
8462   "and{b}\t{%2, %h0|%h0, %2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "length_immediate" "1")
8465    (set_attr "mode" "QI")])
8466
8467 (define_insn "*andqi_ext_1"
8468   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469                          (const_int 8)
8470                          (const_int 8))
8471         (and:SI 
8472           (zero_extract:SI
8473             (match_operand 1 "ext_register_operand" "0")
8474             (const_int 8)
8475             (const_int 8))
8476           (zero_extend:SI
8477             (match_operand:QI 2 "general_operand" "Qm"))))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "!TARGET_64BIT"
8480   "and{b}\t{%2, %h0|%h0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "length_immediate" "0")
8483    (set_attr "mode" "QI")])
8484
8485 (define_insn "*andqi_ext_1_rex64"
8486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487                          (const_int 8)
8488                          (const_int 8))
8489         (and:SI 
8490           (zero_extract:SI
8491             (match_operand 1 "ext_register_operand" "0")
8492             (const_int 8)
8493             (const_int 8))
8494           (zero_extend:SI
8495             (match_operand 2 "ext_register_operand" "Q"))))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "TARGET_64BIT"
8498   "and{b}\t{%2, %h0|%h0, %2}"
8499   [(set_attr "type" "alu")
8500    (set_attr "length_immediate" "0")
8501    (set_attr "mode" "QI")])
8502
8503 (define_insn "*andqi_ext_2"
8504   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505                          (const_int 8)
8506                          (const_int 8))
8507         (and:SI
8508           (zero_extract:SI
8509             (match_operand 1 "ext_register_operand" "%0")
8510             (const_int 8)
8511             (const_int 8))
8512           (zero_extract:SI
8513             (match_operand 2 "ext_register_operand" "Q")
8514             (const_int 8)
8515             (const_int 8))))
8516    (clobber (reg:CC FLAGS_REG))]
8517   ""
8518   "and{b}\t{%h2, %h0|%h0, %h2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "length_immediate" "0")
8521    (set_attr "mode" "QI")])
8522
8523 ;; Convert wide AND instructions with immediate operand to shorter QImode
8524 ;; equivalents when possible.
8525 ;; Don't do the splitting with memory operands, since it introduces risk
8526 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8527 ;; for size, but that can (should?) be handled by generic code instead.
8528 (define_split
8529   [(set (match_operand 0 "register_operand" "")
8530         (and (match_operand 1 "register_operand" "")
8531              (match_operand 2 "const_int_operand" "")))
8532    (clobber (reg:CC FLAGS_REG))]
8533    "reload_completed
8534     && QI_REG_P (operands[0])
8535     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8536     && !(~INTVAL (operands[2]) & ~(255 << 8))
8537     && GET_MODE (operands[0]) != QImode"
8538   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8539                    (and:SI (zero_extract:SI (match_dup 1)
8540                                             (const_int 8) (const_int 8))
8541                            (match_dup 2)))
8542               (clobber (reg:CC FLAGS_REG))])]
8543   "operands[0] = gen_lowpart (SImode, operands[0]);
8544    operands[1] = gen_lowpart (SImode, operands[1]);
8545    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546
8547 ;; Since AND can be encoded with sign extended immediate, this is only
8548 ;; profitable when 7th bit is not set.
8549 (define_split
8550   [(set (match_operand 0 "register_operand" "")
8551         (and (match_operand 1 "general_operand" "")
8552              (match_operand 2 "const_int_operand" "")))
8553    (clobber (reg:CC FLAGS_REG))]
8554    "reload_completed
8555     && ANY_QI_REG_P (operands[0])
8556     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8557     && !(~INTVAL (operands[2]) & ~255)
8558     && !(INTVAL (operands[2]) & 128)
8559     && GET_MODE (operands[0]) != QImode"
8560   [(parallel [(set (strict_low_part (match_dup 0))
8561                    (and:QI (match_dup 1)
8562                            (match_dup 2)))
8563               (clobber (reg:CC FLAGS_REG))])]
8564   "operands[0] = gen_lowpart (QImode, operands[0]);
8565    operands[1] = gen_lowpart (QImode, operands[1]);
8566    operands[2] = gen_lowpart (QImode, operands[2]);")
8567 \f
8568 ;; Logical inclusive OR instructions
8569
8570 ;; %%% This used to optimize known byte-wide and operations to memory.
8571 ;; If this is considered useful, it should be done with splitters.
8572
8573 (define_expand "iordi3"
8574   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8575         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8576                 (match_operand:DI 2 "x86_64_general_operand" "")))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "TARGET_64BIT"
8579   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8580
8581 (define_insn "*iordi_1_rex64"
8582   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8583         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_64BIT
8587    && ix86_binary_operator_ok (IOR, DImode, operands)"
8588   "or{q}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "DI")])
8591
8592 (define_insn "*iordi_2_rex64"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8595                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8596                  (const_int 0)))
8597    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8598         (ior:DI (match_dup 1) (match_dup 2)))]
8599   "TARGET_64BIT
8600    && ix86_match_ccmode (insn, CCNOmode)
8601    && ix86_binary_operator_ok (IOR, DImode, operands)"
8602   "or{q}\t{%2, %0|%0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_3_rex64"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8609                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8610                  (const_int 0)))
8611    (clobber (match_scratch:DI 0 "=r"))]
8612   "TARGET_64BIT
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && ix86_binary_operator_ok (IOR, DImode, operands)"
8615   "or{q}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "DI")])
8618
8619
8620 (define_expand "iorsi3"
8621   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8622         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8623                 (match_operand:SI 2 "general_operand" "")))
8624    (clobber (reg:CC FLAGS_REG))]
8625   ""
8626   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8627
8628 (define_insn "*iorsi_1"
8629   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8630         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8631                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "ix86_binary_operator_ok (IOR, SImode, operands)"
8634   "or{l}\t{%2, %0|%0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "mode" "SI")])
8637
8638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8639 (define_insn "*iorsi_1_zext"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (zero_extend:DI
8642           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8643                   (match_operand:SI 2 "general_operand" "rim"))))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8646   "or{l}\t{%2, %k0|%k0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "SI")])
8649
8650 (define_insn "*iorsi_1_zext_imm"
8651   [(set (match_operand:DI 0 "register_operand" "=rm")
8652         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8653                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8654    (clobber (reg:CC FLAGS_REG))]
8655   "TARGET_64BIT"
8656   "or{l}\t{%2, %k0|%k0, %2}"
8657   [(set_attr "type" "alu")
8658    (set_attr "mode" "SI")])
8659
8660 (define_insn "*iorsi_2"
8661   [(set (reg FLAGS_REG)
8662         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8663                          (match_operand:SI 2 "general_operand" "rim,ri"))
8664                  (const_int 0)))
8665    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8666         (ior:SI (match_dup 1) (match_dup 2)))]
8667   "ix86_match_ccmode (insn, CCNOmode)
8668    && ix86_binary_operator_ok (IOR, SImode, operands)"
8669   "or{l}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 ;; ??? Special case for immediate operand is missing - it is tricky.
8675 (define_insn "*iorsi_2_zext"
8676   [(set (reg FLAGS_REG)
8677         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                          (match_operand:SI 2 "general_operand" "rim"))
8679                  (const_int 0)))
8680    (set (match_operand:DI 0 "register_operand" "=r")
8681         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8682   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8683    && ix86_binary_operator_ok (IOR, SImode, operands)"
8684   "or{l}\t{%2, %k0|%k0, %2}"
8685   [(set_attr "type" "alu")
8686    (set_attr "mode" "SI")])
8687
8688 (define_insn "*iorsi_2_zext_imm"
8689   [(set (reg FLAGS_REG)
8690         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8691                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8692                  (const_int 0)))
8693    (set (match_operand:DI 0 "register_operand" "=r")
8694         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8695   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8696    && ix86_binary_operator_ok (IOR, SImode, operands)"
8697   "or{l}\t{%2, %k0|%k0, %2}"
8698   [(set_attr "type" "alu")
8699    (set_attr "mode" "SI")])
8700
8701 (define_insn "*iorsi_3"
8702   [(set (reg FLAGS_REG)
8703         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704                          (match_operand:SI 2 "general_operand" "rim"))
8705                  (const_int 0)))
8706    (clobber (match_scratch:SI 0 "=r"))]
8707   "ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8709   "or{l}\t{%2, %0|%0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "SI")])
8712
8713 (define_expand "iorhi3"
8714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8715         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8716                 (match_operand:HI 2 "general_operand" "")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "TARGET_HIMODE_MATH"
8719   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8720
8721 (define_insn "*iorhi_1"
8722   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8723         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "ix86_binary_operator_ok (IOR, HImode, operands)"
8727   "or{w}\t{%2, %0|%0, %2}"
8728   [(set_attr "type" "alu")
8729    (set_attr "mode" "HI")])
8730
8731 (define_insn "*iorhi_2"
8732   [(set (reg FLAGS_REG)
8733         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8734                          (match_operand:HI 2 "general_operand" "rim,ri"))
8735                  (const_int 0)))
8736    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8737         (ior:HI (match_dup 1) (match_dup 2)))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && ix86_binary_operator_ok (IOR, HImode, operands)"
8740   "or{w}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "HI")])
8743
8744 (define_insn "*iorhi_3"
8745   [(set (reg FLAGS_REG)
8746         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8747                          (match_operand:HI 2 "general_operand" "rim"))
8748                  (const_int 0)))
8749    (clobber (match_scratch:HI 0 "=r"))]
8750   "ix86_match_ccmode (insn, CCNOmode)
8751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8752   "or{w}\t{%2, %0|%0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "HI")])
8755
8756 (define_expand "iorqi3"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8759                 (match_operand:QI 2 "general_operand" "")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "TARGET_QIMODE_MATH"
8762   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8763
8764 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8765 (define_insn "*iorqi_1"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8767         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8768                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "ix86_binary_operator_ok (IOR, QImode, operands)"
8771   "@
8772    or{b}\t{%2, %0|%0, %2}
8773    or{b}\t{%2, %0|%0, %2}
8774    or{l}\t{%k2, %k0|%k0, %k2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "QI,QI,SI")])
8777
8778 (define_insn "*iorqi_1_slp"
8779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8780         (ior:QI (match_dup 0)
8781                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785   "or{b}\t{%1, %0|%0, %1}"
8786   [(set_attr "type" "alu1")
8787    (set_attr "mode" "QI")])
8788
8789 (define_insn "*iorqi_2"
8790   [(set (reg FLAGS_REG)
8791         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8792                          (match_operand:QI 2 "general_operand" "qim,qi"))
8793                  (const_int 0)))
8794    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8795         (ior:QI (match_dup 1) (match_dup 2)))]
8796   "ix86_match_ccmode (insn, CCNOmode)
8797    && ix86_binary_operator_ok (IOR, QImode, operands)"
8798   "or{b}\t{%2, %0|%0, %2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "mode" "QI")])
8801
8802 (define_insn "*iorqi_2_slp"
8803   [(set (reg FLAGS_REG)
8804         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8805                          (match_operand:QI 1 "general_operand" "qim,qi"))
8806                  (const_int 0)))
8807    (set (strict_low_part (match_dup 0))
8808         (ior:QI (match_dup 0) (match_dup 1)))]
8809   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810    && ix86_match_ccmode (insn, CCNOmode)
8811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8812   "or{b}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "alu1")
8814    (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_3"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8819                          (match_operand:QI 2 "general_operand" "qim"))
8820                  (const_int 0)))
8821    (clobber (match_scratch:QI 0 "=q"))]
8822   "ix86_match_ccmode (insn, CCNOmode)
8823    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8824   "or{b}\t{%2, %0|%0, %2}"
8825   [(set_attr "type" "alu")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "iorqi_ext_0"
8829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830                          (const_int 8)
8831                          (const_int 8))
8832         (ior:SI 
8833           (zero_extract:SI
8834             (match_operand 1 "ext_register_operand" "0")
8835             (const_int 8)
8836             (const_int 8))
8837           (match_operand 2 "const_int_operand" "n")))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8840   "or{b}\t{%2, %h0|%h0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "length_immediate" "1")
8843    (set_attr "mode" "QI")])
8844
8845 (define_insn "*iorqi_ext_1"
8846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8847                          (const_int 8)
8848                          (const_int 8))
8849         (ior:SI 
8850           (zero_extract:SI
8851             (match_operand 1 "ext_register_operand" "0")
8852             (const_int 8)
8853             (const_int 8))
8854           (zero_extend:SI
8855             (match_operand:QI 2 "general_operand" "Qm"))))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "!TARGET_64BIT
8858    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8859   "or{b}\t{%2, %h0|%h0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "length_immediate" "0")
8862    (set_attr "mode" "QI")])
8863
8864 (define_insn "*iorqi_ext_1_rex64"
8865   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8866                          (const_int 8)
8867                          (const_int 8))
8868         (ior:SI 
8869           (zero_extract:SI
8870             (match_operand 1 "ext_register_operand" "0")
8871             (const_int 8)
8872             (const_int 8))
8873           (zero_extend:SI
8874             (match_operand 2 "ext_register_operand" "Q"))))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "TARGET_64BIT
8877    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8878   "or{b}\t{%2, %h0|%h0, %2}"
8879   [(set_attr "type" "alu")
8880    (set_attr "length_immediate" "0")
8881    (set_attr "mode" "QI")])
8882
8883 (define_insn "*iorqi_ext_2"
8884   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885                          (const_int 8)
8886                          (const_int 8))
8887         (ior:SI 
8888           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8889                            (const_int 8)
8890                            (const_int 8))
8891           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8892                            (const_int 8)
8893                            (const_int 8))))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896   "ior{b}\t{%h2, %h0|%h0, %h2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "length_immediate" "0")
8899    (set_attr "mode" "QI")])
8900
8901 (define_split
8902   [(set (match_operand 0 "register_operand" "")
8903         (ior (match_operand 1 "register_operand" "")
8904              (match_operand 2 "const_int_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906    "reload_completed
8907     && QI_REG_P (operands[0])
8908     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8909     && !(INTVAL (operands[2]) & ~(255 << 8))
8910     && GET_MODE (operands[0]) != QImode"
8911   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8912                    (ior:SI (zero_extract:SI (match_dup 1)
8913                                             (const_int 8) (const_int 8))
8914                            (match_dup 2)))
8915               (clobber (reg:CC FLAGS_REG))])]
8916   "operands[0] = gen_lowpart (SImode, operands[0]);
8917    operands[1] = gen_lowpart (SImode, operands[1]);
8918    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8919
8920 ;; Since OR can be encoded with sign extended immediate, this is only
8921 ;; profitable when 7th bit is set.
8922 (define_split
8923   [(set (match_operand 0 "register_operand" "")
8924         (ior (match_operand 1 "general_operand" "")
8925              (match_operand 2 "const_int_operand" "")))
8926    (clobber (reg:CC FLAGS_REG))]
8927    "reload_completed
8928     && ANY_QI_REG_P (operands[0])
8929     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8930     && !(INTVAL (operands[2]) & ~255)
8931     && (INTVAL (operands[2]) & 128)
8932     && GET_MODE (operands[0]) != QImode"
8933   [(parallel [(set (strict_low_part (match_dup 0))
8934                    (ior:QI (match_dup 1)
8935                            (match_dup 2)))
8936               (clobber (reg:CC FLAGS_REG))])]
8937   "operands[0] = gen_lowpart (QImode, operands[0]);
8938    operands[1] = gen_lowpart (QImode, operands[1]);
8939    operands[2] = gen_lowpart (QImode, operands[2]);")
8940 \f
8941 ;; Logical XOR instructions
8942
8943 ;; %%% This used to optimize known byte-wide and operations to memory.
8944 ;; If this is considered useful, it should be done with splitters.
8945
8946 (define_expand "xordi3"
8947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8948         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8949                 (match_operand:DI 2 "x86_64_general_operand" "")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_64BIT"
8952   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8953
8954 (define_insn "*xordi_1_rex64"
8955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8956         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8957                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "TARGET_64BIT
8960    && ix86_binary_operator_ok (XOR, DImode, operands)"
8961   "@
8962    xor{q}\t{%2, %0|%0, %2}
8963    xor{q}\t{%2, %0|%0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "mode" "DI,DI")])
8966
8967 (define_insn "*xordi_2_rex64"
8968   [(set (reg FLAGS_REG)
8969         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8970                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8971                  (const_int 0)))
8972    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8973         (xor:DI (match_dup 1) (match_dup 2)))]
8974   "TARGET_64BIT
8975    && ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (XOR, DImode, operands)"
8977   "@
8978    xor{q}\t{%2, %0|%0, %2}
8979    xor{q}\t{%2, %0|%0, %2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "DI,DI")])
8982
8983 (define_insn "*xordi_3_rex64"
8984   [(set (reg FLAGS_REG)
8985         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8987                  (const_int 0)))
8988    (clobber (match_scratch:DI 0 "=r"))]
8989   "TARGET_64BIT
8990    && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "xor{q}\t{%2, %0|%0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "DI")])
8995
8996 (define_expand "xorsi3"
8997   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8998         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8999                 (match_operand:SI 2 "general_operand" "")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   ""
9002   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9003
9004 (define_insn "*xorsi_1"
9005   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9006         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9007                 (match_operand:SI 2 "general_operand" "ri,rm")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "ix86_binary_operator_ok (XOR, SImode, operands)"
9010   "xor{l}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "SI")])
9013
9014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9015 ;; Add speccase for immediates
9016 (define_insn "*xorsi_1_zext"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (zero_extend:DI
9019           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020                   (match_operand:SI 2 "general_operand" "rim"))))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023   "xor{l}\t{%2, %k0|%k0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "SI")])
9026
9027 (define_insn "*xorsi_1_zext_imm"
9028   [(set (match_operand:DI 0 "register_operand" "=r")
9029         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9030                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9033   "xor{l}\t{%2, %k0|%k0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "SI")])
9036
9037 (define_insn "*xorsi_2"
9038   [(set (reg FLAGS_REG)
9039         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9040                          (match_operand:SI 2 "general_operand" "rim,ri"))
9041                  (const_int 0)))
9042    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9043         (xor:SI (match_dup 1) (match_dup 2)))]
9044   "ix86_match_ccmode (insn, CCNOmode)
9045    && ix86_binary_operator_ok (XOR, SImode, operands)"
9046   "xor{l}\t{%2, %0|%0, %2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "SI")])
9049
9050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9051 ;; ??? Special case for immediate operand is missing - it is tricky.
9052 (define_insn "*xorsi_2_zext"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:SI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (set (match_operand:DI 0 "register_operand" "=r")
9058         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9059   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9060    && ix86_binary_operator_ok (XOR, SImode, operands)"
9061   "xor{l}\t{%2, %k0|%k0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "SI")])
9064
9065 (define_insn "*xorsi_2_zext_imm"
9066   [(set (reg FLAGS_REG)
9067         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9068                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9069                  (const_int 0)))
9070    (set (match_operand:DI 0 "register_operand" "=r")
9071         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9072   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9073    && ix86_binary_operator_ok (XOR, SImode, operands)"
9074   "xor{l}\t{%2, %k0|%k0, %2}"
9075   [(set_attr "type" "alu")
9076    (set_attr "mode" "SI")])
9077
9078 (define_insn "*xorsi_3"
9079   [(set (reg FLAGS_REG)
9080         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081                          (match_operand:SI 2 "general_operand" "rim"))
9082                  (const_int 0)))
9083    (clobber (match_scratch:SI 0 "=r"))]
9084   "ix86_match_ccmode (insn, CCNOmode)
9085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9086   "xor{l}\t{%2, %0|%0, %2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "SI")])
9089
9090 (define_expand "xorhi3"
9091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9092         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9093                 (match_operand:HI 2 "general_operand" "")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "TARGET_HIMODE_MATH"
9096   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9097
9098 (define_insn "*xorhi_1"
9099   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9100         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "ix86_binary_operator_ok (XOR, HImode, operands)"
9104   "xor{w}\t{%2, %0|%0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "mode" "HI")])
9107
9108 (define_insn "*xorhi_2"
9109   [(set (reg FLAGS_REG)
9110         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9111                          (match_operand:HI 2 "general_operand" "rim,ri"))
9112                  (const_int 0)))
9113    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9114         (xor:HI (match_dup 1) (match_dup 2)))]
9115   "ix86_match_ccmode (insn, CCNOmode)
9116    && ix86_binary_operator_ok (XOR, HImode, operands)"
9117   "xor{w}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "HI")])
9120
9121 (define_insn "*xorhi_3"
9122   [(set (reg FLAGS_REG)
9123         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9124                          (match_operand:HI 2 "general_operand" "rim"))
9125                  (const_int 0)))
9126    (clobber (match_scratch:HI 0 "=r"))]
9127   "ix86_match_ccmode (insn, CCNOmode)
9128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9129   "xor{w}\t{%2, %0|%0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "HI")])
9132
9133 (define_expand "xorqi3"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9136                 (match_operand:QI 2 "general_operand" "")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "TARGET_QIMODE_MATH"
9139   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9140
9141 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9142 (define_insn "*xorqi_1"
9143   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9144         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "ix86_binary_operator_ok (XOR, QImode, operands)"
9148   "@
9149    xor{b}\t{%2, %0|%0, %2}
9150    xor{b}\t{%2, %0|%0, %2}
9151    xor{l}\t{%k2, %k0|%k0, %k2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "mode" "QI,QI,SI")])
9154
9155 (define_insn "*xorqi_1_slp"
9156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9157         (xor:QI (match_dup 0)
9158                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9159    (clobber (reg:CC FLAGS_REG))]
9160   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9162   "xor{b}\t{%1, %0|%0, %1}"
9163   [(set_attr "type" "alu1")
9164    (set_attr "mode" "QI")])
9165
9166 (define_insn "xorqi_ext_0"
9167   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9168                          (const_int 8)
9169                          (const_int 8))
9170         (xor:SI 
9171           (zero_extract:SI
9172             (match_operand 1 "ext_register_operand" "0")
9173             (const_int 8)
9174             (const_int 8))
9175           (match_operand 2 "const_int_operand" "n")))
9176    (clobber (reg:CC FLAGS_REG))]
9177   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9178   "xor{b}\t{%2, %h0|%h0, %2}"
9179   [(set_attr "type" "alu")
9180    (set_attr "length_immediate" "1")
9181    (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_ext_1"
9184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9185                          (const_int 8)
9186                          (const_int 8))
9187         (xor:SI 
9188           (zero_extract:SI
9189             (match_operand 1 "ext_register_operand" "0")
9190             (const_int 8)
9191             (const_int 8))
9192           (zero_extend:SI
9193             (match_operand:QI 2 "general_operand" "Qm"))))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "!TARGET_64BIT
9196    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9197   "xor{b}\t{%2, %h0|%h0, %2}"
9198   [(set_attr "type" "alu")
9199    (set_attr "length_immediate" "0")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_ext_1_rex64"
9203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9204                          (const_int 8)
9205                          (const_int 8))
9206         (xor:SI 
9207           (zero_extract:SI
9208             (match_operand 1 "ext_register_operand" "0")
9209             (const_int 8)
9210             (const_int 8))
9211           (zero_extend:SI
9212             (match_operand 2 "ext_register_operand" "Q"))))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "TARGET_64BIT
9215    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9216   "xor{b}\t{%2, %h0|%h0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "length_immediate" "0")
9219    (set_attr "mode" "QI")])
9220
9221 (define_insn "*xorqi_ext_2"
9222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223                          (const_int 8)
9224                          (const_int 8))
9225         (xor:SI 
9226           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9227                            (const_int 8)
9228                            (const_int 8))
9229           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9230                            (const_int 8)
9231                            (const_int 8))))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9234   "xor{b}\t{%h2, %h0|%h0, %h2}"
9235   [(set_attr "type" "alu")
9236    (set_attr "length_immediate" "0")
9237    (set_attr "mode" "QI")])
9238
9239 (define_insn "*xorqi_cc_1"
9240   [(set (reg FLAGS_REG)
9241         (compare
9242           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9243                   (match_operand:QI 2 "general_operand" "qim,qi"))
9244           (const_int 0)))
9245    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9246         (xor:QI (match_dup 1) (match_dup 2)))]
9247   "ix86_match_ccmode (insn, CCNOmode)
9248    && ix86_binary_operator_ok (XOR, QImode, operands)"
9249   "xor{b}\t{%2, %0|%0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_2_slp"
9254   [(set (reg FLAGS_REG)
9255         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9256                          (match_operand:QI 1 "general_operand" "qim,qi"))
9257                  (const_int 0)))
9258    (set (strict_low_part (match_dup 0))
9259         (xor:QI (match_dup 0) (match_dup 1)))]
9260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9261    && ix86_match_ccmode (insn, CCNOmode)
9262    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9263   "xor{b}\t{%1, %0|%0, %1}"
9264   [(set_attr "type" "alu1")
9265    (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_cc_2"
9268   [(set (reg FLAGS_REG)
9269         (compare
9270           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9271                   (match_operand:QI 2 "general_operand" "qim"))
9272           (const_int 0)))
9273    (clobber (match_scratch:QI 0 "=q"))]
9274   "ix86_match_ccmode (insn, CCNOmode)
9275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9276   "xor{b}\t{%2, %0|%0, %2}"
9277   [(set_attr "type" "alu")
9278    (set_attr "mode" "QI")])
9279
9280 (define_insn "*xorqi_cc_ext_1"
9281   [(set (reg FLAGS_REG)
9282         (compare
9283           (xor:SI
9284             (zero_extract:SI
9285               (match_operand 1 "ext_register_operand" "0")
9286               (const_int 8)
9287               (const_int 8))
9288             (match_operand:QI 2 "general_operand" "qmn"))
9289           (const_int 0)))
9290    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9291                          (const_int 8)
9292                          (const_int 8))
9293         (xor:SI 
9294           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9295           (match_dup 2)))]
9296   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9297   "xor{b}\t{%2, %h0|%h0, %2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "mode" "QI")])
9300
9301 (define_insn "*xorqi_cc_ext_1_rex64"
9302   [(set (reg FLAGS_REG)
9303         (compare
9304           (xor:SI
9305             (zero_extract:SI
9306               (match_operand 1 "ext_register_operand" "0")
9307               (const_int 8)
9308               (const_int 8))
9309             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9310           (const_int 0)))
9311    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9312                          (const_int 8)
9313                          (const_int 8))
9314         (xor:SI 
9315           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316           (match_dup 2)))]
9317   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9318   "xor{b}\t{%2, %h0|%h0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "QI")])
9321
9322 (define_expand "xorqi_cc_ext_1"
9323   [(parallel [
9324      (set (reg:CCNO FLAGS_REG)
9325           (compare:CCNO
9326             (xor:SI
9327               (zero_extract:SI
9328                 (match_operand 1 "ext_register_operand" "")
9329                 (const_int 8)
9330                 (const_int 8))
9331               (match_operand:QI 2 "general_operand" ""))
9332             (const_int 0)))
9333      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9334                            (const_int 8)
9335                            (const_int 8))
9336           (xor:SI 
9337             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9338             (match_dup 2)))])]
9339   ""
9340   "")
9341
9342 (define_split
9343   [(set (match_operand 0 "register_operand" "")
9344         (xor (match_operand 1 "register_operand" "")
9345              (match_operand 2 "const_int_operand" "")))
9346    (clobber (reg:CC FLAGS_REG))]
9347    "reload_completed
9348     && QI_REG_P (operands[0])
9349     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9350     && !(INTVAL (operands[2]) & ~(255 << 8))
9351     && GET_MODE (operands[0]) != QImode"
9352   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9353                    (xor:SI (zero_extract:SI (match_dup 1)
9354                                             (const_int 8) (const_int 8))
9355                            (match_dup 2)))
9356               (clobber (reg:CC FLAGS_REG))])]
9357   "operands[0] = gen_lowpart (SImode, operands[0]);
9358    operands[1] = gen_lowpart (SImode, operands[1]);
9359    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9360
9361 ;; Since XOR can be encoded with sign extended immediate, this is only
9362 ;; profitable when 7th bit is set.
9363 (define_split
9364   [(set (match_operand 0 "register_operand" "")
9365         (xor (match_operand 1 "general_operand" "")
9366              (match_operand 2 "const_int_operand" "")))
9367    (clobber (reg:CC FLAGS_REG))]
9368    "reload_completed
9369     && ANY_QI_REG_P (operands[0])
9370     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9371     && !(INTVAL (operands[2]) & ~255)
9372     && (INTVAL (operands[2]) & 128)
9373     && GET_MODE (operands[0]) != QImode"
9374   [(parallel [(set (strict_low_part (match_dup 0))
9375                    (xor:QI (match_dup 1)
9376                            (match_dup 2)))
9377               (clobber (reg:CC FLAGS_REG))])]
9378   "operands[0] = gen_lowpart (QImode, operands[0]);
9379    operands[1] = gen_lowpart (QImode, operands[1]);
9380    operands[2] = gen_lowpart (QImode, operands[2]);")
9381 \f
9382 ;; Negation instructions
9383
9384 (define_expand "negdi2"
9385   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9390
9391 (define_insn "*negdi2_1"
9392   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9393         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "!TARGET_64BIT
9396    && ix86_unary_operator_ok (NEG, DImode, operands)"
9397   "#")
9398
9399 (define_split
9400   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9401         (neg:DI (match_operand:DI 1 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "!TARGET_64BIT && reload_completed"
9404   [(parallel
9405     [(set (reg:CCZ FLAGS_REG)
9406           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9407      (set (match_dup 0) (neg:SI (match_dup 2)))])
9408    (parallel
9409     [(set (match_dup 1)
9410           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9411                             (match_dup 3))
9412                    (const_int 0)))
9413      (clobber (reg:CC FLAGS_REG))])
9414    (parallel
9415     [(set (match_dup 1)
9416           (neg:SI (match_dup 1)))
9417      (clobber (reg:CC FLAGS_REG))])]
9418   "split_di (operands+1, 1, operands+2, operands+3);
9419    split_di (operands+0, 1, operands+0, operands+1);")
9420
9421 (define_insn "*negdi2_1_rex64"
9422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9423         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426   "neg{q}\t%0"
9427   [(set_attr "type" "negnot")
9428    (set_attr "mode" "DI")])
9429
9430 ;; The problem with neg is that it does not perform (compare x 0),
9431 ;; it really performs (compare 0 x), which leaves us with the zero
9432 ;; flag being the only useful item.
9433
9434 (define_insn "*negdi2_cmpz_rex64"
9435   [(set (reg:CCZ FLAGS_REG)
9436         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9437                      (const_int 0)))
9438    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9439         (neg:DI (match_dup 1)))]
9440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9441   "neg{q}\t%0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "DI")])
9444
9445
9446 (define_expand "negsi2"
9447   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9448                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9449               (clobber (reg:CC FLAGS_REG))])]
9450   ""
9451   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9452
9453 (define_insn "*negsi2_1"
9454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 ;; Combine is quite creative about this pattern.
9463 (define_insn "*negsi2_1_zext"
9464   [(set (match_operand:DI 0 "register_operand" "=r")
9465         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9466                                         (const_int 32)))
9467                      (const_int 32)))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9470   "neg{l}\t%k0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "SI")])
9473
9474 ;; The problem with neg is that it does not perform (compare x 0),
9475 ;; it really performs (compare 0 x), which leaves us with the zero
9476 ;; flag being the only useful item.
9477
9478 (define_insn "*negsi2_cmpz"
9479   [(set (reg:CCZ FLAGS_REG)
9480         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9481                      (const_int 0)))
9482    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_dup 1)))]
9484   "ix86_unary_operator_ok (NEG, SImode, operands)"
9485   "neg{l}\t%0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "SI")])
9488
9489 (define_insn "*negsi2_cmpz_zext"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (lshiftrt:DI
9492                        (neg:DI (ashift:DI
9493                                  (match_operand:DI 1 "register_operand" "0")
9494                                  (const_int 32)))
9495                        (const_int 32))
9496                      (const_int 0)))
9497    (set (match_operand:DI 0 "register_operand" "=r")
9498         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9499                                         (const_int 32)))
9500                      (const_int 32)))]
9501   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9502   "neg{l}\t%k0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "SI")])
9505
9506 (define_expand "neghi2"
9507   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9508                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_HIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9512
9513 (define_insn "*neghi2_1"
9514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
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_insn "*neghi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9527         (neg:HI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, HImode, operands)"
9529   "neg{w}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "HI")])
9532
9533 (define_expand "negqi2"
9534   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9535                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9536               (clobber (reg:CC FLAGS_REG))])]
9537   "TARGET_QIMODE_MATH"
9538   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9539
9540 (define_insn "*negqi2_1"
9541   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9543    (clobber (reg:CC FLAGS_REG))]
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 (define_insn "*negqi2_cmpz"
9550   [(set (reg:CCZ FLAGS_REG)
9551         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9552                      (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9554         (neg:QI (match_dup 1)))]
9555   "ix86_unary_operator_ok (NEG, QImode, operands)"
9556   "neg{b}\t%0"
9557   [(set_attr "type" "negnot")
9558    (set_attr "mode" "QI")])
9559
9560 ;; Changing of sign for FP values is doable using integer unit too.
9561
9562 (define_expand "negsf2"
9563   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9564                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9565               (clobber (reg:CC FLAGS_REG))])]
9566   "TARGET_80387"
9567   "if (TARGET_SSE)
9568      {
9569        /* In case operand is in memory,  we will not use SSE.  */
9570        if (memory_operand (operands[0], VOIDmode)
9571            && rtx_equal_p (operands[0], operands[1]))
9572          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9573        else
9574         {
9575           /* Using SSE is tricky, since we need bitwise negation of -0
9576              in register.  */
9577           rtx reg = gen_reg_rtx (SFmode);
9578           rtx dest = operands[0];
9579           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9580
9581           operands[1] = force_reg (SFmode, operands[1]);
9582           operands[0] = force_reg (SFmode, operands[0]);
9583           reg = force_reg (V4SFmode,
9584                            gen_rtx_CONST_VECTOR (V4SFmode,
9585                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9586                                         CONST0_RTX (SFmode),
9587                                         CONST0_RTX (SFmode))));
9588           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9589           if (dest != operands[0])
9590             emit_move_insn (dest, operands[0]);
9591         }
9592        DONE;
9593      }
9594    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9595
9596 (define_insn "negsf2_memory"
9597   [(set (match_operand:SF 0 "memory_operand" "=m")
9598         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9601   "#")
9602
9603 (define_insn "negsf2_ifs"
9604   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9605         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9606    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "TARGET_SSE
9609    && (reload_in_progress || reload_completed
9610        || (register_operand (operands[0], VOIDmode)
9611            && register_operand (operands[1], VOIDmode)))"
9612   "#")
9613
9614 (define_split
9615   [(set (match_operand:SF 0 "memory_operand" "")
9616         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9617    (use (match_operand:SF 2 "" ""))
9618    (clobber (reg:CC FLAGS_REG))]
9619   ""
9620   [(parallel [(set (match_dup 0)
9621                    (neg:SF (match_dup 1)))
9622               (clobber (reg:CC FLAGS_REG))])])
9623
9624 (define_split
9625   [(set (match_operand:SF 0 "register_operand" "")
9626         (neg:SF (match_operand:SF 1 "register_operand" "")))
9627    (use (match_operand:V4SF 2 "" ""))
9628    (clobber (reg:CC FLAGS_REG))]
9629   "reload_completed && !SSE_REG_P (operands[0])"
9630   [(parallel [(set (match_dup 0)
9631                    (neg:SF (match_dup 1)))
9632               (clobber (reg:CC FLAGS_REG))])])
9633
9634 (define_split
9635   [(set (match_operand:SF 0 "register_operand" "")
9636         (neg:SF (match_operand:SF 1 "register_operand" "")))
9637    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "reload_completed && SSE_REG_P (operands[0])"
9640   [(set (match_dup 0)
9641         (xor:V4SF (match_dup 1)
9642                   (match_dup 2)))]
9643 {
9644   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9645   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9646   if (operands_match_p (operands[0], operands[2]))
9647     {
9648       rtx tmp;
9649       tmp = operands[1];
9650       operands[1] = operands[2];
9651       operands[2] = tmp;
9652     }
9653 })
9654
9655
9656 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9657 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9658 ;; to itself.
9659 (define_insn "*negsf2_if"
9660   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9661         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "TARGET_80387 && !TARGET_SSE
9664    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9665   "#")
9666
9667 (define_split
9668   [(set (match_operand:SF 0 "fp_register_operand" "")
9669         (neg:SF (match_operand:SF 1 "register_operand" "")))
9670    (clobber (reg:CC FLAGS_REG))]
9671   "TARGET_80387 && reload_completed"
9672   [(set (match_dup 0)
9673         (neg:SF (match_dup 1)))]
9674   "")
9675
9676 (define_split
9677   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9678         (neg:SF (match_operand:SF 1 "register_operand" "")))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "TARGET_80387 && reload_completed"
9681   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9682               (clobber (reg:CC FLAGS_REG))])]
9683   "operands[1] = gen_int_mode (0x80000000, SImode);
9684    operands[0] = gen_lowpart (SImode, operands[0]);")
9685
9686 (define_split
9687   [(set (match_operand 0 "memory_operand" "")
9688         (neg (match_operand 1 "memory_operand" "")))
9689    (clobber (reg:CC FLAGS_REG))]
9690   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9691   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9692               (clobber (reg:CC FLAGS_REG))])]
9693 {
9694   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9695
9696   if (GET_MODE (operands[1]) == XFmode)
9697     size = 10;
9698   operands[0] = adjust_address (operands[0], QImode, size - 1);
9699   operands[1] = gen_int_mode (0x80, QImode);
9700 })
9701
9702 (define_expand "negdf2"
9703   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9704                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9705               (clobber (reg:CC FLAGS_REG))])]
9706   "TARGET_80387"
9707   "if (TARGET_SSE2)
9708      {
9709        /* In case operand is in memory,  we will not use SSE.  */
9710        if (memory_operand (operands[0], VOIDmode)
9711            && rtx_equal_p (operands[0], operands[1]))
9712          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9713        else
9714         {
9715           /* Using SSE is tricky, since we need bitwise negation of -0
9716              in register.  */
9717           rtx reg;
9718 #if HOST_BITS_PER_WIDE_INT >= 64
9719           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9720 #else
9721           rtx imm = immed_double_const (0, 0x80000000, DImode);
9722 #endif
9723           rtx dest = operands[0];
9724
9725           operands[1] = force_reg (DFmode, operands[1]);
9726           operands[0] = force_reg (DFmode, operands[0]);
9727           imm = gen_lowpart (DFmode, imm);
9728           reg = force_reg (V2DFmode,
9729                            gen_rtx_CONST_VECTOR (V2DFmode,
9730                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9731           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9732           if (dest != operands[0])
9733             emit_move_insn (dest, operands[0]);
9734         }
9735        DONE;
9736      }
9737    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9738
9739 (define_insn "negdf2_memory"
9740   [(set (match_operand:DF 0 "memory_operand" "=m")
9741         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9744   "#")
9745
9746 (define_insn "negdf2_ifs"
9747   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9748         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9749    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "!TARGET_64BIT && TARGET_SSE2
9752    && (reload_in_progress || reload_completed
9753        || (register_operand (operands[0], VOIDmode)
9754            && register_operand (operands[1], VOIDmode)))"
9755   "#")
9756
9757 (define_insn "*negdf2_ifs_rex64"
9758   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9759         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9760    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "TARGET_64BIT && TARGET_SSE2
9763    && (reload_in_progress || reload_completed
9764        || (register_operand (operands[0], VOIDmode)
9765            && register_operand (operands[1], VOIDmode)))"
9766   "#")
9767
9768 (define_split
9769   [(set (match_operand:DF 0 "memory_operand" "")
9770         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9771    (use (match_operand:V2DF 2 "" ""))
9772    (clobber (reg:CC FLAGS_REG))]
9773   ""
9774   [(parallel [(set (match_dup 0)
9775                    (neg:DF (match_dup 1)))
9776               (clobber (reg:CC FLAGS_REG))])])
9777
9778 (define_split
9779   [(set (match_operand:DF 0 "register_operand" "")
9780         (neg:DF (match_operand:DF 1 "register_operand" "")))
9781    (use (match_operand:V2DF 2 "" ""))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "reload_completed && !SSE_REG_P (operands[0])
9784    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9785   [(parallel [(set (match_dup 0)
9786                    (neg:DF (match_dup 1)))
9787               (clobber (reg:CC FLAGS_REG))])])
9788
9789 (define_split
9790   [(set (match_operand:DF 0 "register_operand" "")
9791         (neg:DF (match_operand:DF 1 "register_operand" "")))
9792    (use (match_operand:V2DF 2 "" ""))
9793    (clobber (reg:CC FLAGS_REG))]
9794   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9795   [(parallel [(set (match_dup 0)
9796                    (xor:DI (match_dup 1) (match_dup 2)))
9797               (clobber (reg:CC FLAGS_REG))])]
9798    "operands[0] = gen_lowpart (DImode, operands[0]);
9799     operands[1] = gen_lowpart (DImode, operands[1]);
9800     operands[2] = gen_lowpart (DImode, operands[2]);")
9801
9802 (define_split
9803   [(set (match_operand:DF 0 "register_operand" "")
9804         (neg:DF (match_operand:DF 1 "register_operand" "")))
9805    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "reload_completed && SSE_REG_P (operands[0])"
9808   [(set (match_dup 0)
9809         (xor:V2DF (match_dup 1)
9810                   (match_dup 2)))]
9811 {
9812   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9813   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9814   /* Avoid possible reformatting on the operands.  */
9815   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9816     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9817   if (operands_match_p (operands[0], operands[2]))
9818     {
9819       rtx tmp;
9820       tmp = operands[1];
9821       operands[1] = operands[2];
9822       operands[2] = tmp;
9823     }
9824 })
9825
9826 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9827 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9828 ;; to itself.
9829 (define_insn "*negdf2_if"
9830   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9831         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9832    (clobber (reg:CC FLAGS_REG))]
9833   "!TARGET_64BIT && TARGET_80387
9834    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9835   "#")
9836
9837 ;; FIXME: We should to allow integer registers here.  Problem is that
9838 ;; we need another scratch register to get constant from.
9839 ;; Forcing constant to mem if no register available in peep2 should be
9840 ;; safe even for PIC mode, because of RIP relative addressing.
9841 (define_insn "*negdf2_if_rex64"
9842   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9843         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "TARGET_64BIT && TARGET_80387
9846    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9847   "#")
9848
9849 (define_split
9850   [(set (match_operand:DF 0 "fp_register_operand" "")
9851         (neg:DF (match_operand:DF 1 "register_operand" "")))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "TARGET_80387 && reload_completed"
9854   [(set (match_dup 0)
9855         (neg:DF (match_dup 1)))]
9856   "")
9857
9858 (define_split
9859   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9860         (neg:DF (match_operand:DF 1 "register_operand" "")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9863   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9864               (clobber (reg:CC FLAGS_REG))])]
9865   "operands[4] = gen_int_mode (0x80000000, SImode);
9866    split_di (operands+0, 1, operands+2, operands+3);")
9867
9868 (define_expand "negxf2"
9869   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9870                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9871               (clobber (reg:CC FLAGS_REG))])]
9872   "TARGET_80387"
9873   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9874
9875 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9876 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9877 ;; to itself.
9878 (define_insn "*negxf2_if"
9879   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9880         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9881    (clobber (reg:CC FLAGS_REG))]
9882   "TARGET_80387
9883    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9884   "#")
9885
9886 (define_split
9887   [(set (match_operand:XF 0 "fp_register_operand" "")
9888         (neg:XF (match_operand:XF 1 "register_operand" "")))
9889    (clobber (reg:CC FLAGS_REG))]
9890   "TARGET_80387 && reload_completed"
9891   [(set (match_dup 0)
9892         (neg:XF (match_dup 1)))]
9893   "")
9894
9895 (define_split
9896   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9897         (neg:XF (match_operand:XF 1 "register_operand" "")))
9898    (clobber (reg:CC FLAGS_REG))]
9899   "TARGET_80387 && reload_completed"
9900   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9901               (clobber (reg:CC FLAGS_REG))])]
9902   "operands[1] = GEN_INT (0x8000);
9903    operands[0] = gen_rtx_REG (SImode,
9904                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9905
9906 ;; Conditionalize these after reload. If they matches before reload, we 
9907 ;; lose the clobber and ability to use integer instructions.
9908
9909 (define_insn "*negsf2_1"
9910   [(set (match_operand:SF 0 "register_operand" "=f")
9911         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9912   "TARGET_80387 && reload_completed"
9913   "fchs"
9914   [(set_attr "type" "fsgn")
9915    (set_attr "mode" "SF")])
9916
9917 (define_insn "*negdf2_1"
9918   [(set (match_operand:DF 0 "register_operand" "=f")
9919         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9920   "TARGET_80387 && reload_completed"
9921   "fchs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "DF")])
9924
9925 (define_insn "*negextendsfdf2"
9926   [(set (match_operand:DF 0 "register_operand" "=f")
9927         (neg:DF (float_extend:DF
9928                   (match_operand:SF 1 "register_operand" "0"))))]
9929   "TARGET_80387"
9930   "fchs"
9931   [(set_attr "type" "fsgn")
9932    (set_attr "mode" "DF")])
9933
9934 (define_insn "*negxf2_1"
9935   [(set (match_operand:XF 0 "register_operand" "=f")
9936         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9937   "TARGET_80387 && reload_completed"
9938   "fchs"
9939   [(set_attr "type" "fsgn")
9940    (set_attr "mode" "XF")])
9941
9942 (define_insn "*negextenddfxf2"
9943   [(set (match_operand:XF 0 "register_operand" "=f")
9944         (neg:XF (float_extend:XF
9945                   (match_operand:DF 1 "register_operand" "0"))))]
9946   "TARGET_80387"
9947   "fchs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "XF")])
9950
9951 (define_insn "*negextendsfxf2"
9952   [(set (match_operand:XF 0 "register_operand" "=f")
9953         (neg:XF (float_extend:XF
9954                   (match_operand:SF 1 "register_operand" "0"))))]
9955   "TARGET_80387"
9956   "fchs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "XF")])
9959 \f
9960 ;; Absolute value instructions
9961
9962 (define_expand "abssf2"
9963   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9964                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9965               (clobber (reg:CC FLAGS_REG))])]
9966   "TARGET_80387"
9967   "if (TARGET_SSE)
9968      {
9969        /* In case operand is in memory,  we will not use SSE.  */
9970        if (memory_operand (operands[0], VOIDmode)
9971            && rtx_equal_p (operands[0], operands[1]))
9972          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9973        else
9974         {
9975           /* Using SSE is tricky, since we need bitwise negation of -0
9976              in register.  */
9977           rtx reg = gen_reg_rtx (V4SFmode);
9978           rtx dest = operands[0];
9979           rtx imm;
9980
9981           operands[1] = force_reg (SFmode, operands[1]);
9982           operands[0] = force_reg (SFmode, operands[0]);
9983           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9984           reg = force_reg (V4SFmode,
9985                            gen_rtx_CONST_VECTOR (V4SFmode,
9986                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9987                                       CONST0_RTX (SFmode),
9988                                       CONST0_RTX (SFmode))));
9989           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9990           if (dest != operands[0])
9991             emit_move_insn (dest, operands[0]);
9992         }
9993        DONE;
9994      }
9995    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9996
9997 (define_insn "abssf2_memory"
9998   [(set (match_operand:SF 0 "memory_operand" "=m")
9999         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10000    (clobber (reg:CC FLAGS_REG))]
10001   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10002   "#")
10003
10004 (define_insn "abssf2_ifs"
10005   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10006         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10007    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10008    (clobber (reg:CC FLAGS_REG))]
10009   "TARGET_SSE
10010    && (reload_in_progress || reload_completed
10011        || (register_operand (operands[0], VOIDmode)
10012             && register_operand (operands[1], VOIDmode)))"
10013   "#")
10014
10015 (define_split
10016   [(set (match_operand:SF 0 "memory_operand" "")
10017         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10018    (use (match_operand:V4SF 2 "" ""))
10019    (clobber (reg:CC FLAGS_REG))]
10020   ""
10021   [(parallel [(set (match_dup 0)
10022                    (abs:SF (match_dup 1)))
10023               (clobber (reg:CC FLAGS_REG))])])
10024
10025 (define_split
10026   [(set (match_operand:SF 0 "register_operand" "")
10027         (abs:SF (match_operand:SF 1 "register_operand" "")))
10028    (use (match_operand:V4SF 2 "" ""))
10029    (clobber (reg:CC FLAGS_REG))]
10030   "reload_completed && !SSE_REG_P (operands[0])"
10031   [(parallel [(set (match_dup 0)
10032                    (abs:SF (match_dup 1)))
10033               (clobber (reg:CC FLAGS_REG))])])
10034
10035 (define_split
10036   [(set (match_operand:SF 0 "register_operand" "")
10037         (abs:SF (match_operand:SF 1 "register_operand" "")))
10038    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10039    (clobber (reg:CC FLAGS_REG))]
10040   "reload_completed && SSE_REG_P (operands[0])"
10041   [(set (match_dup 0)
10042         (and:V4SF (match_dup 1)
10043                   (match_dup 2)))]
10044 {
10045   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10046   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10047   if (operands_match_p (operands[0], operands[2]))
10048     {
10049       rtx tmp;
10050       tmp = operands[1];
10051       operands[1] = operands[2];
10052       operands[2] = tmp;
10053     }
10054 })
10055
10056 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10057 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10058 ;; to itself.
10059 (define_insn "*abssf2_if"
10060   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10061         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10062    (clobber (reg:CC FLAGS_REG))]
10063   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10064   "#")
10065
10066 (define_split
10067   [(set (match_operand:SF 0 "fp_register_operand" "")
10068         (abs:SF (match_operand:SF 1 "register_operand" "")))
10069    (clobber (reg:CC FLAGS_REG))]
10070   "TARGET_80387 && reload_completed"
10071   [(set (match_dup 0)
10072         (abs:SF (match_dup 1)))]
10073   "")
10074
10075 (define_split
10076   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10077         (abs:SF (match_operand:SF 1 "register_operand" "")))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "TARGET_80387 && reload_completed"
10080   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10081               (clobber (reg:CC FLAGS_REG))])]
10082   "operands[1] = gen_int_mode (~0x80000000, SImode);
10083    operands[0] = gen_lowpart (SImode, operands[0]);")
10084
10085 (define_split
10086   [(set (match_operand 0 "memory_operand" "")
10087         (abs (match_operand 1 "memory_operand" "")))
10088    (clobber (reg:CC FLAGS_REG))]
10089   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10090   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10091               (clobber (reg:CC FLAGS_REG))])]
10092 {
10093   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10094
10095   if (GET_MODE (operands[1]) == XFmode)
10096     size = 10;
10097   operands[0] = adjust_address (operands[0], QImode, size - 1);
10098   operands[1] = gen_int_mode (~0x80, QImode);
10099 })
10100
10101 (define_expand "absdf2"
10102   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10103                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10104               (clobber (reg:CC FLAGS_REG))])]
10105   "TARGET_80387"
10106   "if (TARGET_SSE2)
10107      {
10108        /* In case operand is in memory,  we will not use SSE.  */
10109        if (memory_operand (operands[0], VOIDmode)
10110            && rtx_equal_p (operands[0], operands[1]))
10111          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10112        else
10113         {
10114           /* Using SSE is tricky, since we need bitwise negation of -0
10115              in register.  */
10116           rtx reg = gen_reg_rtx (V2DFmode);
10117 #if HOST_BITS_PER_WIDE_INT >= 64
10118           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10119 #else
10120           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10121 #endif
10122           rtx dest = operands[0];
10123
10124           operands[1] = force_reg (DFmode, operands[1]);
10125           operands[0] = force_reg (DFmode, operands[0]);
10126
10127           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10128           imm = gen_lowpart (DFmode, imm);
10129           reg = force_reg (V2DFmode,
10130                            gen_rtx_CONST_VECTOR (V2DFmode,
10131                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10132           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10133           if (dest != operands[0])
10134             emit_move_insn (dest, operands[0]);
10135         }
10136        DONE;
10137      }
10138    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10139
10140 (define_insn "absdf2_memory"
10141   [(set (match_operand:DF 0 "memory_operand" "=m")
10142         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10145   "#")
10146
10147 (define_insn "absdf2_ifs"
10148   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10149         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10150    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10151    (clobber (reg:CC FLAGS_REG))]
10152   "!TARGET_64BIT && TARGET_SSE2
10153    && (reload_in_progress || reload_completed
10154        || (register_operand (operands[0], VOIDmode)
10155            && register_operand (operands[1], VOIDmode)))"
10156   "#")
10157
10158 (define_insn "*absdf2_ifs_rex64"
10159   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10160         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10161    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10162    (clobber (reg:CC FLAGS_REG))]
10163   "TARGET_64BIT && TARGET_SSE2
10164    && (reload_in_progress || reload_completed
10165        || (register_operand (operands[0], VOIDmode)
10166            && register_operand (operands[1], VOIDmode)))"
10167   "#")
10168
10169 (define_split
10170   [(set (match_operand:DF 0 "memory_operand" "")
10171         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10172    (use (match_operand:V2DF 2 "" ""))
10173    (clobber (reg:CC FLAGS_REG))]
10174   ""
10175   [(parallel [(set (match_dup 0)
10176                    (abs:DF (match_dup 1)))
10177               (clobber (reg:CC FLAGS_REG))])])
10178
10179 (define_split
10180   [(set (match_operand:DF 0 "register_operand" "")
10181         (abs:DF (match_operand:DF 1 "register_operand" "")))
10182    (use (match_operand:V2DF 2 "" ""))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "reload_completed && !SSE_REG_P (operands[0])"
10185   [(parallel [(set (match_dup 0)
10186                    (abs:DF (match_dup 1)))
10187               (clobber (reg:CC FLAGS_REG))])])
10188
10189 (define_split
10190   [(set (match_operand:DF 0 "register_operand" "")
10191         (abs:DF (match_operand:DF 1 "register_operand" "")))
10192    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10193    (clobber (reg:CC FLAGS_REG))]
10194   "reload_completed && SSE_REG_P (operands[0])"
10195   [(set (match_dup 0)
10196         (and:V2DF (match_dup 1)
10197                   (match_dup 2)))]
10198 {
10199   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10200   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10201   /* Avoid possible reformatting on the operands.  */
10202   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10203     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10204   if (operands_match_p (operands[0], operands[2]))
10205     {
10206       rtx tmp;
10207       tmp = operands[1];
10208       operands[1] = operands[2];
10209       operands[2] = tmp;
10210     }
10211 })
10212
10213
10214 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10215 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10216 ;; to itself.
10217 (define_insn "*absdf2_if"
10218   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10219         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "!TARGET_64BIT && TARGET_80387
10222    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10223   "#")
10224
10225 ;; FIXME: We should to allow integer registers here.  Problem is that
10226 ;; we need another scratch register to get constant from.
10227 ;; Forcing constant to mem if no register available in peep2 should be
10228 ;; safe even for PIC mode, because of RIP relative addressing.
10229 (define_insn "*absdf2_if_rex64"
10230   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10231         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10232    (clobber (reg:CC FLAGS_REG))]
10233   "TARGET_64BIT && TARGET_80387
10234    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10235   "#")
10236
10237 (define_split
10238   [(set (match_operand:DF 0 "fp_register_operand" "")
10239         (abs:DF (match_operand:DF 1 "register_operand" "")))
10240    (clobber (reg:CC FLAGS_REG))]
10241   "TARGET_80387 && reload_completed"
10242   [(set (match_dup 0)
10243         (abs:DF (match_dup 1)))]
10244   "")
10245
10246 (define_split
10247   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10248         (abs:DF (match_operand:DF 1 "register_operand" "")))
10249    (clobber (reg:CC FLAGS_REG))]
10250   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10251   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10252               (clobber (reg:CC FLAGS_REG))])]
10253   "operands[4] = gen_int_mode (~0x80000000, SImode);
10254    split_di (operands+0, 1, operands+2, operands+3);")
10255
10256 (define_expand "absxf2"
10257   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10258                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10259               (clobber (reg:CC FLAGS_REG))])]
10260   "TARGET_80387"
10261   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10262
10263 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10264 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10265 ;; to itself.
10266 (define_insn "*absxf2_if"
10267   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10268         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10269    (clobber (reg:CC FLAGS_REG))]
10270   "TARGET_80387
10271    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10272   "#")
10273
10274 (define_split
10275   [(set (match_operand:XF 0 "fp_register_operand" "")
10276         (abs:XF (match_operand:XF 1 "register_operand" "")))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_80387 && reload_completed"
10279   [(set (match_dup 0)
10280         (abs:XF (match_dup 1)))]
10281   "")
10282
10283 (define_split
10284   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10285         (abs:XF (match_operand:XF 1 "register_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "TARGET_80387 && reload_completed"
10288   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10289               (clobber (reg:CC FLAGS_REG))])]
10290   "operands[1] = GEN_INT (~0x8000);
10291    operands[0] = gen_rtx_REG (SImode,
10292                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10293
10294 (define_insn "*abssf2_1"
10295   [(set (match_operand:SF 0 "register_operand" "=f")
10296         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10297   "TARGET_80387 && reload_completed"
10298   "fabs"
10299   [(set_attr "type" "fsgn")
10300    (set_attr "mode" "SF")])
10301
10302 (define_insn "*absdf2_1"
10303   [(set (match_operand:DF 0 "register_operand" "=f")
10304         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10305   "TARGET_80387 && reload_completed"
10306   "fabs"
10307   [(set_attr "type" "fsgn")
10308    (set_attr "mode" "DF")])
10309
10310 (define_insn "*absextendsfdf2"
10311   [(set (match_operand:DF 0 "register_operand" "=f")
10312         (abs:DF (float_extend:DF
10313                   (match_operand:SF 1 "register_operand" "0"))))]
10314   "TARGET_80387"
10315   "fabs"
10316   [(set_attr "type" "fsgn")
10317    (set_attr "mode" "DF")])
10318
10319 (define_insn "*absxf2_1"
10320   [(set (match_operand:XF 0 "register_operand" "=f")
10321         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10322   "TARGET_80387 && reload_completed"
10323   "fabs"
10324   [(set_attr "type" "fsgn")
10325    (set_attr "mode" "DF")])
10326
10327 (define_insn "*absextenddfxf2"
10328   [(set (match_operand:XF 0 "register_operand" "=f")
10329         (abs:XF (float_extend:XF
10330           (match_operand:DF 1 "register_operand" "0"))))]
10331   "TARGET_80387"
10332   "fabs"
10333   [(set_attr "type" "fsgn")
10334    (set_attr "mode" "XF")])
10335
10336 (define_insn "*absextendsfxf2"
10337   [(set (match_operand:XF 0 "register_operand" "=f")
10338         (abs:XF (float_extend:XF
10339           (match_operand:SF 1 "register_operand" "0"))))]
10340   "TARGET_80387"
10341   "fabs"
10342   [(set_attr "type" "fsgn")
10343    (set_attr "mode" "XF")])
10344 \f
10345 ;; One complement instructions
10346
10347 (define_expand "one_cmpldi2"
10348   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10349         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10350   "TARGET_64BIT"
10351   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10352
10353 (define_insn "*one_cmpldi2_1_rex64"
10354   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10355         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10356   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10357   "not{q}\t%0"
10358   [(set_attr "type" "negnot")
10359    (set_attr "mode" "DI")])
10360
10361 (define_insn "*one_cmpldi2_2_rex64"
10362   [(set (reg FLAGS_REG)
10363         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10364                  (const_int 0)))
10365    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10366         (not:DI (match_dup 1)))]
10367   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10368    && ix86_unary_operator_ok (NOT, DImode, operands)"
10369   "#"
10370   [(set_attr "type" "alu1")
10371    (set_attr "mode" "DI")])
10372
10373 (define_split
10374   [(set (match_operand 0 "flags_reg_operand" "")
10375         (match_operator 2 "compare_operator"
10376           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10377            (const_int 0)]))
10378    (set (match_operand:DI 1 "nonimmediate_operand" "")
10379         (not:DI (match_dup 3)))]
10380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10381   [(parallel [(set (match_dup 0)
10382                    (match_op_dup 2
10383                      [(xor:DI (match_dup 3) (const_int -1))
10384                       (const_int 0)]))
10385               (set (match_dup 1)
10386                    (xor:DI (match_dup 3) (const_int -1)))])]
10387   "")
10388
10389 (define_expand "one_cmplsi2"
10390   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10391         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10392   ""
10393   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10394
10395 (define_insn "*one_cmplsi2_1"
10396   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10397         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10398   "ix86_unary_operator_ok (NOT, SImode, operands)"
10399   "not{l}\t%0"
10400   [(set_attr "type" "negnot")
10401    (set_attr "mode" "SI")])
10402
10403 ;; ??? Currently never generated - xor is used instead.
10404 (define_insn "*one_cmplsi2_1_zext"
10405   [(set (match_operand:DI 0 "register_operand" "=r")
10406         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10407   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10408   "not{l}\t%k0"
10409   [(set_attr "type" "negnot")
10410    (set_attr "mode" "SI")])
10411
10412 (define_insn "*one_cmplsi2_2"
10413   [(set (reg FLAGS_REG)
10414         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10415                  (const_int 0)))
10416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10417         (not:SI (match_dup 1)))]
10418   "ix86_match_ccmode (insn, CCNOmode)
10419    && ix86_unary_operator_ok (NOT, SImode, operands)"
10420   "#"
10421   [(set_attr "type" "alu1")
10422    (set_attr "mode" "SI")])
10423
10424 (define_split
10425   [(set (match_operand 0 "flags_reg_operand" "")
10426         (match_operator 2 "compare_operator"
10427           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10428            (const_int 0)]))
10429    (set (match_operand:SI 1 "nonimmediate_operand" "")
10430         (not:SI (match_dup 3)))]
10431   "ix86_match_ccmode (insn, CCNOmode)"
10432   [(parallel [(set (match_dup 0)
10433                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10434                                     (const_int 0)]))
10435               (set (match_dup 1)
10436                    (xor:SI (match_dup 3) (const_int -1)))])]
10437   "")
10438
10439 ;; ??? Currently never generated - xor is used instead.
10440 (define_insn "*one_cmplsi2_2_zext"
10441   [(set (reg FLAGS_REG)
10442         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10443                  (const_int 0)))
10444    (set (match_operand:DI 0 "register_operand" "=r")
10445         (zero_extend:DI (not:SI (match_dup 1))))]
10446   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10447    && ix86_unary_operator_ok (NOT, SImode, operands)"
10448   "#"
10449   [(set_attr "type" "alu1")
10450    (set_attr "mode" "SI")])
10451
10452 (define_split
10453   [(set (match_operand 0 "flags_reg_operand" "")
10454         (match_operator 2 "compare_operator"
10455           [(not:SI (match_operand:SI 3 "register_operand" ""))
10456            (const_int 0)]))
10457    (set (match_operand:DI 1 "register_operand" "")
10458         (zero_extend:DI (not:SI (match_dup 3))))]
10459   "ix86_match_ccmode (insn, CCNOmode)"
10460   [(parallel [(set (match_dup 0)
10461                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10462                                     (const_int 0)]))
10463               (set (match_dup 1)
10464                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10465   "")
10466
10467 (define_expand "one_cmplhi2"
10468   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10469         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10470   "TARGET_HIMODE_MATH"
10471   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10472
10473 (define_insn "*one_cmplhi2_1"
10474   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10475         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10476   "ix86_unary_operator_ok (NOT, HImode, operands)"
10477   "not{w}\t%0"
10478   [(set_attr "type" "negnot")
10479    (set_attr "mode" "HI")])
10480
10481 (define_insn "*one_cmplhi2_2"
10482   [(set (reg FLAGS_REG)
10483         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10484                  (const_int 0)))
10485    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10486         (not:HI (match_dup 1)))]
10487   "ix86_match_ccmode (insn, CCNOmode)
10488    && ix86_unary_operator_ok (NEG, HImode, operands)"
10489   "#"
10490   [(set_attr "type" "alu1")
10491    (set_attr "mode" "HI")])
10492
10493 (define_split
10494   [(set (match_operand 0 "flags_reg_operand" "")
10495         (match_operator 2 "compare_operator"
10496           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10497            (const_int 0)]))
10498    (set (match_operand:HI 1 "nonimmediate_operand" "")
10499         (not:HI (match_dup 3)))]
10500   "ix86_match_ccmode (insn, CCNOmode)"
10501   [(parallel [(set (match_dup 0)
10502                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10503                                     (const_int 0)]))
10504               (set (match_dup 1)
10505                    (xor:HI (match_dup 3) (const_int -1)))])]
10506   "")
10507
10508 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10509 (define_expand "one_cmplqi2"
10510   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10511         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10512   "TARGET_QIMODE_MATH"
10513   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10514
10515 (define_insn "*one_cmplqi2_1"
10516   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10517         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10518   "ix86_unary_operator_ok (NOT, QImode, operands)"
10519   "@
10520    not{b}\t%0
10521    not{l}\t%k0"
10522   [(set_attr "type" "negnot")
10523    (set_attr "mode" "QI,SI")])
10524
10525 (define_insn "*one_cmplqi2_2"
10526   [(set (reg FLAGS_REG)
10527         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10528                  (const_int 0)))
10529    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10530         (not:QI (match_dup 1)))]
10531   "ix86_match_ccmode (insn, CCNOmode)
10532    && ix86_unary_operator_ok (NOT, QImode, operands)"
10533   "#"
10534   [(set_attr "type" "alu1")
10535    (set_attr "mode" "QI")])
10536
10537 (define_split
10538   [(set (match_operand 0 "flags_reg_operand" "")
10539         (match_operator 2 "compare_operator"
10540           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10541            (const_int 0)]))
10542    (set (match_operand:QI 1 "nonimmediate_operand" "")
10543         (not:QI (match_dup 3)))]
10544   "ix86_match_ccmode (insn, CCNOmode)"
10545   [(parallel [(set (match_dup 0)
10546                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10547                                     (const_int 0)]))
10548               (set (match_dup 1)
10549                    (xor:QI (match_dup 3) (const_int -1)))])]
10550   "")
10551 \f
10552 ;; Arithmetic shift instructions
10553
10554 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10555 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10556 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10557 ;; from the assembler input.
10558 ;;
10559 ;; This instruction shifts the target reg/mem as usual, but instead of
10560 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10561 ;; is a left shift double, bits are taken from the high order bits of
10562 ;; reg, else if the insn is a shift right double, bits are taken from the
10563 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10564 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10565 ;;
10566 ;; Since sh[lr]d does not change the `reg' operand, that is done
10567 ;; separately, making all shifts emit pairs of shift double and normal
10568 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10569 ;; support a 63 bit shift, each shift where the count is in a reg expands
10570 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10571 ;;
10572 ;; If the shift count is a constant, we need never emit more than one
10573 ;; shift pair, instead using moves and sign extension for counts greater
10574 ;; than 31.
10575
10576 (define_expand "ashldi3"
10577   [(set (match_operand:DI 0 "shiftdi_operand" "")
10578         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10579                    (match_operand:QI 2 "nonmemory_operand" "")))]
10580   ""
10581   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10582
10583 (define_insn "*ashldi3_1_rex64"
10584   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10585         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10586                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10587    (clobber (reg:CC FLAGS_REG))]
10588   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10589 {
10590   switch (get_attr_type (insn))
10591     {
10592     case TYPE_ALU:
10593       if (operands[2] != const1_rtx)
10594         abort ();
10595       if (!rtx_equal_p (operands[0], operands[1]))
10596         abort ();
10597       return "add{q}\t{%0, %0|%0, %0}";
10598
10599     case TYPE_LEA:
10600       if (GET_CODE (operands[2]) != CONST_INT
10601           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10602         abort ();
10603       operands[1] = gen_rtx_MULT (DImode, operands[1],
10604                                   GEN_INT (1 << INTVAL (operands[2])));
10605       return "lea{q}\t{%a1, %0|%0, %a1}";
10606
10607     default:
10608       if (REG_P (operands[2]))
10609         return "sal{q}\t{%b2, %0|%0, %b2}";
10610       else if (operands[2] == const1_rtx
10611                && (TARGET_SHIFT1 || optimize_size))
10612         return "sal{q}\t%0";
10613       else
10614         return "sal{q}\t{%2, %0|%0, %2}";
10615     }
10616 }
10617   [(set (attr "type")
10618      (cond [(eq_attr "alternative" "1")
10619               (const_string "lea")
10620             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621                           (const_int 0))
10622                       (match_operand 0 "register_operand" ""))
10623                  (match_operand 2 "const1_operand" ""))
10624               (const_string "alu")
10625            ]
10626            (const_string "ishift")))
10627    (set_attr "mode" "DI")])
10628
10629 ;; Convert lea to the lea pattern to avoid flags dependency.
10630 (define_split
10631   [(set (match_operand:DI 0 "register_operand" "")
10632         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10633                    (match_operand:QI 2 "immediate_operand" "")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "TARGET_64BIT && reload_completed
10636    && true_regnum (operands[0]) != true_regnum (operands[1])"
10637   [(set (match_dup 0)
10638         (mult:DI (match_dup 1)
10639                  (match_dup 2)))]
10640   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10641
10642 ;; This pattern can't accept a variable shift count, since shifts by
10643 ;; zero don't affect the flags.  We assume that shifts by constant
10644 ;; zero are optimized away.
10645 (define_insn "*ashldi3_cmp_rex64"
10646   [(set (reg FLAGS_REG)
10647         (compare
10648           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10649                      (match_operand:QI 2 "immediate_operand" "e"))
10650           (const_int 0)))
10651    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10652         (ashift:DI (match_dup 1) (match_dup 2)))]
10653   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10654    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10655 {
10656   switch (get_attr_type (insn))
10657     {
10658     case TYPE_ALU:
10659       if (operands[2] != const1_rtx)
10660         abort ();
10661       return "add{q}\t{%0, %0|%0, %0}";
10662
10663     default:
10664       if (REG_P (operands[2]))
10665         return "sal{q}\t{%b2, %0|%0, %b2}";
10666       else if (operands[2] == const1_rtx
10667                && (TARGET_SHIFT1 || optimize_size))
10668         return "sal{q}\t%0";
10669       else
10670         return "sal{q}\t{%2, %0|%0, %2}";
10671     }
10672 }
10673   [(set (attr "type")
10674      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10675                           (const_int 0))
10676                       (match_operand 0 "register_operand" ""))
10677                  (match_operand 2 "const1_operand" ""))
10678               (const_string "alu")
10679            ]
10680            (const_string "ishift")))
10681    (set_attr "mode" "DI")])
10682
10683 (define_insn "*ashldi3_1"
10684   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10685         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10686                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10687    (clobber (reg:CC FLAGS_REG))]
10688   "!TARGET_64BIT"
10689   "#"
10690   [(set_attr "type" "multi")])
10691
10692 ;; By default we don't ask for a scratch register, because when DImode
10693 ;; values are manipulated, registers are already at a premium.  But if
10694 ;; we have one handy, we won't turn it away.
10695 (define_peephole2
10696   [(match_scratch:SI 3 "r")
10697    (parallel [(set (match_operand:DI 0 "register_operand" "")
10698                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10699                               (match_operand:QI 2 "nonmemory_operand" "")))
10700               (clobber (reg:CC FLAGS_REG))])
10701    (match_dup 3)]
10702   "!TARGET_64BIT && TARGET_CMOVE"
10703   [(const_int 0)]
10704   "ix86_split_ashldi (operands, operands[3]); DONE;")
10705
10706 (define_split
10707   [(set (match_operand:DI 0 "register_operand" "")
10708         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10709                    (match_operand:QI 2 "nonmemory_operand" "")))
10710    (clobber (reg:CC FLAGS_REG))]
10711   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10712   [(const_int 0)]
10713   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10714
10715 (define_insn "x86_shld_1"
10716   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10717         (ior:SI (ashift:SI (match_dup 0)
10718                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10719                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10720                   (minus:QI (const_int 32) (match_dup 2)))))
10721    (clobber (reg:CC FLAGS_REG))]
10722   ""
10723   "@
10724    shld{l}\t{%2, %1, %0|%0, %1, %2}
10725    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10726   [(set_attr "type" "ishift")
10727    (set_attr "prefix_0f" "1")
10728    (set_attr "mode" "SI")
10729    (set_attr "pent_pair" "np")
10730    (set_attr "athlon_decode" "vector")])
10731
10732 (define_expand "x86_shift_adj_1"
10733   [(set (reg:CCZ FLAGS_REG)
10734         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10735                              (const_int 32))
10736                      (const_int 0)))
10737    (set (match_operand:SI 0 "register_operand" "")
10738         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10739                          (match_operand:SI 1 "register_operand" "")
10740                          (match_dup 0)))
10741    (set (match_dup 1)
10742         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10743                          (match_operand:SI 3 "register_operand" "r")
10744                          (match_dup 1)))]
10745   "TARGET_CMOVE"
10746   "")
10747
10748 (define_expand "x86_shift_adj_2"
10749   [(use (match_operand:SI 0 "register_operand" ""))
10750    (use (match_operand:SI 1 "register_operand" ""))
10751    (use (match_operand:QI 2 "register_operand" ""))]
10752   ""
10753 {
10754   rtx label = gen_label_rtx ();
10755   rtx tmp;
10756
10757   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10758
10759   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10760   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10761   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10762                               gen_rtx_LABEL_REF (VOIDmode, label),
10763                               pc_rtx);
10764   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10765   JUMP_LABEL (tmp) = label;
10766
10767   emit_move_insn (operands[0], operands[1]);
10768   ix86_expand_clear (operands[1]);
10769
10770   emit_label (label);
10771   LABEL_NUSES (label) = 1;
10772
10773   DONE;
10774 })
10775
10776 (define_expand "ashlsi3"
10777   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10778         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10779                    (match_operand:QI 2 "nonmemory_operand" "")))
10780    (clobber (reg:CC FLAGS_REG))]
10781   ""
10782   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10783
10784 (define_insn "*ashlsi3_1"
10785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10786         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10787                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10788    (clobber (reg:CC FLAGS_REG))]
10789   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10790 {
10791   switch (get_attr_type (insn))
10792     {
10793     case TYPE_ALU:
10794       if (operands[2] != const1_rtx)
10795         abort ();
10796       if (!rtx_equal_p (operands[0], operands[1]))
10797         abort ();
10798       return "add{l}\t{%0, %0|%0, %0}";
10799
10800     case TYPE_LEA:
10801       return "#";
10802
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{l}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_size))
10808         return "sal{l}\t%0";
10809       else
10810         return "sal{l}\t{%2, %0|%0, %2}";
10811     }
10812 }
10813   [(set (attr "type")
10814      (cond [(eq_attr "alternative" "1")
10815               (const_string "lea")
10816             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10817                           (const_int 0))
10818                       (match_operand 0 "register_operand" ""))
10819                  (match_operand 2 "const1_operand" ""))
10820               (const_string "alu")
10821            ]
10822            (const_string "ishift")))
10823    (set_attr "mode" "SI")])
10824
10825 ;; Convert lea to the lea pattern to avoid flags dependency.
10826 (define_split
10827   [(set (match_operand 0 "register_operand" "")
10828         (ashift (match_operand 1 "index_register_operand" "")
10829                 (match_operand:QI 2 "const_int_operand" "")))
10830    (clobber (reg:CC FLAGS_REG))]
10831   "reload_completed
10832    && true_regnum (operands[0]) != true_regnum (operands[1])
10833    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10834   [(const_int 0)]
10835 {
10836   rtx pat;
10837   enum machine_mode mode = GET_MODE (operands[0]);
10838
10839   if (GET_MODE_SIZE (mode) < 4)
10840     operands[0] = gen_lowpart (SImode, operands[0]);
10841   if (mode != Pmode)
10842     operands[1] = gen_lowpart (Pmode, operands[1]);
10843   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10844
10845   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10846   if (Pmode != SImode)
10847     pat = gen_rtx_SUBREG (SImode, pat, 0);
10848   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10849   DONE;
10850 })
10851
10852 ;; Rare case of shifting RSP is handled by generating move and shift
10853 (define_split
10854   [(set (match_operand 0 "register_operand" "")
10855         (ashift (match_operand 1 "register_operand" "")
10856                 (match_operand:QI 2 "const_int_operand" "")))
10857    (clobber (reg:CC FLAGS_REG))]
10858   "reload_completed
10859    && true_regnum (operands[0]) != true_regnum (operands[1])"
10860   [(const_int 0)]
10861 {
10862   rtx pat, clob;
10863   emit_move_insn (operands[1], operands[0]);
10864   pat = gen_rtx_SET (VOIDmode, operands[0],
10865                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10866                                      operands[0], operands[2]));
10867   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10868   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10869   DONE;
10870 })
10871
10872 (define_insn "*ashlsi3_1_zext"
10873   [(set (match_operand:DI 0 "register_operand" "=r,r")
10874         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10875                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10878 {
10879   switch (get_attr_type (insn))
10880     {
10881     case TYPE_ALU:
10882       if (operands[2] != const1_rtx)
10883         abort ();
10884       return "add{l}\t{%k0, %k0|%k0, %k0}";
10885
10886     case TYPE_LEA:
10887       return "#";
10888
10889     default:
10890       if (REG_P (operands[2]))
10891         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10892       else if (operands[2] == const1_rtx
10893                && (TARGET_SHIFT1 || optimize_size))
10894         return "sal{l}\t%k0";
10895       else
10896         return "sal{l}\t{%2, %k0|%k0, %2}";
10897     }
10898 }
10899   [(set (attr "type")
10900      (cond [(eq_attr "alternative" "1")
10901               (const_string "lea")
10902             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10903                      (const_int 0))
10904                  (match_operand 2 "const1_operand" ""))
10905               (const_string "alu")
10906            ]
10907            (const_string "ishift")))
10908    (set_attr "mode" "SI")])
10909
10910 ;; Convert lea to the lea pattern to avoid flags dependency.
10911 (define_split
10912   [(set (match_operand:DI 0 "register_operand" "")
10913         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10914                                 (match_operand:QI 2 "const_int_operand" ""))))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "TARGET_64BIT && reload_completed
10917    && true_regnum (operands[0]) != true_regnum (operands[1])"
10918   [(set (match_dup 0) (zero_extend:DI
10919                         (subreg:SI (mult:SI (match_dup 1)
10920                                             (match_dup 2)) 0)))]
10921 {
10922   operands[1] = gen_lowpart (Pmode, operands[1]);
10923   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10924 })
10925
10926 ;; This pattern can't accept a variable shift count, since shifts by
10927 ;; zero don't affect the flags.  We assume that shifts by constant
10928 ;; zero are optimized away.
10929 (define_insn "*ashlsi3_cmp"
10930   [(set (reg FLAGS_REG)
10931         (compare
10932           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10933                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10934           (const_int 0)))
10935    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10936         (ashift:SI (match_dup 1) (match_dup 2)))]
10937   "ix86_match_ccmode (insn, CCGOCmode)
10938    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10939 {
10940   switch (get_attr_type (insn))
10941     {
10942     case TYPE_ALU:
10943       if (operands[2] != const1_rtx)
10944         abort ();
10945       return "add{l}\t{%0, %0|%0, %0}";
10946
10947     default:
10948       if (REG_P (operands[2]))
10949         return "sal{l}\t{%b2, %0|%0, %b2}";
10950       else if (operands[2] == const1_rtx
10951                && (TARGET_SHIFT1 || optimize_size))
10952         return "sal{l}\t%0";
10953       else
10954         return "sal{l}\t{%2, %0|%0, %2}";
10955     }
10956 }
10957   [(set (attr "type")
10958      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10959                           (const_int 0))
10960                       (match_operand 0 "register_operand" ""))
10961                  (match_operand 2 "const1_operand" ""))
10962               (const_string "alu")
10963            ]
10964            (const_string "ishift")))
10965    (set_attr "mode" "SI")])
10966
10967 (define_insn "*ashlsi3_cmp_zext"
10968   [(set (reg FLAGS_REG)
10969         (compare
10970           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10971                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10972           (const_int 0)))
10973    (set (match_operand:DI 0 "register_operand" "=r")
10974         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10975   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10976    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10977 {
10978   switch (get_attr_type (insn))
10979     {
10980     case TYPE_ALU:
10981       if (operands[2] != const1_rtx)
10982         abort ();
10983       return "add{l}\t{%k0, %k0|%k0, %k0}";
10984
10985     default:
10986       if (REG_P (operands[2]))
10987         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10988       else if (operands[2] == const1_rtx
10989                && (TARGET_SHIFT1 || optimize_size))
10990         return "sal{l}\t%k0";
10991       else
10992         return "sal{l}\t{%2, %k0|%k0, %2}";
10993     }
10994 }
10995   [(set (attr "type")
10996      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997                      (const_int 0))
10998                  (match_operand 2 "const1_operand" ""))
10999               (const_string "alu")
11000            ]
11001            (const_string "ishift")))
11002    (set_attr "mode" "SI")])
11003
11004 (define_expand "ashlhi3"
11005   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11006         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11007                    (match_operand:QI 2 "nonmemory_operand" "")))
11008    (clobber (reg:CC FLAGS_REG))]
11009   "TARGET_HIMODE_MATH"
11010   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11011
11012 (define_insn "*ashlhi3_1_lea"
11013   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11014         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11015                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11016    (clobber (reg:CC FLAGS_REG))]
11017   "!TARGET_PARTIAL_REG_STALL
11018    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11019 {
11020   switch (get_attr_type (insn))
11021     {
11022     case TYPE_LEA:
11023       return "#";
11024     case TYPE_ALU:
11025       if (operands[2] != const1_rtx)
11026         abort ();
11027       return "add{w}\t{%0, %0|%0, %0}";
11028
11029     default:
11030       if (REG_P (operands[2]))
11031         return "sal{w}\t{%b2, %0|%0, %b2}";
11032       else if (operands[2] == const1_rtx
11033                && (TARGET_SHIFT1 || optimize_size))
11034         return "sal{w}\t%0";
11035       else
11036         return "sal{w}\t{%2, %0|%0, %2}";
11037     }
11038 }
11039   [(set (attr "type")
11040      (cond [(eq_attr "alternative" "1")
11041               (const_string "lea")
11042             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11043                           (const_int 0))
11044                       (match_operand 0 "register_operand" ""))
11045                  (match_operand 2 "const1_operand" ""))
11046               (const_string "alu")
11047            ]
11048            (const_string "ishift")))
11049    (set_attr "mode" "HI,SI")])
11050
11051 (define_insn "*ashlhi3_1"
11052   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11053         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11054                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "TARGET_PARTIAL_REG_STALL
11057    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11058 {
11059   switch (get_attr_type (insn))
11060     {
11061     case TYPE_ALU:
11062       if (operands[2] != const1_rtx)
11063         abort ();
11064       return "add{w}\t{%0, %0|%0, %0}";
11065
11066     default:
11067       if (REG_P (operands[2]))
11068         return "sal{w}\t{%b2, %0|%0, %b2}";
11069       else if (operands[2] == const1_rtx
11070                && (TARGET_SHIFT1 || optimize_size))
11071         return "sal{w}\t%0";
11072       else
11073         return "sal{w}\t{%2, %0|%0, %2}";
11074     }
11075 }
11076   [(set (attr "type")
11077      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11078                           (const_int 0))
11079                       (match_operand 0 "register_operand" ""))
11080                  (match_operand 2 "const1_operand" ""))
11081               (const_string "alu")
11082            ]
11083            (const_string "ishift")))
11084    (set_attr "mode" "HI")])
11085
11086 ;; This pattern can't accept a variable shift count, since shifts by
11087 ;; zero don't affect the flags.  We assume that shifts by constant
11088 ;; zero are optimized away.
11089 (define_insn "*ashlhi3_cmp"
11090   [(set (reg FLAGS_REG)
11091         (compare
11092           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11093                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11094           (const_int 0)))
11095    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11096         (ashift:HI (match_dup 1) (match_dup 2)))]
11097   "ix86_match_ccmode (insn, CCGOCmode)
11098    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11099 {
11100   switch (get_attr_type (insn))
11101     {
11102     case TYPE_ALU:
11103       if (operands[2] != const1_rtx)
11104         abort ();
11105       return "add{w}\t{%0, %0|%0, %0}";
11106
11107     default:
11108       if (REG_P (operands[2]))
11109         return "sal{w}\t{%b2, %0|%0, %b2}";
11110       else if (operands[2] == const1_rtx
11111                && (TARGET_SHIFT1 || optimize_size))
11112         return "sal{w}\t%0";
11113       else
11114         return "sal{w}\t{%2, %0|%0, %2}";
11115     }
11116 }
11117   [(set (attr "type")
11118      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11119                           (const_int 0))
11120                       (match_operand 0 "register_operand" ""))
11121                  (match_operand 2 "const1_operand" ""))
11122               (const_string "alu")
11123            ]
11124            (const_string "ishift")))
11125    (set_attr "mode" "HI")])
11126
11127 (define_expand "ashlqi3"
11128   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11129         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11130                    (match_operand:QI 2 "nonmemory_operand" "")))
11131    (clobber (reg:CC FLAGS_REG))]
11132   "TARGET_QIMODE_MATH"
11133   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11134
11135 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11136
11137 (define_insn "*ashlqi3_1_lea"
11138   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11139         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11140                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11141    (clobber (reg:CC FLAGS_REG))]
11142   "!TARGET_PARTIAL_REG_STALL
11143    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11144 {
11145   switch (get_attr_type (insn))
11146     {
11147     case TYPE_LEA:
11148       return "#";
11149     case TYPE_ALU:
11150       if (operands[2] != const1_rtx)
11151         abort ();
11152       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11153         return "add{l}\t{%k0, %k0|%k0, %k0}";
11154       else
11155         return "add{b}\t{%0, %0|%0, %0}";
11156
11157     default:
11158       if (REG_P (operands[2]))
11159         {
11160           if (get_attr_mode (insn) == MODE_SI)
11161             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11162           else
11163             return "sal{b}\t{%b2, %0|%0, %b2}";
11164         }
11165       else if (operands[2] == const1_rtx
11166                && (TARGET_SHIFT1 || optimize_size))
11167         {
11168           if (get_attr_mode (insn) == MODE_SI)
11169             return "sal{l}\t%0";
11170           else
11171             return "sal{b}\t%0";
11172         }
11173       else
11174         {
11175           if (get_attr_mode (insn) == MODE_SI)
11176             return "sal{l}\t{%2, %k0|%k0, %2}";
11177           else
11178             return "sal{b}\t{%2, %0|%0, %2}";
11179         }
11180     }
11181 }
11182   [(set (attr "type")
11183      (cond [(eq_attr "alternative" "2")
11184               (const_string "lea")
11185             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11186                           (const_int 0))
11187                       (match_operand 0 "register_operand" ""))
11188                  (match_operand 2 "const1_operand" ""))
11189               (const_string "alu")
11190            ]
11191            (const_string "ishift")))
11192    (set_attr "mode" "QI,SI,SI")])
11193
11194 (define_insn "*ashlqi3_1"
11195   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11196         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11197                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11198    (clobber (reg:CC FLAGS_REG))]
11199   "TARGET_PARTIAL_REG_STALL
11200    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11201 {
11202   switch (get_attr_type (insn))
11203     {
11204     case TYPE_ALU:
11205       if (operands[2] != const1_rtx)
11206         abort ();
11207       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11208         return "add{l}\t{%k0, %k0|%k0, %k0}";
11209       else
11210         return "add{b}\t{%0, %0|%0, %0}";
11211
11212     default:
11213       if (REG_P (operands[2]))
11214         {
11215           if (get_attr_mode (insn) == MODE_SI)
11216             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11217           else
11218             return "sal{b}\t{%b2, %0|%0, %b2}";
11219         }
11220       else if (operands[2] == const1_rtx
11221                && (TARGET_SHIFT1 || optimize_size))
11222         {
11223           if (get_attr_mode (insn) == MODE_SI)
11224             return "sal{l}\t%0";
11225           else
11226             return "sal{b}\t%0";
11227         }
11228       else
11229         {
11230           if (get_attr_mode (insn) == MODE_SI)
11231             return "sal{l}\t{%2, %k0|%k0, %2}";
11232           else
11233             return "sal{b}\t{%2, %0|%0, %2}";
11234         }
11235     }
11236 }
11237   [(set (attr "type")
11238      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11239                           (const_int 0))
11240                       (match_operand 0 "register_operand" ""))
11241                  (match_operand 2 "const1_operand" ""))
11242               (const_string "alu")
11243            ]
11244            (const_string "ishift")))
11245    (set_attr "mode" "QI,SI")])
11246
11247 ;; This pattern can't accept a variable shift count, since shifts by
11248 ;; zero don't affect the flags.  We assume that shifts by constant
11249 ;; zero are optimized away.
11250 (define_insn "*ashlqi3_cmp"
11251   [(set (reg FLAGS_REG)
11252         (compare
11253           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11254                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11255           (const_int 0)))
11256    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11257         (ashift:QI (match_dup 1) (match_dup 2)))]
11258   "ix86_match_ccmode (insn, CCGOCmode)
11259    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11260 {
11261   switch (get_attr_type (insn))
11262     {
11263     case TYPE_ALU:
11264       if (operands[2] != const1_rtx)
11265         abort ();
11266       return "add{b}\t{%0, %0|%0, %0}";
11267
11268     default:
11269       if (REG_P (operands[2]))
11270         return "sal{b}\t{%b2, %0|%0, %b2}";
11271       else if (operands[2] == const1_rtx
11272                && (TARGET_SHIFT1 || optimize_size))
11273         return "sal{b}\t%0";
11274       else
11275         return "sal{b}\t{%2, %0|%0, %2}";
11276     }
11277 }
11278   [(set (attr "type")
11279      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11280                           (const_int 0))
11281                       (match_operand 0 "register_operand" ""))
11282                  (match_operand 2 "const1_operand" ""))
11283               (const_string "alu")
11284            ]
11285            (const_string "ishift")))
11286    (set_attr "mode" "QI")])
11287
11288 ;; See comment above `ashldi3' about how this works.
11289
11290 (define_expand "ashrdi3"
11291   [(set (match_operand:DI 0 "shiftdi_operand" "")
11292         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))]
11294   ""
11295   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11296
11297 (define_insn "*ashrdi3_63_rex64"
11298   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11299         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11300                      (match_operand:DI 2 "const_int_operand" "i,i")))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_64BIT && INTVAL (operands[2]) == 63
11303    && (TARGET_USE_CLTD || optimize_size)
11304    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11305   "@
11306    {cqto|cqo}
11307    sar{q}\t{%2, %0|%0, %2}"
11308   [(set_attr "type" "imovx,ishift")
11309    (set_attr "prefix_0f" "0,*")
11310    (set_attr "length_immediate" "0,*")
11311    (set_attr "modrm" "0,1")
11312    (set_attr "mode" "DI")])
11313
11314 (define_insn "*ashrdi3_1_one_bit_rex64"
11315   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11316         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const1_operand" "")))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{q}\t%0"
11322   [(set_attr "type" "ishift")
11323    (set (attr "length") 
11324      (if_then_else (match_operand:DI 0 "register_operand" "") 
11325         (const_string "2")
11326         (const_string "*")))])
11327
11328 (define_insn "*ashrdi3_1_rex64"
11329   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11330         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11331                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11334   "@
11335    sar{q}\t{%2, %0|%0, %2}
11336    sar{q}\t{%b2, %0|%0, %b2}"
11337   [(set_attr "type" "ishift")
11338    (set_attr "mode" "DI")])
11339
11340 ;; This pattern can't accept a variable shift count, since shifts by
11341 ;; zero don't affect the flags.  We assume that shifts by constant
11342 ;; zero are optimized away.
11343 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11344   [(set (reg FLAGS_REG)
11345         (compare
11346           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347                        (match_operand:QI 2 "const1_operand" ""))
11348           (const_int 0)))
11349    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11350         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11351   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11352    && (TARGET_SHIFT1 || optimize_size)
11353    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354   "sar{q}\t%0"
11355   [(set_attr "type" "ishift")
11356    (set (attr "length") 
11357      (if_then_else (match_operand:DI 0 "register_operand" "") 
11358         (const_string "2")
11359         (const_string "*")))])
11360
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags.  We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashrdi3_cmp_rex64"
11365   [(set (reg FLAGS_REG)
11366         (compare
11367           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11368                        (match_operand:QI 2 "const_int_operand" "n"))
11369           (const_int 0)))
11370    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11371         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11372   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11373    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11374   "sar{q}\t{%2, %0|%0, %2}"
11375   [(set_attr "type" "ishift")
11376    (set_attr "mode" "DI")])
11377
11378 (define_insn "*ashrdi3_1"
11379   [(set (match_operand:DI 0 "register_operand" "=r")
11380         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11381                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "!TARGET_64BIT"
11384   "#"
11385   [(set_attr "type" "multi")])
11386
11387 ;; By default we don't ask for a scratch register, because when DImode
11388 ;; values are manipulated, registers are already at a premium.  But if
11389 ;; we have one handy, we won't turn it away.
11390 (define_peephole2
11391   [(match_scratch:SI 3 "r")
11392    (parallel [(set (match_operand:DI 0 "register_operand" "")
11393                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11394                                 (match_operand:QI 2 "nonmemory_operand" "")))
11395               (clobber (reg:CC FLAGS_REG))])
11396    (match_dup 3)]
11397   "!TARGET_64BIT && TARGET_CMOVE"
11398   [(const_int 0)]
11399   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11400
11401 (define_split
11402   [(set (match_operand:DI 0 "register_operand" "")
11403         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11404                      (match_operand:QI 2 "nonmemory_operand" "")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11407   [(const_int 0)]
11408   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11409
11410 (define_insn "x86_shrd_1"
11411   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11412         (ior:SI (ashiftrt:SI (match_dup 0)
11413                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11414                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11415                   (minus:QI (const_int 32) (match_dup 2)))))
11416    (clobber (reg:CC FLAGS_REG))]
11417   ""
11418   "@
11419    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11420    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11421   [(set_attr "type" "ishift")
11422    (set_attr "prefix_0f" "1")
11423    (set_attr "pent_pair" "np")
11424    (set_attr "mode" "SI")])
11425
11426 (define_expand "x86_shift_adj_3"
11427   [(use (match_operand:SI 0 "register_operand" ""))
11428    (use (match_operand:SI 1 "register_operand" ""))
11429    (use (match_operand:QI 2 "register_operand" ""))]
11430   ""
11431 {
11432   rtx label = gen_label_rtx ();
11433   rtx tmp;
11434
11435   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11436
11437   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11438   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11439   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11440                               gen_rtx_LABEL_REF (VOIDmode, label),
11441                               pc_rtx);
11442   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11443   JUMP_LABEL (tmp) = label;
11444
11445   emit_move_insn (operands[0], operands[1]);
11446   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11447
11448   emit_label (label);
11449   LABEL_NUSES (label) = 1;
11450
11451   DONE;
11452 })
11453
11454 (define_insn "ashrsi3_31"
11455   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11456         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11457                      (match_operand:SI 2 "const_int_operand" "i,i")))
11458    (clobber (reg:CC FLAGS_REG))]
11459   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11460    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11461   "@
11462    {cltd|cdq}
11463    sar{l}\t{%2, %0|%0, %2}"
11464   [(set_attr "type" "imovx,ishift")
11465    (set_attr "prefix_0f" "0,*")
11466    (set_attr "length_immediate" "0,*")
11467    (set_attr "modrm" "0,1")
11468    (set_attr "mode" "SI")])
11469
11470 (define_insn "*ashrsi3_31_zext"
11471   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11472         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11473                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11474    (clobber (reg:CC FLAGS_REG))]
11475   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11476    && INTVAL (operands[2]) == 31
11477    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11478   "@
11479    {cltd|cdq}
11480    sar{l}\t{%2, %k0|%k0, %2}"
11481   [(set_attr "type" "imovx,ishift")
11482    (set_attr "prefix_0f" "0,*")
11483    (set_attr "length_immediate" "0,*")
11484    (set_attr "modrm" "0,1")
11485    (set_attr "mode" "SI")])
11486
11487 (define_expand "ashrsi3"
11488   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11489         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11490                      (match_operand:QI 2 "nonmemory_operand" "")))
11491    (clobber (reg:CC FLAGS_REG))]
11492   ""
11493   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11494
11495 (define_insn "*ashrsi3_1_one_bit"
11496   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11497         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11498                      (match_operand:QI 2 "const1_operand" "")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11501    && (TARGET_SHIFT1 || optimize_size)"
11502   "sar{l}\t%0"
11503   [(set_attr "type" "ishift")
11504    (set (attr "length") 
11505      (if_then_else (match_operand:SI 0 "register_operand" "") 
11506         (const_string "2")
11507         (const_string "*")))])
11508
11509 (define_insn "*ashrsi3_1_one_bit_zext"
11510   [(set (match_operand:DI 0 "register_operand" "=r")
11511         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11512                                      (match_operand:QI 2 "const1_operand" ""))))
11513    (clobber (reg:CC FLAGS_REG))]
11514   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11515    && (TARGET_SHIFT1 || optimize_size)"
11516   "sar{l}\t%k0"
11517   [(set_attr "type" "ishift")
11518    (set_attr "length" "2")])
11519
11520 (define_insn "*ashrsi3_1"
11521   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11522         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11523                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11524    (clobber (reg:CC FLAGS_REG))]
11525   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11526   "@
11527    sar{l}\t{%2, %0|%0, %2}
11528    sar{l}\t{%b2, %0|%0, %b2}"
11529   [(set_attr "type" "ishift")
11530    (set_attr "mode" "SI")])
11531
11532 (define_insn "*ashrsi3_1_zext"
11533   [(set (match_operand:DI 0 "register_operand" "=r,r")
11534         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11535                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11536    (clobber (reg:CC FLAGS_REG))]
11537   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11538   "@
11539    sar{l}\t{%2, %k0|%k0, %2}
11540    sar{l}\t{%b2, %k0|%k0, %b2}"
11541   [(set_attr "type" "ishift")
11542    (set_attr "mode" "SI")])
11543
11544 ;; This pattern can't accept a variable shift count, since shifts by
11545 ;; zero don't affect the flags.  We assume that shifts by constant
11546 ;; zero are optimized away.
11547 (define_insn "*ashrsi3_one_bit_cmp"
11548   [(set (reg FLAGS_REG)
11549         (compare
11550           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11551                        (match_operand:QI 2 "const1_operand" ""))
11552           (const_int 0)))
11553    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11554         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11555   "ix86_match_ccmode (insn, CCGOCmode)
11556    && (TARGET_SHIFT1 || optimize_size)
11557    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "sar{l}\t%0"
11559   [(set_attr "type" "ishift")
11560    (set (attr "length") 
11561      (if_then_else (match_operand:SI 0 "register_operand" "") 
11562         (const_string "2")
11563         (const_string "*")))])
11564
11565 (define_insn "*ashrsi3_one_bit_cmp_zext"
11566   [(set (reg FLAGS_REG)
11567         (compare
11568           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11569                        (match_operand:QI 2 "const1_operand" ""))
11570           (const_int 0)))
11571    (set (match_operand:DI 0 "register_operand" "=r")
11572         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11573   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11574    && (TARGET_SHIFT1 || optimize_size)
11575    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11576   "sar{l}\t%k0"
11577   [(set_attr "type" "ishift")
11578    (set_attr "length" "2")])
11579
11580 ;; This pattern can't accept a variable shift count, since shifts by
11581 ;; zero don't affect the flags.  We assume that shifts by constant
11582 ;; zero are optimized away.
11583 (define_insn "*ashrsi3_cmp"
11584   [(set (reg FLAGS_REG)
11585         (compare
11586           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11587                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11588           (const_int 0)))
11589    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11590         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11591   "ix86_match_ccmode (insn, CCGOCmode)
11592    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11593   "sar{l}\t{%2, %0|%0, %2}"
11594   [(set_attr "type" "ishift")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*ashrsi3_cmp_zext"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11601                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11602           (const_int 0)))
11603    (set (match_operand:DI 0 "register_operand" "=r")
11604         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11605   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11606    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607   "sar{l}\t{%2, %k0|%k0, %2}"
11608   [(set_attr "type" "ishift")
11609    (set_attr "mode" "SI")])
11610
11611 (define_expand "ashrhi3"
11612   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11613         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11614                      (match_operand:QI 2 "nonmemory_operand" "")))
11615    (clobber (reg:CC FLAGS_REG))]
11616   "TARGET_HIMODE_MATH"
11617   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11618
11619 (define_insn "*ashrhi3_1_one_bit"
11620   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11621         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11622                      (match_operand:QI 2 "const1_operand" "")))
11623    (clobber (reg:CC FLAGS_REG))]
11624   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11625    && (TARGET_SHIFT1 || optimize_size)"
11626   "sar{w}\t%0"
11627   [(set_attr "type" "ishift")
11628    (set (attr "length") 
11629      (if_then_else (match_operand 0 "register_operand" "") 
11630         (const_string "2")
11631         (const_string "*")))])
11632
11633 (define_insn "*ashrhi3_1"
11634   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11635         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11636                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11637    (clobber (reg:CC FLAGS_REG))]
11638   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11639   "@
11640    sar{w}\t{%2, %0|%0, %2}
11641    sar{w}\t{%b2, %0|%0, %b2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "HI")])
11644
11645 ;; This pattern can't accept a variable shift count, since shifts by
11646 ;; zero don't affect the flags.  We assume that shifts by constant
11647 ;; zero are optimized away.
11648 (define_insn "*ashrhi3_one_bit_cmp"
11649   [(set (reg FLAGS_REG)
11650         (compare
11651           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11652                        (match_operand:QI 2 "const1_operand" ""))
11653           (const_int 0)))
11654    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11655         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11656   "ix86_match_ccmode (insn, CCGOCmode)
11657    && (TARGET_SHIFT1 || optimize_size)
11658    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11659   "sar{w}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length") 
11662      (if_then_else (match_operand 0 "register_operand" "") 
11663         (const_string "2")
11664         (const_string "*")))])
11665
11666 ;; This pattern can't accept a variable shift count, since shifts by
11667 ;; zero don't affect the flags.  We assume that shifts by constant
11668 ;; zero are optimized away.
11669 (define_insn "*ashrhi3_cmp"
11670   [(set (reg FLAGS_REG)
11671         (compare
11672           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11673                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11674           (const_int 0)))
11675    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11676         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11677   "ix86_match_ccmode (insn, CCGOCmode)
11678    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11679   "sar{w}\t{%2, %0|%0, %2}"
11680   [(set_attr "type" "ishift")
11681    (set_attr "mode" "HI")])
11682
11683 (define_expand "ashrqi3"
11684   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11685         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11686                      (match_operand:QI 2 "nonmemory_operand" "")))
11687    (clobber (reg:CC FLAGS_REG))]
11688   "TARGET_QIMODE_MATH"
11689   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11690
11691 (define_insn "*ashrqi3_1_one_bit"
11692   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11693         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11694                      (match_operand:QI 2 "const1_operand" "")))
11695    (clobber (reg:CC FLAGS_REG))]
11696   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11697    && (TARGET_SHIFT1 || optimize_size)"
11698   "sar{b}\t%0"
11699   [(set_attr "type" "ishift")
11700    (set (attr "length") 
11701      (if_then_else (match_operand 0 "register_operand" "") 
11702         (const_string "2")
11703         (const_string "*")))])
11704
11705 (define_insn "*ashrqi3_1_one_bit_slp"
11706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11707         (ashiftrt:QI (match_dup 0)
11708                      (match_operand:QI 1 "const1_operand" "")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11711    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11712    && (TARGET_SHIFT1 || optimize_size)"
11713   "sar{b}\t%0"
11714   [(set_attr "type" "ishift1")
11715    (set (attr "length") 
11716      (if_then_else (match_operand 0 "register_operand" "") 
11717         (const_string "2")
11718         (const_string "*")))])
11719
11720 (define_insn "*ashrqi3_1"
11721   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11722         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11723                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11724    (clobber (reg:CC FLAGS_REG))]
11725   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11726   "@
11727    sar{b}\t{%2, %0|%0, %2}
11728    sar{b}\t{%b2, %0|%0, %b2}"
11729   [(set_attr "type" "ishift")
11730    (set_attr "mode" "QI")])
11731
11732 (define_insn "*ashrqi3_1_slp"
11733   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11734         (ashiftrt:QI (match_dup 0)
11735                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11738    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11739   "@
11740    sar{b}\t{%1, %0|%0, %1}
11741    sar{b}\t{%b1, %0|%0, %b1}"
11742   [(set_attr "type" "ishift1")
11743    (set_attr "mode" "QI")])
11744
11745 ;; This pattern can't accept a variable shift count, since shifts by
11746 ;; zero don't affect the flags.  We assume that shifts by constant
11747 ;; zero are optimized away.
11748 (define_insn "*ashrqi3_one_bit_cmp"
11749   [(set (reg FLAGS_REG)
11750         (compare
11751           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11752                        (match_operand:QI 2 "const1_operand" "I"))
11753           (const_int 0)))
11754    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11755         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11756   "ix86_match_ccmode (insn, CCGOCmode)
11757    && (TARGET_SHIFT1 || optimize_size)
11758    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11759   "sar{b}\t%0"
11760   [(set_attr "type" "ishift")
11761    (set (attr "length") 
11762      (if_then_else (match_operand 0 "register_operand" "") 
11763         (const_string "2")
11764         (const_string "*")))])
11765
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags.  We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*ashrqi3_cmp"
11770   [(set (reg FLAGS_REG)
11771         (compare
11772           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11773                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11774           (const_int 0)))
11775    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11776         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11777   "ix86_match_ccmode (insn, CCGOCmode)
11778    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11779   "sar{b}\t{%2, %0|%0, %2}"
11780   [(set_attr "type" "ishift")
11781    (set_attr "mode" "QI")])
11782 \f
11783 ;; Logical shift instructions
11784
11785 ;; See comment above `ashldi3' about how this works.
11786
11787 (define_expand "lshrdi3"
11788   [(set (match_operand:DI 0 "shiftdi_operand" "")
11789         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11790                      (match_operand:QI 2 "nonmemory_operand" "")))]
11791   ""
11792   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11793
11794 (define_insn "*lshrdi3_1_one_bit_rex64"
11795   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11796         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11797                      (match_operand:QI 2 "const1_operand" "")))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11800    && (TARGET_SHIFT1 || optimize_size)"
11801   "shr{q}\t%0"
11802   [(set_attr "type" "ishift")
11803    (set (attr "length") 
11804      (if_then_else (match_operand:DI 0 "register_operand" "") 
11805         (const_string "2")
11806         (const_string "*")))])
11807
11808 (define_insn "*lshrdi3_1_rex64"
11809   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11810         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11811                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11814   "@
11815    shr{q}\t{%2, %0|%0, %2}
11816    shr{q}\t{%b2, %0|%0, %b2}"
11817   [(set_attr "type" "ishift")
11818    (set_attr "mode" "DI")])
11819
11820 ;; This pattern can't accept a variable shift count, since shifts by
11821 ;; zero don't affect the flags.  We assume that shifts by constant
11822 ;; zero are optimized away.
11823 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11824   [(set (reg FLAGS_REG)
11825         (compare
11826           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11827                        (match_operand:QI 2 "const1_operand" ""))
11828           (const_int 0)))
11829    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11830         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11831   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11832    && (TARGET_SHIFT1 || optimize_size)
11833    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11834   "shr{q}\t%0"
11835   [(set_attr "type" "ishift")
11836    (set (attr "length") 
11837      (if_then_else (match_operand:DI 0 "register_operand" "") 
11838         (const_string "2")
11839         (const_string "*")))])
11840
11841 ;; This pattern can't accept a variable shift count, since shifts by
11842 ;; zero don't affect the flags.  We assume that shifts by constant
11843 ;; zero are optimized away.
11844 (define_insn "*lshrdi3_cmp_rex64"
11845   [(set (reg FLAGS_REG)
11846         (compare
11847           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11848                        (match_operand:QI 2 "const_int_operand" "e"))
11849           (const_int 0)))
11850    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11851         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11852   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11853    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11854   "shr{q}\t{%2, %0|%0, %2}"
11855   [(set_attr "type" "ishift")
11856    (set_attr "mode" "DI")])
11857
11858 (define_insn "*lshrdi3_1"
11859   [(set (match_operand:DI 0 "register_operand" "=r")
11860         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11861                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11862    (clobber (reg:CC FLAGS_REG))]
11863   "!TARGET_64BIT"
11864   "#"
11865   [(set_attr "type" "multi")])
11866
11867 ;; By default we don't ask for a scratch register, because when DImode
11868 ;; values are manipulated, registers are already at a premium.  But if
11869 ;; we have one handy, we won't turn it away.
11870 (define_peephole2
11871   [(match_scratch:SI 3 "r")
11872    (parallel [(set (match_operand:DI 0 "register_operand" "")
11873                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11874                                 (match_operand:QI 2 "nonmemory_operand" "")))
11875               (clobber (reg:CC FLAGS_REG))])
11876    (match_dup 3)]
11877   "!TARGET_64BIT && TARGET_CMOVE"
11878   [(const_int 0)]
11879   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11880
11881 (define_split 
11882   [(set (match_operand:DI 0 "register_operand" "")
11883         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11884                      (match_operand:QI 2 "nonmemory_operand" "")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11887   [(const_int 0)]
11888   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11889
11890 (define_expand "lshrsi3"
11891   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11892         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11893                      (match_operand:QI 2 "nonmemory_operand" "")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   ""
11896   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11897
11898 (define_insn "*lshrsi3_1_one_bit"
11899   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11900         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11901                      (match_operand:QI 2 "const1_operand" "")))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11904    && (TARGET_SHIFT1 || optimize_size)"
11905   "shr{l}\t%0"
11906   [(set_attr "type" "ishift")
11907    (set (attr "length") 
11908      (if_then_else (match_operand:SI 0 "register_operand" "") 
11909         (const_string "2")
11910         (const_string "*")))])
11911
11912 (define_insn "*lshrsi3_1_one_bit_zext"
11913   [(set (match_operand:DI 0 "register_operand" "=r")
11914         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11915                      (match_operand:QI 2 "const1_operand" "")))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11918    && (TARGET_SHIFT1 || optimize_size)"
11919   "shr{l}\t%k0"
11920   [(set_attr "type" "ishift")
11921    (set_attr "length" "2")])
11922
11923 (define_insn "*lshrsi3_1"
11924   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11925         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11929   "@
11930    shr{l}\t{%2, %0|%0, %2}
11931    shr{l}\t{%b2, %0|%0, %b2}"
11932   [(set_attr "type" "ishift")
11933    (set_attr "mode" "SI")])
11934
11935 (define_insn "*lshrsi3_1_zext"
11936   [(set (match_operand:DI 0 "register_operand" "=r,r")
11937         (zero_extend:DI
11938           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11939                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11942   "@
11943    shr{l}\t{%2, %k0|%k0, %2}
11944    shr{l}\t{%b2, %k0|%k0, %b2}"
11945   [(set_attr "type" "ishift")
11946    (set_attr "mode" "SI")])
11947
11948 ;; This pattern can't accept a variable shift count, since shifts by
11949 ;; zero don't affect the flags.  We assume that shifts by constant
11950 ;; zero are optimized away.
11951 (define_insn "*lshrsi3_one_bit_cmp"
11952   [(set (reg FLAGS_REG)
11953         (compare
11954           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11955                        (match_operand:QI 2 "const1_operand" ""))
11956           (const_int 0)))
11957    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11958         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11959   "ix86_match_ccmode (insn, CCGOCmode)
11960    && (TARGET_SHIFT1 || optimize_size)
11961    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11962   "shr{l}\t%0"
11963   [(set_attr "type" "ishift")
11964    (set (attr "length") 
11965      (if_then_else (match_operand:SI 0 "register_operand" "") 
11966         (const_string "2")
11967         (const_string "*")))])
11968
11969 (define_insn "*lshrsi3_cmp_one_bit_zext"
11970   [(set (reg FLAGS_REG)
11971         (compare
11972           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11973                        (match_operand:QI 2 "const1_operand" ""))
11974           (const_int 0)))
11975    (set (match_operand:DI 0 "register_operand" "=r")
11976         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11977   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11980   "shr{l}\t%k0"
11981   [(set_attr "type" "ishift")
11982    (set_attr "length" "2")])
11983
11984 ;; This pattern can't accept a variable shift count, since shifts by
11985 ;; zero don't affect the flags.  We assume that shifts by constant
11986 ;; zero are optimized away.
11987 (define_insn "*lshrsi3_cmp"
11988   [(set (reg FLAGS_REG)
11989         (compare
11990           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11992           (const_int 0)))
11993    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11994         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11995   "ix86_match_ccmode (insn, CCGOCmode)
11996    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11997   "shr{l}\t{%2, %0|%0, %2}"
11998   [(set_attr "type" "ishift")
11999    (set_attr "mode" "SI")])
12000
12001 (define_insn "*lshrsi3_cmp_zext"
12002   [(set (reg FLAGS_REG)
12003         (compare
12004           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12006           (const_int 0)))
12007    (set (match_operand:DI 0 "register_operand" "=r")
12008         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12011   "shr{l}\t{%2, %k0|%k0, %2}"
12012   [(set_attr "type" "ishift")
12013    (set_attr "mode" "SI")])
12014
12015 (define_expand "lshrhi3"
12016   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12017         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12018                      (match_operand:QI 2 "nonmemory_operand" "")))
12019    (clobber (reg:CC FLAGS_REG))]
12020   "TARGET_HIMODE_MATH"
12021   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12022
12023 (define_insn "*lshrhi3_1_one_bit"
12024   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12025         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12026                      (match_operand:QI 2 "const1_operand" "")))
12027    (clobber (reg:CC FLAGS_REG))]
12028   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12029    && (TARGET_SHIFT1 || optimize_size)"
12030   "shr{w}\t%0"
12031   [(set_attr "type" "ishift")
12032    (set (attr "length") 
12033      (if_then_else (match_operand 0 "register_operand" "") 
12034         (const_string "2")
12035         (const_string "*")))])
12036
12037 (define_insn "*lshrhi3_1"
12038   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12039         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12040                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12041    (clobber (reg:CC FLAGS_REG))]
12042   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12043   "@
12044    shr{w}\t{%2, %0|%0, %2}
12045    shr{w}\t{%b2, %0|%0, %b2}"
12046   [(set_attr "type" "ishift")
12047    (set_attr "mode" "HI")])
12048
12049 ;; This pattern can't accept a variable shift count, since shifts by
12050 ;; zero don't affect the flags.  We assume that shifts by constant
12051 ;; zero are optimized away.
12052 (define_insn "*lshrhi3_one_bit_cmp"
12053   [(set (reg FLAGS_REG)
12054         (compare
12055           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12056                        (match_operand:QI 2 "const1_operand" ""))
12057           (const_int 0)))
12058    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12059         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12060   "ix86_match_ccmode (insn, CCGOCmode)
12061    && (TARGET_SHIFT1 || optimize_size)
12062    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063   "shr{w}\t%0"
12064   [(set_attr "type" "ishift")
12065    (set (attr "length") 
12066      (if_then_else (match_operand:SI 0 "register_operand" "") 
12067         (const_string "2")
12068         (const_string "*")))])
12069
12070 ;; This pattern can't accept a variable shift count, since shifts by
12071 ;; zero don't affect the flags.  We assume that shifts by constant
12072 ;; zero are optimized away.
12073 (define_insn "*lshrhi3_cmp"
12074   [(set (reg FLAGS_REG)
12075         (compare
12076           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12077                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12078           (const_int 0)))
12079    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12080         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12081   "ix86_match_ccmode (insn, CCGOCmode)
12082    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12083   "shr{w}\t{%2, %0|%0, %2}"
12084   [(set_attr "type" "ishift")
12085    (set_attr "mode" "HI")])
12086
12087 (define_expand "lshrqi3"
12088   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12089         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12090                      (match_operand:QI 2 "nonmemory_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "TARGET_QIMODE_MATH"
12093   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12094
12095 (define_insn "*lshrqi3_1_one_bit"
12096   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12097         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12098                      (match_operand:QI 2 "const1_operand" "")))
12099    (clobber (reg:CC FLAGS_REG))]
12100   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12101    && (TARGET_SHIFT1 || optimize_size)"
12102   "shr{b}\t%0"
12103   [(set_attr "type" "ishift")
12104    (set (attr "length") 
12105      (if_then_else (match_operand 0 "register_operand" "") 
12106         (const_string "2")
12107         (const_string "*")))])
12108
12109 (define_insn "*lshrqi3_1_one_bit_slp"
12110   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12111         (lshiftrt:QI (match_dup 0)
12112                      (match_operand:QI 1 "const1_operand" "")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12115    && (TARGET_SHIFT1 || optimize_size)"
12116   "shr{b}\t%0"
12117   [(set_attr "type" "ishift1")
12118    (set (attr "length") 
12119      (if_then_else (match_operand 0 "register_operand" "") 
12120         (const_string "2")
12121         (const_string "*")))])
12122
12123 (define_insn "*lshrqi3_1"
12124   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12125         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12126                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12129   "@
12130    shr{b}\t{%2, %0|%0, %2}
12131    shr{b}\t{%b2, %0|%0, %b2}"
12132   [(set_attr "type" "ishift")
12133    (set_attr "mode" "QI")])
12134
12135 (define_insn "*lshrqi3_1_slp"
12136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12137         (lshiftrt:QI (match_dup 0)
12138                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12142   "@
12143    shr{b}\t{%1, %0|%0, %1}
12144    shr{b}\t{%b1, %0|%0, %b1}"
12145   [(set_attr "type" "ishift1")
12146    (set_attr "mode" "QI")])
12147
12148 ;; This pattern can't accept a variable shift count, since shifts by
12149 ;; zero don't affect the flags.  We assume that shifts by constant
12150 ;; zero are optimized away.
12151 (define_insn "*lshrqi2_one_bit_cmp"
12152   [(set (reg FLAGS_REG)
12153         (compare
12154           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12155                        (match_operand:QI 2 "const1_operand" ""))
12156           (const_int 0)))
12157    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12158         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12159   "ix86_match_ccmode (insn, CCGOCmode)
12160    && (TARGET_SHIFT1 || optimize_size)
12161    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12162   "shr{b}\t%0"
12163   [(set_attr "type" "ishift")
12164    (set (attr "length") 
12165      (if_then_else (match_operand:SI 0 "register_operand" "") 
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 ;; This pattern can't accept a variable shift count, since shifts by
12170 ;; zero don't affect the flags.  We assume that shifts by constant
12171 ;; zero are optimized away.
12172 (define_insn "*lshrqi2_cmp"
12173   [(set (reg FLAGS_REG)
12174         (compare
12175           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12176                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12177           (const_int 0)))
12178    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12179         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12180   "ix86_match_ccmode (insn, CCGOCmode)
12181    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12182   "shr{b}\t{%2, %0|%0, %2}"
12183   [(set_attr "type" "ishift")
12184    (set_attr "mode" "QI")])
12185 \f
12186 ;; Rotate instructions
12187
12188 (define_expand "rotldi3"
12189   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12190         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12191                    (match_operand:QI 2 "nonmemory_operand" "")))
12192    (clobber (reg:CC FLAGS_REG))]
12193   "TARGET_64BIT"
12194   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12195
12196 (define_insn "*rotlsi3_1_one_bit_rex64"
12197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12198         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12199                    (match_operand:QI 2 "const1_operand" "")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12202    && (TARGET_SHIFT1 || optimize_size)"
12203   "rol{q}\t%0"
12204   [(set_attr "type" "rotate")
12205    (set (attr "length") 
12206      (if_then_else (match_operand:DI 0 "register_operand" "") 
12207         (const_string "2")
12208         (const_string "*")))])
12209
12210 (define_insn "*rotldi3_1_rex64"
12211   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12212         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12213                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12214    (clobber (reg:CC FLAGS_REG))]
12215   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12216   "@
12217    rol{q}\t{%2, %0|%0, %2}
12218    rol{q}\t{%b2, %0|%0, %b2}"
12219   [(set_attr "type" "rotate")
12220    (set_attr "mode" "DI")])
12221
12222 (define_expand "rotlsi3"
12223   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12224         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12225                    (match_operand:QI 2 "nonmemory_operand" "")))
12226    (clobber (reg:CC FLAGS_REG))]
12227   ""
12228   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12229
12230 (define_insn "*rotlsi3_1_one_bit"
12231   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12232         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233                    (match_operand:QI 2 "const1_operand" "")))
12234    (clobber (reg:CC FLAGS_REG))]
12235   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12236    && (TARGET_SHIFT1 || optimize_size)"
12237   "rol{l}\t%0"
12238   [(set_attr "type" "rotate")
12239    (set (attr "length") 
12240      (if_then_else (match_operand:SI 0 "register_operand" "") 
12241         (const_string "2")
12242         (const_string "*")))])
12243
12244 (define_insn "*rotlsi3_1_one_bit_zext"
12245   [(set (match_operand:DI 0 "register_operand" "=r")
12246         (zero_extend:DI
12247           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12248                      (match_operand:QI 2 "const1_operand" ""))))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12251    && (TARGET_SHIFT1 || optimize_size)"
12252   "rol{l}\t%k0"
12253   [(set_attr "type" "rotate")
12254    (set_attr "length" "2")])
12255
12256 (define_insn "*rotlsi3_1"
12257   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12258         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12259                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12260    (clobber (reg:CC FLAGS_REG))]
12261   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12262   "@
12263    rol{l}\t{%2, %0|%0, %2}
12264    rol{l}\t{%b2, %0|%0, %b2}"
12265   [(set_attr "type" "rotate")
12266    (set_attr "mode" "SI")])
12267
12268 (define_insn "*rotlsi3_1_zext"
12269   [(set (match_operand:DI 0 "register_operand" "=r,r")
12270         (zero_extend:DI
12271           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12272                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12273    (clobber (reg:CC FLAGS_REG))]
12274   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12275   "@
12276    rol{l}\t{%2, %k0|%k0, %2}
12277    rol{l}\t{%b2, %k0|%k0, %b2}"
12278   [(set_attr "type" "rotate")
12279    (set_attr "mode" "SI")])
12280
12281 (define_expand "rotlhi3"
12282   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12283         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12284                    (match_operand:QI 2 "nonmemory_operand" "")))
12285    (clobber (reg:CC FLAGS_REG))]
12286   "TARGET_HIMODE_MATH"
12287   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12288
12289 (define_insn "*rotlhi3_1_one_bit"
12290   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12291         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12292                    (match_operand:QI 2 "const1_operand" "")))
12293    (clobber (reg:CC FLAGS_REG))]
12294   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12295    && (TARGET_SHIFT1 || optimize_size)"
12296   "rol{w}\t%0"
12297   [(set_attr "type" "rotate")
12298    (set (attr "length") 
12299      (if_then_else (match_operand 0 "register_operand" "") 
12300         (const_string "2")
12301         (const_string "*")))])
12302
12303 (define_insn "*rotlhi3_1"
12304   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12305         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12306                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12307    (clobber (reg:CC FLAGS_REG))]
12308   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12309   "@
12310    rol{w}\t{%2, %0|%0, %2}
12311    rol{w}\t{%b2, %0|%0, %b2}"
12312   [(set_attr "type" "rotate")
12313    (set_attr "mode" "HI")])
12314
12315 (define_expand "rotlqi3"
12316   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12317         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12318                    (match_operand:QI 2 "nonmemory_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "TARGET_QIMODE_MATH"
12321   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12322
12323 (define_insn "*rotlqi3_1_one_bit_slp"
12324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12325         (rotate:QI (match_dup 0)
12326                    (match_operand:QI 1 "const1_operand" "")))
12327    (clobber (reg:CC FLAGS_REG))]
12328   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12329    && (TARGET_SHIFT1 || optimize_size)"
12330   "rol{b}\t%0"
12331   [(set_attr "type" "rotate1")
12332    (set (attr "length") 
12333      (if_then_else (match_operand 0 "register_operand" "") 
12334         (const_string "2")
12335         (const_string "*")))])
12336
12337 (define_insn "*rotlqi3_1_one_bit"
12338   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12339         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12340                    (match_operand:QI 2 "const1_operand" "")))
12341    (clobber (reg:CC FLAGS_REG))]
12342   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12343    && (TARGET_SHIFT1 || optimize_size)"
12344   "rol{b}\t%0"
12345   [(set_attr "type" "rotate")
12346    (set (attr "length") 
12347      (if_then_else (match_operand 0 "register_operand" "") 
12348         (const_string "2")
12349         (const_string "*")))])
12350
12351 (define_insn "*rotlqi3_1_slp"
12352   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12353         (rotate:QI (match_dup 0)
12354                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12355    (clobber (reg:CC FLAGS_REG))]
12356   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12357    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12358   "@
12359    rol{b}\t{%1, %0|%0, %1}
12360    rol{b}\t{%b1, %0|%0, %b1}"
12361   [(set_attr "type" "rotate1")
12362    (set_attr "mode" "QI")])
12363
12364 (define_insn "*rotlqi3_1"
12365   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12366         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12367                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12370   "@
12371    rol{b}\t{%2, %0|%0, %2}
12372    rol{b}\t{%b2, %0|%0, %b2}"
12373   [(set_attr "type" "rotate")
12374    (set_attr "mode" "QI")])
12375
12376 (define_expand "rotrdi3"
12377   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12378         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12379                      (match_operand:QI 2 "nonmemory_operand" "")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "TARGET_64BIT"
12382   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12383
12384 (define_insn "*rotrdi3_1_one_bit_rex64"
12385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12386         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12387                      (match_operand:QI 2 "const1_operand" "")))
12388    (clobber (reg:CC FLAGS_REG))]
12389   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12390    && (TARGET_SHIFT1 || optimize_size)"
12391   "ror{q}\t%0"
12392   [(set_attr "type" "rotate")
12393    (set (attr "length") 
12394      (if_then_else (match_operand:DI 0 "register_operand" "") 
12395         (const_string "2")
12396         (const_string "*")))])
12397
12398 (define_insn "*rotrdi3_1_rex64"
12399   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12400         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12401                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12402    (clobber (reg:CC FLAGS_REG))]
12403   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12404   "@
12405    ror{q}\t{%2, %0|%0, %2}
12406    ror{q}\t{%b2, %0|%0, %b2}"
12407   [(set_attr "type" "rotate")
12408    (set_attr "mode" "DI")])
12409
12410 (define_expand "rotrsi3"
12411   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12412         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12413                      (match_operand:QI 2 "nonmemory_operand" "")))
12414    (clobber (reg:CC FLAGS_REG))]
12415   ""
12416   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12417
12418 (define_insn "*rotrsi3_1_one_bit"
12419   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12420         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12421                      (match_operand:QI 2 "const1_operand" "")))
12422    (clobber (reg:CC FLAGS_REG))]
12423   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12424    && (TARGET_SHIFT1 || optimize_size)"
12425   "ror{l}\t%0"
12426   [(set_attr "type" "rotate")
12427    (set (attr "length") 
12428      (if_then_else (match_operand:SI 0 "register_operand" "") 
12429         (const_string "2")
12430         (const_string "*")))])
12431
12432 (define_insn "*rotrsi3_1_one_bit_zext"
12433   [(set (match_operand:DI 0 "register_operand" "=r")
12434         (zero_extend:DI
12435           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12436                        (match_operand:QI 2 "const1_operand" ""))))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12439    && (TARGET_SHIFT1 || optimize_size)"
12440   "ror{l}\t%k0"
12441   [(set_attr "type" "rotate")
12442    (set (attr "length") 
12443      (if_then_else (match_operand:SI 0 "register_operand" "") 
12444         (const_string "2")
12445         (const_string "*")))])
12446
12447 (define_insn "*rotrsi3_1"
12448   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12449         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12450                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12453   "@
12454    ror{l}\t{%2, %0|%0, %2}
12455    ror{l}\t{%b2, %0|%0, %b2}"
12456   [(set_attr "type" "rotate")
12457    (set_attr "mode" "SI")])
12458
12459 (define_insn "*rotrsi3_1_zext"
12460   [(set (match_operand:DI 0 "register_operand" "=r,r")
12461         (zero_extend:DI
12462           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12463                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12466   "@
12467    ror{l}\t{%2, %k0|%k0, %2}
12468    ror{l}\t{%b2, %k0|%k0, %b2}"
12469   [(set_attr "type" "rotate")
12470    (set_attr "mode" "SI")])
12471
12472 (define_expand "rotrhi3"
12473   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12474         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12475                      (match_operand:QI 2 "nonmemory_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   "TARGET_HIMODE_MATH"
12478   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12479
12480 (define_insn "*rotrhi3_one_bit"
12481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12482         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12483                      (match_operand:QI 2 "const1_operand" "")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12486    && (TARGET_SHIFT1 || optimize_size)"
12487   "ror{w}\t%0"
12488   [(set_attr "type" "rotate")
12489    (set (attr "length") 
12490      (if_then_else (match_operand 0 "register_operand" "") 
12491         (const_string "2")
12492         (const_string "*")))])
12493
12494 (define_insn "*rotrhi3"
12495   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12496         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12497                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12500   "@
12501    ror{w}\t{%2, %0|%0, %2}
12502    ror{w}\t{%b2, %0|%0, %b2}"
12503   [(set_attr "type" "rotate")
12504    (set_attr "mode" "HI")])
12505
12506 (define_expand "rotrqi3"
12507   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12508         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12509                      (match_operand:QI 2 "nonmemory_operand" "")))
12510    (clobber (reg:CC FLAGS_REG))]
12511   "TARGET_QIMODE_MATH"
12512   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12513
12514 (define_insn "*rotrqi3_1_one_bit"
12515   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12516         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12517                      (match_operand:QI 2 "const1_operand" "")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12520    && (TARGET_SHIFT1 || optimize_size)"
12521   "ror{b}\t%0"
12522   [(set_attr "type" "rotate")
12523    (set (attr "length") 
12524      (if_then_else (match_operand 0 "register_operand" "") 
12525         (const_string "2")
12526         (const_string "*")))])
12527
12528 (define_insn "*rotrqi3_1_one_bit_slp"
12529   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12530         (rotatert:QI (match_dup 0)
12531                      (match_operand:QI 1 "const1_operand" "")))
12532    (clobber (reg:CC FLAGS_REG))]
12533   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12534    && (TARGET_SHIFT1 || optimize_size)"
12535   "ror{b}\t%0"
12536   [(set_attr "type" "rotate1")
12537    (set (attr "length") 
12538      (if_then_else (match_operand 0 "register_operand" "") 
12539         (const_string "2")
12540         (const_string "*")))])
12541
12542 (define_insn "*rotrqi3_1"
12543   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12544         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12545                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12546    (clobber (reg:CC FLAGS_REG))]
12547   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12548   "@
12549    ror{b}\t{%2, %0|%0, %2}
12550    ror{b}\t{%b2, %0|%0, %b2}"
12551   [(set_attr "type" "rotate")
12552    (set_attr "mode" "QI")])
12553
12554 (define_insn "*rotrqi3_1_slp"
12555   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12556         (rotatert:QI (match_dup 0)
12557                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12558    (clobber (reg:CC FLAGS_REG))]
12559   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12561   "@
12562    ror{b}\t{%1, %0|%0, %1}
12563    ror{b}\t{%b1, %0|%0, %b1}"
12564   [(set_attr "type" "rotate1")
12565    (set_attr "mode" "QI")])
12566 \f
12567 ;; Bit set / bit test instructions
12568
12569 (define_expand "extv"
12570   [(set (match_operand:SI 0 "register_operand" "")
12571         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12572                          (match_operand:SI 2 "immediate_operand" "")
12573                          (match_operand:SI 3 "immediate_operand" "")))]
12574   ""
12575 {
12576   /* Handle extractions from %ah et al.  */
12577   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12578     FAIL;
12579
12580   /* From mips.md: extract_bit_field doesn't verify that our source
12581      matches the predicate, so check it again here.  */
12582   if (! register_operand (operands[1], VOIDmode))
12583     FAIL;
12584 })
12585
12586 (define_expand "extzv"
12587   [(set (match_operand:SI 0 "register_operand" "")
12588         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12589                          (match_operand:SI 2 "immediate_operand" "")
12590                          (match_operand:SI 3 "immediate_operand" "")))]
12591   ""
12592 {
12593   /* Handle extractions from %ah et al.  */
12594   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12595     FAIL;
12596
12597   /* From mips.md: extract_bit_field doesn't verify that our source
12598      matches the predicate, so check it again here.  */
12599   if (! register_operand (operands[1], VOIDmode))
12600     FAIL;
12601 })
12602
12603 (define_expand "insv"
12604   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12605                       (match_operand 1 "immediate_operand" "")
12606                       (match_operand 2 "immediate_operand" ""))
12607         (match_operand 3 "register_operand" ""))]
12608   ""
12609 {
12610   /* Handle extractions from %ah et al.  */
12611   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12612     FAIL;
12613
12614   /* From mips.md: insert_bit_field doesn't verify that our source
12615      matches the predicate, so check it again here.  */
12616   if (! register_operand (operands[0], VOIDmode))
12617     FAIL;
12618
12619   if (TARGET_64BIT)
12620     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12621   else
12622     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12623
12624   DONE;
12625 })
12626
12627 ;; %%% bts, btr, btc, bt.
12628 \f
12629 ;; Store-flag instructions.
12630
12631 ;; For all sCOND expanders, also expand the compare or test insn that
12632 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12633
12634 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12635 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12636 ;; way, which can later delete the movzx if only QImode is needed.
12637
12638 (define_expand "seq"
12639   [(set (match_operand:QI 0 "register_operand" "")
12640         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12641   ""
12642   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12643
12644 (define_expand "sne"
12645   [(set (match_operand:QI 0 "register_operand" "")
12646         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12647   ""
12648   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12649
12650 (define_expand "sgt"
12651   [(set (match_operand:QI 0 "register_operand" "")
12652         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12653   ""
12654   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12655
12656 (define_expand "sgtu"
12657   [(set (match_operand:QI 0 "register_operand" "")
12658         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12659   ""
12660   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12661
12662 (define_expand "slt"
12663   [(set (match_operand:QI 0 "register_operand" "")
12664         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12665   ""
12666   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12667
12668 (define_expand "sltu"
12669   [(set (match_operand:QI 0 "register_operand" "")
12670         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12671   ""
12672   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sge"
12675   [(set (match_operand:QI 0 "register_operand" "")
12676         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12677   ""
12678   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sgeu"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   ""
12684   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sle"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   ""
12690   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sleu"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   ""
12696   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sunordered"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   "TARGET_80387 || TARGET_SSE"
12702   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sordered"
12705   [(set (match_operand:QI 0 "register_operand" "")
12706         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707   "TARGET_80387"
12708   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "suneq"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   "TARGET_80387 || TARGET_SSE"
12714   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sunge"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   "TARGET_80387 || TARGET_SSE"
12720   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sungt"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   "TARGET_80387 || TARGET_SSE"
12726   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sunle"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   "TARGET_80387 || TARGET_SSE"
12732   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sunlt"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   "TARGET_80387 || TARGET_SSE"
12738   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sltgt"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   "TARGET_80387 || TARGET_SSE"
12744   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12745
12746 (define_insn "*setcc_1"
12747   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12748         (match_operator:QI 1 "ix86_comparison_operator"
12749           [(reg FLAGS_REG) (const_int 0)]))]
12750   ""
12751   "set%C1\t%0"
12752   [(set_attr "type" "setcc")
12753    (set_attr "mode" "QI")])
12754
12755 (define_insn "*setcc_2"
12756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757         (match_operator:QI 1 "ix86_comparison_operator"
12758           [(reg FLAGS_REG) (const_int 0)]))]
12759   ""
12760   "set%C1\t%0"
12761   [(set_attr "type" "setcc")
12762    (set_attr "mode" "QI")])
12763
12764 ;; In general it is not safe to assume too much about CCmode registers,
12765 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12766 ;; conditions this is safe on x86, so help combine not create
12767 ;;
12768 ;;      seta    %al
12769 ;;      testb   %al, %al
12770 ;;      sete    %al
12771
12772 (define_split 
12773   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12774         (ne:QI (match_operator 1 "ix86_comparison_operator"
12775                  [(reg FLAGS_REG) (const_int 0)])
12776             (const_int 0)))]
12777   ""
12778   [(set (match_dup 0) (match_dup 1))]
12779 {
12780   PUT_MODE (operands[1], QImode);
12781 })
12782
12783 (define_split 
12784   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12785         (ne:QI (match_operator 1 "ix86_comparison_operator"
12786                  [(reg FLAGS_REG) (const_int 0)])
12787             (const_int 0)))]
12788   ""
12789   [(set (match_dup 0) (match_dup 1))]
12790 {
12791   PUT_MODE (operands[1], QImode);
12792 })
12793
12794 (define_split 
12795   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12796         (eq:QI (match_operator 1 "ix86_comparison_operator"
12797                  [(reg FLAGS_REG) (const_int 0)])
12798             (const_int 0)))]
12799   ""
12800   [(set (match_dup 0) (match_dup 1))]
12801 {
12802   rtx new_op1 = copy_rtx (operands[1]);
12803   operands[1] = new_op1;
12804   PUT_MODE (new_op1, QImode);
12805   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12806                                              GET_MODE (XEXP (new_op1, 0))));
12807
12808   /* Make sure that (a) the CCmode we have for the flags is strong
12809      enough for the reversed compare or (b) we have a valid FP compare.  */
12810   if (! ix86_comparison_operator (new_op1, VOIDmode))
12811     FAIL;
12812 })
12813
12814 (define_split 
12815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12816         (eq:QI (match_operator 1 "ix86_comparison_operator"
12817                  [(reg FLAGS_REG) (const_int 0)])
12818             (const_int 0)))]
12819   ""
12820   [(set (match_dup 0) (match_dup 1))]
12821 {
12822   rtx new_op1 = copy_rtx (operands[1]);
12823   operands[1] = new_op1;
12824   PUT_MODE (new_op1, QImode);
12825   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12826                                              GET_MODE (XEXP (new_op1, 0))));
12827
12828   /* Make sure that (a) the CCmode we have for the flags is strong
12829      enough for the reversed compare or (b) we have a valid FP compare.  */
12830   if (! ix86_comparison_operator (new_op1, VOIDmode))
12831     FAIL;
12832 })
12833
12834 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12835 ;; subsequent logical operations are used to imitate conditional moves.
12836 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12837 ;; it directly.  Further holding this value in pseudo register might bring
12838 ;; problem in implicit normalization in spill code.
12839 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12840 ;; instructions after reload by splitting the conditional move patterns.
12841
12842 (define_insn "*sse_setccsf"
12843   [(set (match_operand:SF 0 "register_operand" "=x")
12844         (match_operator:SF 1 "sse_comparison_operator"
12845           [(match_operand:SF 2 "register_operand" "0")
12846            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12847   "TARGET_SSE && reload_completed"
12848   "cmp%D1ss\t{%3, %0|%0, %3}"
12849   [(set_attr "type" "ssecmp")
12850    (set_attr "mode" "SF")])
12851
12852 (define_insn "*sse_setccdf"
12853   [(set (match_operand:DF 0 "register_operand" "=Y")
12854         (match_operator:DF 1 "sse_comparison_operator"
12855           [(match_operand:DF 2 "register_operand" "0")
12856            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12857   "TARGET_SSE2 && reload_completed"
12858   "cmp%D1sd\t{%3, %0|%0, %3}"
12859   [(set_attr "type" "ssecmp")
12860    (set_attr "mode" "DF")])
12861 \f
12862 ;; Basic conditional jump instructions.
12863 ;; We ignore the overflow flag for signed branch instructions.
12864
12865 ;; For all bCOND expanders, also expand the compare or test insn that
12866 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12867
12868 (define_expand "beq"
12869   [(set (pc)
12870         (if_then_else (match_dup 1)
12871                       (label_ref (match_operand 0 "" ""))
12872                       (pc)))]
12873   ""
12874   "ix86_expand_branch (EQ, operands[0]); DONE;")
12875
12876 (define_expand "bne"
12877   [(set (pc)
12878         (if_then_else (match_dup 1)
12879                       (label_ref (match_operand 0 "" ""))
12880                       (pc)))]
12881   ""
12882   "ix86_expand_branch (NE, operands[0]); DONE;")
12883
12884 (define_expand "bgt"
12885   [(set (pc)
12886         (if_then_else (match_dup 1)
12887                       (label_ref (match_operand 0 "" ""))
12888                       (pc)))]
12889   ""
12890   "ix86_expand_branch (GT, operands[0]); DONE;")
12891
12892 (define_expand "bgtu"
12893   [(set (pc)
12894         (if_then_else (match_dup 1)
12895                       (label_ref (match_operand 0 "" ""))
12896                       (pc)))]
12897   ""
12898   "ix86_expand_branch (GTU, operands[0]); DONE;")
12899
12900 (define_expand "blt"
12901   [(set (pc)
12902         (if_then_else (match_dup 1)
12903                       (label_ref (match_operand 0 "" ""))
12904                       (pc)))]
12905   ""
12906   "ix86_expand_branch (LT, operands[0]); DONE;")
12907
12908 (define_expand "bltu"
12909   [(set (pc)
12910         (if_then_else (match_dup 1)
12911                       (label_ref (match_operand 0 "" ""))
12912                       (pc)))]
12913   ""
12914   "ix86_expand_branch (LTU, operands[0]); DONE;")
12915
12916 (define_expand "bge"
12917   [(set (pc)
12918         (if_then_else (match_dup 1)
12919                       (label_ref (match_operand 0 "" ""))
12920                       (pc)))]
12921   ""
12922   "ix86_expand_branch (GE, operands[0]); DONE;")
12923
12924 (define_expand "bgeu"
12925   [(set (pc)
12926         (if_then_else (match_dup 1)
12927                       (label_ref (match_operand 0 "" ""))
12928                       (pc)))]
12929   ""
12930   "ix86_expand_branch (GEU, operands[0]); DONE;")
12931
12932 (define_expand "ble"
12933   [(set (pc)
12934         (if_then_else (match_dup 1)
12935                       (label_ref (match_operand 0 "" ""))
12936                       (pc)))]
12937   ""
12938   "ix86_expand_branch (LE, operands[0]); DONE;")
12939
12940 (define_expand "bleu"
12941   [(set (pc)
12942         (if_then_else (match_dup 1)
12943                       (label_ref (match_operand 0 "" ""))
12944                       (pc)))]
12945   ""
12946   "ix86_expand_branch (LEU, operands[0]); DONE;")
12947
12948 (define_expand "bunordered"
12949   [(set (pc)
12950         (if_then_else (match_dup 1)
12951                       (label_ref (match_operand 0 "" ""))
12952                       (pc)))]
12953   "TARGET_80387 || TARGET_SSE"
12954   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12955
12956 (define_expand "bordered"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   "TARGET_80387 || TARGET_SSE"
12962   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12963
12964 (define_expand "buneq"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   "TARGET_80387 || TARGET_SSE"
12970   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12971
12972 (define_expand "bunge"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   "TARGET_80387 || TARGET_SSE"
12978   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12979
12980 (define_expand "bungt"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   "TARGET_80387 || TARGET_SSE"
12986   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12987
12988 (define_expand "bunle"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   "TARGET_80387 || TARGET_SSE"
12994   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12995
12996 (define_expand "bunlt"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   "TARGET_80387 || TARGET_SSE"
13002   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13003
13004 (define_expand "bltgt"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   "TARGET_80387 || TARGET_SSE"
13010   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13011
13012 (define_insn "*jcc_1"
13013   [(set (pc)
13014         (if_then_else (match_operator 1 "ix86_comparison_operator"
13015                                       [(reg FLAGS_REG) (const_int 0)])
13016                       (label_ref (match_operand 0 "" ""))
13017                       (pc)))]
13018   ""
13019   "%+j%C1\t%l0"
13020   [(set_attr "type" "ibr")
13021    (set_attr "modrm" "0")
13022    (set (attr "length")
13023            (if_then_else (and (ge (minus (match_dup 0) (pc))
13024                                   (const_int -126))
13025                               (lt (minus (match_dup 0) (pc))
13026                                   (const_int 128)))
13027              (const_int 2)
13028              (const_int 6)))])
13029
13030 (define_insn "*jcc_2"
13031   [(set (pc)
13032         (if_then_else (match_operator 1 "ix86_comparison_operator"
13033                                       [(reg FLAGS_REG) (const_int 0)])
13034                       (pc)
13035                       (label_ref (match_operand 0 "" ""))))]
13036   ""
13037   "%+j%c1\t%l0"
13038   [(set_attr "type" "ibr")
13039    (set_attr "modrm" "0")
13040    (set (attr "length")
13041            (if_then_else (and (ge (minus (match_dup 0) (pc))
13042                                   (const_int -126))
13043                               (lt (minus (match_dup 0) (pc))
13044                                   (const_int 128)))
13045              (const_int 2)
13046              (const_int 6)))])
13047
13048 ;; In general it is not safe to assume too much about CCmode registers,
13049 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13050 ;; conditions this is safe on x86, so help combine not create
13051 ;;
13052 ;;      seta    %al
13053 ;;      testb   %al, %al
13054 ;;      je      Lfoo
13055
13056 (define_split 
13057   [(set (pc)
13058         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13059                                       [(reg FLAGS_REG) (const_int 0)])
13060                           (const_int 0))
13061                       (label_ref (match_operand 1 "" ""))
13062                       (pc)))]
13063   ""
13064   [(set (pc)
13065         (if_then_else (match_dup 0)
13066                       (label_ref (match_dup 1))
13067                       (pc)))]
13068 {
13069   PUT_MODE (operands[0], VOIDmode);
13070 })
13071   
13072 (define_split 
13073   [(set (pc)
13074         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13075                                       [(reg FLAGS_REG) (const_int 0)])
13076                           (const_int 0))
13077                       (label_ref (match_operand 1 "" ""))
13078                       (pc)))]
13079   ""
13080   [(set (pc)
13081         (if_then_else (match_dup 0)
13082                       (label_ref (match_dup 1))
13083                       (pc)))]
13084 {
13085   rtx new_op0 = copy_rtx (operands[0]);
13086   operands[0] = new_op0;
13087   PUT_MODE (new_op0, VOIDmode);
13088   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13089                                              GET_MODE (XEXP (new_op0, 0))));
13090
13091   /* Make sure that (a) the CCmode we have for the flags is strong
13092      enough for the reversed compare or (b) we have a valid FP compare.  */
13093   if (! ix86_comparison_operator (new_op0, VOIDmode))
13094     FAIL;
13095 })
13096
13097 ;; Define combination compare-and-branch fp compare instructions to use
13098 ;; during early optimization.  Splitting the operation apart early makes
13099 ;; for bad code when we want to reverse the operation.
13100
13101 (define_insn "*fp_jcc_1"
13102   [(set (pc)
13103         (if_then_else (match_operator 0 "comparison_operator"
13104                         [(match_operand 1 "register_operand" "f")
13105                          (match_operand 2 "register_operand" "f")])
13106           (label_ref (match_operand 3 "" ""))
13107           (pc)))
13108    (clobber (reg:CCFP FPSR_REG))
13109    (clobber (reg:CCFP FLAGS_REG))]
13110   "TARGET_CMOVE && TARGET_80387
13111    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13112    && FLOAT_MODE_P (GET_MODE (operands[1]))
13113    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13114    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13115   "#")
13116
13117 (define_insn "*fp_jcc_1_sse"
13118   [(set (pc)
13119         (if_then_else (match_operator 0 "comparison_operator"
13120                         [(match_operand 1 "register_operand" "f#x,x#f")
13121                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13122           (label_ref (match_operand 3 "" ""))
13123           (pc)))
13124    (clobber (reg:CCFP FPSR_REG))
13125    (clobber (reg:CCFP FLAGS_REG))]
13126   "TARGET_80387
13127    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13128    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13129    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13130   "#")
13131
13132 (define_insn "*fp_jcc_1_sse_only"
13133   [(set (pc)
13134         (if_then_else (match_operator 0 "comparison_operator"
13135                         [(match_operand 1 "register_operand" "x")
13136                          (match_operand 2 "nonimmediate_operand" "xm")])
13137           (label_ref (match_operand 3 "" ""))
13138           (pc)))
13139    (clobber (reg:CCFP FPSR_REG))
13140    (clobber (reg:CCFP FLAGS_REG))]
13141   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13142    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13143    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13144   "#")
13145
13146 (define_insn "*fp_jcc_2"
13147   [(set (pc)
13148         (if_then_else (match_operator 0 "comparison_operator"
13149                         [(match_operand 1 "register_operand" "f")
13150                          (match_operand 2 "register_operand" "f")])
13151           (pc)
13152           (label_ref (match_operand 3 "" ""))))
13153    (clobber (reg:CCFP FPSR_REG))
13154    (clobber (reg:CCFP FLAGS_REG))]
13155   "TARGET_CMOVE && TARGET_80387
13156    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13157    && FLOAT_MODE_P (GET_MODE (operands[1]))
13158    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13159    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13160   "#")
13161
13162 (define_insn "*fp_jcc_2_sse"
13163   [(set (pc)
13164         (if_then_else (match_operator 0 "comparison_operator"
13165                         [(match_operand 1 "register_operand" "f#x,x#f")
13166                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13167           (pc)
13168           (label_ref (match_operand 3 "" ""))))
13169    (clobber (reg:CCFP FPSR_REG))
13170    (clobber (reg:CCFP FLAGS_REG))]
13171   "TARGET_80387
13172    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13173    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13174    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13175   "#")
13176
13177 (define_insn "*fp_jcc_2_sse_only"
13178   [(set (pc)
13179         (if_then_else (match_operator 0 "comparison_operator"
13180                         [(match_operand 1 "register_operand" "x")
13181                          (match_operand 2 "nonimmediate_operand" "xm")])
13182           (pc)
13183           (label_ref (match_operand 3 "" ""))))
13184    (clobber (reg:CCFP FPSR_REG))
13185    (clobber (reg:CCFP FLAGS_REG))]
13186   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13187    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13188    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13189   "#")
13190
13191 (define_insn "*fp_jcc_3"
13192   [(set (pc)
13193         (if_then_else (match_operator 0 "comparison_operator"
13194                         [(match_operand 1 "register_operand" "f")
13195                          (match_operand 2 "nonimmediate_operand" "fm")])
13196           (label_ref (match_operand 3 "" ""))
13197           (pc)))
13198    (clobber (reg:CCFP FPSR_REG))
13199    (clobber (reg:CCFP FLAGS_REG))
13200    (clobber (match_scratch:HI 4 "=a"))]
13201   "TARGET_80387
13202    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13203    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13204    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13205    && SELECT_CC_MODE (GET_CODE (operands[0]),
13206                       operands[1], operands[2]) == CCFPmode
13207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208   "#")
13209
13210 (define_insn "*fp_jcc_4"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "nonimmediate_operand" "fm")])
13215           (pc)
13216           (label_ref (match_operand 3 "" ""))))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))
13219    (clobber (match_scratch:HI 4 "=a"))]
13220   "TARGET_80387
13221    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13224    && SELECT_CC_MODE (GET_CODE (operands[0]),
13225                       operands[1], operands[2]) == CCFPmode
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13228
13229 (define_insn "*fp_jcc_5"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "f")
13233                          (match_operand 2 "register_operand" "f")])
13234           (label_ref (match_operand 3 "" ""))
13235           (pc)))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))
13238    (clobber (match_scratch:HI 4 "=a"))]
13239   "TARGET_80387
13240    && FLOAT_MODE_P (GET_MODE (operands[1]))
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13244
13245 (define_insn "*fp_jcc_6"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "register_operand" "f")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))
13254    (clobber (match_scratch:HI 4 "=a"))]
13255   "TARGET_80387
13256    && FLOAT_MODE_P (GET_MODE (operands[1]))
13257    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13259   "#")
13260
13261 (define_insn "*fp_jcc_7"
13262   [(set (pc)
13263         (if_then_else (match_operator 0 "comparison_operator"
13264                         [(match_operand 1 "register_operand" "f")
13265                          (match_operand 2 "const_double_operand" "C")])
13266           (label_ref (match_operand 3 "" ""))
13267           (pc)))
13268    (clobber (reg:CCFP FPSR_REG))
13269    (clobber (reg:CCFP FLAGS_REG))
13270    (clobber (match_scratch:HI 4 "=a"))]
13271   "TARGET_80387
13272    && FLOAT_MODE_P (GET_MODE (operands[1]))
13273    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13274    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13275    && SELECT_CC_MODE (GET_CODE (operands[0]),
13276                       operands[1], operands[2]) == CCFPmode
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13279
13280 ;; The order of operands in *fp_jcc_8 is forced by combine in
13281 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13282 ;; with a precedence over other operators and is always put in the first
13283 ;; place. Swap condition and operands to match ficom instruction.
13284
13285 (define_insn "*fp_jcc_8"
13286   [(set (pc)
13287         (if_then_else (match_operator 0 "comparison_operator"
13288                         [(match_operator 1 "float_operator"
13289                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13290                            (match_operand 3 "register_operand" "f,f")])
13291           (label_ref (match_operand 4 "" ""))
13292           (pc)))
13293    (clobber (reg:CCFP FPSR_REG))
13294    (clobber (reg:CCFP FLAGS_REG))
13295    (clobber (match_scratch:HI 5 "=a,a"))]
13296   "TARGET_80387 && TARGET_USE_FIOP
13297    && FLOAT_MODE_P (GET_MODE (operands[3]))
13298    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13299    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13300    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13301    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13302   "#")
13303
13304 (define_split
13305   [(set (pc)
13306         (if_then_else (match_operator 0 "comparison_operator"
13307                         [(match_operand 1 "register_operand" "")
13308                          (match_operand 2 "nonimmediate_operand" "")])
13309           (match_operand 3 "" "")
13310           (match_operand 4 "" "")))
13311    (clobber (reg:CCFP FPSR_REG))
13312    (clobber (reg:CCFP FLAGS_REG))]
13313   "reload_completed"
13314   [(const_int 0)]
13315 {
13316   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13317                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13318   DONE;
13319 })
13320
13321 (define_split
13322   [(set (pc)
13323         (if_then_else (match_operator 0 "comparison_operator"
13324                         [(match_operand 1 "register_operand" "")
13325                          (match_operand 2 "general_operand" "")])
13326           (match_operand 3 "" "")
13327           (match_operand 4 "" "")))
13328    (clobber (reg:CCFP FPSR_REG))
13329    (clobber (reg:CCFP FLAGS_REG))
13330    (clobber (match_scratch:HI 5 "=a"))]
13331   "reload_completed"
13332   [(const_int 0)]
13333 {
13334   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13335                         operands[3], operands[4], operands[5], NULL_RTX);
13336   DONE;
13337 })
13338
13339 (define_split
13340   [(set (pc)
13341         (if_then_else (match_operator 0 "comparison_operator"
13342                         [(match_operator 1 "float_operator"
13343                            [(match_operand:SI 2 "memory_operand" "")])
13344                            (match_operand 3 "register_operand" "")])
13345           (match_operand 4 "" "")
13346           (match_operand 5 "" "")))
13347    (clobber (reg:CCFP FPSR_REG))
13348    (clobber (reg:CCFP FLAGS_REG))
13349    (clobber (match_scratch:HI 6 "=a"))]
13350   "reload_completed"
13351   [(const_int 0)]
13352 {
13353   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13354   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13355                         operands[3], operands[7],
13356                         operands[4], operands[5], operands[6], NULL_RTX);
13357   DONE;
13358 })
13359
13360 ;; %%% Kill this when reload knows how to do it.
13361 (define_split
13362   [(set (pc)
13363         (if_then_else (match_operator 0 "comparison_operator"
13364                         [(match_operator 1 "float_operator"
13365                            [(match_operand:SI 2 "register_operand" "")])
13366                            (match_operand 3 "register_operand" "")])
13367           (match_operand 4 "" "")
13368           (match_operand 5 "" "")))
13369    (clobber (reg:CCFP FPSR_REG))
13370    (clobber (reg:CCFP FLAGS_REG))
13371    (clobber (match_scratch:HI 6 "=a"))]
13372   "reload_completed"
13373   [(const_int 0)]
13374 {
13375   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13376   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13377   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13378                         operands[3], operands[7],
13379                         operands[4], operands[5], operands[6], operands[2]);
13380   DONE;
13381 })
13382 \f
13383 ;; Unconditional and other jump instructions
13384
13385 (define_insn "jump"
13386   [(set (pc)
13387         (label_ref (match_operand 0 "" "")))]
13388   ""
13389   "jmp\t%l0"
13390   [(set_attr "type" "ibr")
13391    (set (attr "length")
13392            (if_then_else (and (ge (minus (match_dup 0) (pc))
13393                                   (const_int -126))
13394                               (lt (minus (match_dup 0) (pc))
13395                                   (const_int 128)))
13396              (const_int 2)
13397              (const_int 5)))
13398    (set_attr "modrm" "0")])
13399
13400 (define_expand "indirect_jump"
13401   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13402   ""
13403   "")
13404
13405 (define_insn "*indirect_jump"
13406   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13407   "!TARGET_64BIT"
13408   "jmp\t%A0"
13409   [(set_attr "type" "ibr")
13410    (set_attr "length_immediate" "0")])
13411
13412 (define_insn "*indirect_jump_rtx64"
13413   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13414   "TARGET_64BIT"
13415   "jmp\t%A0"
13416   [(set_attr "type" "ibr")
13417    (set_attr "length_immediate" "0")])
13418
13419 (define_expand "tablejump"
13420   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13421               (use (label_ref (match_operand 1 "" "")))])]
13422   ""
13423 {
13424   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13425      relative.  Convert the relative address to an absolute address.  */
13426   if (flag_pic)
13427     {
13428       rtx op0, op1;
13429       enum rtx_code code;
13430
13431       if (TARGET_64BIT)
13432         {
13433           code = PLUS;
13434           op0 = operands[0];
13435           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13436         }
13437       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13438         {
13439           code = PLUS;
13440           op0 = operands[0];
13441           op1 = pic_offset_table_rtx;
13442         }
13443       else
13444         {
13445           code = MINUS;
13446           op0 = pic_offset_table_rtx;
13447           op1 = operands[0];
13448         }
13449
13450       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13451                                          OPTAB_DIRECT);
13452     }
13453 })
13454
13455 (define_insn "*tablejump_1"
13456   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13457    (use (label_ref (match_operand 1 "" "")))]
13458   "!TARGET_64BIT"
13459   "jmp\t%A0"
13460   [(set_attr "type" "ibr")
13461    (set_attr "length_immediate" "0")])
13462
13463 (define_insn "*tablejump_1_rtx64"
13464   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13465    (use (label_ref (match_operand 1 "" "")))]
13466   "TARGET_64BIT"
13467   "jmp\t%A0"
13468   [(set_attr "type" "ibr")
13469    (set_attr "length_immediate" "0")])
13470 \f
13471 ;; Loop instruction
13472 ;;
13473 ;; This is all complicated by the fact that since this is a jump insn
13474 ;; we must handle our own reloads.
13475
13476 (define_expand "doloop_end"
13477   [(use (match_operand 0 "" ""))        ; loop pseudo
13478    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13479    (use (match_operand 2 "" ""))        ; max iterations
13480    (use (match_operand 3 "" ""))        ; loop level 
13481    (use (match_operand 4 "" ""))]       ; label
13482   "!TARGET_64BIT && TARGET_USE_LOOP"
13483   "                                 
13484 {
13485   /* Only use cloop on innermost loops.  */
13486   if (INTVAL (operands[3]) > 1)
13487     FAIL;
13488   if (GET_MODE (operands[0]) != SImode)
13489     FAIL;
13490   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13491                                            operands[0]));
13492   DONE;
13493 }")
13494
13495 (define_insn "doloop_end_internal"
13496   [(set (pc)
13497         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13498                           (const_int 1))
13499                       (label_ref (match_operand 0 "" ""))
13500                       (pc)))
13501    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13502         (plus:SI (match_dup 1)
13503                  (const_int -1)))
13504    (clobber (match_scratch:SI 3 "=X,X,r"))
13505    (clobber (reg:CC FLAGS_REG))]
13506   "!TARGET_64BIT && TARGET_USE_LOOP
13507    && (reload_in_progress || reload_completed
13508        || register_operand (operands[2], VOIDmode))"
13509 {
13510   if (which_alternative != 0)
13511     return "#";
13512   if (get_attr_length (insn) == 2)
13513     return "%+loop\t%l0";
13514   else
13515     return "dec{l}\t%1\;%+jne\t%l0";
13516 }
13517   [(set (attr "length")
13518         (if_then_else (and (eq_attr "alternative" "0")
13519                            (and (ge (minus (match_dup 0) (pc))
13520                                     (const_int -126))
13521                                 (lt (minus (match_dup 0) (pc))
13522                                     (const_int 128))))
13523                       (const_int 2)
13524                       (const_int 16)))
13525    ;; We don't know the type before shorten branches.  Optimistically expect
13526    ;; the loop instruction to match.
13527    (set (attr "type") (const_string "ibr"))])
13528
13529 (define_split
13530   [(set (pc)
13531         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13532                           (const_int 1))
13533                       (match_operand 0 "" "")
13534                       (pc)))
13535    (set (match_dup 1)
13536         (plus:SI (match_dup 1)
13537                  (const_int -1)))
13538    (clobber (match_scratch:SI 2 ""))
13539    (clobber (reg:CC FLAGS_REG))]
13540   "!TARGET_64BIT && TARGET_USE_LOOP
13541    && reload_completed
13542    && REGNO (operands[1]) != 2"
13543   [(parallel [(set (reg:CCZ FLAGS_REG)
13544                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13545                                  (const_int 0)))
13546               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13547    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13548                            (match_dup 0)
13549                            (pc)))]
13550   "")
13551   
13552 (define_split
13553   [(set (pc)
13554         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13555                           (const_int 1))
13556                       (match_operand 0 "" "")
13557                       (pc)))
13558    (set (match_operand:SI 2 "nonimmediate_operand" "")
13559         (plus:SI (match_dup 1)
13560                  (const_int -1)))
13561    (clobber (match_scratch:SI 3 ""))
13562    (clobber (reg:CC FLAGS_REG))]
13563   "!TARGET_64BIT && TARGET_USE_LOOP
13564    && reload_completed
13565    && (! REG_P (operands[2])
13566        || ! rtx_equal_p (operands[1], operands[2]))"
13567   [(set (match_dup 3) (match_dup 1))
13568    (parallel [(set (reg:CCZ FLAGS_REG)
13569                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13570                                 (const_int 0)))
13571               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13572    (set (match_dup 2) (match_dup 3))
13573    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13574                            (match_dup 0)
13575                            (pc)))]
13576   "")
13577
13578 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13579
13580 (define_peephole2
13581   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13582    (set (match_operand:QI 1 "register_operand" "")
13583         (match_operator:QI 2 "ix86_comparison_operator"
13584           [(reg FLAGS_REG) (const_int 0)]))
13585    (set (match_operand 3 "q_regs_operand" "")
13586         (zero_extend (match_dup 1)))]
13587   "(peep2_reg_dead_p (3, operands[1])
13588     || operands_match_p (operands[1], operands[3]))
13589    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13590   [(set (match_dup 4) (match_dup 0))
13591    (set (strict_low_part (match_dup 5))
13592         (match_dup 2))]
13593 {
13594   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13595   operands[5] = gen_lowpart (QImode, operands[3]);
13596   ix86_expand_clear (operands[3]);
13597 })
13598
13599 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13600
13601 (define_peephole2
13602   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13603    (set (match_operand:QI 1 "register_operand" "")
13604         (match_operator:QI 2 "ix86_comparison_operator"
13605           [(reg FLAGS_REG) (const_int 0)]))
13606    (parallel [(set (match_operand 3 "q_regs_operand" "")
13607                    (zero_extend (match_dup 1)))
13608               (clobber (reg:CC FLAGS_REG))])]
13609   "(peep2_reg_dead_p (3, operands[1])
13610     || operands_match_p (operands[1], operands[3]))
13611    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13612   [(set (match_dup 4) (match_dup 0))
13613    (set (strict_low_part (match_dup 5))
13614         (match_dup 2))]
13615 {
13616   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13617   operands[5] = gen_lowpart (QImode, operands[3]);
13618   ix86_expand_clear (operands[3]);
13619 })
13620 \f
13621 ;; Call instructions.
13622
13623 ;; The predicates normally associated with named expanders are not properly
13624 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13625 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13626
13627 ;; Call subroutine returning no value.
13628
13629 (define_expand "call_pop"
13630   [(parallel [(call (match_operand:QI 0 "" "")
13631                     (match_operand:SI 1 "" ""))
13632               (set (reg:SI SP_REG)
13633                    (plus:SI (reg:SI SP_REG)
13634                             (match_operand:SI 3 "" "")))])]
13635   "!TARGET_64BIT"
13636 {
13637   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13638   DONE;
13639 })
13640
13641 (define_insn "*call_pop_0"
13642   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13643          (match_operand:SI 1 "" ""))
13644    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13645                             (match_operand:SI 2 "immediate_operand" "")))]
13646   "!TARGET_64BIT"
13647 {
13648   if (SIBLING_CALL_P (insn))
13649     return "jmp\t%P0";
13650   else
13651     return "call\t%P0";
13652 }
13653   [(set_attr "type" "call")])
13654   
13655 (define_insn "*call_pop_1"
13656   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13657          (match_operand:SI 1 "" ""))
13658    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13659                             (match_operand:SI 2 "immediate_operand" "i")))]
13660   "!TARGET_64BIT"
13661 {
13662   if (constant_call_address_operand (operands[0], Pmode))
13663     {
13664       if (SIBLING_CALL_P (insn))
13665         return "jmp\t%P0";
13666       else
13667         return "call\t%P0";
13668     }
13669   if (SIBLING_CALL_P (insn))
13670     return "jmp\t%A0";
13671   else
13672     return "call\t%A0";
13673 }
13674   [(set_attr "type" "call")])
13675
13676 (define_expand "call"
13677   [(call (match_operand:QI 0 "" "")
13678          (match_operand 1 "" ""))
13679    (use (match_operand 2 "" ""))]
13680   ""
13681 {
13682   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13683   DONE;
13684 })
13685
13686 (define_expand "sibcall"
13687   [(call (match_operand:QI 0 "" "")
13688          (match_operand 1 "" ""))
13689    (use (match_operand 2 "" ""))]
13690   ""
13691 {
13692   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13693   DONE;
13694 })
13695
13696 (define_insn "*call_0"
13697   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13698          (match_operand 1 "" ""))]
13699   ""
13700 {
13701   if (SIBLING_CALL_P (insn))
13702     return "jmp\t%P0";
13703   else
13704     return "call\t%P0";
13705 }
13706   [(set_attr "type" "call")])
13707
13708 (define_insn "*call_1"
13709   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13710          (match_operand 1 "" ""))]
13711   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13712 {
13713   if (constant_call_address_operand (operands[0], Pmode))
13714     return "call\t%P0";
13715   return "call\t%A0";
13716 }
13717   [(set_attr "type" "call")])
13718
13719 (define_insn "*sibcall_1"
13720   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13721          (match_operand 1 "" ""))]
13722   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13723 {
13724   if (constant_call_address_operand (operands[0], Pmode))
13725     return "jmp\t%P0";
13726   return "jmp\t%A0";
13727 }
13728   [(set_attr "type" "call")])
13729
13730 (define_insn "*call_1_rex64"
13731   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13732          (match_operand 1 "" ""))]
13733   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13734 {
13735   if (constant_call_address_operand (operands[0], Pmode))
13736     return "call\t%P0";
13737   return "call\t%A0";
13738 }
13739   [(set_attr "type" "call")])
13740
13741 (define_insn "*sibcall_1_rex64"
13742   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13743          (match_operand 1 "" ""))]
13744   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13745   "jmp\t%P0"
13746   [(set_attr "type" "call")])
13747
13748 (define_insn "*sibcall_1_rex64_v"
13749   [(call (mem:QI (reg:DI 40))
13750          (match_operand 0 "" ""))]
13751   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13752   "jmp\t*%%r11"
13753   [(set_attr "type" "call")])
13754
13755
13756 ;; Call subroutine, returning value in operand 0
13757
13758 (define_expand "call_value_pop"
13759   [(parallel [(set (match_operand 0 "" "")
13760                    (call (match_operand:QI 1 "" "")
13761                          (match_operand:SI 2 "" "")))
13762               (set (reg:SI SP_REG)
13763                    (plus:SI (reg:SI SP_REG)
13764                             (match_operand:SI 4 "" "")))])]
13765   "!TARGET_64BIT"
13766 {
13767   ix86_expand_call (operands[0], operands[1], operands[2],
13768                     operands[3], operands[4], 0);
13769   DONE;
13770 })
13771
13772 (define_expand "call_value"
13773   [(set (match_operand 0 "" "")
13774         (call (match_operand:QI 1 "" "")
13775               (match_operand:SI 2 "" "")))
13776    (use (match_operand:SI 3 "" ""))]
13777   ;; Operand 2 not used on the i386.
13778   ""
13779 {
13780   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13781   DONE;
13782 })
13783
13784 (define_expand "sibcall_value"
13785   [(set (match_operand 0 "" "")
13786         (call (match_operand:QI 1 "" "")
13787               (match_operand:SI 2 "" "")))
13788    (use (match_operand:SI 3 "" ""))]
13789   ;; Operand 2 not used on the i386.
13790   ""
13791 {
13792   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13793   DONE;
13794 })
13795
13796 ;; Call subroutine returning any type.
13797
13798 (define_expand "untyped_call"
13799   [(parallel [(call (match_operand 0 "" "")
13800                     (const_int 0))
13801               (match_operand 1 "" "")
13802               (match_operand 2 "" "")])]
13803   ""
13804 {
13805   int i;
13806
13807   /* In order to give reg-stack an easier job in validating two
13808      coprocessor registers as containing a possible return value,
13809      simply pretend the untyped call returns a complex long double
13810      value.  */
13811
13812   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13813                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13814                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13815                     NULL, 0);
13816
13817   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13818     {
13819       rtx set = XVECEXP (operands[2], 0, i);
13820       emit_move_insn (SET_DEST (set), SET_SRC (set));
13821     }
13822
13823   /* The optimizer does not know that the call sets the function value
13824      registers we stored in the result block.  We avoid problems by
13825      claiming that all hard registers are used and clobbered at this
13826      point.  */
13827   emit_insn (gen_blockage (const0_rtx));
13828
13829   DONE;
13830 })
13831 \f
13832 ;; Prologue and epilogue instructions
13833
13834 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13835 ;; all of memory.  This blocks insns from being moved across this point.
13836
13837 (define_insn "blockage"
13838   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13839   ""
13840   ""
13841   [(set_attr "length" "0")])
13842
13843 ;; Insn emitted into the body of a function to return from a function.
13844 ;; This is only done if the function's epilogue is known to be simple.
13845 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13846
13847 (define_expand "return"
13848   [(return)]
13849   "ix86_can_use_return_insn_p ()"
13850 {
13851   if (current_function_pops_args)
13852     {
13853       rtx popc = GEN_INT (current_function_pops_args);
13854       emit_jump_insn (gen_return_pop_internal (popc));
13855       DONE;
13856     }
13857 })
13858
13859 (define_insn "return_internal"
13860   [(return)]
13861   "reload_completed"
13862   "ret"
13863   [(set_attr "length" "1")
13864    (set_attr "length_immediate" "0")
13865    (set_attr "modrm" "0")])
13866
13867 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13868 ;; instruction Athlon and K8 have.
13869
13870 (define_insn "return_internal_long"
13871   [(return)
13872    (unspec [(const_int 0)] UNSPEC_REP)]
13873   "reload_completed"
13874   "rep {;} ret"
13875   [(set_attr "length" "1")
13876    (set_attr "length_immediate" "0")
13877    (set_attr "prefix_rep" "1")
13878    (set_attr "modrm" "0")])
13879
13880 (define_insn "return_pop_internal"
13881   [(return)
13882    (use (match_operand:SI 0 "const_int_operand" ""))]
13883   "reload_completed"
13884   "ret\t%0"
13885   [(set_attr "length" "3")
13886    (set_attr "length_immediate" "2")
13887    (set_attr "modrm" "0")])
13888
13889 (define_insn "return_indirect_internal"
13890   [(return)
13891    (use (match_operand:SI 0 "register_operand" "r"))]
13892   "reload_completed"
13893   "jmp\t%A0"
13894   [(set_attr "type" "ibr")
13895    (set_attr "length_immediate" "0")])
13896
13897 (define_insn "nop"
13898   [(const_int 0)]
13899   ""
13900   "nop"
13901   [(set_attr "length" "1")
13902    (set_attr "length_immediate" "0")
13903    (set_attr "modrm" "0")])
13904
13905 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13906 ;; branch prediction penalty for the third jump in a 16-byte
13907 ;; block on K8.
13908
13909 (define_insn "align"
13910   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13911   ""
13912 {
13913 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13914   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13915 #else
13916   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13917      The align insn is used to avoid 3 jump instructions in the row to improve
13918      branch prediction and the benefits hardly outweight the cost of extra 8
13919      nops on the average inserted by full alignment pseudo operation.  */
13920 #endif
13921   return "";
13922 }
13923   [(set_attr "length" "16")])
13924
13925 (define_expand "prologue"
13926   [(const_int 1)]
13927   ""
13928   "ix86_expand_prologue (); DONE;")
13929
13930 (define_insn "set_got"
13931   [(set (match_operand:SI 0 "register_operand" "=r")
13932         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13933    (clobber (reg:CC FLAGS_REG))]
13934   "!TARGET_64BIT"
13935   { return output_set_got (operands[0]); }
13936   [(set_attr "type" "multi")
13937    (set_attr "length" "12")])
13938
13939 (define_expand "epilogue"
13940   [(const_int 1)]
13941   ""
13942   "ix86_expand_epilogue (1); DONE;")
13943
13944 (define_expand "sibcall_epilogue"
13945   [(const_int 1)]
13946   ""
13947   "ix86_expand_epilogue (0); DONE;")
13948
13949 (define_expand "eh_return"
13950   [(use (match_operand 0 "register_operand" ""))]
13951   ""
13952 {
13953   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13954
13955   /* Tricky bit: we write the address of the handler to which we will
13956      be returning into someone else's stack frame, one word below the
13957      stack address we wish to restore.  */
13958   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13959   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13960   tmp = gen_rtx_MEM (Pmode, tmp);
13961   emit_move_insn (tmp, ra);
13962
13963   if (Pmode == SImode)
13964     emit_jump_insn (gen_eh_return_si (sa));
13965   else
13966     emit_jump_insn (gen_eh_return_di (sa));
13967   emit_barrier ();
13968   DONE;
13969 })
13970
13971 (define_insn_and_split "eh_return_si"
13972   [(set (pc) 
13973         (unspec [(match_operand:SI 0 "register_operand" "c")]
13974                  UNSPEC_EH_RETURN))]
13975   "!TARGET_64BIT"
13976   "#"
13977   "reload_completed"
13978   [(const_int 1)]
13979   "ix86_expand_epilogue (2); DONE;")
13980
13981 (define_insn_and_split "eh_return_di"
13982   [(set (pc) 
13983         (unspec [(match_operand:DI 0 "register_operand" "c")]
13984                  UNSPEC_EH_RETURN))]
13985   "TARGET_64BIT"
13986   "#"
13987   "reload_completed"
13988   [(const_int 1)]
13989   "ix86_expand_epilogue (2); DONE;")
13990
13991 (define_insn "leave"
13992   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13993    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13994    (clobber (mem:BLK (scratch)))]
13995   "!TARGET_64BIT"
13996   "leave"
13997   [(set_attr "type" "leave")])
13998
13999 (define_insn "leave_rex64"
14000   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14001    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14002    (clobber (mem:BLK (scratch)))]
14003   "TARGET_64BIT"
14004   "leave"
14005   [(set_attr "type" "leave")])
14006 \f
14007 (define_expand "ffssi2"
14008   [(parallel
14009      [(set (match_operand:SI 0 "register_operand" "") 
14010            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14011       (clobber (match_scratch:SI 2 ""))
14012       (clobber (reg:CC FLAGS_REG))])]
14013   ""
14014   "")
14015
14016 (define_insn_and_split "*ffs_cmove"
14017   [(set (match_operand:SI 0 "register_operand" "=r") 
14018         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14019    (clobber (match_scratch:SI 2 "=&r"))
14020    (clobber (reg:CC FLAGS_REG))]
14021   "TARGET_CMOVE"
14022   "#"
14023   "&& reload_completed"
14024   [(set (match_dup 2) (const_int -1))
14025    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14026               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14027    (set (match_dup 0) (if_then_else:SI
14028                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14029                         (match_dup 2)
14030                         (match_dup 0)))
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033   "")
14034
14035 (define_insn_and_split "*ffs_no_cmove"
14036   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14037         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14038    (clobber (match_scratch:SI 2 "=&q"))
14039    (clobber (reg:CC FLAGS_REG))]
14040   ""
14041   "#"
14042   "reload_completed"
14043   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14044               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14045    (set (strict_low_part (match_dup 3))
14046         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14047    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14048               (clobber (reg:CC FLAGS_REG))])
14049    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14050               (clobber (reg:CC FLAGS_REG))])
14051    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14052               (clobber (reg:CC FLAGS_REG))])]
14053 {
14054   operands[3] = gen_lowpart (QImode, operands[2]);
14055   ix86_expand_clear (operands[2]);
14056 })
14057
14058 (define_insn "*ffssi_1"
14059   [(set (reg:CCZ FLAGS_REG)
14060         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14061                      (const_int 0)))
14062    (set (match_operand:SI 0 "register_operand" "=r")
14063         (ctz:SI (match_dup 1)))]
14064   ""
14065   "bsf{l}\t{%1, %0|%0, %1}"
14066   [(set_attr "prefix_0f" "1")])
14067
14068 (define_expand "ffsdi2"
14069   [(parallel
14070      [(set (match_operand:DI 0 "register_operand" "") 
14071            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14072       (clobber (match_scratch:DI 2 ""))
14073       (clobber (reg:CC FLAGS_REG))])]
14074   "TARGET_64BIT && TARGET_CMOVE"
14075   "")
14076
14077 (define_insn_and_split "*ffs_rex64"
14078   [(set (match_operand:DI 0 "register_operand" "=r") 
14079         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14080    (clobber (match_scratch:DI 2 "=&r"))
14081    (clobber (reg:CC FLAGS_REG))]
14082   "TARGET_64BIT && TARGET_CMOVE"
14083   "#"
14084   "&& reload_completed"
14085   [(set (match_dup 2) (const_int -1))
14086    (parallel [(set (reg:CCZ FLAGS_REG)
14087                    (compare:CCZ (match_dup 1) (const_int 0)))
14088               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14089    (set (match_dup 0) (if_then_else:DI
14090                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14091                         (match_dup 2)
14092                         (match_dup 0)))
14093    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14094               (clobber (reg:CC FLAGS_REG))])]
14095   "")
14096
14097 (define_insn "*ffsdi_1"
14098   [(set (reg:CCZ FLAGS_REG)
14099         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14100                      (const_int 0)))
14101    (set (match_operand:DI 0 "register_operand" "=r")
14102         (ctz:DI (match_dup 1)))]
14103   "TARGET_64BIT"
14104   "bsf{q}\t{%1, %0|%0, %1}"
14105   [(set_attr "prefix_0f" "1")])
14106
14107 (define_insn "ctzsi2"
14108   [(set (match_operand:SI 0 "register_operand" "=r")
14109         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14110    (clobber (reg:CC FLAGS_REG))]
14111   ""
14112   "bsf{l}\t{%1, %0|%0, %1}"
14113   [(set_attr "prefix_0f" "1")])
14114
14115 (define_insn "ctzdi2"
14116   [(set (match_operand:DI 0 "register_operand" "=r")
14117         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14118    (clobber (reg:CC FLAGS_REG))]
14119   "TARGET_64BIT"
14120   "bsf{q}\t{%1, %0|%0, %1}"
14121   [(set_attr "prefix_0f" "1")])
14122
14123 (define_expand "clzsi2"
14124   [(parallel
14125      [(set (match_operand:SI 0 "register_operand" "")
14126            (minus:SI (const_int 31)
14127                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14128       (clobber (reg:CC FLAGS_REG))])
14129    (parallel
14130      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14131       (clobber (reg:CC FLAGS_REG))])]
14132   ""
14133   "")
14134
14135 (define_insn "*bsr"
14136   [(set (match_operand:SI 0 "register_operand" "=r")
14137         (minus:SI (const_int 31)
14138                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14139    (clobber (reg:CC FLAGS_REG))]
14140   ""
14141   "bsr{l}\t{%1, %0|%0, %1}"
14142   [(set_attr "prefix_0f" "1")])
14143
14144 (define_expand "clzdi2"
14145   [(parallel
14146      [(set (match_operand:DI 0 "register_operand" "")
14147            (minus:DI (const_int 63)
14148                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14149       (clobber (reg:CC FLAGS_REG))])
14150    (parallel
14151      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14152       (clobber (reg:CC FLAGS_REG))])]
14153   "TARGET_64BIT"
14154   "")
14155
14156 (define_insn "*bsr_rex64"
14157   [(set (match_operand:DI 0 "register_operand" "=r")
14158         (minus:DI (const_int 63)
14159                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14160    (clobber (reg:CC FLAGS_REG))]
14161   "TARGET_64BIT"
14162   "bsr{q}\t{%1, %0|%0, %1}"
14163   [(set_attr "prefix_0f" "1")])
14164 \f
14165 ;; Thread-local storage patterns for ELF.
14166 ;;
14167 ;; Note that these code sequences must appear exactly as shown
14168 ;; in order to allow linker relaxation.
14169
14170 (define_insn "*tls_global_dynamic_32_gnu"
14171   [(set (match_operand:SI 0 "register_operand" "=a")
14172         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14173                     (match_operand:SI 2 "tls_symbolic_operand" "")
14174                     (match_operand:SI 3 "call_insn_operand" "")]
14175                     UNSPEC_TLS_GD))
14176    (clobber (match_scratch:SI 4 "=d"))
14177    (clobber (match_scratch:SI 5 "=c"))
14178    (clobber (reg:CC FLAGS_REG))]
14179   "!TARGET_64BIT && TARGET_GNU_TLS"
14180   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14181   [(set_attr "type" "multi")
14182    (set_attr "length" "12")])
14183
14184 (define_insn "*tls_global_dynamic_32_sun"
14185   [(set (match_operand:SI 0 "register_operand" "=a")
14186         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14187                     (match_operand:SI 2 "tls_symbolic_operand" "")
14188                     (match_operand:SI 3 "call_insn_operand" "")]
14189                     UNSPEC_TLS_GD))
14190    (clobber (match_scratch:SI 4 "=d"))
14191    (clobber (match_scratch:SI 5 "=c"))
14192    (clobber (reg:CC FLAGS_REG))]
14193   "!TARGET_64BIT && TARGET_SUN_TLS"
14194   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14195         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14196   [(set_attr "type" "multi")
14197    (set_attr "length" "14")])
14198
14199 (define_expand "tls_global_dynamic_32"
14200   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14201                    (unspec:SI
14202                     [(match_dup 2)
14203                      (match_operand:SI 1 "tls_symbolic_operand" "")
14204                      (match_dup 3)]
14205                     UNSPEC_TLS_GD))
14206               (clobber (match_scratch:SI 4 ""))
14207               (clobber (match_scratch:SI 5 ""))
14208               (clobber (reg:CC FLAGS_REG))])]
14209   ""
14210 {
14211   if (flag_pic)
14212     operands[2] = pic_offset_table_rtx;
14213   else
14214     {
14215       operands[2] = gen_reg_rtx (Pmode);
14216       emit_insn (gen_set_got (operands[2]));
14217     }
14218   operands[3] = ix86_tls_get_addr ();
14219 })
14220
14221 (define_insn "*tls_global_dynamic_64"
14222   [(set (match_operand:DI 0 "register_operand" "=a")
14223         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14224                       (match_operand:DI 3 "" "")))
14225    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14226               UNSPEC_TLS_GD)]
14227   "TARGET_64BIT"
14228   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14229   [(set_attr "type" "multi")
14230    (set_attr "length" "16")])
14231
14232 (define_expand "tls_global_dynamic_64"
14233   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14234                    (call (mem:QI (match_dup 2)) (const_int 0)))
14235               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14236                          UNSPEC_TLS_GD)])]
14237   ""
14238 {
14239   operands[2] = ix86_tls_get_addr ();
14240 })
14241
14242 (define_insn "*tls_local_dynamic_base_32_gnu"
14243   [(set (match_operand:SI 0 "register_operand" "=a")
14244         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14245                     (match_operand:SI 2 "call_insn_operand" "")]
14246                    UNSPEC_TLS_LD_BASE))
14247    (clobber (match_scratch:SI 3 "=d"))
14248    (clobber (match_scratch:SI 4 "=c"))
14249    (clobber (reg:CC FLAGS_REG))]
14250   "!TARGET_64BIT && TARGET_GNU_TLS"
14251   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14252   [(set_attr "type" "multi")
14253    (set_attr "length" "11")])
14254
14255 (define_insn "*tls_local_dynamic_base_32_sun"
14256   [(set (match_operand:SI 0 "register_operand" "=a")
14257         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14258                     (match_operand:SI 2 "call_insn_operand" "")]
14259                    UNSPEC_TLS_LD_BASE))
14260    (clobber (match_scratch:SI 3 "=d"))
14261    (clobber (match_scratch:SI 4 "=c"))
14262    (clobber (reg:CC FLAGS_REG))]
14263   "!TARGET_64BIT && TARGET_SUN_TLS"
14264   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14265         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14266   [(set_attr "type" "multi")
14267    (set_attr "length" "13")])
14268
14269 (define_expand "tls_local_dynamic_base_32"
14270   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14271                    (unspec:SI [(match_dup 1) (match_dup 2)]
14272                               UNSPEC_TLS_LD_BASE))
14273               (clobber (match_scratch:SI 3 ""))
14274               (clobber (match_scratch:SI 4 ""))
14275               (clobber (reg:CC FLAGS_REG))])]
14276   ""
14277 {
14278   if (flag_pic)
14279     operands[1] = pic_offset_table_rtx;
14280   else
14281     {
14282       operands[1] = gen_reg_rtx (Pmode);
14283       emit_insn (gen_set_got (operands[1]));
14284     }
14285   operands[2] = ix86_tls_get_addr ();
14286 })
14287
14288 (define_insn "*tls_local_dynamic_base_64"
14289   [(set (match_operand:DI 0 "register_operand" "=a")
14290         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14291                       (match_operand:DI 2 "" "")))
14292    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14293   "TARGET_64BIT"
14294   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14295   [(set_attr "type" "multi")
14296    (set_attr "length" "12")])
14297
14298 (define_expand "tls_local_dynamic_base_64"
14299   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14300                    (call (mem:QI (match_dup 1)) (const_int 0)))
14301               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14302   ""
14303 {
14304   operands[1] = ix86_tls_get_addr ();
14305 })
14306
14307 ;; Local dynamic of a single variable is a lose.  Show combine how
14308 ;; to convert that back to global dynamic.
14309
14310 (define_insn_and_split "*tls_local_dynamic_32_once"
14311   [(set (match_operand:SI 0 "register_operand" "=a")
14312         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14313                              (match_operand:SI 2 "call_insn_operand" "")]
14314                             UNSPEC_TLS_LD_BASE)
14315                  (const:SI (unspec:SI
14316                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14317                             UNSPEC_DTPOFF))))
14318    (clobber (match_scratch:SI 4 "=d"))
14319    (clobber (match_scratch:SI 5 "=c"))
14320    (clobber (reg:CC FLAGS_REG))]
14321   ""
14322   "#"
14323   ""
14324   [(parallel [(set (match_dup 0)
14325                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14326                               UNSPEC_TLS_GD))
14327               (clobber (match_dup 4))
14328               (clobber (match_dup 5))
14329               (clobber (reg:CC FLAGS_REG))])]
14330   "")
14331
14332 ;; Load and add the thread base pointer from %gs:0.
14333
14334 (define_insn "*load_tp_si"
14335   [(set (match_operand:SI 0 "register_operand" "=r")
14336         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14337   "!TARGET_64BIT"
14338   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14339   [(set_attr "type" "imov")
14340    (set_attr "modrm" "0")
14341    (set_attr "length" "7")
14342    (set_attr "memory" "load")
14343    (set_attr "imm_disp" "false")])
14344
14345 (define_insn "*add_tp_si"
14346   [(set (match_operand:SI 0 "register_operand" "=r")
14347         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14348                  (match_operand:SI 1 "register_operand" "0")))
14349    (clobber (reg:CC FLAGS_REG))]
14350   "!TARGET_64BIT"
14351   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14352   [(set_attr "type" "alu")
14353    (set_attr "modrm" "0")
14354    (set_attr "length" "7")
14355    (set_attr "memory" "load")
14356    (set_attr "imm_disp" "false")])
14357
14358 (define_insn "*load_tp_di"
14359   [(set (match_operand:DI 0 "register_operand" "=r")
14360         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14361   "TARGET_64BIT"
14362   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14363   [(set_attr "type" "imov")
14364    (set_attr "modrm" "0")
14365    (set_attr "length" "7")
14366    (set_attr "memory" "load")
14367    (set_attr "imm_disp" "false")])
14368
14369 (define_insn "*add_tp_di"
14370   [(set (match_operand:DI 0 "register_operand" "=r")
14371         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14372                  (match_operand:DI 1 "register_operand" "0")))
14373    (clobber (reg:CC FLAGS_REG))]
14374   "TARGET_64BIT"
14375   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14376   [(set_attr "type" "alu")
14377    (set_attr "modrm" "0")
14378    (set_attr "length" "7")
14379    (set_attr "memory" "load")
14380    (set_attr "imm_disp" "false")])
14381 \f
14382 ;; These patterns match the binary 387 instructions for addM3, subM3,
14383 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14384 ;; SFmode.  The first is the normal insn, the second the same insn but
14385 ;; with one operand a conversion, and the third the same insn but with
14386 ;; the other operand a conversion.  The conversion may be SFmode or
14387 ;; SImode if the target mode DFmode, but only SImode if the target mode
14388 ;; is SFmode.
14389
14390 ;; Gcc is slightly more smart about handling normal two address instructions
14391 ;; so use special patterns for add and mull.
14392 (define_insn "*fop_sf_comm_nosse"
14393   [(set (match_operand:SF 0 "register_operand" "=f")
14394         (match_operator:SF 3 "binary_fp_operator"
14395                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14396                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14397   "TARGET_80387 && !TARGET_SSE_MATH
14398    && COMMUTATIVE_ARITH_P (operands[3])
14399    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14400   "* return output_387_binary_op (insn, operands);"
14401   [(set (attr "type") 
14402         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14403            (const_string "fmul")
14404            (const_string "fop")))
14405    (set_attr "mode" "SF")])
14406
14407 (define_insn "*fop_sf_comm"
14408   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14409         (match_operator:SF 3 "binary_fp_operator"
14410                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14411                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14412   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14413    && COMMUTATIVE_ARITH_P (operands[3])
14414    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14415   "* return output_387_binary_op (insn, operands);"
14416   [(set (attr "type") 
14417         (if_then_else (eq_attr "alternative" "1")
14418            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14419               (const_string "ssemul")
14420               (const_string "sseadd"))
14421            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14422               (const_string "fmul")
14423               (const_string "fop"))))
14424    (set_attr "mode" "SF")])
14425
14426 (define_insn "*fop_sf_comm_sse"
14427   [(set (match_operand:SF 0 "register_operand" "=x")
14428         (match_operator:SF 3 "binary_fp_operator"
14429                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14430                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14431   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14432    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14433   "* return output_387_binary_op (insn, operands);"
14434   [(set (attr "type") 
14435         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14436            (const_string "ssemul")
14437            (const_string "sseadd")))
14438    (set_attr "mode" "SF")])
14439
14440 (define_insn "*fop_df_comm_nosse"
14441   [(set (match_operand:DF 0 "register_operand" "=f")
14442         (match_operator:DF 3 "binary_fp_operator"
14443                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14444                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14445   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14446    && COMMUTATIVE_ARITH_P (operands[3])
14447    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14448   "* return output_387_binary_op (insn, operands);"
14449   [(set (attr "type") 
14450         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14451            (const_string "fmul")
14452            (const_string "fop")))
14453    (set_attr "mode" "DF")])
14454
14455 (define_insn "*fop_df_comm"
14456   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14457         (match_operator:DF 3 "binary_fp_operator"
14458                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14459                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14460   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14461    && COMMUTATIVE_ARITH_P (operands[3])
14462    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14463   "* return output_387_binary_op (insn, operands);"
14464   [(set (attr "type") 
14465         (if_then_else (eq_attr "alternative" "1")
14466            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14467               (const_string "ssemul")
14468               (const_string "sseadd"))
14469            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14470               (const_string "fmul")
14471               (const_string "fop"))))
14472    (set_attr "mode" "DF")])
14473
14474 (define_insn "*fop_df_comm_sse"
14475   [(set (match_operand:DF 0 "register_operand" "=Y")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14479   "TARGET_SSE2 && TARGET_SSE_MATH
14480    && COMMUTATIVE_ARITH_P (operands[3])
14481    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14485            (const_string "ssemul")
14486            (const_string "sseadd")))
14487    (set_attr "mode" "DF")])
14488
14489 (define_insn "*fop_xf_comm"
14490   [(set (match_operand:XF 0 "register_operand" "=f")
14491         (match_operator:XF 3 "binary_fp_operator"
14492                         [(match_operand:XF 1 "register_operand" "%0")
14493                          (match_operand:XF 2 "register_operand" "f")]))]
14494   "TARGET_80387
14495    && COMMUTATIVE_ARITH_P (operands[3])"
14496   "* return output_387_binary_op (insn, operands);"
14497   [(set (attr "type") 
14498         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14499            (const_string "fmul")
14500            (const_string "fop")))
14501    (set_attr "mode" "XF")])
14502
14503 (define_insn "*fop_sf_1_nosse"
14504   [(set (match_operand:SF 0 "register_operand" "=f,f")
14505         (match_operator:SF 3 "binary_fp_operator"
14506                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14507                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14508   "TARGET_80387 && !TARGET_SSE_MATH
14509    && !COMMUTATIVE_ARITH_P (operands[3])
14510    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14511   "* return output_387_binary_op (insn, operands);"
14512   [(set (attr "type") 
14513         (cond [(match_operand:SF 3 "mult_operator" "") 
14514                  (const_string "fmul")
14515                (match_operand:SF 3 "div_operator" "") 
14516                  (const_string "fdiv")
14517               ]
14518               (const_string "fop")))
14519    (set_attr "mode" "SF")])
14520
14521 (define_insn "*fop_sf_1"
14522   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14523         (match_operator:SF 3 "binary_fp_operator"
14524                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14525                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14526   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14527    && !COMMUTATIVE_ARITH_P (operands[3])
14528    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14529   "* return output_387_binary_op (insn, operands);"
14530   [(set (attr "type") 
14531         (cond [(and (eq_attr "alternative" "2")
14532                     (match_operand:SF 3 "mult_operator" ""))
14533                  (const_string "ssemul")
14534                (and (eq_attr "alternative" "2")
14535                     (match_operand:SF 3 "div_operator" ""))
14536                  (const_string "ssediv")
14537                (eq_attr "alternative" "2")
14538                  (const_string "sseadd")
14539                (match_operand:SF 3 "mult_operator" "") 
14540                  (const_string "fmul")
14541                (match_operand:SF 3 "div_operator" "") 
14542                  (const_string "fdiv")
14543               ]
14544               (const_string "fop")))
14545    (set_attr "mode" "SF")])
14546
14547 (define_insn "*fop_sf_1_sse"
14548   [(set (match_operand:SF 0 "register_operand" "=x")
14549         (match_operator:SF 3 "binary_fp_operator"
14550                         [(match_operand:SF 1 "register_operand" "0")
14551                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14552   "TARGET_SSE_MATH
14553    && !COMMUTATIVE_ARITH_P (operands[3])"
14554   "* return output_387_binary_op (insn, operands);"
14555   [(set (attr "type") 
14556         (cond [(match_operand:SF 3 "mult_operator" "")
14557                  (const_string "ssemul")
14558                (match_operand:SF 3 "div_operator" "")
14559                  (const_string "ssediv")
14560               ]
14561               (const_string "sseadd")))
14562    (set_attr "mode" "SF")])
14563
14564 ;; ??? Add SSE splitters for these!
14565 (define_insn "*fop_sf_2"
14566   [(set (match_operand:SF 0 "register_operand" "=f,f")
14567         (match_operator:SF 3 "binary_fp_operator"
14568           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14569            (match_operand:SF 2 "register_operand" "0,0")]))]
14570   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14571   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14572   [(set (attr "type") 
14573         (cond [(match_operand:SF 3 "mult_operator" "") 
14574                  (const_string "fmul")
14575                (match_operand:SF 3 "div_operator" "") 
14576                  (const_string "fdiv")
14577               ]
14578               (const_string "fop")))
14579    (set_attr "fp_int_src" "true")
14580    (set_attr "mode" "SI")])
14581
14582 (define_insn "*fop_sf_3"
14583   [(set (match_operand:SF 0 "register_operand" "=f,f")
14584         (match_operator:SF 3 "binary_fp_operator"
14585           [(match_operand:SF 1 "register_operand" "0,0")
14586            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14587   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14588   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14589   [(set (attr "type") 
14590         (cond [(match_operand:SF 3 "mult_operator" "") 
14591                  (const_string "fmul")
14592                (match_operand:SF 3 "div_operator" "") 
14593                  (const_string "fdiv")
14594               ]
14595               (const_string "fop")))
14596    (set_attr "fp_int_src" "true")
14597    (set_attr "mode" "SI")])
14598
14599 (define_insn "*fop_df_1_nosse"
14600   [(set (match_operand:DF 0 "register_operand" "=f,f")
14601         (match_operator:DF 3 "binary_fp_operator"
14602                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14603                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14604   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14605    && !COMMUTATIVE_ARITH_P (operands[3])
14606    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14607   "* return output_387_binary_op (insn, operands);"
14608   [(set (attr "type") 
14609         (cond [(match_operand:DF 3 "mult_operator" "") 
14610                  (const_string "fmul")
14611                (match_operand:DF 3 "div_operator" "")
14612                  (const_string "fdiv")
14613               ]
14614               (const_string "fop")))
14615    (set_attr "mode" "DF")])
14616
14617
14618 (define_insn "*fop_df_1"
14619   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14620         (match_operator:DF 3 "binary_fp_operator"
14621                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14622                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14623   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14624    && !COMMUTATIVE_ARITH_P (operands[3])
14625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14626   "* return output_387_binary_op (insn, operands);"
14627   [(set (attr "type") 
14628         (cond [(and (eq_attr "alternative" "2")
14629                     (match_operand:SF 3 "mult_operator" ""))
14630                  (const_string "ssemul")
14631                (and (eq_attr "alternative" "2")
14632                     (match_operand:SF 3 "div_operator" ""))
14633                  (const_string "ssediv")
14634                (eq_attr "alternative" "2")
14635                  (const_string "sseadd")
14636                (match_operand:DF 3 "mult_operator" "") 
14637                  (const_string "fmul")
14638                (match_operand:DF 3 "div_operator" "") 
14639                  (const_string "fdiv")
14640               ]
14641               (const_string "fop")))
14642    (set_attr "mode" "DF")])
14643
14644 (define_insn "*fop_df_1_sse"
14645   [(set (match_operand:DF 0 "register_operand" "=Y")
14646         (match_operator:DF 3 "binary_fp_operator"
14647                         [(match_operand:DF 1 "register_operand" "0")
14648                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14649   "TARGET_SSE2 && TARGET_SSE_MATH
14650    && !COMMUTATIVE_ARITH_P (operands[3])"
14651   "* return output_387_binary_op (insn, operands);"
14652   [(set_attr "mode" "DF")
14653    (set (attr "type") 
14654         (cond [(match_operand:SF 3 "mult_operator" "")
14655                  (const_string "ssemul")
14656                (match_operand:SF 3 "div_operator" "")
14657                  (const_string "ssediv")
14658               ]
14659               (const_string "sseadd")))])
14660
14661 ;; ??? Add SSE splitters for these!
14662 (define_insn "*fop_df_2"
14663   [(set (match_operand:DF 0 "register_operand" "=f,f")
14664         (match_operator:DF 3 "binary_fp_operator"
14665            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14666             (match_operand:DF 2 "register_operand" "0,0")]))]
14667   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14668   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14669   [(set (attr "type") 
14670         (cond [(match_operand:DF 3 "mult_operator" "") 
14671                  (const_string "fmul")
14672                (match_operand:DF 3 "div_operator" "") 
14673                  (const_string "fdiv")
14674               ]
14675               (const_string "fop")))
14676    (set_attr "fp_int_src" "true")
14677    (set_attr "mode" "SI")])
14678
14679 (define_insn "*fop_df_3"
14680   [(set (match_operand:DF 0 "register_operand" "=f,f")
14681         (match_operator:DF 3 "binary_fp_operator"
14682            [(match_operand:DF 1 "register_operand" "0,0")
14683             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14684   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14685   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14686   [(set (attr "type") 
14687         (cond [(match_operand:DF 3 "mult_operator" "") 
14688                  (const_string "fmul")
14689                (match_operand:DF 3 "div_operator" "") 
14690                  (const_string "fdiv")
14691               ]
14692               (const_string "fop")))
14693    (set_attr "fp_int_src" "true")
14694    (set_attr "mode" "SI")])
14695
14696 (define_insn "*fop_df_4"
14697   [(set (match_operand:DF 0 "register_operand" "=f,f")
14698         (match_operator:DF 3 "binary_fp_operator"
14699            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14700             (match_operand:DF 2 "register_operand" "0,f")]))]
14701   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14702    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14703   "* return output_387_binary_op (insn, operands);"
14704   [(set (attr "type") 
14705         (cond [(match_operand:DF 3 "mult_operator" "") 
14706                  (const_string "fmul")
14707                (match_operand:DF 3 "div_operator" "") 
14708                  (const_string "fdiv")
14709               ]
14710               (const_string "fop")))
14711    (set_attr "mode" "SF")])
14712
14713 (define_insn "*fop_df_5"
14714   [(set (match_operand:DF 0 "register_operand" "=f,f")
14715         (match_operator:DF 3 "binary_fp_operator"
14716           [(match_operand:DF 1 "register_operand" "0,f")
14717            (float_extend:DF
14718             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14719   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14720   "* return output_387_binary_op (insn, operands);"
14721   [(set (attr "type") 
14722         (cond [(match_operand:DF 3 "mult_operator" "") 
14723                  (const_string "fmul")
14724                (match_operand:DF 3 "div_operator" "") 
14725                  (const_string "fdiv")
14726               ]
14727               (const_string "fop")))
14728    (set_attr "mode" "SF")])
14729
14730 (define_insn "*fop_df_6"
14731   [(set (match_operand:DF 0 "register_operand" "=f,f")
14732         (match_operator:DF 3 "binary_fp_operator"
14733           [(float_extend:DF
14734             (match_operand:SF 1 "register_operand" "0,f"))
14735            (float_extend:DF
14736             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14737   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14738   "* return output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:DF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:DF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "mode" "SF")])
14747
14748 (define_insn "*fop_xf_1"
14749   [(set (match_operand:XF 0 "register_operand" "=f,f")
14750         (match_operator:XF 3 "binary_fp_operator"
14751                         [(match_operand:XF 1 "register_operand" "0,f")
14752                          (match_operand:XF 2 "register_operand" "f,0")]))]
14753   "TARGET_80387
14754    && !COMMUTATIVE_ARITH_P (operands[3])"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "XF")])
14764
14765 (define_insn "*fop_xf_2"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14769             (match_operand:XF 2 "register_operand" "0,0")]))]
14770   "TARGET_80387 && TARGET_USE_FIOP"
14771   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14772   [(set (attr "type") 
14773         (cond [(match_operand:XF 3 "mult_operator" "") 
14774                  (const_string "fmul")
14775                (match_operand:XF 3 "div_operator" "") 
14776                  (const_string "fdiv")
14777               ]
14778               (const_string "fop")))
14779    (set_attr "fp_int_src" "true")
14780    (set_attr "mode" "SI")])
14781
14782 (define_insn "*fop_xf_3"
14783   [(set (match_operand:XF 0 "register_operand" "=f,f")
14784         (match_operator:XF 3 "binary_fp_operator"
14785           [(match_operand:XF 1 "register_operand" "0,0")
14786            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14787   "TARGET_80387 && TARGET_USE_FIOP"
14788   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14789   [(set (attr "type") 
14790         (cond [(match_operand:XF 3 "mult_operator" "") 
14791                  (const_string "fmul")
14792                (match_operand:XF 3 "div_operator" "") 
14793                  (const_string "fdiv")
14794               ]
14795               (const_string "fop")))
14796    (set_attr "fp_int_src" "true")
14797    (set_attr "mode" "SI")])
14798
14799 (define_insn "*fop_xf_4"
14800   [(set (match_operand:XF 0 "register_operand" "=f,f")
14801         (match_operator:XF 3 "binary_fp_operator"
14802            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14803             (match_operand:XF 2 "register_operand" "0,f")]))]
14804   "TARGET_80387"
14805   "* return output_387_binary_op (insn, operands);"
14806   [(set (attr "type") 
14807         (cond [(match_operand:XF 3 "mult_operator" "") 
14808                  (const_string "fmul")
14809                (match_operand:XF 3 "div_operator" "") 
14810                  (const_string "fdiv")
14811               ]
14812               (const_string "fop")))
14813    (set_attr "mode" "SF")])
14814
14815 (define_insn "*fop_xf_5"
14816   [(set (match_operand:XF 0 "register_operand" "=f,f")
14817         (match_operator:XF 3 "binary_fp_operator"
14818           [(match_operand:XF 1 "register_operand" "0,f")
14819            (float_extend:XF
14820             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14821   "TARGET_80387"
14822   "* return output_387_binary_op (insn, operands);"
14823   [(set (attr "type") 
14824         (cond [(match_operand:XF 3 "mult_operator" "") 
14825                  (const_string "fmul")
14826                (match_operand:XF 3 "div_operator" "") 
14827                  (const_string "fdiv")
14828               ]
14829               (const_string "fop")))
14830    (set_attr "mode" "SF")])
14831
14832 (define_insn "*fop_xf_6"
14833   [(set (match_operand:XF 0 "register_operand" "=f,f")
14834         (match_operator:XF 3 "binary_fp_operator"
14835           [(float_extend:XF
14836             (match_operand 1 "register_operand" "0,f"))
14837            (float_extend:XF
14838             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14839   "TARGET_80387"
14840   "* return output_387_binary_op (insn, operands);"
14841   [(set (attr "type") 
14842         (cond [(match_operand:XF 3 "mult_operator" "") 
14843                  (const_string "fmul")
14844                (match_operand:XF 3 "div_operator" "") 
14845                  (const_string "fdiv")
14846               ]
14847               (const_string "fop")))
14848    (set_attr "mode" "SF")])
14849
14850 (define_split
14851   [(set (match_operand 0 "register_operand" "")
14852         (match_operator 3 "binary_fp_operator"
14853            [(float (match_operand:SI 1 "register_operand" ""))
14854             (match_operand 2 "register_operand" "")]))]
14855   "TARGET_80387 && reload_completed
14856    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14857   [(const_int 0)]
14858
14859   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14860   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14861   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14862                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14863                                           GET_MODE (operands[3]),
14864                                           operands[4],
14865                                           operands[2])));
14866   ix86_free_from_memory (GET_MODE (operands[1]));
14867   DONE;
14868 })
14869
14870 (define_split
14871   [(set (match_operand 0 "register_operand" "")
14872         (match_operator 3 "binary_fp_operator"
14873            [(match_operand 1 "register_operand" "")
14874             (float (match_operand:SI 2 "register_operand" ""))]))]
14875   "TARGET_80387 && reload_completed
14876    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14877   [(const_int 0)]
14878 {
14879   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14880   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14881   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14882                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14883                                           GET_MODE (operands[3]),
14884                                           operands[1],
14885                                           operands[4])));
14886   ix86_free_from_memory (GET_MODE (operands[2]));
14887   DONE;
14888 })
14889 \f
14890 ;; FPU special functions.
14891
14892 (define_expand "sqrtsf2"
14893   [(set (match_operand:SF 0 "register_operand" "")
14894         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14895   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14896 {
14897   if (!TARGET_SSE_MATH)
14898     operands[1] = force_reg (SFmode, operands[1]);
14899 })
14900
14901 (define_insn "sqrtsf2_1"
14902   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14903         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14904   "TARGET_USE_FANCY_MATH_387
14905    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14906   "@
14907    fsqrt
14908    sqrtss\t{%1, %0|%0, %1}"
14909   [(set_attr "type" "fpspc,sse")
14910    (set_attr "mode" "SF,SF")
14911    (set_attr "athlon_decode" "direct,*")])
14912
14913 (define_insn "sqrtsf2_1_sse_only"
14914   [(set (match_operand:SF 0 "register_operand" "=x")
14915         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14916   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14917   "sqrtss\t{%1, %0|%0, %1}"
14918   [(set_attr "type" "sse")
14919    (set_attr "mode" "SF")
14920    (set_attr "athlon_decode" "*")])
14921
14922 (define_insn "sqrtsf2_i387"
14923   [(set (match_operand:SF 0 "register_operand" "=f")
14924         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && !TARGET_SSE_MATH"
14927   "fsqrt"
14928   [(set_attr "type" "fpspc")
14929    (set_attr "mode" "SF")
14930    (set_attr "athlon_decode" "direct")])
14931
14932 (define_expand "sqrtdf2"
14933   [(set (match_operand:DF 0 "register_operand" "")
14934         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14935   "TARGET_USE_FANCY_MATH_387
14936    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14937 {
14938   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14939     operands[1] = force_reg (DFmode, operands[1]);
14940 })
14941
14942 (define_insn "sqrtdf2_1"
14943   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14944         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14947   "@
14948    fsqrt
14949    sqrtsd\t{%1, %0|%0, %1}"
14950   [(set_attr "type" "fpspc,sse")
14951    (set_attr "mode" "DF,DF")
14952    (set_attr "athlon_decode" "direct,*")])
14953
14954 (define_insn "sqrtdf2_1_sse_only"
14955   [(set (match_operand:DF 0 "register_operand" "=Y")
14956         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14957   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14958   "sqrtsd\t{%1, %0|%0, %1}"
14959   [(set_attr "type" "sse")
14960    (set_attr "mode" "DF")
14961    (set_attr "athlon_decode" "*")])
14962
14963 (define_insn "sqrtdf2_i387"
14964   [(set (match_operand:DF 0 "register_operand" "=f")
14965         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14966   "TARGET_USE_FANCY_MATH_387
14967    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14968   "fsqrt"
14969   [(set_attr "type" "fpspc")
14970    (set_attr "mode" "DF")
14971    (set_attr "athlon_decode" "direct")])
14972
14973 (define_insn "*sqrtextendsfdf2"
14974   [(set (match_operand:DF 0 "register_operand" "=f")
14975         (sqrt:DF (float_extend:DF
14976                   (match_operand:SF 1 "register_operand" "0"))))]
14977   "TARGET_USE_FANCY_MATH_387
14978    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14979   "fsqrt"
14980   [(set_attr "type" "fpspc")
14981    (set_attr "mode" "DF")
14982    (set_attr "athlon_decode" "direct")])
14983
14984 (define_insn "sqrtxf2"
14985   [(set (match_operand:XF 0 "register_operand" "=f")
14986         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14987   "TARGET_USE_FANCY_MATH_387 
14988    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14989   "fsqrt"
14990   [(set_attr "type" "fpspc")
14991    (set_attr "mode" "XF")
14992    (set_attr "athlon_decode" "direct")])
14993
14994 (define_insn "*sqrtextenddfxf2"
14995   [(set (match_operand:XF 0 "register_operand" "=f")
14996         (sqrt:XF (float_extend:XF
14997                   (match_operand:DF 1 "register_operand" "0"))))]
14998   "TARGET_USE_FANCY_MATH_387"
14999   "fsqrt"
15000   [(set_attr "type" "fpspc")
15001    (set_attr "mode" "XF")
15002    (set_attr "athlon_decode" "direct")])
15003
15004 (define_insn "*sqrtextendsfxf2"
15005   [(set (match_operand:XF 0 "register_operand" "=f")
15006         (sqrt:XF (float_extend:XF
15007                   (match_operand:SF 1 "register_operand" "0"))))]
15008   "TARGET_USE_FANCY_MATH_387"
15009   "fsqrt"
15010   [(set_attr "type" "fpspc")
15011    (set_attr "mode" "XF")
15012    (set_attr "athlon_decode" "direct")])
15013
15014 (define_insn "fpremxf4"
15015   [(set (match_operand:XF 0 "register_operand" "=f")
15016         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15017                     (match_operand:XF 3 "register_operand" "1")]
15018                    UNSPEC_FPREM_F))
15019    (set (match_operand:XF 1 "register_operand" "=u")
15020         (unspec:XF [(match_dup 2) (match_dup 3)]
15021                    UNSPEC_FPREM_U))
15022    (set (reg:CCFP FPSR_REG)
15023         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15024   "TARGET_USE_FANCY_MATH_387
15025    && flag_unsafe_math_optimizations"
15026   "fprem"
15027   [(set_attr "type" "fpspc")
15028    (set_attr "mode" "XF")])
15029
15030 (define_expand "fmodsf3"
15031   [(use (match_operand:SF 0 "register_operand" ""))
15032    (use (match_operand:SF 1 "register_operand" ""))
15033    (use (match_operand:SF 2 "register_operand" ""))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations"
15036 {
15037   rtx label = gen_label_rtx ();
15038
15039   rtx op1 = gen_reg_rtx (XFmode);
15040   rtx op2 = gen_reg_rtx (XFmode);
15041
15042   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15043   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15044
15045   emit_label (label);
15046
15047   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15048   ix86_emit_fp_unordered_jump (label);
15049
15050   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15051   DONE;
15052 })
15053
15054 (define_expand "fmoddf3"
15055   [(use (match_operand:DF 0 "register_operand" ""))
15056    (use (match_operand:DF 1 "register_operand" ""))
15057    (use (match_operand:DF 2 "register_operand" ""))]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations"
15060 {
15061   rtx label = gen_label_rtx ();
15062
15063   rtx op1 = gen_reg_rtx (XFmode);
15064   rtx op2 = gen_reg_rtx (XFmode);
15065
15066   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15067   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15068
15069   emit_label (label);
15070
15071   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15072   ix86_emit_fp_unordered_jump (label);
15073
15074   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15075   DONE;
15076 })
15077
15078 (define_expand "fmodxf3"
15079   [(use (match_operand:XF 0 "register_operand" ""))
15080    (use (match_operand:XF 1 "register_operand" ""))
15081    (use (match_operand:XF 2 "register_operand" ""))]
15082   "TARGET_USE_FANCY_MATH_387
15083    && flag_unsafe_math_optimizations"
15084 {
15085   rtx label = gen_label_rtx ();
15086
15087   emit_label (label);
15088
15089   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15090                            operands[1], operands[2]));
15091   ix86_emit_fp_unordered_jump (label);
15092
15093   emit_move_insn (operands[0], operands[1]);
15094   DONE;
15095 })
15096
15097 (define_insn "fprem1xf4"
15098   [(set (match_operand:XF 0 "register_operand" "=f")
15099         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15100                     (match_operand:XF 3 "register_operand" "1")]
15101                    UNSPEC_FPREM1_F))
15102    (set (match_operand:XF 1 "register_operand" "=u")
15103         (unspec:XF [(match_dup 2) (match_dup 3)]
15104                    UNSPEC_FPREM1_U))
15105    (set (reg:CCFP FPSR_REG)
15106         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15107   "TARGET_USE_FANCY_MATH_387
15108    && flag_unsafe_math_optimizations"
15109   "fprem1"
15110   [(set_attr "type" "fpspc")
15111    (set_attr "mode" "XF")])
15112
15113 (define_expand "dremsf3"
15114   [(use (match_operand:SF 0 "register_operand" ""))
15115    (use (match_operand:SF 1 "register_operand" ""))
15116    (use (match_operand:SF 2 "register_operand" ""))]
15117   "TARGET_USE_FANCY_MATH_387
15118    && flag_unsafe_math_optimizations"
15119 {
15120   rtx label = gen_label_rtx ();
15121
15122   rtx op1 = gen_reg_rtx (XFmode);
15123   rtx op2 = gen_reg_rtx (XFmode);
15124
15125   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15126   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15127
15128   emit_label (label);
15129
15130   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15131   ix86_emit_fp_unordered_jump (label);
15132
15133   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15134   DONE;
15135 })
15136
15137 (define_expand "dremdf3"
15138   [(use (match_operand:DF 0 "register_operand" ""))
15139    (use (match_operand:DF 1 "register_operand" ""))
15140    (use (match_operand:DF 2 "register_operand" ""))]
15141   "TARGET_USE_FANCY_MATH_387
15142    && flag_unsafe_math_optimizations"
15143 {
15144   rtx label = gen_label_rtx ();
15145
15146   rtx op1 = gen_reg_rtx (XFmode);
15147   rtx op2 = gen_reg_rtx (XFmode);
15148
15149   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15150   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15151
15152   emit_label (label);
15153
15154   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15155   ix86_emit_fp_unordered_jump (label);
15156
15157   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15158   DONE;
15159 })
15160
15161 (define_expand "dremxf3"
15162   [(use (match_operand:XF 0 "register_operand" ""))
15163    (use (match_operand:XF 1 "register_operand" ""))
15164    (use (match_operand:XF 2 "register_operand" ""))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167 {
15168   rtx label = gen_label_rtx ();
15169
15170   emit_label (label);
15171
15172   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15173                             operands[1], operands[2]));
15174   ix86_emit_fp_unordered_jump (label);
15175
15176   emit_move_insn (operands[0], operands[1]);
15177   DONE;
15178 })
15179
15180 (define_insn "*sindf2"
15181   [(set (match_operand:DF 0 "register_operand" "=f")
15182         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15183   "TARGET_USE_FANCY_MATH_387
15184    && flag_unsafe_math_optimizations"
15185   "fsin"
15186   [(set_attr "type" "fpspc")
15187    (set_attr "mode" "DF")])
15188
15189 (define_insn "*sinsf2"
15190   [(set (match_operand:SF 0 "register_operand" "=f")
15191         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15192   "TARGET_USE_FANCY_MATH_387
15193    && flag_unsafe_math_optimizations"
15194   "fsin"
15195   [(set_attr "type" "fpspc")
15196    (set_attr "mode" "SF")])
15197
15198 (define_insn "*sinextendsfdf2"
15199   [(set (match_operand:DF 0 "register_operand" "=f")
15200         (unspec:DF [(float_extend:DF
15201                      (match_operand:SF 1 "register_operand" "0"))]
15202                    UNSPEC_SIN))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && flag_unsafe_math_optimizations"
15205   "fsin"
15206   [(set_attr "type" "fpspc")
15207    (set_attr "mode" "DF")])
15208
15209 (define_insn "*sinxf2"
15210   [(set (match_operand:XF 0 "register_operand" "=f")
15211         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15212   "TARGET_USE_FANCY_MATH_387
15213    && flag_unsafe_math_optimizations"
15214   "fsin"
15215   [(set_attr "type" "fpspc")
15216    (set_attr "mode" "XF")])
15217
15218 (define_insn "*cosdf2"
15219   [(set (match_operand:DF 0 "register_operand" "=f")
15220         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15221   "TARGET_USE_FANCY_MATH_387
15222    && flag_unsafe_math_optimizations"
15223   "fcos"
15224   [(set_attr "type" "fpspc")
15225    (set_attr "mode" "DF")])
15226
15227 (define_insn "*cossf2"
15228   [(set (match_operand:SF 0 "register_operand" "=f")
15229         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15232   "fcos"
15233   [(set_attr "type" "fpspc")
15234    (set_attr "mode" "SF")])
15235
15236 (define_insn "*cosextendsfdf2"
15237   [(set (match_operand:DF 0 "register_operand" "=f")
15238         (unspec:DF [(float_extend:DF
15239                      (match_operand:SF 1 "register_operand" "0"))]
15240                    UNSPEC_COS))]
15241   "TARGET_USE_FANCY_MATH_387
15242    && flag_unsafe_math_optimizations"
15243   "fcos"
15244   [(set_attr "type" "fpspc")
15245    (set_attr "mode" "DF")])
15246
15247 (define_insn "*cosxf2"
15248   [(set (match_operand:XF 0 "register_operand" "=f")
15249         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15250   "TARGET_USE_FANCY_MATH_387
15251    && flag_unsafe_math_optimizations"
15252   "fcos"
15253   [(set_attr "type" "fpspc")
15254    (set_attr "mode" "XF")])
15255
15256 ;; With sincos pattern defined, sin and cos builtin function will be
15257 ;; expanded to sincos pattern with one of its outputs left unused. 
15258 ;; Cse pass  will detected, if two sincos patterns can be combined,
15259 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15260 ;; depending on the unused output.
15261
15262 (define_insn "sincosdf3"
15263   [(set (match_operand:DF 0 "register_operand" "=f")
15264         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15265                    UNSPEC_SINCOS_COS))
15266    (set (match_operand:DF 1 "register_operand" "=u")
15267         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15268   "TARGET_USE_FANCY_MATH_387
15269    && flag_unsafe_math_optimizations"
15270   "fsincos"
15271   [(set_attr "type" "fpspc")
15272    (set_attr "mode" "DF")])
15273
15274 (define_split
15275   [(set (match_operand:DF 0 "register_operand" "")
15276         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15277                    UNSPEC_SINCOS_COS))
15278    (set (match_operand:DF 1 "register_operand" "")
15279         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15280   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15281    && !reload_completed && !reload_in_progress"
15282   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15283   "")
15284
15285 (define_split
15286   [(set (match_operand:DF 0 "register_operand" "")
15287         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15288                    UNSPEC_SINCOS_COS))
15289    (set (match_operand:DF 1 "register_operand" "")
15290         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15291   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15292    && !reload_completed && !reload_in_progress"
15293   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15294   "")
15295
15296 (define_insn "sincossf3"
15297   [(set (match_operand:SF 0 "register_operand" "=f")
15298         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15299                    UNSPEC_SINCOS_COS))
15300    (set (match_operand:SF 1 "register_operand" "=u")
15301         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15302   "TARGET_USE_FANCY_MATH_387
15303    && flag_unsafe_math_optimizations"
15304   "fsincos"
15305   [(set_attr "type" "fpspc")
15306    (set_attr "mode" "SF")])
15307
15308 (define_split
15309   [(set (match_operand:SF 0 "register_operand" "")
15310         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15311                    UNSPEC_SINCOS_COS))
15312    (set (match_operand:SF 1 "register_operand" "")
15313         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15314   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15315    && !reload_completed && !reload_in_progress"
15316   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15317   "")
15318
15319 (define_split
15320   [(set (match_operand:SF 0 "register_operand" "")
15321         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15322                    UNSPEC_SINCOS_COS))
15323    (set (match_operand:SF 1 "register_operand" "")
15324         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15325   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15326    && !reload_completed && !reload_in_progress"
15327   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15328   "")
15329
15330 (define_insn "*sincosextendsfdf3"
15331   [(set (match_operand:DF 0 "register_operand" "=f")
15332         (unspec:DF [(float_extend:DF
15333                      (match_operand:SF 2 "register_operand" "0"))]
15334                    UNSPEC_SINCOS_COS))
15335    (set (match_operand:DF 1 "register_operand" "=u")
15336         (unspec:DF [(float_extend:DF
15337                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15338   "TARGET_USE_FANCY_MATH_387
15339    && flag_unsafe_math_optimizations"
15340   "fsincos"
15341   [(set_attr "type" "fpspc")
15342    (set_attr "mode" "DF")])
15343
15344 (define_split
15345   [(set (match_operand:DF 0 "register_operand" "")
15346         (unspec:DF [(float_extend:DF
15347                      (match_operand:SF 2 "register_operand" ""))]
15348                    UNSPEC_SINCOS_COS))
15349    (set (match_operand:DF 1 "register_operand" "")
15350         (unspec:DF [(float_extend:DF
15351                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15352   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15353    && !reload_completed && !reload_in_progress"
15354   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15355                                    (match_dup 2))] UNSPEC_SIN))]
15356   "")
15357
15358 (define_split
15359   [(set (match_operand:DF 0 "register_operand" "")
15360         (unspec:DF [(float_extend:DF
15361                      (match_operand:SF 2 "register_operand" ""))]
15362                    UNSPEC_SINCOS_COS))
15363    (set (match_operand:DF 1 "register_operand" "")
15364         (unspec:DF [(float_extend:DF
15365                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15366   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15367    && !reload_completed && !reload_in_progress"
15368   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15369                                    (match_dup 2))] UNSPEC_COS))]
15370   "")
15371
15372 (define_insn "sincosxf3"
15373   [(set (match_operand:XF 0 "register_operand" "=f")
15374         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15375                    UNSPEC_SINCOS_COS))
15376    (set (match_operand:XF 1 "register_operand" "=u")
15377         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15378   "TARGET_USE_FANCY_MATH_387
15379    && flag_unsafe_math_optimizations"
15380   "fsincos"
15381   [(set_attr "type" "fpspc")
15382    (set_attr "mode" "XF")])
15383
15384 (define_split
15385   [(set (match_operand:XF 0 "register_operand" "")
15386         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15387                    UNSPEC_SINCOS_COS))
15388    (set (match_operand:XF 1 "register_operand" "")
15389         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15390   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15391    && !reload_completed && !reload_in_progress"
15392   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15393   "")
15394
15395 (define_split
15396   [(set (match_operand:XF 0 "register_operand" "")
15397         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15398                    UNSPEC_SINCOS_COS))
15399    (set (match_operand:XF 1 "register_operand" "")
15400         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15401   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15402    && !reload_completed && !reload_in_progress"
15403   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15404   "")
15405
15406 (define_insn "*tandf3_1"
15407   [(set (match_operand:DF 0 "register_operand" "=f")
15408         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15409                    UNSPEC_TAN_ONE))
15410    (set (match_operand:DF 1 "register_operand" "=u")
15411         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15412   "TARGET_USE_FANCY_MATH_387
15413    && flag_unsafe_math_optimizations"
15414   "fptan"
15415   [(set_attr "type" "fpspc")
15416    (set_attr "mode" "DF")])
15417
15418 ;; optimize sequence: fptan
15419 ;;                    fstp    %st(0)
15420 ;;                    fld1
15421 ;; into fptan insn.
15422
15423 (define_peephole2
15424   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15425                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15426                              UNSPEC_TAN_ONE))
15427              (set (match_operand:DF 1 "register_operand" "")
15428                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15429    (set (match_dup 0)
15430         (match_operand:DF 3 "immediate_operand" ""))]
15431   "standard_80387_constant_p (operands[3]) == 2"
15432   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15433              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15434   "")
15435
15436 (define_expand "tandf2"
15437   [(parallel [(set (match_dup 2)
15438                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15439                               UNSPEC_TAN_ONE))
15440               (set (match_operand:DF 0 "register_operand" "")
15441                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations"
15444 {
15445   operands[2] = gen_reg_rtx (DFmode);
15446 })
15447
15448 (define_insn "*tansf3_1"
15449   [(set (match_operand:SF 0 "register_operand" "=f")
15450         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15451                    UNSPEC_TAN_ONE))
15452    (set (match_operand:SF 1 "register_operand" "=u")
15453         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15454   "TARGET_USE_FANCY_MATH_387
15455    && flag_unsafe_math_optimizations"
15456   "fptan"
15457   [(set_attr "type" "fpspc")
15458    (set_attr "mode" "SF")])
15459
15460 ;; optimize sequence: fptan
15461 ;;                    fstp    %st(0)
15462 ;;                    fld1
15463 ;; into fptan insn.
15464
15465 (define_peephole2
15466   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15467                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15468                              UNSPEC_TAN_ONE))
15469              (set (match_operand:SF 1 "register_operand" "")
15470                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15471    (set (match_dup 0)
15472         (match_operand:SF 3 "immediate_operand" ""))]
15473   "standard_80387_constant_p (operands[3]) == 2"
15474   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15475              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15476   "")
15477
15478 (define_expand "tansf2"
15479   [(parallel [(set (match_dup 2)
15480                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15481                               UNSPEC_TAN_ONE))
15482               (set (match_operand:SF 0 "register_operand" "")
15483                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15484   "TARGET_USE_FANCY_MATH_387
15485    && flag_unsafe_math_optimizations"
15486 {
15487   operands[2] = gen_reg_rtx (SFmode);
15488 })
15489
15490 (define_insn "*tanxf3_1"
15491   [(set (match_operand:XF 0 "register_operand" "=f")
15492         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15493                    UNSPEC_TAN_ONE))
15494    (set (match_operand:XF 1 "register_operand" "=u")
15495         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15496   "TARGET_USE_FANCY_MATH_387
15497    && flag_unsafe_math_optimizations"
15498   "fptan"
15499   [(set_attr "type" "fpspc")
15500    (set_attr "mode" "XF")])
15501
15502 ;; optimize sequence: fptan
15503 ;;                    fstp    %st(0)
15504 ;;                    fld1
15505 ;; into fptan insn.
15506
15507 (define_peephole2
15508   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15509                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15510                              UNSPEC_TAN_ONE))
15511              (set (match_operand:XF 1 "register_operand" "")
15512                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15513    (set (match_dup 0)
15514         (match_operand:XF 3 "immediate_operand" ""))]
15515   "standard_80387_constant_p (operands[3]) == 2"
15516   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15517              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15518   "")
15519
15520 (define_expand "tanxf2"
15521   [(parallel [(set (match_dup 2)
15522                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15523                               UNSPEC_TAN_ONE))
15524               (set (match_operand:XF 0 "register_operand" "")
15525                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15526   "TARGET_USE_FANCY_MATH_387
15527    && flag_unsafe_math_optimizations"
15528 {
15529   operands[2] = gen_reg_rtx (XFmode);
15530 })
15531
15532 (define_insn "atan2df3_1"
15533   [(set (match_operand:DF 0 "register_operand" "=f")
15534         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15535                     (match_operand:DF 1 "register_operand" "u")]
15536                    UNSPEC_FPATAN))
15537    (clobber (match_scratch:DF 3 "=1"))]
15538   "TARGET_USE_FANCY_MATH_387
15539    && flag_unsafe_math_optimizations"
15540   "fpatan"
15541   [(set_attr "type" "fpspc")
15542    (set_attr "mode" "DF")])
15543
15544 (define_expand "atan2df3"
15545   [(use (match_operand:DF 0 "register_operand" "=f"))
15546    (use (match_operand:DF 2 "register_operand" "0"))
15547    (use (match_operand:DF 1 "register_operand" "u"))]
15548   "TARGET_USE_FANCY_MATH_387
15549    && flag_unsafe_math_optimizations"
15550 {
15551   rtx copy = gen_reg_rtx (DFmode);
15552   emit_move_insn (copy, operands[1]);
15553   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15554   DONE;
15555 })
15556
15557 (define_expand "atandf2"
15558   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15559                    (unspec:DF [(match_dup 2)
15560                                (match_operand:DF 1 "register_operand" "")]
15561                     UNSPEC_FPATAN))
15562               (clobber (match_scratch:DF 3 ""))])]
15563   "TARGET_USE_FANCY_MATH_387
15564    && flag_unsafe_math_optimizations"
15565 {
15566   operands[2] = gen_reg_rtx (DFmode);
15567   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15568 })
15569
15570 (define_insn "atan2sf3_1"
15571   [(set (match_operand:SF 0 "register_operand" "=f")
15572         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15573                     (match_operand:SF 1 "register_operand" "u")]
15574                    UNSPEC_FPATAN))
15575    (clobber (match_scratch:SF 3 "=1"))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && flag_unsafe_math_optimizations"
15578   "fpatan"
15579   [(set_attr "type" "fpspc")
15580    (set_attr "mode" "SF")])
15581
15582 (define_expand "atan2sf3"
15583   [(use (match_operand:SF 0 "register_operand" "=f"))
15584    (use (match_operand:SF 2 "register_operand" "0"))
15585    (use (match_operand:SF 1 "register_operand" "u"))]
15586   "TARGET_USE_FANCY_MATH_387
15587    && flag_unsafe_math_optimizations"
15588 {
15589   rtx copy = gen_reg_rtx (SFmode);
15590   emit_move_insn (copy, operands[1]);
15591   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15592   DONE;
15593 })
15594
15595 (define_expand "atansf2"
15596   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15597                    (unspec:SF [(match_dup 2)
15598                                (match_operand:SF 1 "register_operand" "")]
15599                     UNSPEC_FPATAN))
15600               (clobber (match_scratch:SF 3 ""))])]
15601   "TARGET_USE_FANCY_MATH_387
15602    && flag_unsafe_math_optimizations"
15603 {
15604   operands[2] = gen_reg_rtx (SFmode);
15605   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15606 })
15607
15608 (define_insn "atan2xf3_1"
15609   [(set (match_operand:XF 0 "register_operand" "=f")
15610         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15611                     (match_operand:XF 1 "register_operand" "u")]
15612                    UNSPEC_FPATAN))
15613    (clobber (match_scratch:XF 3 "=1"))]
15614   "TARGET_USE_FANCY_MATH_387
15615    && flag_unsafe_math_optimizations"
15616   "fpatan"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "XF")])
15619
15620 (define_expand "atan2xf3"
15621   [(use (match_operand:XF 0 "register_operand" "=f"))
15622    (use (match_operand:XF 2 "register_operand" "0"))
15623    (use (match_operand:XF 1 "register_operand" "u"))]
15624   "TARGET_USE_FANCY_MATH_387
15625    && flag_unsafe_math_optimizations"
15626 {
15627   rtx copy = gen_reg_rtx (XFmode);
15628   emit_move_insn (copy, operands[1]);
15629   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15630   DONE;
15631 })
15632
15633 (define_expand "atanxf2"
15634   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15635                    (unspec:XF [(match_dup 2)
15636                                (match_operand:XF 1 "register_operand" "")]
15637                     UNSPEC_FPATAN))
15638               (clobber (match_scratch:XF 3 ""))])]
15639   "TARGET_USE_FANCY_MATH_387
15640    && flag_unsafe_math_optimizations"
15641 {
15642   operands[2] = gen_reg_rtx (XFmode);
15643   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15644 })
15645
15646 (define_expand "asindf2"
15647   [(set (match_dup 2)
15648         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15649    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15650    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15651    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15652    (parallel [(set (match_dup 7)
15653                    (unspec:XF [(match_dup 6) (match_dup 2)]
15654                               UNSPEC_FPATAN))
15655               (clobber (match_scratch:XF 8 ""))])
15656    (set (match_operand:DF 0 "register_operand" "")
15657         (float_truncate:DF (match_dup 7)))]
15658   "TARGET_USE_FANCY_MATH_387
15659    && flag_unsafe_math_optimizations"
15660 {
15661   int i;
15662
15663   for (i=2; i<8; i++)
15664     operands[i] = gen_reg_rtx (XFmode);
15665
15666   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15667 })
15668
15669 (define_expand "asinsf2"
15670   [(set (match_dup 2)
15671         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15672    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15673    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15674    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15675    (parallel [(set (match_dup 7)
15676                    (unspec:XF [(match_dup 6) (match_dup 2)]
15677                               UNSPEC_FPATAN))
15678               (clobber (match_scratch:XF 8 ""))])
15679    (set (match_operand:SF 0 "register_operand" "")
15680         (float_truncate:SF (match_dup 7)))]
15681   "TARGET_USE_FANCY_MATH_387
15682    && flag_unsafe_math_optimizations"
15683 {
15684   int i;
15685
15686   for (i=2; i<8; i++)
15687     operands[i] = gen_reg_rtx (XFmode);
15688
15689   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15690 })
15691
15692 (define_expand "asinxf2"
15693   [(set (match_dup 2)
15694         (mult:XF (match_operand:XF 1 "register_operand" "")
15695                  (match_dup 1)))
15696    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15697    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15698    (parallel [(set (match_operand:XF 0 "register_operand" "")
15699                    (unspec:XF [(match_dup 5) (match_dup 1)]
15700                               UNSPEC_FPATAN))
15701               (clobber (match_scratch:XF 6 ""))])]
15702   "TARGET_USE_FANCY_MATH_387
15703    && flag_unsafe_math_optimizations"
15704 {
15705   int i;
15706
15707   for (i=2; i<6; i++)
15708     operands[i] = gen_reg_rtx (XFmode);
15709
15710   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15711 })
15712
15713 (define_expand "acosdf2"
15714   [(set (match_dup 2)
15715         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15716    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15717    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15718    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15719    (parallel [(set (match_dup 7)
15720                    (unspec:XF [(match_dup 2) (match_dup 6)]
15721                               UNSPEC_FPATAN))
15722               (clobber (match_scratch:XF 8 ""))])
15723    (set (match_operand:DF 0 "register_operand" "")
15724         (float_truncate:DF (match_dup 7)))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727 {
15728   int i;
15729
15730   for (i=2; i<8; i++)
15731     operands[i] = gen_reg_rtx (XFmode);
15732
15733   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15734 })
15735
15736 (define_expand "acossf2"
15737   [(set (match_dup 2)
15738         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15739    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15740    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15741    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15742    (parallel [(set (match_dup 7)
15743                    (unspec:XF [(match_dup 2) (match_dup 6)]
15744                               UNSPEC_FPATAN))
15745               (clobber (match_scratch:XF 8 ""))])
15746    (set (match_operand:SF 0 "register_operand" "")
15747         (float_truncate:SF (match_dup 7)))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && flag_unsafe_math_optimizations"
15750 {
15751   int i;
15752
15753   for (i=2; i<8; i++)
15754     operands[i] = gen_reg_rtx (XFmode);
15755
15756   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15757 })
15758
15759 (define_expand "acosxf2"
15760   [(set (match_dup 2)
15761         (mult:XF (match_operand:XF 1 "register_operand" "")
15762                  (match_dup 1)))
15763    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15764    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15765    (parallel [(set (match_operand:XF 0 "register_operand" "")
15766                    (unspec:XF [(match_dup 1) (match_dup 5)]
15767                               UNSPEC_FPATAN))
15768               (clobber (match_scratch:XF 6 ""))])]
15769   "TARGET_USE_FANCY_MATH_387
15770    && flag_unsafe_math_optimizations"
15771 {
15772   int i;
15773
15774   for (i=2; i<6; i++)
15775     operands[i] = gen_reg_rtx (XFmode);
15776
15777   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15778 })
15779
15780 (define_insn "fyl2x_xf3"
15781   [(set (match_operand:XF 0 "register_operand" "=f")
15782         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15783                     (match_operand:XF 1 "register_operand" "u")]
15784                    UNSPEC_FYL2X))
15785    (clobber (match_scratch:XF 3 "=1"))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788   "fyl2x"
15789   [(set_attr "type" "fpspc")
15790    (set_attr "mode" "XF")])
15791
15792 (define_expand "logsf2"
15793   [(set (match_dup 2)
15794         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15795    (parallel [(set (match_dup 4)
15796                    (unspec:XF [(match_dup 2)
15797                                (match_dup 3)] UNSPEC_FYL2X))
15798               (clobber (match_scratch:XF 5 ""))])
15799    (set (match_operand:SF 0 "register_operand" "")
15800         (float_truncate:SF (match_dup 4)))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && flag_unsafe_math_optimizations"
15803 {
15804   rtx temp;
15805
15806   operands[2] = gen_reg_rtx (XFmode);
15807   operands[3] = gen_reg_rtx (XFmode);
15808   operands[4] = gen_reg_rtx (XFmode);
15809
15810   temp = standard_80387_constant_rtx (4); /* fldln2 */
15811   emit_move_insn (operands[3], temp);
15812 })
15813
15814 (define_expand "logdf2"
15815   [(set (match_dup 2)
15816         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15817    (parallel [(set (match_dup 4)
15818                    (unspec:XF [(match_dup 2)
15819                                (match_dup 3)] UNSPEC_FYL2X))
15820               (clobber (match_scratch:XF 5 ""))])
15821    (set (match_operand:DF 0 "register_operand" "")
15822         (float_truncate:DF (match_dup 4)))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && flag_unsafe_math_optimizations"
15825 {
15826   rtx temp;
15827
15828   operands[2] = gen_reg_rtx (XFmode);
15829   operands[3] = gen_reg_rtx (XFmode);
15830   operands[4] = gen_reg_rtx (XFmode);
15831
15832   temp = standard_80387_constant_rtx (4); /* fldln2 */
15833   emit_move_insn (operands[3], temp);
15834 })
15835
15836 (define_expand "logxf2"
15837   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15838                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15839                                (match_dup 2)] UNSPEC_FYL2X))
15840               (clobber (match_scratch:XF 3 ""))])]
15841   "TARGET_USE_FANCY_MATH_387
15842    && flag_unsafe_math_optimizations"
15843 {
15844   rtx temp;
15845
15846   operands[2] = gen_reg_rtx (XFmode);
15847   temp = standard_80387_constant_rtx (4); /* fldln2 */
15848   emit_move_insn (operands[2], temp);
15849 })
15850
15851 (define_expand "log10sf2"
15852   [(set (match_dup 2)
15853         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15854    (parallel [(set (match_dup 4)
15855                    (unspec:XF [(match_dup 2)
15856                                (match_dup 3)] UNSPEC_FYL2X))
15857               (clobber (match_scratch:XF 5 ""))])
15858    (set (match_operand:SF 0 "register_operand" "")
15859         (float_truncate:SF (match_dup 4)))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && flag_unsafe_math_optimizations"
15862 {
15863   rtx temp;
15864
15865   operands[2] = gen_reg_rtx (XFmode);
15866   operands[3] = gen_reg_rtx (XFmode);
15867   operands[4] = gen_reg_rtx (XFmode);
15868
15869   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15870   emit_move_insn (operands[3], temp);
15871 })
15872
15873 (define_expand "log10df2"
15874   [(set (match_dup 2)
15875         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15876    (parallel [(set (match_dup 4)
15877                    (unspec:XF [(match_dup 2)
15878                                (match_dup 3)] UNSPEC_FYL2X))
15879               (clobber (match_scratch:XF 5 ""))])
15880    (set (match_operand:DF 0 "register_operand" "")
15881         (float_truncate:DF (match_dup 4)))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && flag_unsafe_math_optimizations"
15884 {
15885   rtx temp;
15886
15887   operands[2] = gen_reg_rtx (XFmode);
15888   operands[3] = gen_reg_rtx (XFmode);
15889   operands[4] = gen_reg_rtx (XFmode);
15890
15891   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15892   emit_move_insn (operands[3], temp);
15893 })
15894
15895 (define_expand "log10xf2"
15896   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15897                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15898                                (match_dup 2)] UNSPEC_FYL2X))
15899               (clobber (match_scratch:XF 3 ""))])]
15900   "TARGET_USE_FANCY_MATH_387
15901    && flag_unsafe_math_optimizations"
15902 {
15903   rtx temp;
15904
15905   operands[2] = gen_reg_rtx (XFmode);
15906   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15907   emit_move_insn (operands[2], temp);
15908 })
15909
15910 (define_expand "log2sf2"
15911   [(set (match_dup 2)
15912         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15913    (parallel [(set (match_dup 4)
15914                    (unspec:XF [(match_dup 2)
15915                                (match_dup 3)] UNSPEC_FYL2X))
15916               (clobber (match_scratch:XF 5 ""))])
15917    (set (match_operand:SF 0 "register_operand" "")
15918         (float_truncate:SF (match_dup 4)))]
15919   "TARGET_USE_FANCY_MATH_387
15920    && flag_unsafe_math_optimizations"
15921 {
15922   operands[2] = gen_reg_rtx (XFmode);
15923   operands[3] = gen_reg_rtx (XFmode);
15924   operands[4] = gen_reg_rtx (XFmode);
15925
15926   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15927 })
15928
15929 (define_expand "log2df2"
15930   [(set (match_dup 2)
15931         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15932    (parallel [(set (match_dup 4)
15933                    (unspec:XF [(match_dup 2)
15934                                (match_dup 3)] UNSPEC_FYL2X))
15935               (clobber (match_scratch:XF 5 ""))])
15936    (set (match_operand:DF 0 "register_operand" "")
15937         (float_truncate:DF (match_dup 4)))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15940 {
15941   operands[2] = gen_reg_rtx (XFmode);
15942   operands[3] = gen_reg_rtx (XFmode);
15943   operands[4] = gen_reg_rtx (XFmode);
15944
15945   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15946 })
15947
15948 (define_expand "log2xf2"
15949   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15950                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15951                                (match_dup 2)] UNSPEC_FYL2X))
15952               (clobber (match_scratch:XF 3 ""))])]
15953   "TARGET_USE_FANCY_MATH_387
15954    && flag_unsafe_math_optimizations"
15955 {
15956   operands[2] = gen_reg_rtx (XFmode);
15957   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15958 })
15959
15960 (define_insn "fyl2xp1_xf3"
15961   [(set (match_operand:XF 0 "register_operand" "=f")
15962         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15963                     (match_operand:XF 1 "register_operand" "u")]
15964                    UNSPEC_FYL2XP1))
15965    (clobber (match_scratch:XF 3 "=1"))]
15966   "TARGET_USE_FANCY_MATH_387
15967    && flag_unsafe_math_optimizations"
15968   "fyl2xp1"
15969   [(set_attr "type" "fpspc")
15970    (set_attr "mode" "XF")])
15971
15972 (define_expand "log1psf2"
15973   [(use (match_operand:XF 0 "register_operand" ""))
15974    (use (match_operand:XF 1 "register_operand" ""))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && flag_unsafe_math_optimizations"
15977 {
15978   rtx op0 = gen_reg_rtx (XFmode);
15979   rtx op1 = gen_reg_rtx (XFmode);
15980
15981   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15982   ix86_emit_i387_log1p (op0, op1);
15983   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15984   DONE;
15985 })
15986
15987 (define_expand "log1pdf2"
15988   [(use (match_operand:XF 0 "register_operand" ""))
15989    (use (match_operand:XF 1 "register_operand" ""))]
15990   "TARGET_USE_FANCY_MATH_387
15991    && flag_unsafe_math_optimizations"
15992 {
15993   rtx op0 = gen_reg_rtx (XFmode);
15994   rtx op1 = gen_reg_rtx (XFmode);
15995
15996   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15997   ix86_emit_i387_log1p (op0, op1);
15998   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15999   DONE;
16000 })
16001
16002 (define_expand "log1pxf2"
16003   [(use (match_operand:XF 0 "register_operand" ""))
16004    (use (match_operand:XF 1 "register_operand" ""))]
16005   "TARGET_USE_FANCY_MATH_387
16006    && flag_unsafe_math_optimizations"
16007 {
16008   ix86_emit_i387_log1p (operands[0], operands[1]);
16009   DONE;
16010 })
16011
16012 (define_insn "*fxtractxf3"
16013   [(set (match_operand:XF 0 "register_operand" "=f")
16014         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16015                    UNSPEC_XTRACT_FRACT))
16016    (set (match_operand:XF 1 "register_operand" "=u")
16017         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16018   "TARGET_USE_FANCY_MATH_387
16019    && flag_unsafe_math_optimizations"
16020   "fxtract"
16021   [(set_attr "type" "fpspc")
16022    (set_attr "mode" "XF")])
16023
16024 (define_expand "logbsf2"
16025   [(set (match_dup 2)
16026         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16027    (parallel [(set (match_dup 3)
16028                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16029               (set (match_dup 4)
16030                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16031    (set (match_operand:SF 0 "register_operand" "")
16032         (float_truncate:SF (match_dup 4)))]
16033   "TARGET_USE_FANCY_MATH_387
16034    && flag_unsafe_math_optimizations"
16035 {
16036   operands[2] = gen_reg_rtx (XFmode);
16037   operands[3] = gen_reg_rtx (XFmode);
16038   operands[4] = gen_reg_rtx (XFmode);
16039 })
16040
16041 (define_expand "logbdf2"
16042   [(set (match_dup 2)
16043         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16044    (parallel [(set (match_dup 3)
16045                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16046               (set (match_dup 4)
16047                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16048    (set (match_operand:DF 0 "register_operand" "")
16049         (float_truncate:DF (match_dup 4)))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && flag_unsafe_math_optimizations"
16052 {
16053   operands[2] = gen_reg_rtx (XFmode);
16054   operands[3] = gen_reg_rtx (XFmode);
16055   operands[4] = gen_reg_rtx (XFmode);
16056 })
16057
16058 (define_expand "logbxf2"
16059   [(parallel [(set (match_dup 2)
16060                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16061                               UNSPEC_XTRACT_FRACT))
16062               (set (match_operand:XF 0 "register_operand" "")
16063                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16064   "TARGET_USE_FANCY_MATH_387
16065    && flag_unsafe_math_optimizations"
16066 {
16067   operands[2] = gen_reg_rtx (XFmode);
16068 })
16069
16070 (define_expand "ilogbsi2"
16071   [(parallel [(set (match_dup 2)
16072                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16073                               UNSPEC_XTRACT_FRACT))
16074               (set (match_operand:XF 3 "register_operand" "")
16075                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16076    (parallel [(set (match_operand:SI 0 "register_operand" "")
16077                    (fix:SI (match_dup 3)))
16078               (clobber (reg:CC FLAGS_REG))])]
16079   "TARGET_USE_FANCY_MATH_387
16080    && flag_unsafe_math_optimizations"
16081 {
16082   operands[2] = gen_reg_rtx (XFmode);
16083   operands[3] = gen_reg_rtx (XFmode);
16084 })
16085
16086 (define_insn "*f2xm1xf2"
16087   [(set (match_operand:XF 0 "register_operand" "=f")
16088         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16089          UNSPEC_F2XM1))]
16090   "TARGET_USE_FANCY_MATH_387
16091    && flag_unsafe_math_optimizations"
16092   "f2xm1"
16093   [(set_attr "type" "fpspc")
16094    (set_attr "mode" "XF")])
16095
16096 (define_insn "*fscalexf4"
16097   [(set (match_operand:XF 0 "register_operand" "=f")
16098         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16099                     (match_operand:XF 3 "register_operand" "1")]
16100                    UNSPEC_FSCALE_FRACT))
16101    (set (match_operand:XF 1 "register_operand" "=u")
16102         (unspec:XF [(match_dup 2) (match_dup 3)]
16103                    UNSPEC_FSCALE_EXP))]
16104   "TARGET_USE_FANCY_MATH_387
16105    && flag_unsafe_math_optimizations"
16106   "fscale"
16107   [(set_attr "type" "fpspc")
16108    (set_attr "mode" "XF")])
16109
16110 (define_expand "expsf2"
16111   [(set (match_dup 2)
16112         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16113    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16114    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16115    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16116    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16117    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16118    (parallel [(set (match_dup 10)
16119                    (unspec:XF [(match_dup 9) (match_dup 5)]
16120                               UNSPEC_FSCALE_FRACT))
16121               (set (match_dup 11)
16122                    (unspec:XF [(match_dup 9) (match_dup 5)]
16123                               UNSPEC_FSCALE_EXP))])
16124    (set (match_operand:SF 0 "register_operand" "")
16125         (float_truncate:SF (match_dup 10)))]
16126   "TARGET_USE_FANCY_MATH_387
16127    && flag_unsafe_math_optimizations"
16128 {
16129   rtx temp;
16130   int i;
16131
16132   for (i=2; i<12; i++)
16133     operands[i] = gen_reg_rtx (XFmode);
16134   temp = standard_80387_constant_rtx (5); /* fldl2e */
16135   emit_move_insn (operands[3], temp);
16136   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16137 })
16138
16139 (define_expand "expdf2"
16140   [(set (match_dup 2)
16141         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16142    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16143    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16144    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16145    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16146    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16147    (parallel [(set (match_dup 10)
16148                    (unspec:XF [(match_dup 9) (match_dup 5)]
16149                               UNSPEC_FSCALE_FRACT))
16150               (set (match_dup 11)
16151                    (unspec:XF [(match_dup 9) (match_dup 5)]
16152                               UNSPEC_FSCALE_EXP))])
16153    (set (match_operand:DF 0 "register_operand" "")
16154         (float_truncate:DF (match_dup 10)))]
16155   "TARGET_USE_FANCY_MATH_387
16156    && flag_unsafe_math_optimizations"
16157 {
16158   rtx temp;
16159   int i;
16160
16161   for (i=2; i<12; i++)
16162     operands[i] = gen_reg_rtx (XFmode);
16163   temp = standard_80387_constant_rtx (5); /* fldl2e */
16164   emit_move_insn (operands[3], temp);
16165   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16166 })
16167
16168 (define_expand "expxf2"
16169   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16170                                (match_dup 2)))
16171    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16172    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16173    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16174    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16175    (parallel [(set (match_operand:XF 0 "register_operand" "")
16176                    (unspec:XF [(match_dup 8) (match_dup 4)]
16177                               UNSPEC_FSCALE_FRACT))
16178               (set (match_dup 9)
16179                    (unspec:XF [(match_dup 8) (match_dup 4)]
16180                               UNSPEC_FSCALE_EXP))])]
16181   "TARGET_USE_FANCY_MATH_387
16182    && flag_unsafe_math_optimizations"
16183 {
16184   rtx temp;
16185   int i;
16186
16187   for (i=2; i<10; i++)
16188     operands[i] = gen_reg_rtx (XFmode);
16189   temp = standard_80387_constant_rtx (5); /* fldl2e */
16190   emit_move_insn (operands[2], temp);
16191   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16192 })
16193
16194 (define_expand "exp10sf2"
16195   [(set (match_dup 2)
16196         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16197    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16198    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16199    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16200    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16201    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16202    (parallel [(set (match_dup 10)
16203                    (unspec:XF [(match_dup 9) (match_dup 5)]
16204                               UNSPEC_FSCALE_FRACT))
16205               (set (match_dup 11)
16206                    (unspec:XF [(match_dup 9) (match_dup 5)]
16207                               UNSPEC_FSCALE_EXP))])
16208    (set (match_operand:SF 0 "register_operand" "")
16209         (float_truncate:SF (match_dup 10)))]
16210   "TARGET_USE_FANCY_MATH_387
16211    && flag_unsafe_math_optimizations"
16212 {
16213   rtx temp;
16214   int i;
16215
16216   for (i=2; i<12; i++)
16217     operands[i] = gen_reg_rtx (XFmode);
16218   temp = standard_80387_constant_rtx (6); /* fldl2t */
16219   emit_move_insn (operands[3], temp);
16220   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16221 })
16222
16223 (define_expand "exp10df2"
16224   [(set (match_dup 2)
16225         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16226    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16227    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16228    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16229    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16230    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16231    (parallel [(set (match_dup 10)
16232                    (unspec:XF [(match_dup 9) (match_dup 5)]
16233                               UNSPEC_FSCALE_FRACT))
16234               (set (match_dup 11)
16235                    (unspec:XF [(match_dup 9) (match_dup 5)]
16236                               UNSPEC_FSCALE_EXP))])
16237    (set (match_operand:DF 0 "register_operand" "")
16238         (float_truncate:DF (match_dup 10)))]
16239   "TARGET_USE_FANCY_MATH_387
16240    && flag_unsafe_math_optimizations"
16241 {
16242   rtx temp;
16243   int i;
16244
16245   for (i=2; i<12; i++)
16246     operands[i] = gen_reg_rtx (XFmode);
16247   temp = standard_80387_constant_rtx (6); /* fldl2t */
16248   emit_move_insn (operands[3], temp);
16249   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16250 })
16251
16252 (define_expand "exp10xf2"
16253   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16254                                (match_dup 2)))
16255    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16256    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16257    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16258    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16259    (parallel [(set (match_operand:XF 0 "register_operand" "")
16260                    (unspec:XF [(match_dup 8) (match_dup 4)]
16261                               UNSPEC_FSCALE_FRACT))
16262               (set (match_dup 9)
16263                    (unspec:XF [(match_dup 8) (match_dup 4)]
16264                               UNSPEC_FSCALE_EXP))])]
16265   "TARGET_USE_FANCY_MATH_387
16266    && flag_unsafe_math_optimizations"
16267 {
16268   rtx temp;
16269   int i;
16270
16271   for (i=2; i<10; i++)
16272     operands[i] = gen_reg_rtx (XFmode);
16273   temp = standard_80387_constant_rtx (6); /* fldl2t */
16274   emit_move_insn (operands[2], temp);
16275   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16276 })
16277
16278 (define_expand "exp2sf2"
16279   [(set (match_dup 2)
16280         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16281    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16282    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16283    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16284    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16285    (parallel [(set (match_dup 8)
16286                    (unspec:XF [(match_dup 7) (match_dup 3)]
16287                               UNSPEC_FSCALE_FRACT))
16288               (set (match_dup 9)
16289                    (unspec:XF [(match_dup 7) (match_dup 3)]
16290                               UNSPEC_FSCALE_EXP))])
16291    (set (match_operand:SF 0 "register_operand" "")
16292         (float_truncate:SF (match_dup 8)))]
16293   "TARGET_USE_FANCY_MATH_387
16294    && flag_unsafe_math_optimizations"
16295 {
16296   int i;
16297
16298   for (i=2; i<10; i++)
16299     operands[i] = gen_reg_rtx (XFmode);
16300   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16301 })
16302
16303 (define_expand "exp2df2"
16304   [(set (match_dup 2)
16305         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16306    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16307    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16308    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16309    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16310    (parallel [(set (match_dup 8)
16311                    (unspec:XF [(match_dup 7) (match_dup 3)]
16312                               UNSPEC_FSCALE_FRACT))
16313               (set (match_dup 9)
16314                    (unspec:XF [(match_dup 7) (match_dup 3)]
16315                               UNSPEC_FSCALE_EXP))])
16316    (set (match_operand:DF 0 "register_operand" "")
16317         (float_truncate:DF (match_dup 8)))]
16318   "TARGET_USE_FANCY_MATH_387
16319    && flag_unsafe_math_optimizations"
16320 {
16321   int i;
16322
16323   for (i=2; i<10; i++)
16324     operands[i] = gen_reg_rtx (XFmode);
16325   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16326 })
16327
16328 (define_expand "exp2xf2"
16329   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16330    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16331    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16332    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16333    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16334    (parallel [(set (match_operand:XF 0 "register_operand" "")
16335                    (unspec:XF [(match_dup 7) (match_dup 3)]
16336                               UNSPEC_FSCALE_FRACT))
16337               (set (match_dup 8)
16338                    (unspec:XF [(match_dup 7) (match_dup 3)]
16339                               UNSPEC_FSCALE_EXP))])]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342 {
16343   int i;
16344
16345   for (i=2; i<9; i++)
16346     operands[i] = gen_reg_rtx (XFmode);
16347   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16348 })
16349
16350 (define_expand "expm1df2"
16351   [(set (match_dup 2)
16352         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16353    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16354    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16355    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16356    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16357    (parallel [(set (match_dup 8)
16358                    (unspec:XF [(match_dup 7) (match_dup 5)]
16359                               UNSPEC_FSCALE_FRACT))
16360                    (set (match_dup 9)
16361                    (unspec:XF [(match_dup 7) (match_dup 5)]
16362                               UNSPEC_FSCALE_EXP))])
16363    (parallel [(set (match_dup 11)
16364                    (unspec:XF [(match_dup 10) (match_dup 9)]
16365                               UNSPEC_FSCALE_FRACT))
16366               (set (match_dup 12)
16367                    (unspec:XF [(match_dup 10) (match_dup 9)]
16368                               UNSPEC_FSCALE_EXP))])
16369    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16370    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16371    (set (match_operand:DF 0 "register_operand" "")
16372         (float_truncate:DF (match_dup 14)))]
16373   "TARGET_USE_FANCY_MATH_387
16374    && flag_unsafe_math_optimizations"
16375 {
16376   rtx temp;
16377   int i;
16378
16379   for (i=2; i<15; i++)
16380     operands[i] = gen_reg_rtx (XFmode);
16381   temp = standard_80387_constant_rtx (5); /* fldl2e */
16382   emit_move_insn (operands[3], temp);
16383   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16384 })
16385
16386 (define_expand "expm1sf2"
16387   [(set (match_dup 2)
16388         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16389    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16390    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16391    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16392    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16393    (parallel [(set (match_dup 8)
16394                    (unspec:XF [(match_dup 7) (match_dup 5)]
16395                               UNSPEC_FSCALE_FRACT))
16396                    (set (match_dup 9)
16397                    (unspec:XF [(match_dup 7) (match_dup 5)]
16398                               UNSPEC_FSCALE_EXP))])
16399    (parallel [(set (match_dup 11)
16400                    (unspec:XF [(match_dup 10) (match_dup 9)]
16401                               UNSPEC_FSCALE_FRACT))
16402               (set (match_dup 12)
16403                    (unspec:XF [(match_dup 10) (match_dup 9)]
16404                               UNSPEC_FSCALE_EXP))])
16405    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16406    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16407    (set (match_operand:SF 0 "register_operand" "")
16408         (float_truncate:SF (match_dup 14)))]
16409   "TARGET_USE_FANCY_MATH_387
16410    && flag_unsafe_math_optimizations"
16411 {
16412   rtx temp;
16413   int i;
16414
16415   for (i=2; i<15; i++)
16416     operands[i] = gen_reg_rtx (XFmode);
16417   temp = standard_80387_constant_rtx (5); /* fldl2e */
16418   emit_move_insn (operands[3], temp);
16419   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16420 })
16421
16422 (define_expand "expm1xf2"
16423   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16424                                (match_dup 2)))
16425    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16426    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16427    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16428    (parallel [(set (match_dup 7)
16429                    (unspec:XF [(match_dup 6) (match_dup 4)]
16430                               UNSPEC_FSCALE_FRACT))
16431                    (set (match_dup 8)
16432                    (unspec:XF [(match_dup 6) (match_dup 4)]
16433                               UNSPEC_FSCALE_EXP))])
16434    (parallel [(set (match_dup 10)
16435                    (unspec:XF [(match_dup 9) (match_dup 8)]
16436                               UNSPEC_FSCALE_FRACT))
16437               (set (match_dup 11)
16438                    (unspec:XF [(match_dup 9) (match_dup 8)]
16439                               UNSPEC_FSCALE_EXP))])
16440    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16441    (set (match_operand:XF 0 "register_operand" "")
16442         (plus:XF (match_dup 12) (match_dup 7)))]
16443   "TARGET_USE_FANCY_MATH_387
16444    && flag_unsafe_math_optimizations"
16445 {
16446   rtx temp;
16447   int i;
16448
16449   for (i=2; i<13; i++)
16450     operands[i] = gen_reg_rtx (XFmode);
16451   temp = standard_80387_constant_rtx (5); /* fldl2e */
16452   emit_move_insn (operands[2], temp);
16453   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16454 })
16455 \f
16456
16457 (define_insn "frndintxf2"
16458   [(set (match_operand:XF 0 "register_operand" "=f")
16459         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16460          UNSPEC_FRNDINT))]
16461   "TARGET_USE_FANCY_MATH_387
16462    && flag_unsafe_math_optimizations"
16463   "frndint"
16464   [(set_attr "type" "fpspc")
16465    (set_attr "mode" "XF")])
16466
16467 (define_expand "rintdf2"
16468   [(use (match_operand:DF 0 "register_operand" ""))
16469    (use (match_operand:DF 1 "register_operand" ""))]
16470   "TARGET_USE_FANCY_MATH_387
16471    && flag_unsafe_math_optimizations"
16472 {
16473   rtx op0 = gen_reg_rtx (XFmode);
16474   rtx op1 = gen_reg_rtx (XFmode);
16475
16476   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16477   emit_insn (gen_frndintxf2 (op0, op1));
16478
16479   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16480   DONE;
16481 })
16482
16483 (define_expand "rintsf2"
16484   [(use (match_operand:SF 0 "register_operand" ""))
16485    (use (match_operand:SF 1 "register_operand" ""))]
16486   "TARGET_USE_FANCY_MATH_387
16487    && flag_unsafe_math_optimizations"
16488 {
16489   rtx op0 = gen_reg_rtx (XFmode);
16490   rtx op1 = gen_reg_rtx (XFmode);
16491
16492   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16493   emit_insn (gen_frndintxf2 (op0, op1));
16494
16495   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16496   DONE;
16497 })
16498
16499 (define_expand "rintxf2"
16500   [(use (match_operand:XF 0 "register_operand" ""))
16501    (use (match_operand:XF 1 "register_operand" ""))]
16502   "TARGET_USE_FANCY_MATH_387
16503    && flag_unsafe_math_optimizations"
16504 {
16505   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16506   DONE;
16507 })
16508
16509 (define_insn "frndintxf2_floor"
16510   [(set (match_operand:XF 0 "register_operand" "=f")
16511         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16512          UNSPEC_FRNDINT_FLOOR))
16513    (use (match_operand:HI 2 "memory_operand" "m"))
16514    (use (match_operand:HI 3 "memory_operand" "m"))]
16515   "TARGET_USE_FANCY_MATH_387
16516    && flag_unsafe_math_optimizations"
16517   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16518   [(set_attr "type" "frndint")
16519    (set_attr "i387_cw" "floor")
16520    (set_attr "mode" "XF")])
16521
16522 (define_expand "floordf2"
16523   [(use (match_operand:DF 0 "register_operand" ""))
16524    (use (match_operand:DF 1 "register_operand" ""))]
16525   "TARGET_USE_FANCY_MATH_387
16526    && flag_unsafe_math_optimizations"
16527 {
16528   rtx op0 = gen_reg_rtx (XFmode);
16529   rtx op1 = gen_reg_rtx (XFmode);
16530   rtx op2 = assign_386_stack_local (HImode, 1);
16531   rtx op3 = assign_386_stack_local (HImode, 2);
16532         
16533   ix86_optimize_mode_switching = 1;
16534
16535   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16536   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16537
16538   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16539   DONE;
16540 })
16541
16542 (define_expand "floorsf2"
16543   [(use (match_operand:SF 0 "register_operand" ""))
16544    (use (match_operand:SF 1 "register_operand" ""))]
16545   "TARGET_USE_FANCY_MATH_387
16546    && flag_unsafe_math_optimizations"
16547 {
16548   rtx op0 = gen_reg_rtx (XFmode);
16549   rtx op1 = gen_reg_rtx (XFmode);
16550   rtx op2 = assign_386_stack_local (HImode, 1);
16551   rtx op3 = assign_386_stack_local (HImode, 2);
16552         
16553   ix86_optimize_mode_switching = 1;
16554
16555   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16556   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16557
16558   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16559   DONE;
16560 })
16561
16562 (define_expand "floorxf2"
16563   [(use (match_operand:XF 0 "register_operand" ""))
16564    (use (match_operand:XF 1 "register_operand" ""))]
16565   "TARGET_USE_FANCY_MATH_387
16566    && flag_unsafe_math_optimizations"
16567 {
16568   rtx op2 = assign_386_stack_local (HImode, 1);
16569   rtx op3 = assign_386_stack_local (HImode, 2);
16570         
16571   ix86_optimize_mode_switching = 1;
16572
16573   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16574   DONE;
16575 })
16576
16577 (define_insn "frndintxf2_ceil"
16578   [(set (match_operand:XF 0 "register_operand" "=f")
16579         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16580          UNSPEC_FRNDINT_CEIL))
16581    (use (match_operand:HI 2 "memory_operand" "m"))
16582    (use (match_operand:HI 3 "memory_operand" "m"))]
16583   "TARGET_USE_FANCY_MATH_387
16584    && flag_unsafe_math_optimizations"
16585   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16586   [(set_attr "type" "frndint")
16587    (set_attr "i387_cw" "ceil")
16588    (set_attr "mode" "XF")])
16589
16590 (define_expand "ceildf2"
16591   [(use (match_operand:DF 0 "register_operand" ""))
16592    (use (match_operand:DF 1 "register_operand" ""))]
16593   "TARGET_USE_FANCY_MATH_387
16594    && flag_unsafe_math_optimizations"
16595 {
16596   rtx op0 = gen_reg_rtx (XFmode);
16597   rtx op1 = gen_reg_rtx (XFmode);
16598   rtx op2 = assign_386_stack_local (HImode, 1);
16599   rtx op3 = assign_386_stack_local (HImode, 2);
16600         
16601   ix86_optimize_mode_switching = 1;
16602
16603   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16604   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16605
16606   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16607   DONE;
16608 })
16609
16610 (define_expand "ceilsf2"
16611   [(use (match_operand:SF 0 "register_operand" ""))
16612    (use (match_operand:SF 1 "register_operand" ""))]
16613   "TARGET_USE_FANCY_MATH_387
16614    && flag_unsafe_math_optimizations"
16615 {
16616   rtx op0 = gen_reg_rtx (XFmode);
16617   rtx op1 = gen_reg_rtx (XFmode);
16618   rtx op2 = assign_386_stack_local (HImode, 1);
16619   rtx op3 = assign_386_stack_local (HImode, 2);
16620         
16621   ix86_optimize_mode_switching = 1;
16622
16623   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16624   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16625
16626   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16627   DONE;
16628 })
16629
16630 (define_expand "ceilxf2"
16631   [(use (match_operand:XF 0 "register_operand" ""))
16632    (use (match_operand:XF 1 "register_operand" ""))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations"
16635 {
16636   rtx op2 = assign_386_stack_local (HImode, 1);
16637   rtx op3 = assign_386_stack_local (HImode, 2);
16638         
16639   ix86_optimize_mode_switching = 1;
16640
16641   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16642   DONE;
16643 })
16644
16645 (define_insn "frndintxf2_trunc"
16646   [(set (match_operand:XF 0 "register_operand" "=f")
16647         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16648          UNSPEC_FRNDINT_TRUNC))
16649    (use (match_operand:HI 2 "memory_operand" "m"))
16650    (use (match_operand:HI 3 "memory_operand" "m"))]
16651   "TARGET_USE_FANCY_MATH_387
16652    && flag_unsafe_math_optimizations"
16653   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16654   [(set_attr "type" "frndint")
16655    (set_attr "i387_cw" "trunc")
16656    (set_attr "mode" "XF")])
16657
16658 (define_expand "btruncdf2"
16659   [(use (match_operand:DF 0 "register_operand" ""))
16660    (use (match_operand:DF 1 "register_operand" ""))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663 {
16664   rtx op0 = gen_reg_rtx (XFmode);
16665   rtx op1 = gen_reg_rtx (XFmode);
16666   rtx op2 = assign_386_stack_local (HImode, 1);
16667   rtx op3 = assign_386_stack_local (HImode, 2);
16668         
16669   ix86_optimize_mode_switching = 1;
16670
16671   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16672   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16673
16674   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16675   DONE;
16676 })
16677
16678 (define_expand "btruncsf2"
16679   [(use (match_operand:SF 0 "register_operand" ""))
16680    (use (match_operand:SF 1 "register_operand" ""))]
16681   "TARGET_USE_FANCY_MATH_387
16682    && flag_unsafe_math_optimizations"
16683 {
16684   rtx op0 = gen_reg_rtx (XFmode);
16685   rtx op1 = gen_reg_rtx (XFmode);
16686   rtx op2 = assign_386_stack_local (HImode, 1);
16687   rtx op3 = assign_386_stack_local (HImode, 2);
16688         
16689   ix86_optimize_mode_switching = 1;
16690
16691   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16692   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16693
16694   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16695   DONE;
16696 })
16697
16698 (define_expand "btruncxf2"
16699   [(use (match_operand:XF 0 "register_operand" ""))
16700    (use (match_operand:XF 1 "register_operand" ""))]
16701   "TARGET_USE_FANCY_MATH_387
16702    && flag_unsafe_math_optimizations"
16703 {
16704   rtx op2 = assign_386_stack_local (HImode, 1);
16705   rtx op3 = assign_386_stack_local (HImode, 2);
16706         
16707   ix86_optimize_mode_switching = 1;
16708
16709   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16710   DONE;
16711 })
16712
16713 (define_insn "frndintxf2_mask_pm"
16714   [(set (match_operand:XF 0 "register_operand" "=f")
16715         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16716          UNSPEC_FRNDINT_MASK_PM))
16717    (use (match_operand:HI 2 "memory_operand" "m"))
16718    (use (match_operand:HI 3 "memory_operand" "m"))]
16719   "TARGET_USE_FANCY_MATH_387
16720    && flag_unsafe_math_optimizations"
16721   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16722   [(set_attr "type" "frndint")
16723    (set_attr "i387_cw" "mask_pm")
16724    (set_attr "mode" "XF")])
16725
16726 (define_expand "nearbyintdf2"
16727   [(use (match_operand:DF 0 "register_operand" ""))
16728    (use (match_operand:DF 1 "register_operand" ""))]
16729   "TARGET_USE_FANCY_MATH_387
16730    && flag_unsafe_math_optimizations"
16731 {
16732   rtx op0 = gen_reg_rtx (XFmode);
16733   rtx op1 = gen_reg_rtx (XFmode);
16734   rtx op2 = assign_386_stack_local (HImode, 1);
16735   rtx op3 = assign_386_stack_local (HImode, 2);
16736         
16737   ix86_optimize_mode_switching = 1;
16738
16739   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16740   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16741
16742   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16743   DONE;
16744 })
16745
16746 (define_expand "nearbyintsf2"
16747   [(use (match_operand:SF 0 "register_operand" ""))
16748    (use (match_operand:SF 1 "register_operand" ""))]
16749   "TARGET_USE_FANCY_MATH_387
16750    && flag_unsafe_math_optimizations"
16751 {
16752   rtx op0 = gen_reg_rtx (XFmode);
16753   rtx op1 = gen_reg_rtx (XFmode);
16754   rtx op2 = assign_386_stack_local (HImode, 1);
16755   rtx op3 = assign_386_stack_local (HImode, 2);
16756         
16757   ix86_optimize_mode_switching = 1;
16758
16759   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16760   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16761
16762   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16763   DONE;
16764 })
16765
16766 (define_expand "nearbyintxf2"
16767   [(use (match_operand:XF 0 "register_operand" ""))
16768    (use (match_operand:XF 1 "register_operand" ""))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && flag_unsafe_math_optimizations"
16771 {
16772   rtx op2 = assign_386_stack_local (HImode, 1);
16773   rtx op3 = assign_386_stack_local (HImode, 2);
16774         
16775   ix86_optimize_mode_switching = 1;
16776
16777   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16778                                      op2, op3));
16779   DONE;
16780 })
16781
16782 \f
16783 ;; Block operation instructions
16784
16785 (define_insn "cld"
16786  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16787  ""
16788  "cld"
16789   [(set_attr "type" "cld")])
16790
16791 (define_expand "movmemsi"
16792   [(use (match_operand:BLK 0 "memory_operand" ""))
16793    (use (match_operand:BLK 1 "memory_operand" ""))
16794    (use (match_operand:SI 2 "nonmemory_operand" ""))
16795    (use (match_operand:SI 3 "const_int_operand" ""))]
16796   "! optimize_size"
16797 {
16798  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16799    DONE;
16800  else
16801    FAIL;
16802 })
16803
16804 (define_expand "movmemdi"
16805   [(use (match_operand:BLK 0 "memory_operand" ""))
16806    (use (match_operand:BLK 1 "memory_operand" ""))
16807    (use (match_operand:DI 2 "nonmemory_operand" ""))
16808    (use (match_operand:DI 3 "const_int_operand" ""))]
16809   "TARGET_64BIT"
16810 {
16811  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16812    DONE;
16813  else
16814    FAIL;
16815 })
16816
16817 ;; Most CPUs don't like single string operations
16818 ;; Handle this case here to simplify previous expander.
16819
16820 (define_expand "strmov"
16821   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16822    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16823    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16824               (clobber (reg:CC FLAGS_REG))])
16825    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16826               (clobber (reg:CC FLAGS_REG))])]
16827   ""
16828 {
16829   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16830
16831   /* If .md ever supports :P for Pmode, these can be directly
16832      in the pattern above.  */
16833   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16834   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16835
16836   if (TARGET_SINGLE_STRINGOP || optimize_size)
16837     {
16838       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16839                                       operands[2], operands[3],
16840                                       operands[5], operands[6]));
16841       DONE;
16842     }
16843
16844   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16845 })
16846
16847 (define_expand "strmov_singleop"
16848   [(parallel [(set (match_operand 1 "memory_operand" "")
16849                    (match_operand 3 "memory_operand" ""))
16850               (set (match_operand 0 "register_operand" "")
16851                    (match_operand 4 "" ""))
16852               (set (match_operand 2 "register_operand" "")
16853                    (match_operand 5 "" ""))
16854               (use (reg:SI DIRFLAG_REG))])]
16855   "TARGET_SINGLE_STRINGOP || optimize_size"
16856   "")
16857
16858 (define_insn "*strmovdi_rex_1"
16859   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16860         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16861    (set (match_operand:DI 0 "register_operand" "=D")
16862         (plus:DI (match_dup 2)
16863                  (const_int 8)))
16864    (set (match_operand:DI 1 "register_operand" "=S")
16865         (plus:DI (match_dup 3)
16866                  (const_int 8)))
16867    (use (reg:SI DIRFLAG_REG))]
16868   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16869   "movsq"
16870   [(set_attr "type" "str")
16871    (set_attr "mode" "DI")
16872    (set_attr "memory" "both")])
16873
16874 (define_insn "*strmovsi_1"
16875   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16876         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16877    (set (match_operand:SI 0 "register_operand" "=D")
16878         (plus:SI (match_dup 2)
16879                  (const_int 4)))
16880    (set (match_operand:SI 1 "register_operand" "=S")
16881         (plus:SI (match_dup 3)
16882                  (const_int 4)))
16883    (use (reg:SI DIRFLAG_REG))]
16884   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16885   "{movsl|movsd}"
16886   [(set_attr "type" "str")
16887    (set_attr "mode" "SI")
16888    (set_attr "memory" "both")])
16889
16890 (define_insn "*strmovsi_rex_1"
16891   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16892         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16893    (set (match_operand:DI 0 "register_operand" "=D")
16894         (plus:DI (match_dup 2)
16895                  (const_int 4)))
16896    (set (match_operand:DI 1 "register_operand" "=S")
16897         (plus:DI (match_dup 3)
16898                  (const_int 4)))
16899    (use (reg:SI DIRFLAG_REG))]
16900   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16901   "{movsl|movsd}"
16902   [(set_attr "type" "str")
16903    (set_attr "mode" "SI")
16904    (set_attr "memory" "both")])
16905
16906 (define_insn "*strmovhi_1"
16907   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16908         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16909    (set (match_operand:SI 0 "register_operand" "=D")
16910         (plus:SI (match_dup 2)
16911                  (const_int 2)))
16912    (set (match_operand:SI 1 "register_operand" "=S")
16913         (plus:SI (match_dup 3)
16914                  (const_int 2)))
16915    (use (reg:SI DIRFLAG_REG))]
16916   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16917   "movsw"
16918   [(set_attr "type" "str")
16919    (set_attr "memory" "both")
16920    (set_attr "mode" "HI")])
16921
16922 (define_insn "*strmovhi_rex_1"
16923   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16924         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16925    (set (match_operand:DI 0 "register_operand" "=D")
16926         (plus:DI (match_dup 2)
16927                  (const_int 2)))
16928    (set (match_operand:DI 1 "register_operand" "=S")
16929         (plus:DI (match_dup 3)
16930                  (const_int 2)))
16931    (use (reg:SI DIRFLAG_REG))]
16932   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933   "movsw"
16934   [(set_attr "type" "str")
16935    (set_attr "memory" "both")
16936    (set_attr "mode" "HI")])
16937
16938 (define_insn "*strmovqi_1"
16939   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16940         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16941    (set (match_operand:SI 0 "register_operand" "=D")
16942         (plus:SI (match_dup 2)
16943                  (const_int 1)))
16944    (set (match_operand:SI 1 "register_operand" "=S")
16945         (plus:SI (match_dup 3)
16946                  (const_int 1)))
16947    (use (reg:SI DIRFLAG_REG))]
16948   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16949   "movsb"
16950   [(set_attr "type" "str")
16951    (set_attr "memory" "both")
16952    (set_attr "mode" "QI")])
16953
16954 (define_insn "*strmovqi_rex_1"
16955   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16956         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16957    (set (match_operand:DI 0 "register_operand" "=D")
16958         (plus:DI (match_dup 2)
16959                  (const_int 1)))
16960    (set (match_operand:DI 1 "register_operand" "=S")
16961         (plus:DI (match_dup 3)
16962                  (const_int 1)))
16963    (use (reg:SI DIRFLAG_REG))]
16964   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16965   "movsb"
16966   [(set_attr "type" "str")
16967    (set_attr "memory" "both")
16968    (set_attr "mode" "QI")])
16969
16970 (define_expand "rep_mov"
16971   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16972               (set (match_operand 0 "register_operand" "")
16973                    (match_operand 5 "" ""))
16974               (set (match_operand 2 "register_operand" "")
16975                    (match_operand 6 "" ""))
16976               (set (match_operand 1 "memory_operand" "")
16977                    (match_operand 3 "memory_operand" ""))
16978               (use (match_dup 4))
16979               (use (reg:SI DIRFLAG_REG))])]
16980   ""
16981   "")
16982
16983 (define_insn "*rep_movdi_rex64"
16984   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16985    (set (match_operand:DI 0 "register_operand" "=D") 
16986         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16987                             (const_int 3))
16988                  (match_operand:DI 3 "register_operand" "0")))
16989    (set (match_operand:DI 1 "register_operand" "=S") 
16990         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16991                  (match_operand:DI 4 "register_operand" "1")))
16992    (set (mem:BLK (match_dup 3))
16993         (mem:BLK (match_dup 4)))
16994    (use (match_dup 5))
16995    (use (reg:SI DIRFLAG_REG))]
16996   "TARGET_64BIT"
16997   "{rep\;movsq|rep movsq}"
16998   [(set_attr "type" "str")
16999    (set_attr "prefix_rep" "1")
17000    (set_attr "memory" "both")
17001    (set_attr "mode" "DI")])
17002
17003 (define_insn "*rep_movsi"
17004   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17005    (set (match_operand:SI 0 "register_operand" "=D") 
17006         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17007                             (const_int 2))
17008                  (match_operand:SI 3 "register_operand" "0")))
17009    (set (match_operand:SI 1 "register_operand" "=S") 
17010         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17011                  (match_operand:SI 4 "register_operand" "1")))
17012    (set (mem:BLK (match_dup 3))
17013         (mem:BLK (match_dup 4)))
17014    (use (match_dup 5))
17015    (use (reg:SI DIRFLAG_REG))]
17016   "!TARGET_64BIT"
17017   "{rep\;movsl|rep movsd}"
17018   [(set_attr "type" "str")
17019    (set_attr "prefix_rep" "1")
17020    (set_attr "memory" "both")
17021    (set_attr "mode" "SI")])
17022
17023 (define_insn "*rep_movsi_rex64"
17024   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17025    (set (match_operand:DI 0 "register_operand" "=D") 
17026         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17027                             (const_int 2))
17028                  (match_operand:DI 3 "register_operand" "0")))
17029    (set (match_operand:DI 1 "register_operand" "=S") 
17030         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17031                  (match_operand:DI 4 "register_operand" "1")))
17032    (set (mem:BLK (match_dup 3))
17033         (mem:BLK (match_dup 4)))
17034    (use (match_dup 5))
17035    (use (reg:SI DIRFLAG_REG))]
17036   "TARGET_64BIT"
17037   "{rep\;movsl|rep movsd}"
17038   [(set_attr "type" "str")
17039    (set_attr "prefix_rep" "1")
17040    (set_attr "memory" "both")
17041    (set_attr "mode" "SI")])
17042
17043 (define_insn "*rep_movqi"
17044   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17045    (set (match_operand:SI 0 "register_operand" "=D") 
17046         (plus:SI (match_operand:SI 3 "register_operand" "0")
17047                  (match_operand:SI 5 "register_operand" "2")))
17048    (set (match_operand:SI 1 "register_operand" "=S") 
17049         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17050    (set (mem:BLK (match_dup 3))
17051         (mem:BLK (match_dup 4)))
17052    (use (match_dup 5))
17053    (use (reg:SI DIRFLAG_REG))]
17054   "!TARGET_64BIT"
17055   "{rep\;movsb|rep movsb}"
17056   [(set_attr "type" "str")
17057    (set_attr "prefix_rep" "1")
17058    (set_attr "memory" "both")
17059    (set_attr "mode" "SI")])
17060
17061 (define_insn "*rep_movqi_rex64"
17062   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17063    (set (match_operand:DI 0 "register_operand" "=D") 
17064         (plus:DI (match_operand:DI 3 "register_operand" "0")
17065                  (match_operand:DI 5 "register_operand" "2")))
17066    (set (match_operand:DI 1 "register_operand" "=S") 
17067         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17068    (set (mem:BLK (match_dup 3))
17069         (mem:BLK (match_dup 4)))
17070    (use (match_dup 5))
17071    (use (reg:SI DIRFLAG_REG))]
17072   "TARGET_64BIT"
17073   "{rep\;movsb|rep movsb}"
17074   [(set_attr "type" "str")
17075    (set_attr "prefix_rep" "1")
17076    (set_attr "memory" "both")
17077    (set_attr "mode" "SI")])
17078
17079 (define_expand "clrmemsi"
17080    [(use (match_operand:BLK 0 "memory_operand" ""))
17081     (use (match_operand:SI 1 "nonmemory_operand" ""))
17082     (use (match_operand 2 "const_int_operand" ""))]
17083   ""
17084 {
17085  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17086    DONE;
17087  else
17088    FAIL;
17089 })
17090
17091 (define_expand "clrmemdi"
17092    [(use (match_operand:BLK 0 "memory_operand" ""))
17093     (use (match_operand:DI 1 "nonmemory_operand" ""))
17094     (use (match_operand 2 "const_int_operand" ""))]
17095   "TARGET_64BIT"
17096 {
17097  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17098    DONE;
17099  else
17100    FAIL;
17101 })
17102
17103 ;; Most CPUs don't like single string operations
17104 ;; Handle this case here to simplify previous expander.
17105
17106 (define_expand "strset"
17107   [(set (match_operand 1 "memory_operand" "")
17108         (match_operand 2 "register_operand" ""))
17109    (parallel [(set (match_operand 0 "register_operand" "")
17110                    (match_dup 3))
17111               (clobber (reg:CC FLAGS_REG))])]
17112   ""
17113 {
17114   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17115     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17116
17117   /* If .md ever supports :P for Pmode, this can be directly
17118      in the pattern above.  */
17119   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17120                               GEN_INT (GET_MODE_SIZE (GET_MODE
17121                                                       (operands[2]))));
17122   if (TARGET_SINGLE_STRINGOP || optimize_size)
17123     {
17124       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17125                                       operands[3]));
17126       DONE;
17127     }
17128 })
17129
17130 (define_expand "strset_singleop"
17131   [(parallel [(set (match_operand 1 "memory_operand" "")
17132                    (match_operand 2 "register_operand" ""))
17133               (set (match_operand 0 "register_operand" "")
17134                    (match_operand 3 "" ""))
17135               (use (reg:SI DIRFLAG_REG))])]
17136   "TARGET_SINGLE_STRINGOP || optimize_size"
17137   "")
17138
17139 (define_insn "*strsetdi_rex_1"
17140   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17141         (match_operand:DI 2 "register_operand" "a"))
17142    (set (match_operand:DI 0 "register_operand" "=D")
17143         (plus:DI (match_dup 1)
17144                  (const_int 8)))
17145    (use (reg:SI DIRFLAG_REG))]
17146   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17147   "stosq"
17148   [(set_attr "type" "str")
17149    (set_attr "memory" "store")
17150    (set_attr "mode" "DI")])
17151
17152 (define_insn "*strsetsi_1"
17153   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17154         (match_operand:SI 2 "register_operand" "a"))
17155    (set (match_operand:SI 0 "register_operand" "=D")
17156         (plus:SI (match_dup 1)
17157                  (const_int 4)))
17158    (use (reg:SI DIRFLAG_REG))]
17159   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17160   "{stosl|stosd}"
17161   [(set_attr "type" "str")
17162    (set_attr "memory" "store")
17163    (set_attr "mode" "SI")])
17164
17165 (define_insn "*strsetsi_rex_1"
17166   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17167         (match_operand:SI 2 "register_operand" "a"))
17168    (set (match_operand:DI 0 "register_operand" "=D")
17169         (plus:DI (match_dup 1)
17170                  (const_int 4)))
17171    (use (reg:SI DIRFLAG_REG))]
17172   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17173   "{stosl|stosd}"
17174   [(set_attr "type" "str")
17175    (set_attr "memory" "store")
17176    (set_attr "mode" "SI")])
17177
17178 (define_insn "*strsethi_1"
17179   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17180         (match_operand:HI 2 "register_operand" "a"))
17181    (set (match_operand:SI 0 "register_operand" "=D")
17182         (plus:SI (match_dup 1)
17183                  (const_int 2)))
17184    (use (reg:SI DIRFLAG_REG))]
17185   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17186   "stosw"
17187   [(set_attr "type" "str")
17188    (set_attr "memory" "store")
17189    (set_attr "mode" "HI")])
17190
17191 (define_insn "*strsethi_rex_1"
17192   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17193         (match_operand:HI 2 "register_operand" "a"))
17194    (set (match_operand:DI 0 "register_operand" "=D")
17195         (plus:DI (match_dup 1)
17196                  (const_int 2)))
17197    (use (reg:SI DIRFLAG_REG))]
17198   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17199   "stosw"
17200   [(set_attr "type" "str")
17201    (set_attr "memory" "store")
17202    (set_attr "mode" "HI")])
17203
17204 (define_insn "*strsetqi_1"
17205   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17206         (match_operand:QI 2 "register_operand" "a"))
17207    (set (match_operand:SI 0 "register_operand" "=D")
17208         (plus:SI (match_dup 1)
17209                  (const_int 1)))
17210    (use (reg:SI DIRFLAG_REG))]
17211   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17212   "stosb"
17213   [(set_attr "type" "str")
17214    (set_attr "memory" "store")
17215    (set_attr "mode" "QI")])
17216
17217 (define_insn "*strsetqi_rex_1"
17218   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17219         (match_operand:QI 2 "register_operand" "a"))
17220    (set (match_operand:DI 0 "register_operand" "=D")
17221         (plus:DI (match_dup 1)
17222                  (const_int 1)))
17223    (use (reg:SI DIRFLAG_REG))]
17224   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17225   "stosb"
17226   [(set_attr "type" "str")
17227    (set_attr "memory" "store")
17228    (set_attr "mode" "QI")])
17229
17230 (define_expand "rep_stos"
17231   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17232               (set (match_operand 0 "register_operand" "")
17233                    (match_operand 4 "" ""))
17234               (set (match_operand 2 "memory_operand" "") (const_int 0))
17235               (use (match_operand 3 "register_operand" ""))
17236               (use (match_dup 1))
17237               (use (reg:SI DIRFLAG_REG))])]
17238   ""
17239   "")
17240
17241 (define_insn "*rep_stosdi_rex64"
17242   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17243    (set (match_operand:DI 0 "register_operand" "=D") 
17244         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17245                             (const_int 3))
17246                  (match_operand:DI 3 "register_operand" "0")))
17247    (set (mem:BLK (match_dup 3))
17248         (const_int 0))
17249    (use (match_operand:DI 2 "register_operand" "a"))
17250    (use (match_dup 4))
17251    (use (reg:SI DIRFLAG_REG))]
17252   "TARGET_64BIT"
17253   "{rep\;stosq|rep stosq}"
17254   [(set_attr "type" "str")
17255    (set_attr "prefix_rep" "1")
17256    (set_attr "memory" "store")
17257    (set_attr "mode" "DI")])
17258
17259 (define_insn "*rep_stossi"
17260   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17261    (set (match_operand:SI 0 "register_operand" "=D") 
17262         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17263                             (const_int 2))
17264                  (match_operand:SI 3 "register_operand" "0")))
17265    (set (mem:BLK (match_dup 3))
17266         (const_int 0))
17267    (use (match_operand:SI 2 "register_operand" "a"))
17268    (use (match_dup 4))
17269    (use (reg:SI DIRFLAG_REG))]
17270   "!TARGET_64BIT"
17271   "{rep\;stosl|rep stosd}"
17272   [(set_attr "type" "str")
17273    (set_attr "prefix_rep" "1")
17274    (set_attr "memory" "store")
17275    (set_attr "mode" "SI")])
17276
17277 (define_insn "*rep_stossi_rex64"
17278   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17279    (set (match_operand:DI 0 "register_operand" "=D") 
17280         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17281                             (const_int 2))
17282                  (match_operand:DI 3 "register_operand" "0")))
17283    (set (mem:BLK (match_dup 3))
17284         (const_int 0))
17285    (use (match_operand:SI 2 "register_operand" "a"))
17286    (use (match_dup 4))
17287    (use (reg:SI DIRFLAG_REG))]
17288   "TARGET_64BIT"
17289   "{rep\;stosl|rep stosd}"
17290   [(set_attr "type" "str")
17291    (set_attr "prefix_rep" "1")
17292    (set_attr "memory" "store")
17293    (set_attr "mode" "SI")])
17294
17295 (define_insn "*rep_stosqi"
17296   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17297    (set (match_operand:SI 0 "register_operand" "=D") 
17298         (plus:SI (match_operand:SI 3 "register_operand" "0")
17299                  (match_operand:SI 4 "register_operand" "1")))
17300    (set (mem:BLK (match_dup 3))
17301         (const_int 0))
17302    (use (match_operand:QI 2 "register_operand" "a"))
17303    (use (match_dup 4))
17304    (use (reg:SI DIRFLAG_REG))]
17305   "!TARGET_64BIT"
17306   "{rep\;stosb|rep stosb}"
17307   [(set_attr "type" "str")
17308    (set_attr "prefix_rep" "1")
17309    (set_attr "memory" "store")
17310    (set_attr "mode" "QI")])
17311
17312 (define_insn "*rep_stosqi_rex64"
17313   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17314    (set (match_operand:DI 0 "register_operand" "=D") 
17315         (plus:DI (match_operand:DI 3 "register_operand" "0")
17316                  (match_operand:DI 4 "register_operand" "1")))
17317    (set (mem:BLK (match_dup 3))
17318         (const_int 0))
17319    (use (match_operand:QI 2 "register_operand" "a"))
17320    (use (match_dup 4))
17321    (use (reg:SI DIRFLAG_REG))]
17322   "TARGET_64BIT"
17323   "{rep\;stosb|rep stosb}"
17324   [(set_attr "type" "str")
17325    (set_attr "prefix_rep" "1")
17326    (set_attr "memory" "store")
17327    (set_attr "mode" "QI")])
17328
17329 (define_expand "cmpstrsi"
17330   [(set (match_operand:SI 0 "register_operand" "")
17331         (compare:SI (match_operand:BLK 1 "general_operand" "")
17332                     (match_operand:BLK 2 "general_operand" "")))
17333    (use (match_operand 3 "general_operand" ""))
17334    (use (match_operand 4 "immediate_operand" ""))]
17335   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17336 {
17337   rtx addr1, addr2, out, outlow, count, countreg, align;
17338
17339   /* Can't use this if the user has appropriated esi or edi.  */
17340   if (global_regs[4] || global_regs[5])
17341     FAIL;
17342
17343   out = operands[0];
17344   if (GET_CODE (out) != REG)
17345     out = gen_reg_rtx (SImode);
17346
17347   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17348   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17349   if (addr1 != XEXP (operands[1], 0))
17350     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17351   if (addr2 != XEXP (operands[2], 0))
17352     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17353
17354   count = operands[3];
17355   countreg = ix86_zero_extend_to_Pmode (count);
17356
17357   /* %%% Iff we are testing strict equality, we can use known alignment
17358      to good advantage.  This may be possible with combine, particularly
17359      once cc0 is dead.  */
17360   align = operands[4];
17361
17362   emit_insn (gen_cld ());
17363   if (GET_CODE (count) == CONST_INT)
17364     {
17365       if (INTVAL (count) == 0)
17366         {
17367           emit_move_insn (operands[0], const0_rtx);
17368           DONE;
17369         }
17370       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17371                                     operands[1], operands[2]));
17372     }
17373   else
17374     {
17375       if (TARGET_64BIT)
17376         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17377       else
17378         emit_insn (gen_cmpsi_1 (countreg, countreg));
17379       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17380                                  operands[1], operands[2]));
17381     }
17382
17383   outlow = gen_lowpart (QImode, out);
17384   emit_insn (gen_cmpintqi (outlow));
17385   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17386
17387   if (operands[0] != out)
17388     emit_move_insn (operands[0], out);
17389
17390   DONE;
17391 })
17392
17393 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17394
17395 (define_expand "cmpintqi"
17396   [(set (match_dup 1)
17397         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17398    (set (match_dup 2)
17399         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17400    (parallel [(set (match_operand:QI 0 "register_operand" "")
17401                    (minus:QI (match_dup 1)
17402                              (match_dup 2)))
17403               (clobber (reg:CC FLAGS_REG))])]
17404   ""
17405   "operands[1] = gen_reg_rtx (QImode);
17406    operands[2] = gen_reg_rtx (QImode);")
17407
17408 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17409 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17410
17411 (define_expand "cmpstrqi_nz_1"
17412   [(parallel [(set (reg:CC FLAGS_REG)
17413                    (compare:CC (match_operand 4 "memory_operand" "")
17414                                (match_operand 5 "memory_operand" "")))
17415               (use (match_operand 2 "register_operand" ""))
17416               (use (match_operand:SI 3 "immediate_operand" ""))
17417               (use (reg:SI DIRFLAG_REG))
17418               (clobber (match_operand 0 "register_operand" ""))
17419               (clobber (match_operand 1 "register_operand" ""))
17420               (clobber (match_dup 2))])]
17421   ""
17422   "")
17423
17424 (define_insn "*cmpstrqi_nz_1"
17425   [(set (reg:CC FLAGS_REG)
17426         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17427                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17428    (use (match_operand:SI 6 "register_operand" "2"))
17429    (use (match_operand:SI 3 "immediate_operand" "i"))
17430    (use (reg:SI DIRFLAG_REG))
17431    (clobber (match_operand:SI 0 "register_operand" "=S"))
17432    (clobber (match_operand:SI 1 "register_operand" "=D"))
17433    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17434   "!TARGET_64BIT"
17435   "repz{\;| }cmpsb"
17436   [(set_attr "type" "str")
17437    (set_attr "mode" "QI")
17438    (set_attr "prefix_rep" "1")])
17439
17440 (define_insn "*cmpstrqi_nz_rex_1"
17441   [(set (reg:CC FLAGS_REG)
17442         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17443                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17444    (use (match_operand:DI 6 "register_operand" "2"))
17445    (use (match_operand:SI 3 "immediate_operand" "i"))
17446    (use (reg:SI DIRFLAG_REG))
17447    (clobber (match_operand:DI 0 "register_operand" "=S"))
17448    (clobber (match_operand:DI 1 "register_operand" "=D"))
17449    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17450   "TARGET_64BIT"
17451   "repz{\;| }cmpsb"
17452   [(set_attr "type" "str")
17453    (set_attr "mode" "QI")
17454    (set_attr "prefix_rep" "1")])
17455
17456 ;; The same, but the count is not known to not be zero.
17457
17458 (define_expand "cmpstrqi_1"
17459   [(parallel [(set (reg:CC FLAGS_REG)
17460                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17461                                      (const_int 0))
17462                   (compare:CC (match_operand 4 "memory_operand" "")
17463                               (match_operand 5 "memory_operand" ""))
17464                   (const_int 0)))
17465               (use (match_operand:SI 3 "immediate_operand" ""))
17466               (use (reg:CC FLAGS_REG))
17467               (use (reg:SI DIRFLAG_REG))
17468               (clobber (match_operand 0 "register_operand" ""))
17469               (clobber (match_operand 1 "register_operand" ""))
17470               (clobber (match_dup 2))])]
17471   ""
17472   "")
17473
17474 (define_insn "*cmpstrqi_1"
17475   [(set (reg:CC FLAGS_REG)
17476         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17477                              (const_int 0))
17478           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17479                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17480           (const_int 0)))
17481    (use (match_operand:SI 3 "immediate_operand" "i"))
17482    (use (reg:CC FLAGS_REG))
17483    (use (reg:SI DIRFLAG_REG))
17484    (clobber (match_operand:SI 0 "register_operand" "=S"))
17485    (clobber (match_operand:SI 1 "register_operand" "=D"))
17486    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17487   "!TARGET_64BIT"
17488   "repz{\;| }cmpsb"
17489   [(set_attr "type" "str")
17490    (set_attr "mode" "QI")
17491    (set_attr "prefix_rep" "1")])
17492
17493 (define_insn "*cmpstrqi_rex_1"
17494   [(set (reg:CC FLAGS_REG)
17495         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17496                              (const_int 0))
17497           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17498                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17499           (const_int 0)))
17500    (use (match_operand:SI 3 "immediate_operand" "i"))
17501    (use (reg:CC FLAGS_REG))
17502    (use (reg:SI DIRFLAG_REG))
17503    (clobber (match_operand:DI 0 "register_operand" "=S"))
17504    (clobber (match_operand:DI 1 "register_operand" "=D"))
17505    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17506   "TARGET_64BIT"
17507   "repz{\;| }cmpsb"
17508   [(set_attr "type" "str")
17509    (set_attr "mode" "QI")
17510    (set_attr "prefix_rep" "1")])
17511
17512 (define_expand "strlensi"
17513   [(set (match_operand:SI 0 "register_operand" "")
17514         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17515                     (match_operand:QI 2 "immediate_operand" "")
17516                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17517   ""
17518 {
17519  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17520    DONE;
17521  else
17522    FAIL;
17523 })
17524
17525 (define_expand "strlendi"
17526   [(set (match_operand:DI 0 "register_operand" "")
17527         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17528                     (match_operand:QI 2 "immediate_operand" "")
17529                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17530   ""
17531 {
17532  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17533    DONE;
17534  else
17535    FAIL;
17536 })
17537
17538 (define_expand "strlenqi_1"
17539   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17540               (use (reg:SI DIRFLAG_REG))
17541               (clobber (match_operand 1 "register_operand" ""))
17542               (clobber (reg:CC FLAGS_REG))])]
17543   ""
17544   "")
17545
17546 (define_insn "*strlenqi_1"
17547   [(set (match_operand:SI 0 "register_operand" "=&c")
17548         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17549                     (match_operand:QI 2 "register_operand" "a")
17550                     (match_operand:SI 3 "immediate_operand" "i")
17551                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17552    (use (reg:SI DIRFLAG_REG))
17553    (clobber (match_operand:SI 1 "register_operand" "=D"))
17554    (clobber (reg:CC FLAGS_REG))]
17555   "!TARGET_64BIT"
17556   "repnz{\;| }scasb"
17557   [(set_attr "type" "str")
17558    (set_attr "mode" "QI")
17559    (set_attr "prefix_rep" "1")])
17560
17561 (define_insn "*strlenqi_rex_1"
17562   [(set (match_operand:DI 0 "register_operand" "=&c")
17563         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17564                     (match_operand:QI 2 "register_operand" "a")
17565                     (match_operand:DI 3 "immediate_operand" "i")
17566                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17567    (use (reg:SI DIRFLAG_REG))
17568    (clobber (match_operand:DI 1 "register_operand" "=D"))
17569    (clobber (reg:CC FLAGS_REG))]
17570   "TARGET_64BIT"
17571   "repnz{\;| }scasb"
17572   [(set_attr "type" "str")
17573    (set_attr "mode" "QI")
17574    (set_attr "prefix_rep" "1")])
17575
17576 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17577 ;; handled in combine, but it is not currently up to the task.
17578 ;; When used for their truth value, the cmpstr* expanders generate
17579 ;; code like this:
17580 ;;
17581 ;;   repz cmpsb
17582 ;;   seta       %al
17583 ;;   setb       %dl
17584 ;;   cmpb       %al, %dl
17585 ;;   jcc        label
17586 ;;
17587 ;; The intermediate three instructions are unnecessary.
17588
17589 ;; This one handles cmpstr*_nz_1...
17590 (define_peephole2
17591   [(parallel[
17592      (set (reg:CC FLAGS_REG)
17593           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17594                       (mem:BLK (match_operand 5 "register_operand" ""))))
17595      (use (match_operand 6 "register_operand" ""))
17596      (use (match_operand:SI 3 "immediate_operand" ""))
17597      (use (reg:SI DIRFLAG_REG))
17598      (clobber (match_operand 0 "register_operand" ""))
17599      (clobber (match_operand 1 "register_operand" ""))
17600      (clobber (match_operand 2 "register_operand" ""))])
17601    (set (match_operand:QI 7 "register_operand" "")
17602         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17603    (set (match_operand:QI 8 "register_operand" "")
17604         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17605    (set (reg FLAGS_REG)
17606         (compare (match_dup 7) (match_dup 8)))
17607   ]
17608   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17609   [(parallel[
17610      (set (reg:CC FLAGS_REG)
17611           (compare:CC (mem:BLK (match_dup 4))
17612                       (mem:BLK (match_dup 5))))
17613      (use (match_dup 6))
17614      (use (match_dup 3))
17615      (use (reg:SI DIRFLAG_REG))
17616      (clobber (match_dup 0))
17617      (clobber (match_dup 1))
17618      (clobber (match_dup 2))])]
17619   "")
17620
17621 ;; ...and this one handles cmpstr*_1.
17622 (define_peephole2
17623   [(parallel[
17624      (set (reg:CC FLAGS_REG)
17625           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17626                                (const_int 0))
17627             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17628                         (mem:BLK (match_operand 5 "register_operand" "")))
17629             (const_int 0)))
17630      (use (match_operand:SI 3 "immediate_operand" ""))
17631      (use (reg:CC FLAGS_REG))
17632      (use (reg:SI DIRFLAG_REG))
17633      (clobber (match_operand 0 "register_operand" ""))
17634      (clobber (match_operand 1 "register_operand" ""))
17635      (clobber (match_operand 2 "register_operand" ""))])
17636    (set (match_operand:QI 7 "register_operand" "")
17637         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17638    (set (match_operand:QI 8 "register_operand" "")
17639         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17640    (set (reg FLAGS_REG)
17641         (compare (match_dup 7) (match_dup 8)))
17642   ]
17643   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17644   [(parallel[
17645      (set (reg:CC FLAGS_REG)
17646           (if_then_else:CC (ne (match_dup 6)
17647                                (const_int 0))
17648             (compare:CC (mem:BLK (match_dup 4))
17649                         (mem:BLK (match_dup 5)))
17650             (const_int 0)))
17651      (use (match_dup 3))
17652      (use (reg:CC FLAGS_REG))
17653      (use (reg:SI DIRFLAG_REG))
17654      (clobber (match_dup 0))
17655      (clobber (match_dup 1))
17656      (clobber (match_dup 2))])]
17657   "")
17658
17659
17660 \f
17661 ;; Conditional move instructions.
17662
17663 (define_expand "movdicc"
17664   [(set (match_operand:DI 0 "register_operand" "")
17665         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17666                          (match_operand:DI 2 "general_operand" "")
17667                          (match_operand:DI 3 "general_operand" "")))]
17668   "TARGET_64BIT"
17669   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17670
17671 (define_insn "x86_movdicc_0_m1_rex64"
17672   [(set (match_operand:DI 0 "register_operand" "=r")
17673         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17674           (const_int -1)
17675           (const_int 0)))
17676    (clobber (reg:CC FLAGS_REG))]
17677   "TARGET_64BIT"
17678   "sbb{q}\t%0, %0"
17679   ; Since we don't have the proper number of operands for an alu insn,
17680   ; fill in all the blanks.
17681   [(set_attr "type" "alu")
17682    (set_attr "pent_pair" "pu")
17683    (set_attr "memory" "none")
17684    (set_attr "imm_disp" "false")
17685    (set_attr "mode" "DI")
17686    (set_attr "length_immediate" "0")])
17687
17688 (define_insn "movdicc_c_rex64"
17689   [(set (match_operand:DI 0 "register_operand" "=r,r")
17690         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17691                                 [(reg FLAGS_REG) (const_int 0)])
17692                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17693                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17694   "TARGET_64BIT && TARGET_CMOVE
17695    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17696   "@
17697    cmov%O2%C1\t{%2, %0|%0, %2}
17698    cmov%O2%c1\t{%3, %0|%0, %3}"
17699   [(set_attr "type" "icmov")
17700    (set_attr "mode" "DI")])
17701
17702 (define_expand "movsicc"
17703   [(set (match_operand:SI 0 "register_operand" "")
17704         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17705                          (match_operand:SI 2 "general_operand" "")
17706                          (match_operand:SI 3 "general_operand" "")))]
17707   ""
17708   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17709
17710 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17711 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17712 ;; So just document what we're doing explicitly.
17713
17714 (define_insn "x86_movsicc_0_m1"
17715   [(set (match_operand:SI 0 "register_operand" "=r")
17716         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17717           (const_int -1)
17718           (const_int 0)))
17719    (clobber (reg:CC FLAGS_REG))]
17720   ""
17721   "sbb{l}\t%0, %0"
17722   ; Since we don't have the proper number of operands for an alu insn,
17723   ; fill in all the blanks.
17724   [(set_attr "type" "alu")
17725    (set_attr "pent_pair" "pu")
17726    (set_attr "memory" "none")
17727    (set_attr "imm_disp" "false")
17728    (set_attr "mode" "SI")
17729    (set_attr "length_immediate" "0")])
17730
17731 (define_insn "*movsicc_noc"
17732   [(set (match_operand:SI 0 "register_operand" "=r,r")
17733         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17734                                 [(reg FLAGS_REG) (const_int 0)])
17735                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17736                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17737   "TARGET_CMOVE
17738    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17739   "@
17740    cmov%O2%C1\t{%2, %0|%0, %2}
17741    cmov%O2%c1\t{%3, %0|%0, %3}"
17742   [(set_attr "type" "icmov")
17743    (set_attr "mode" "SI")])
17744
17745 (define_expand "movhicc"
17746   [(set (match_operand:HI 0 "register_operand" "")
17747         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17748                          (match_operand:HI 2 "general_operand" "")
17749                          (match_operand:HI 3 "general_operand" "")))]
17750   "TARGET_HIMODE_MATH"
17751   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17752
17753 (define_insn "*movhicc_noc"
17754   [(set (match_operand:HI 0 "register_operand" "=r,r")
17755         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17756                                 [(reg FLAGS_REG) (const_int 0)])
17757                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17758                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17759   "TARGET_CMOVE
17760    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17761   "@
17762    cmov%O2%C1\t{%2, %0|%0, %2}
17763    cmov%O2%c1\t{%3, %0|%0, %3}"
17764   [(set_attr "type" "icmov")
17765    (set_attr "mode" "HI")])
17766
17767 (define_expand "movqicc"
17768   [(set (match_operand:QI 0 "register_operand" "")
17769         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17770                          (match_operand:QI 2 "general_operand" "")
17771                          (match_operand:QI 3 "general_operand" "")))]
17772   "TARGET_QIMODE_MATH"
17773   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17774
17775 (define_insn_and_split "*movqicc_noc"
17776   [(set (match_operand:QI 0 "register_operand" "=r,r")
17777         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17778                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17779                       (match_operand:QI 2 "register_operand" "r,0")
17780                       (match_operand:QI 3 "register_operand" "0,r")))]
17781   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17782   "#"
17783   "&& reload_completed"
17784   [(set (match_dup 0)
17785         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17786                       (match_dup 2)
17787                       (match_dup 3)))]
17788   "operands[0] = gen_lowpart (SImode, operands[0]);
17789    operands[2] = gen_lowpart (SImode, operands[2]);
17790    operands[3] = gen_lowpart (SImode, operands[3]);"
17791   [(set_attr "type" "icmov")
17792    (set_attr "mode" "SI")])
17793
17794 (define_expand "movsfcc"
17795   [(set (match_operand:SF 0 "register_operand" "")
17796         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17797                          (match_operand:SF 2 "register_operand" "")
17798                          (match_operand:SF 3 "register_operand" "")))]
17799   "TARGET_CMOVE"
17800   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17801
17802 (define_insn "*movsfcc_1"
17803   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17804         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17805                                 [(reg FLAGS_REG) (const_int 0)])
17806                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17807                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17808   "TARGET_CMOVE
17809    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17810   "@
17811    fcmov%F1\t{%2, %0|%0, %2}
17812    fcmov%f1\t{%3, %0|%0, %3}
17813    cmov%O2%C1\t{%2, %0|%0, %2}
17814    cmov%O2%c1\t{%3, %0|%0, %3}"
17815   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17816    (set_attr "mode" "SF,SF,SI,SI")])
17817
17818 (define_expand "movdfcc"
17819   [(set (match_operand:DF 0 "register_operand" "")
17820         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17821                          (match_operand:DF 2 "register_operand" "")
17822                          (match_operand:DF 3 "register_operand" "")))]
17823   "TARGET_CMOVE"
17824   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17825
17826 (define_insn "*movdfcc_1"
17827   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17828         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17829                                 [(reg FLAGS_REG) (const_int 0)])
17830                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17831                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17832   "!TARGET_64BIT && TARGET_CMOVE
17833    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17834   "@
17835    fcmov%F1\t{%2, %0|%0, %2}
17836    fcmov%f1\t{%3, %0|%0, %3}
17837    #
17838    #"
17839   [(set_attr "type" "fcmov,fcmov,multi,multi")
17840    (set_attr "mode" "DF")])
17841
17842 (define_insn "*movdfcc_1_rex64"
17843   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17844         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17845                                 [(reg FLAGS_REG) (const_int 0)])
17846                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17847                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17848   "TARGET_64BIT && TARGET_CMOVE
17849    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17850   "@
17851    fcmov%F1\t{%2, %0|%0, %2}
17852    fcmov%f1\t{%3, %0|%0, %3}
17853    cmov%O2%C1\t{%2, %0|%0, %2}
17854    cmov%O2%c1\t{%3, %0|%0, %3}"
17855   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17856    (set_attr "mode" "DF")])
17857
17858 (define_split
17859   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17860         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17861                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17862                       (match_operand:DF 2 "nonimmediate_operand" "")
17863                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17864   "!TARGET_64BIT && reload_completed"
17865   [(set (match_dup 2)
17866         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17867                       (match_dup 5)
17868                       (match_dup 7)))
17869    (set (match_dup 3)
17870         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17871                       (match_dup 6)
17872                       (match_dup 8)))]
17873   "split_di (operands+2, 1, operands+5, operands+6);
17874    split_di (operands+3, 1, operands+7, operands+8);
17875    split_di (operands, 1, operands+2, operands+3);")
17876
17877 (define_expand "movxfcc"
17878   [(set (match_operand:XF 0 "register_operand" "")
17879         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17880                          (match_operand:XF 2 "register_operand" "")
17881                          (match_operand:XF 3 "register_operand" "")))]
17882   "TARGET_CMOVE"
17883   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17884
17885 (define_insn "*movxfcc_1"
17886   [(set (match_operand:XF 0 "register_operand" "=f,f")
17887         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17888                                 [(reg FLAGS_REG) (const_int 0)])
17889                       (match_operand:XF 2 "register_operand" "f,0")
17890                       (match_operand:XF 3 "register_operand" "0,f")))]
17891   "TARGET_CMOVE"
17892   "@
17893    fcmov%F1\t{%2, %0|%0, %2}
17894    fcmov%f1\t{%3, %0|%0, %3}"
17895   [(set_attr "type" "fcmov")
17896    (set_attr "mode" "XF")])
17897
17898 (define_expand "minsf3"
17899   [(parallel [
17900      (set (match_operand:SF 0 "register_operand" "")
17901           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17902                                (match_operand:SF 2 "nonimmediate_operand" ""))
17903                            (match_dup 1)
17904                            (match_dup 2)))
17905      (clobber (reg:CC FLAGS_REG))])]
17906   "TARGET_SSE"
17907   "")
17908
17909 (define_insn "*minsf"
17910   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17911         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17912                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17913                          (match_dup 1)
17914                          (match_dup 2)))
17915    (clobber (reg:CC FLAGS_REG))]
17916   "TARGET_SSE && TARGET_IEEE_FP"
17917   "#")
17918
17919 (define_insn "*minsf_nonieee"
17920   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17921         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17922                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17923                          (match_dup 1)
17924                          (match_dup 2)))
17925    (clobber (reg:CC FLAGS_REG))]
17926   "TARGET_SSE && !TARGET_IEEE_FP
17927    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17928   "#")
17929
17930 (define_split
17931   [(set (match_operand:SF 0 "register_operand" "")
17932         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17933                              (match_operand:SF 2 "nonimmediate_operand" ""))
17934                          (match_operand:SF 3 "register_operand" "")
17935                          (match_operand:SF 4 "nonimmediate_operand" "")))
17936    (clobber (reg:CC FLAGS_REG))]
17937   "SSE_REG_P (operands[0]) && reload_completed
17938    && ((operands_match_p (operands[1], operands[3])
17939         && operands_match_p (operands[2], operands[4]))
17940        || (operands_match_p (operands[1], operands[4])
17941            && operands_match_p (operands[2], operands[3])))"
17942   [(set (match_dup 0)
17943         (if_then_else:SF (lt (match_dup 1)
17944                              (match_dup 2))
17945                          (match_dup 1)
17946                          (match_dup 2)))])
17947
17948 ;; Conditional addition patterns
17949 (define_expand "addqicc"
17950   [(match_operand:QI 0 "register_operand" "")
17951    (match_operand 1 "comparison_operator" "")
17952    (match_operand:QI 2 "register_operand" "")
17953    (match_operand:QI 3 "const_int_operand" "")]
17954   ""
17955   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17956
17957 (define_expand "addhicc"
17958   [(match_operand:HI 0 "register_operand" "")
17959    (match_operand 1 "comparison_operator" "")
17960    (match_operand:HI 2 "register_operand" "")
17961    (match_operand:HI 3 "const_int_operand" "")]
17962   ""
17963   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17964
17965 (define_expand "addsicc"
17966   [(match_operand:SI 0 "register_operand" "")
17967    (match_operand 1 "comparison_operator" "")
17968    (match_operand:SI 2 "register_operand" "")
17969    (match_operand:SI 3 "const_int_operand" "")]
17970   ""
17971   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17972
17973 (define_expand "adddicc"
17974   [(match_operand:DI 0 "register_operand" "")
17975    (match_operand 1 "comparison_operator" "")
17976    (match_operand:DI 2 "register_operand" "")
17977    (match_operand:DI 3 "const_int_operand" "")]
17978   "TARGET_64BIT"
17979   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17980
17981 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17982
17983 (define_split
17984   [(set (match_operand:SF 0 "fp_register_operand" "")
17985         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17986                              (match_operand:SF 2 "register_operand" ""))
17987                          (match_operand:SF 3 "register_operand" "")
17988                          (match_operand:SF 4 "register_operand" "")))
17989    (clobber (reg:CC FLAGS_REG))]
17990   "reload_completed
17991    && ((operands_match_p (operands[1], operands[3])
17992         && operands_match_p (operands[2], operands[4]))
17993        || (operands_match_p (operands[1], operands[4])
17994            && operands_match_p (operands[2], operands[3])))"
17995   [(set (reg:CCFP FLAGS_REG)
17996         (compare:CCFP (match_dup 2)
17997                       (match_dup 1)))
17998    (set (match_dup 0)
17999         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18000                          (match_dup 1)
18001                          (match_dup 2)))])
18002
18003 (define_insn "*minsf_sse"
18004   [(set (match_operand:SF 0 "register_operand" "=x")
18005         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
18006                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18007                          (match_dup 1)
18008                          (match_dup 2)))]
18009   "TARGET_SSE && reload_completed"
18010   "minss\t{%2, %0|%0, %2}"
18011   [(set_attr "type" "sse")
18012    (set_attr "mode" "SF")])
18013
18014 (define_expand "mindf3"
18015   [(parallel [
18016      (set (match_operand:DF 0 "register_operand" "")
18017           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18018                                (match_operand:DF 2 "nonimmediate_operand" ""))
18019                            (match_dup 1)
18020                            (match_dup 2)))
18021      (clobber (reg:CC FLAGS_REG))])]
18022   "TARGET_SSE2 && TARGET_SSE_MATH"
18023   "#")
18024
18025 (define_insn "*mindf"
18026   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18027         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18028                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18029                          (match_dup 1)
18030                          (match_dup 2)))
18031    (clobber (reg:CC FLAGS_REG))]
18032   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18033   "#")
18034
18035 (define_insn "*mindf_nonieee"
18036   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18037         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18038                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18039                          (match_dup 1)
18040                          (match_dup 2)))
18041    (clobber (reg:CC FLAGS_REG))]
18042   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18043    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18044   "#")
18045
18046 (define_split
18047   [(set (match_operand:DF 0 "register_operand" "")
18048         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18049                              (match_operand:DF 2 "nonimmediate_operand" ""))
18050                          (match_operand:DF 3 "register_operand" "")
18051                          (match_operand:DF 4 "nonimmediate_operand" "")))
18052    (clobber (reg:CC FLAGS_REG))]
18053   "SSE_REG_P (operands[0]) && reload_completed
18054    && ((operands_match_p (operands[1], operands[3])
18055         && operands_match_p (operands[2], operands[4]))
18056        || (operands_match_p (operands[1], operands[4])
18057            && operands_match_p (operands[2], operands[3])))"
18058   [(set (match_dup 0)
18059         (if_then_else:DF (lt (match_dup 1)
18060                              (match_dup 2))
18061                          (match_dup 1)
18062                          (match_dup 2)))])
18063
18064 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18065 (define_split
18066   [(set (match_operand:DF 0 "fp_register_operand" "")
18067         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18068                              (match_operand:DF 2 "register_operand" ""))
18069                          (match_operand:DF 3 "register_operand" "")
18070                          (match_operand:DF 4 "register_operand" "")))
18071    (clobber (reg:CC FLAGS_REG))]
18072   "reload_completed
18073    && ((operands_match_p (operands[1], operands[3])
18074         && operands_match_p (operands[2], operands[4]))
18075        || (operands_match_p (operands[1], operands[4])
18076            && operands_match_p (operands[2], operands[3])))"
18077   [(set (reg:CCFP FLAGS_REG)
18078         (compare:CCFP (match_dup 2)
18079                       (match_dup 1)))
18080    (set (match_dup 0)
18081         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18082                          (match_dup 1)
18083                          (match_dup 2)))])
18084
18085 (define_insn "*mindf_sse"
18086   [(set (match_operand:DF 0 "register_operand" "=Y")
18087         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18088                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18089                          (match_dup 1)
18090                          (match_dup 2)))]
18091   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18092   "minsd\t{%2, %0|%0, %2}"
18093   [(set_attr "type" "sse")
18094    (set_attr "mode" "DF")])
18095
18096 (define_expand "maxsf3"
18097   [(parallel [
18098      (set (match_operand:SF 0 "register_operand" "")
18099           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18100                                (match_operand:SF 2 "nonimmediate_operand" ""))
18101                            (match_dup 1)
18102                            (match_dup 2)))
18103      (clobber (reg:CC FLAGS_REG))])]
18104   "TARGET_SSE"
18105   "#")
18106
18107 (define_insn "*maxsf"
18108   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18109         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18110                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18111                          (match_dup 1)
18112                          (match_dup 2)))
18113    (clobber (reg:CC FLAGS_REG))]
18114   "TARGET_SSE && TARGET_IEEE_FP"
18115   "#")
18116
18117 (define_insn "*maxsf_nonieee"
18118   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18119         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18120                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18121                          (match_dup 1)
18122                          (match_dup 2)))
18123    (clobber (reg:CC FLAGS_REG))]
18124   "TARGET_SSE && !TARGET_IEEE_FP
18125    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18126   "#")
18127
18128 (define_split
18129   [(set (match_operand:SF 0 "register_operand" "")
18130         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18131                              (match_operand:SF 2 "nonimmediate_operand" ""))
18132                          (match_operand:SF 3 "register_operand" "")
18133                          (match_operand:SF 4 "nonimmediate_operand" "")))
18134    (clobber (reg:CC FLAGS_REG))]
18135   "SSE_REG_P (operands[0]) && reload_completed
18136    && ((operands_match_p (operands[1], operands[3])
18137         && operands_match_p (operands[2], operands[4]))
18138        || (operands_match_p (operands[1], operands[4])
18139            && operands_match_p (operands[2], operands[3])))"
18140   [(set (match_dup 0)
18141         (if_then_else:SF (gt (match_dup 1)
18142                              (match_dup 2))
18143                          (match_dup 1)
18144                          (match_dup 2)))])
18145
18146 (define_split
18147   [(set (match_operand:SF 0 "fp_register_operand" "")
18148         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18149                              (match_operand:SF 2 "register_operand" ""))
18150                          (match_operand:SF 3 "register_operand" "")
18151                          (match_operand:SF 4 "register_operand" "")))
18152    (clobber (reg:CC FLAGS_REG))]
18153   "reload_completed
18154    && ((operands_match_p (operands[1], operands[3])
18155         && operands_match_p (operands[2], operands[4]))
18156        || (operands_match_p (operands[1], operands[4])
18157            && operands_match_p (operands[2], operands[3])))"
18158   [(set (reg:CCFP FLAGS_REG)
18159         (compare:CCFP (match_dup 1)
18160                       (match_dup 2)))
18161    (set (match_dup 0)
18162         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18163                          (match_dup 1)
18164                          (match_dup 2)))])
18165
18166 (define_insn "*maxsf_sse"
18167   [(set (match_operand:SF 0 "register_operand" "=x")
18168         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18169                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18170                          (match_dup 1)
18171                          (match_dup 2)))]
18172   "TARGET_SSE && reload_completed"
18173   "maxss\t{%2, %0|%0, %2}"
18174   [(set_attr "type" "sse")
18175    (set_attr "mode" "SF")])
18176
18177 (define_expand "maxdf3"
18178   [(parallel [
18179      (set (match_operand:DF 0 "register_operand" "")
18180           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18181                                (match_operand:DF 2 "nonimmediate_operand" ""))
18182                            (match_dup 1)
18183                            (match_dup 2)))
18184      (clobber (reg:CC FLAGS_REG))])]
18185   "TARGET_SSE2 && TARGET_SSE_MATH"
18186   "#")
18187
18188 (define_insn "*maxdf"
18189   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18190         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18191                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18192                          (match_dup 1)
18193                          (match_dup 2)))
18194    (clobber (reg:CC FLAGS_REG))]
18195   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18196   "#")
18197
18198 (define_insn "*maxdf_nonieee"
18199   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18200         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18201                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18202                          (match_dup 1)
18203                          (match_dup 2)))
18204    (clobber (reg:CC FLAGS_REG))]
18205   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18207   "#")
18208
18209 (define_split
18210   [(set (match_operand:DF 0 "register_operand" "")
18211         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18212                              (match_operand:DF 2 "nonimmediate_operand" ""))
18213                          (match_operand:DF 3 "register_operand" "")
18214                          (match_operand:DF 4 "nonimmediate_operand" "")))
18215    (clobber (reg:CC FLAGS_REG))]
18216   "SSE_REG_P (operands[0]) && reload_completed
18217    && ((operands_match_p (operands[1], operands[3])
18218         && operands_match_p (operands[2], operands[4]))
18219        || (operands_match_p (operands[1], operands[4])
18220            && operands_match_p (operands[2], operands[3])))"
18221   [(set (match_dup 0)
18222         (if_then_else:DF (gt (match_dup 1)
18223                              (match_dup 2))
18224                          (match_dup 1)
18225                          (match_dup 2)))])
18226
18227 (define_split
18228   [(set (match_operand:DF 0 "fp_register_operand" "")
18229         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18230                              (match_operand:DF 2 "register_operand" ""))
18231                          (match_operand:DF 3 "register_operand" "")
18232                          (match_operand:DF 4 "register_operand" "")))
18233    (clobber (reg:CC FLAGS_REG))]
18234   "reload_completed
18235    && ((operands_match_p (operands[1], operands[3])
18236         && operands_match_p (operands[2], operands[4]))
18237        || (operands_match_p (operands[1], operands[4])
18238            && operands_match_p (operands[2], operands[3])))"
18239   [(set (reg:CCFP FLAGS_REG)
18240         (compare:CCFP (match_dup 1)
18241                       (match_dup 2)))
18242    (set (match_dup 0)
18243         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18244                          (match_dup 1)
18245                          (match_dup 2)))])
18246
18247 (define_insn "*maxdf_sse"
18248   [(set (match_operand:DF 0 "register_operand" "=Y")
18249         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18250                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18251                          (match_dup 1)
18252                          (match_dup 2)))]
18253   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18254   "maxsd\t{%2, %0|%0, %2}"
18255   [(set_attr "type" "sse")
18256    (set_attr "mode" "DF")])
18257 \f
18258 ;; Misc patterns (?)
18259
18260 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18261 ;; Otherwise there will be nothing to keep
18262 ;; 
18263 ;; [(set (reg ebp) (reg esp))]
18264 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18265 ;;  (clobber (eflags)]
18266 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18267 ;;
18268 ;; in proper program order.
18269 (define_insn "pro_epilogue_adjust_stack_1"
18270   [(set (match_operand:SI 0 "register_operand" "=r,r")
18271         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18272                  (match_operand:SI 2 "immediate_operand" "i,i")))
18273    (clobber (reg:CC FLAGS_REG))
18274    (clobber (mem:BLK (scratch)))]
18275   "!TARGET_64BIT"
18276 {
18277   switch (get_attr_type (insn))
18278     {
18279     case TYPE_IMOV:
18280       return "mov{l}\t{%1, %0|%0, %1}";
18281
18282     case TYPE_ALU:
18283       if (GET_CODE (operands[2]) == CONST_INT
18284           && (INTVAL (operands[2]) == 128
18285               || (INTVAL (operands[2]) < 0
18286                   && INTVAL (operands[2]) != -128)))
18287         {
18288           operands[2] = GEN_INT (-INTVAL (operands[2]));
18289           return "sub{l}\t{%2, %0|%0, %2}";
18290         }
18291       return "add{l}\t{%2, %0|%0, %2}";
18292
18293     case TYPE_LEA:
18294       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18295       return "lea{l}\t{%a2, %0|%0, %a2}";
18296
18297     default:
18298       abort ();
18299     }
18300 }
18301   [(set (attr "type")
18302         (cond [(eq_attr "alternative" "0")
18303                  (const_string "alu")
18304                (match_operand:SI 2 "const0_operand" "")
18305                  (const_string "imov")
18306               ]
18307               (const_string "lea")))
18308    (set_attr "mode" "SI")])
18309
18310 (define_insn "pro_epilogue_adjust_stack_rex64"
18311   [(set (match_operand:DI 0 "register_operand" "=r,r")
18312         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18313                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18314    (clobber (reg:CC FLAGS_REG))
18315    (clobber (mem:BLK (scratch)))]
18316   "TARGET_64BIT"
18317 {
18318   switch (get_attr_type (insn))
18319     {
18320     case TYPE_IMOV:
18321       return "mov{q}\t{%1, %0|%0, %1}";
18322
18323     case TYPE_ALU:
18324       if (GET_CODE (operands[2]) == CONST_INT
18325           /* Avoid overflows.  */
18326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18327           && (INTVAL (operands[2]) == 128
18328               || (INTVAL (operands[2]) < 0
18329                   && INTVAL (operands[2]) != -128)))
18330         {
18331           operands[2] = GEN_INT (-INTVAL (operands[2]));
18332           return "sub{q}\t{%2, %0|%0, %2}";
18333         }
18334       return "add{q}\t{%2, %0|%0, %2}";
18335
18336     case TYPE_LEA:
18337       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18338       return "lea{q}\t{%a2, %0|%0, %a2}";
18339
18340     default:
18341       abort ();
18342     }
18343 }
18344   [(set (attr "type")
18345         (cond [(eq_attr "alternative" "0")
18346                  (const_string "alu")
18347                (match_operand:DI 2 "const0_operand" "")
18348                  (const_string "imov")
18349               ]
18350               (const_string "lea")))
18351    (set_attr "mode" "DI")])
18352
18353 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18354   [(set (match_operand:DI 0 "register_operand" "=r,r")
18355         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18356                  (match_operand:DI 3 "immediate_operand" "i,i")))
18357    (use (match_operand:DI 2 "register_operand" "r,r"))
18358    (clobber (reg:CC FLAGS_REG))
18359    (clobber (mem:BLK (scratch)))]
18360   "TARGET_64BIT"
18361 {
18362   switch (get_attr_type (insn))
18363     {
18364     case TYPE_ALU:
18365       return "add{q}\t{%2, %0|%0, %2}";
18366
18367     case TYPE_LEA:
18368       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18369       return "lea{q}\t{%a2, %0|%0, %a2}";
18370
18371     default:
18372       abort ();
18373     }
18374 }
18375   [(set_attr "type" "alu,lea")
18376    (set_attr "mode" "DI")])
18377
18378 ;; Placeholder for the conditional moves.  This one is split either to SSE
18379 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18380 ;; fact is that compares supported by the cmp??ss instructions are exactly
18381 ;; swapped of those supported by cmove sequence.
18382 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18383 ;; supported by i387 comparisons and we do need to emit two conditional moves
18384 ;; in tandem.
18385
18386 (define_insn "sse_movsfcc"
18387   [(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")
18388         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18389                         [(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")
18390                          (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")])
18391                       (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")
18392                       (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")))
18393    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18394    (clobber (reg:CC FLAGS_REG))]
18395   "TARGET_SSE
18396    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18397    /* Avoid combine from being smart and converting min/max
18398       instruction patterns into conditional moves.  */
18399    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18400         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18401        || !rtx_equal_p (operands[4], operands[2])
18402        || !rtx_equal_p (operands[5], operands[3]))
18403    && (!TARGET_IEEE_FP
18404        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18405   "#")
18406
18407 (define_insn "sse_movsfcc_eq"
18408   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18409         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18410                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18411                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18412                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18413    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18414    (clobber (reg:CC FLAGS_REG))]
18415   "TARGET_SSE
18416    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18417   "#")
18418
18419 (define_insn "sse_movdfcc"
18420   [(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")
18421         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18422                         [(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")
18423                          (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")])
18424                       (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")
18425                       (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")))
18426    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18427    (clobber (reg:CC FLAGS_REG))]
18428   "TARGET_SSE2
18429    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18430    /* Avoid combine from being smart and converting min/max
18431       instruction patterns into conditional moves.  */
18432    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18433         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18434        || !rtx_equal_p (operands[4], operands[2])
18435        || !rtx_equal_p (operands[5], operands[3]))
18436    && (!TARGET_IEEE_FP
18437        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18438   "#")
18439
18440 (define_insn "sse_movdfcc_eq"
18441   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18442         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18443                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18444                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18445                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18446    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18447    (clobber (reg:CC FLAGS_REG))]
18448   "TARGET_SSE
18449    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18450   "#")
18451
18452 ;; For non-sse moves just expand the usual cmove sequence.
18453 (define_split
18454   [(set (match_operand 0 "register_operand" "")
18455         (if_then_else (match_operator 1 "comparison_operator"
18456                         [(match_operand 4 "nonimmediate_operand" "")
18457                          (match_operand 5 "register_operand" "")])
18458                       (match_operand 2 "nonimmediate_operand" "")
18459                       (match_operand 3 "nonimmediate_operand" "")))
18460    (clobber (match_operand 6 "" ""))
18461    (clobber (reg:CC FLAGS_REG))]
18462   "!SSE_REG_P (operands[0]) && reload_completed
18463    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18464   [(const_int 0)]
18465 {
18466    ix86_compare_op0 = operands[5];
18467    ix86_compare_op1 = operands[4];
18468    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18469                                  VOIDmode, operands[5], operands[4]);
18470    ix86_expand_fp_movcc (operands);
18471    DONE;
18472 })
18473
18474 ;; Split SSE based conditional move into sequence:
18475 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18476 ;; and   op2, op0   -  zero op2 if comparison was false
18477 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18478 ;; or    op2, op0   -  get the nonzero one into the result.
18479 (define_split
18480   [(set (match_operand:SF 0 "register_operand" "")
18481         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18482                         [(match_operand:SF 4 "register_operand" "")
18483                          (match_operand:SF 5 "nonimmediate_operand" "")])
18484                       (match_operand:SF 2 "register_operand" "")
18485                       (match_operand:SF 3 "register_operand" "")))
18486    (clobber (match_operand 6 "" ""))
18487    (clobber (reg:CC FLAGS_REG))]
18488   "SSE_REG_P (operands[0]) && reload_completed"
18489   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18490    (set (match_dup 2) (and:V4SF (match_dup 2)
18491                                 (match_dup 8)))
18492    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18493                                           (match_dup 3)))
18494    (set (match_dup 0) (ior:V4SF (match_dup 6)
18495                                 (match_dup 7)))]
18496 {
18497   /* If op2 == op3, op3 would be clobbered before it is used.  */
18498   if (operands_match_p (operands[2], operands[3]))
18499     {
18500       emit_move_insn (operands[0], operands[2]);
18501       DONE;
18502     }
18503
18504   PUT_MODE (operands[1], GET_MODE (operands[0]));
18505   if (operands_match_p (operands[0], operands[4]))
18506     operands[6] = operands[4], operands[7] = operands[2];
18507   else
18508     operands[6] = operands[2], operands[7] = operands[4];
18509   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18510   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18511   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18512   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18513   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18514   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18515 })
18516
18517 (define_split
18518   [(set (match_operand:DF 0 "register_operand" "")
18519         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18520                         [(match_operand:DF 4 "register_operand" "")
18521                          (match_operand:DF 5 "nonimmediate_operand" "")])
18522                       (match_operand:DF 2 "register_operand" "")
18523                       (match_operand:DF 3 "register_operand" "")))
18524    (clobber (match_operand 6 "" ""))
18525    (clobber (reg:CC FLAGS_REG))]
18526   "SSE_REG_P (operands[0]) && reload_completed"
18527   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18528    (set (match_dup 2) (and:V2DF (match_dup 2)
18529                                 (match_dup 8)))
18530    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18531                                           (match_dup 3)))
18532    (set (match_dup 0) (ior:V2DF (match_dup 6)
18533                                 (match_dup 7)))]
18534 {
18535   if (GET_MODE (operands[2]) == DFmode
18536       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18537     {
18538       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18539       emit_insn (gen_sse2_unpcklpd (op, op, op));
18540       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18541       emit_insn (gen_sse2_unpcklpd (op, op, op));
18542     }
18543
18544   /* If op2 == op3, op3 would be clobbered before it is used.  */
18545   if (operands_match_p (operands[2], operands[3]))
18546     {
18547       emit_move_insn (operands[0], operands[2]);
18548       DONE;
18549     }
18550
18551   PUT_MODE (operands[1], GET_MODE (operands[0]));
18552   if (operands_match_p (operands[0], operands[4]))
18553     operands[6] = operands[4], operands[7] = operands[2];
18554   else
18555     operands[6] = operands[2], operands[7] = operands[4];
18556   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18557   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18558   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18559   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18560   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18561   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18562 })
18563
18564 ;; Special case of conditional move we can handle effectively.
18565 ;; Do not brother with the integer/floating point case, since these are
18566 ;; bot considerably slower, unlike in the generic case.
18567 (define_insn "*sse_movsfcc_const0_1"
18568   [(set (match_operand:SF 0 "register_operand" "=&x")
18569         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18570                         [(match_operand:SF 4 "register_operand" "0")
18571                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18572                       (match_operand:SF 2 "register_operand" "x")
18573                       (match_operand:SF 3 "const0_operand" "X")))]
18574   "TARGET_SSE"
18575   "#")
18576
18577 (define_insn "*sse_movsfcc_const0_2"
18578   [(set (match_operand:SF 0 "register_operand" "=&x")
18579         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18580                         [(match_operand:SF 4 "register_operand" "0")
18581                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18582                       (match_operand:SF 2 "const0_operand" "X")
18583                       (match_operand:SF 3 "register_operand" "x")))]
18584   "TARGET_SSE"
18585   "#")
18586
18587 (define_insn "*sse_movsfcc_const0_3"
18588   [(set (match_operand:SF 0 "register_operand" "=&x")
18589         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18590                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18591                          (match_operand:SF 5 "register_operand" "0")])
18592                       (match_operand:SF 2 "register_operand" "x")
18593                       (match_operand:SF 3 "const0_operand" "X")))]
18594   "TARGET_SSE"
18595   "#")
18596
18597 (define_insn "*sse_movsfcc_const0_4"
18598   [(set (match_operand:SF 0 "register_operand" "=&x")
18599         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18600                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18601                          (match_operand:SF 5 "register_operand" "0")])
18602                       (match_operand:SF 2 "const0_operand" "X")
18603                       (match_operand:SF 3 "register_operand" "x")))]
18604   "TARGET_SSE"
18605   "#")
18606
18607 (define_insn "*sse_movdfcc_const0_1"
18608   [(set (match_operand:DF 0 "register_operand" "=&Y")
18609         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18610                         [(match_operand:DF 4 "register_operand" "0")
18611                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18612                       (match_operand:DF 2 "register_operand" "Y")
18613                       (match_operand:DF 3 "const0_operand" "X")))]
18614   "TARGET_SSE2"
18615   "#")
18616
18617 (define_insn "*sse_movdfcc_const0_2"
18618   [(set (match_operand:DF 0 "register_operand" "=&Y")
18619         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18620                         [(match_operand:DF 4 "register_operand" "0")
18621                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18622                       (match_operand:DF 2 "const0_operand" "X")
18623                       (match_operand:DF 3 "register_operand" "Y")))]
18624   "TARGET_SSE2"
18625   "#")
18626
18627 (define_insn "*sse_movdfcc_const0_3"
18628   [(set (match_operand:DF 0 "register_operand" "=&Y")
18629         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18630                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18631                          (match_operand:DF 5 "register_operand" "0")])
18632                       (match_operand:DF 2 "register_operand" "Y")
18633                       (match_operand:DF 3 "const0_operand" "X")))]
18634   "TARGET_SSE2"
18635   "#")
18636
18637 (define_insn "*sse_movdfcc_const0_4"
18638   [(set (match_operand:DF 0 "register_operand" "=&Y")
18639         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18640                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18641                          (match_operand:DF 5 "register_operand" "0")])
18642                       (match_operand:DF 2 "const0_operand" "X")
18643                       (match_operand:DF 3 "register_operand" "Y")))]
18644   "TARGET_SSE2"
18645   "#")
18646
18647 (define_split
18648   [(set (match_operand:SF 0 "register_operand" "")
18649         (if_then_else (match_operator 1 "comparison_operator"
18650                         [(match_operand:SF 4 "nonimmediate_operand" "")
18651                          (match_operand:SF 5 "nonimmediate_operand" "")])
18652                       (match_operand:SF 2 "nonmemory_operand" "")
18653                       (match_operand:SF 3 "nonmemory_operand" "")))]
18654   "SSE_REG_P (operands[0]) && reload_completed
18655    && (const0_operand (operands[2], GET_MODE (operands[0]))
18656        || const0_operand (operands[3], GET_MODE (operands[0])))"
18657   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18658    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18659 {
18660   PUT_MODE (operands[1], GET_MODE (operands[0]));
18661   if (!sse_comparison_operator (operands[1], VOIDmode)
18662       || !rtx_equal_p (operands[0], operands[4]))
18663     {
18664       rtx tmp = operands[5];
18665       operands[5] = operands[4];
18666       operands[4] = tmp;
18667       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18668     }
18669   if (!rtx_equal_p (operands[0], operands[4]))
18670     abort ();
18671   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18672   if (const0_operand (operands[2], GET_MODE (operands[2])))
18673     {
18674       operands[7] = operands[3];
18675       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18676     }
18677   else
18678     {
18679       operands[7] = operands[2];
18680       operands[6] = operands[8];
18681     }
18682   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18683 })
18684
18685 (define_split
18686   [(set (match_operand:DF 0 "register_operand" "")
18687         (if_then_else (match_operator 1 "comparison_operator"
18688                         [(match_operand:DF 4 "nonimmediate_operand" "")
18689                          (match_operand:DF 5 "nonimmediate_operand" "")])
18690                       (match_operand:DF 2 "nonmemory_operand" "")
18691                       (match_operand:DF 3 "nonmemory_operand" "")))]
18692   "SSE_REG_P (operands[0]) && reload_completed
18693    && (const0_operand (operands[2], GET_MODE (operands[0]))
18694        || const0_operand (operands[3], GET_MODE (operands[0])))"
18695   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18696    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18697 {
18698   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18699       && GET_MODE (operands[2]) == DFmode)
18700     {
18701       if (REG_P (operands[2]))
18702         {
18703           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18704           emit_insn (gen_sse2_unpcklpd (op, op, op));
18705         }
18706       if (REG_P (operands[3]))
18707         {
18708           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18709           emit_insn (gen_sse2_unpcklpd (op, op, op));
18710         }
18711     }
18712   PUT_MODE (operands[1], GET_MODE (operands[0]));
18713   if (!sse_comparison_operator (operands[1], VOIDmode)
18714       || !rtx_equal_p (operands[0], operands[4]))
18715     {
18716       rtx tmp = operands[5];
18717       operands[5] = operands[4];
18718       operands[4] = tmp;
18719       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18720     }
18721   if (!rtx_equal_p (operands[0], operands[4]))
18722     abort ();
18723   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18724   if (const0_operand (operands[2], GET_MODE (operands[2])))
18725     {
18726       operands[7] = operands[3];
18727       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18728     }
18729   else
18730     {
18731       operands[7] = operands[2];
18732       operands[6] = operands[8];
18733     }
18734   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18735 })
18736
18737 (define_expand "allocate_stack_worker"
18738   [(match_operand:SI 0 "register_operand" "")]
18739   "TARGET_STACK_PROBE"
18740 {
18741   if (reload_completed)
18742     {
18743       if (TARGET_64BIT)
18744         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18745       else
18746         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18747     }
18748   else
18749     {
18750       if (TARGET_64BIT)
18751         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18752       else
18753         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18754     }
18755   DONE;
18756 })
18757
18758 (define_insn "allocate_stack_worker_1"
18759   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18760     UNSPECV_STACK_PROBE)
18761    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18762    (clobber (match_scratch:SI 1 "=0"))
18763    (clobber (reg:CC FLAGS_REG))]
18764   "!TARGET_64BIT && TARGET_STACK_PROBE"
18765   "call\t__alloca"
18766   [(set_attr "type" "multi")
18767    (set_attr "length" "5")])
18768
18769 (define_expand "allocate_stack_worker_postreload"
18770   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18771                                     UNSPECV_STACK_PROBE)
18772               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18773               (clobber (match_dup 0))
18774               (clobber (reg:CC FLAGS_REG))])]
18775   ""
18776   "")
18777
18778 (define_insn "allocate_stack_worker_rex64"
18779   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18780     UNSPECV_STACK_PROBE)
18781    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18782    (clobber (match_scratch:DI 1 "=0"))
18783    (clobber (reg:CC FLAGS_REG))]
18784   "TARGET_64BIT && TARGET_STACK_PROBE"
18785   "call\t__alloca"
18786   [(set_attr "type" "multi")
18787    (set_attr "length" "5")])
18788
18789 (define_expand "allocate_stack_worker_rex64_postreload"
18790   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18791                                     UNSPECV_STACK_PROBE)
18792               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18793               (clobber (match_dup 0))
18794               (clobber (reg:CC FLAGS_REG))])]
18795   ""
18796   "")
18797
18798 (define_expand "allocate_stack"
18799   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18800                    (minus:SI (reg:SI SP_REG)
18801                              (match_operand:SI 1 "general_operand" "")))
18802               (clobber (reg:CC FLAGS_REG))])
18803    (parallel [(set (reg:SI SP_REG)
18804                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18805               (clobber (reg:CC FLAGS_REG))])]
18806   "TARGET_STACK_PROBE"
18807 {
18808 #ifdef CHECK_STACK_LIMIT
18809   if (GET_CODE (operands[1]) == CONST_INT
18810       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18811     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18812                            operands[1]));
18813   else 
18814 #endif
18815     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18816                                                             operands[1])));
18817
18818   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18819   DONE;
18820 })
18821
18822 (define_expand "builtin_setjmp_receiver"
18823   [(label_ref (match_operand 0 "" ""))]
18824   "!TARGET_64BIT && flag_pic"
18825 {
18826   emit_insn (gen_set_got (pic_offset_table_rtx));
18827   DONE;
18828 })
18829 \f
18830 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18831
18832 (define_split
18833   [(set (match_operand 0 "register_operand" "")
18834         (match_operator 3 "promotable_binary_operator"
18835            [(match_operand 1 "register_operand" "")
18836             (match_operand 2 "aligned_operand" "")]))
18837    (clobber (reg:CC FLAGS_REG))]
18838   "! TARGET_PARTIAL_REG_STALL && reload_completed
18839    && ((GET_MODE (operands[0]) == HImode 
18840         && ((!optimize_size && !TARGET_FAST_PREFIX)
18841             || GET_CODE (operands[2]) != CONST_INT
18842             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18843        || (GET_MODE (operands[0]) == QImode 
18844            && (TARGET_PROMOTE_QImode || optimize_size)))"
18845   [(parallel [(set (match_dup 0)
18846                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18847               (clobber (reg:CC FLAGS_REG))])]
18848   "operands[0] = gen_lowpart (SImode, operands[0]);
18849    operands[1] = gen_lowpart (SImode, operands[1]);
18850    if (GET_CODE (operands[3]) != ASHIFT)
18851      operands[2] = gen_lowpart (SImode, operands[2]);
18852    PUT_MODE (operands[3], SImode);")
18853
18854 ; Promote the QImode tests, as i386 has encoding of the AND
18855 ; instruction with 32-bit sign-extended immediate and thus the
18856 ; instruction size is unchanged, except in the %eax case for
18857 ; which it is increased by one byte, hence the ! optimize_size.
18858 (define_split
18859   [(set (match_operand 0 "flags_reg_operand" "")
18860         (match_operator 2 "compare_operator"
18861           [(and (match_operand 3 "aligned_operand" "")
18862                 (match_operand 4 "const_int_operand" ""))
18863            (const_int 0)]))
18864    (set (match_operand 1 "register_operand" "")
18865         (and (match_dup 3) (match_dup 4)))]
18866   "! TARGET_PARTIAL_REG_STALL && reload_completed
18867    /* Ensure that the operand will remain sign-extended immediate.  */
18868    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18869    && ! optimize_size
18870    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18871        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18872   [(parallel [(set (match_dup 0)
18873                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18874                                     (const_int 0)]))
18875               (set (match_dup 1)
18876                    (and:SI (match_dup 3) (match_dup 4)))])]
18877 {
18878   operands[4]
18879     = gen_int_mode (INTVAL (operands[4])
18880                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18881   operands[1] = gen_lowpart (SImode, operands[1]);
18882   operands[3] = gen_lowpart (SImode, operands[3]);
18883 })
18884
18885 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18886 ; the TEST instruction with 32-bit sign-extended immediate and thus
18887 ; the instruction size would at least double, which is not what we
18888 ; want even with ! optimize_size.
18889 (define_split
18890   [(set (match_operand 0 "flags_reg_operand" "")
18891         (match_operator 1 "compare_operator"
18892           [(and (match_operand:HI 2 "aligned_operand" "")
18893                 (match_operand:HI 3 "const_int_operand" ""))
18894            (const_int 0)]))]
18895   "! TARGET_PARTIAL_REG_STALL && reload_completed
18896    /* Ensure that the operand will remain sign-extended immediate.  */
18897    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18898    && ! TARGET_FAST_PREFIX
18899    && ! optimize_size"
18900   [(set (match_dup 0)
18901         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18902                          (const_int 0)]))]
18903 {
18904   operands[3]
18905     = gen_int_mode (INTVAL (operands[3])
18906                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18907   operands[2] = gen_lowpart (SImode, operands[2]);
18908 })
18909
18910 (define_split
18911   [(set (match_operand 0 "register_operand" "")
18912         (neg (match_operand 1 "register_operand" "")))
18913    (clobber (reg:CC FLAGS_REG))]
18914   "! TARGET_PARTIAL_REG_STALL && reload_completed
18915    && (GET_MODE (operands[0]) == HImode
18916        || (GET_MODE (operands[0]) == QImode 
18917            && (TARGET_PROMOTE_QImode || optimize_size)))"
18918   [(parallel [(set (match_dup 0)
18919                    (neg:SI (match_dup 1)))
18920               (clobber (reg:CC FLAGS_REG))])]
18921   "operands[0] = gen_lowpart (SImode, operands[0]);
18922    operands[1] = gen_lowpart (SImode, operands[1]);")
18923
18924 (define_split
18925   [(set (match_operand 0 "register_operand" "")
18926         (not (match_operand 1 "register_operand" "")))]
18927   "! TARGET_PARTIAL_REG_STALL && reload_completed
18928    && (GET_MODE (operands[0]) == HImode
18929        || (GET_MODE (operands[0]) == QImode 
18930            && (TARGET_PROMOTE_QImode || optimize_size)))"
18931   [(set (match_dup 0)
18932         (not:SI (match_dup 1)))]
18933   "operands[0] = gen_lowpart (SImode, operands[0]);
18934    operands[1] = gen_lowpart (SImode, operands[1]);")
18935
18936 (define_split 
18937   [(set (match_operand 0 "register_operand" "")
18938         (if_then_else (match_operator 1 "comparison_operator" 
18939                                 [(reg FLAGS_REG) (const_int 0)])
18940                       (match_operand 2 "register_operand" "")
18941                       (match_operand 3 "register_operand" "")))]
18942   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18943    && (GET_MODE (operands[0]) == HImode
18944        || (GET_MODE (operands[0]) == QImode 
18945            && (TARGET_PROMOTE_QImode || optimize_size)))"
18946   [(set (match_dup 0)
18947         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18948   "operands[0] = gen_lowpart (SImode, operands[0]);
18949    operands[2] = gen_lowpart (SImode, operands[2]);
18950    operands[3] = gen_lowpart (SImode, operands[3]);")
18951                         
18952 \f
18953 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18954 ;; transform a complex memory operation into two memory to register operations.
18955
18956 ;; Don't push memory operands
18957 (define_peephole2
18958   [(set (match_operand:SI 0 "push_operand" "")
18959         (match_operand:SI 1 "memory_operand" ""))
18960    (match_scratch:SI 2 "r")]
18961   "! optimize_size && ! TARGET_PUSH_MEMORY"
18962   [(set (match_dup 2) (match_dup 1))
18963    (set (match_dup 0) (match_dup 2))]
18964   "")
18965
18966 (define_peephole2
18967   [(set (match_operand:DI 0 "push_operand" "")
18968         (match_operand:DI 1 "memory_operand" ""))
18969    (match_scratch:DI 2 "r")]
18970   "! optimize_size && ! TARGET_PUSH_MEMORY"
18971   [(set (match_dup 2) (match_dup 1))
18972    (set (match_dup 0) (match_dup 2))]
18973   "")
18974
18975 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18976 ;; SImode pushes.
18977 (define_peephole2
18978   [(set (match_operand:SF 0 "push_operand" "")
18979         (match_operand:SF 1 "memory_operand" ""))
18980    (match_scratch:SF 2 "r")]
18981   "! optimize_size && ! TARGET_PUSH_MEMORY"
18982   [(set (match_dup 2) (match_dup 1))
18983    (set (match_dup 0) (match_dup 2))]
18984   "")
18985
18986 (define_peephole2
18987   [(set (match_operand:HI 0 "push_operand" "")
18988         (match_operand:HI 1 "memory_operand" ""))
18989    (match_scratch:HI 2 "r")]
18990   "! optimize_size && ! TARGET_PUSH_MEMORY"
18991   [(set (match_dup 2) (match_dup 1))
18992    (set (match_dup 0) (match_dup 2))]
18993   "")
18994
18995 (define_peephole2
18996   [(set (match_operand:QI 0 "push_operand" "")
18997         (match_operand:QI 1 "memory_operand" ""))
18998    (match_scratch:QI 2 "q")]
18999   "! optimize_size && ! TARGET_PUSH_MEMORY"
19000   [(set (match_dup 2) (match_dup 1))
19001    (set (match_dup 0) (match_dup 2))]
19002   "")
19003
19004 ;; Don't move an immediate directly to memory when the instruction
19005 ;; gets too big.
19006 (define_peephole2
19007   [(match_scratch:SI 1 "r")
19008    (set (match_operand:SI 0 "memory_operand" "")
19009         (const_int 0))]
19010   "! optimize_size
19011    && ! TARGET_USE_MOV0
19012    && TARGET_SPLIT_LONG_MOVES
19013    && get_attr_length (insn) >= ix86_cost->large_insn
19014    && peep2_regno_dead_p (0, FLAGS_REG)"
19015   [(parallel [(set (match_dup 1) (const_int 0))
19016               (clobber (reg:CC FLAGS_REG))])
19017    (set (match_dup 0) (match_dup 1))]
19018   "")
19019
19020 (define_peephole2
19021   [(match_scratch:HI 1 "r")
19022    (set (match_operand:HI 0 "memory_operand" "")
19023         (const_int 0))]
19024   "! optimize_size
19025    && ! TARGET_USE_MOV0
19026    && TARGET_SPLIT_LONG_MOVES
19027    && get_attr_length (insn) >= ix86_cost->large_insn
19028    && peep2_regno_dead_p (0, FLAGS_REG)"
19029   [(parallel [(set (match_dup 2) (const_int 0))
19030               (clobber (reg:CC FLAGS_REG))])
19031    (set (match_dup 0) (match_dup 1))]
19032   "operands[2] = gen_lowpart (SImode, operands[1]);")
19033
19034 (define_peephole2
19035   [(match_scratch:QI 1 "q")
19036    (set (match_operand:QI 0 "memory_operand" "")
19037         (const_int 0))]
19038   "! optimize_size
19039    && ! TARGET_USE_MOV0
19040    && TARGET_SPLIT_LONG_MOVES
19041    && get_attr_length (insn) >= ix86_cost->large_insn
19042    && peep2_regno_dead_p (0, FLAGS_REG)"
19043   [(parallel [(set (match_dup 2) (const_int 0))
19044               (clobber (reg:CC FLAGS_REG))])
19045    (set (match_dup 0) (match_dup 1))]
19046   "operands[2] = gen_lowpart (SImode, operands[1]);")
19047
19048 (define_peephole2
19049   [(match_scratch:SI 2 "r")
19050    (set (match_operand:SI 0 "memory_operand" "")
19051         (match_operand:SI 1 "immediate_operand" ""))]
19052   "! optimize_size
19053    && get_attr_length (insn) >= ix86_cost->large_insn
19054    && TARGET_SPLIT_LONG_MOVES"
19055   [(set (match_dup 2) (match_dup 1))
19056    (set (match_dup 0) (match_dup 2))]
19057   "")
19058
19059 (define_peephole2
19060   [(match_scratch:HI 2 "r")
19061    (set (match_operand:HI 0 "memory_operand" "")
19062         (match_operand:HI 1 "immediate_operand" ""))]
19063   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19064   && TARGET_SPLIT_LONG_MOVES"
19065   [(set (match_dup 2) (match_dup 1))
19066    (set (match_dup 0) (match_dup 2))]
19067   "")
19068
19069 (define_peephole2
19070   [(match_scratch:QI 2 "q")
19071    (set (match_operand:QI 0 "memory_operand" "")
19072         (match_operand:QI 1 "immediate_operand" ""))]
19073   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19074   && TARGET_SPLIT_LONG_MOVES"
19075   [(set (match_dup 2) (match_dup 1))
19076    (set (match_dup 0) (match_dup 2))]
19077   "")
19078
19079 ;; Don't compare memory with zero, load and use a test instead.
19080 (define_peephole2
19081   [(set (match_operand 0 "flags_reg_operand" "")
19082         (match_operator 1 "compare_operator"
19083           [(match_operand:SI 2 "memory_operand" "")
19084            (const_int 0)]))
19085    (match_scratch:SI 3 "r")]
19086   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19087   [(set (match_dup 3) (match_dup 2))
19088    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19089   "")
19090
19091 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19092 ;; Don't split NOTs with a displacement operand, because resulting XOR
19093 ;; will not be pairable anyway.
19094 ;;
19095 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19096 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19097 ;; so this split helps here as well.
19098 ;;
19099 ;; Note: Can't do this as a regular split because we can't get proper
19100 ;; lifetime information then.
19101
19102 (define_peephole2
19103   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19104         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19105   "!optimize_size
19106    && peep2_regno_dead_p (0, FLAGS_REG)
19107    && ((TARGET_PENTIUM 
19108         && (GET_CODE (operands[0]) != MEM
19109             || !memory_displacement_operand (operands[0], SImode)))
19110        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19111   [(parallel [(set (match_dup 0)
19112                    (xor:SI (match_dup 1) (const_int -1)))
19113               (clobber (reg:CC FLAGS_REG))])]
19114   "")
19115
19116 (define_peephole2
19117   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19118         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19119   "!optimize_size
19120    && peep2_regno_dead_p (0, FLAGS_REG)
19121    && ((TARGET_PENTIUM 
19122         && (GET_CODE (operands[0]) != MEM
19123             || !memory_displacement_operand (operands[0], HImode)))
19124        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19125   [(parallel [(set (match_dup 0)
19126                    (xor:HI (match_dup 1) (const_int -1)))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   "")
19129
19130 (define_peephole2
19131   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19132         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19133   "!optimize_size
19134    && peep2_regno_dead_p (0, FLAGS_REG)
19135    && ((TARGET_PENTIUM 
19136         && (GET_CODE (operands[0]) != MEM
19137             || !memory_displacement_operand (operands[0], QImode)))
19138        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19139   [(parallel [(set (match_dup 0)
19140                    (xor:QI (match_dup 1) (const_int -1)))
19141               (clobber (reg:CC FLAGS_REG))])]
19142   "")
19143
19144 ;; Non pairable "test imm, reg" instructions can be translated to
19145 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19146 ;; byte opcode instead of two, have a short form for byte operands),
19147 ;; so do it for other CPUs as well.  Given that the value was dead,
19148 ;; this should not create any new dependencies.  Pass on the sub-word
19149 ;; versions if we're concerned about partial register stalls.
19150
19151 (define_peephole2
19152   [(set (match_operand 0 "flags_reg_operand" "")
19153         (match_operator 1 "compare_operator"
19154           [(and:SI (match_operand:SI 2 "register_operand" "")
19155                    (match_operand:SI 3 "immediate_operand" ""))
19156            (const_int 0)]))]
19157   "ix86_match_ccmode (insn, CCNOmode)
19158    && (true_regnum (operands[2]) != 0
19159        || (GET_CODE (operands[3]) == CONST_INT
19160            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19161    && peep2_reg_dead_p (1, operands[2])"
19162   [(parallel
19163      [(set (match_dup 0)
19164            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19165                             (const_int 0)]))
19166       (set (match_dup 2)
19167            (and:SI (match_dup 2) (match_dup 3)))])]
19168   "")
19169
19170 ;; We don't need to handle HImode case, because it will be promoted to SImode
19171 ;; on ! TARGET_PARTIAL_REG_STALL
19172
19173 (define_peephole2
19174   [(set (match_operand 0 "flags_reg_operand" "")
19175         (match_operator 1 "compare_operator"
19176           [(and:QI (match_operand:QI 2 "register_operand" "")
19177                    (match_operand:QI 3 "immediate_operand" ""))
19178            (const_int 0)]))]
19179   "! TARGET_PARTIAL_REG_STALL
19180    && ix86_match_ccmode (insn, CCNOmode)
19181    && true_regnum (operands[2]) != 0
19182    && peep2_reg_dead_p (1, operands[2])"
19183   [(parallel
19184      [(set (match_dup 0)
19185            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19186                             (const_int 0)]))
19187       (set (match_dup 2)
19188            (and:QI (match_dup 2) (match_dup 3)))])]
19189   "")
19190
19191 (define_peephole2
19192   [(set (match_operand 0 "flags_reg_operand" "")
19193         (match_operator 1 "compare_operator"
19194           [(and:SI
19195              (zero_extract:SI
19196                (match_operand 2 "ext_register_operand" "")
19197                (const_int 8)
19198                (const_int 8))
19199              (match_operand 3 "const_int_operand" ""))
19200            (const_int 0)]))]
19201   "! TARGET_PARTIAL_REG_STALL
19202    && ix86_match_ccmode (insn, CCNOmode)
19203    && true_regnum (operands[2]) != 0
19204    && peep2_reg_dead_p (1, operands[2])"
19205   [(parallel [(set (match_dup 0)
19206                    (match_op_dup 1
19207                      [(and:SI
19208                         (zero_extract:SI
19209                           (match_dup 2)
19210                           (const_int 8)
19211                           (const_int 8))
19212                         (match_dup 3))
19213                       (const_int 0)]))
19214               (set (zero_extract:SI (match_dup 2)
19215                                     (const_int 8)
19216                                     (const_int 8))
19217                    (and:SI 
19218                      (zero_extract:SI
19219                        (match_dup 2)
19220                        (const_int 8)
19221                        (const_int 8))
19222                      (match_dup 3)))])]
19223   "")
19224
19225 ;; Don't do logical operations with memory inputs.
19226 (define_peephole2
19227   [(match_scratch:SI 2 "r")
19228    (parallel [(set (match_operand:SI 0 "register_operand" "")
19229                    (match_operator:SI 3 "arith_or_logical_operator"
19230                      [(match_dup 0)
19231                       (match_operand:SI 1 "memory_operand" "")]))
19232               (clobber (reg:CC FLAGS_REG))])]
19233   "! optimize_size && ! TARGET_READ_MODIFY"
19234   [(set (match_dup 2) (match_dup 1))
19235    (parallel [(set (match_dup 0)
19236                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19237               (clobber (reg:CC FLAGS_REG))])]
19238   "")
19239
19240 (define_peephole2
19241   [(match_scratch:SI 2 "r")
19242    (parallel [(set (match_operand:SI 0 "register_operand" "")
19243                    (match_operator:SI 3 "arith_or_logical_operator"
19244                      [(match_operand:SI 1 "memory_operand" "")
19245                       (match_dup 0)]))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "! optimize_size && ! TARGET_READ_MODIFY"
19248   [(set (match_dup 2) (match_dup 1))
19249    (parallel [(set (match_dup 0)
19250                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19251               (clobber (reg:CC FLAGS_REG))])]
19252   "")
19253
19254 ; Don't do logical operations with memory outputs
19255 ;
19256 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19257 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19258 ; the same decoder scheduling characteristics as the original.
19259
19260 (define_peephole2
19261   [(match_scratch:SI 2 "r")
19262    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19263                    (match_operator:SI 3 "arith_or_logical_operator"
19264                      [(match_dup 0)
19265                       (match_operand:SI 1 "nonmemory_operand" "")]))
19266               (clobber (reg:CC FLAGS_REG))])]
19267   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19268   [(set (match_dup 2) (match_dup 0))
19269    (parallel [(set (match_dup 2)
19270                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19271               (clobber (reg:CC FLAGS_REG))])
19272    (set (match_dup 0) (match_dup 2))]
19273   "")
19274
19275 (define_peephole2
19276   [(match_scratch:SI 2 "r")
19277    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19278                    (match_operator:SI 3 "arith_or_logical_operator"
19279                      [(match_operand:SI 1 "nonmemory_operand" "")
19280                       (match_dup 0)]))
19281               (clobber (reg:CC FLAGS_REG))])]
19282   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19283   [(set (match_dup 2) (match_dup 0))
19284    (parallel [(set (match_dup 2)
19285                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19286               (clobber (reg:CC FLAGS_REG))])
19287    (set (match_dup 0) (match_dup 2))]
19288   "")
19289
19290 ;; Attempt to always use XOR for zeroing registers.
19291 (define_peephole2
19292   [(set (match_operand 0 "register_operand" "")
19293         (const_int 0))]
19294   "(GET_MODE (operands[0]) == QImode
19295     || GET_MODE (operands[0]) == HImode
19296     || GET_MODE (operands[0]) == SImode
19297     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19298    && (! TARGET_USE_MOV0 || optimize_size)
19299    && peep2_regno_dead_p (0, FLAGS_REG)"
19300   [(parallel [(set (match_dup 0) (const_int 0))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19303                               operands[0]);")
19304
19305 (define_peephole2
19306   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19307         (const_int 0))]
19308   "(GET_MODE (operands[0]) == QImode
19309     || GET_MODE (operands[0]) == HImode)
19310    && (! TARGET_USE_MOV0 || optimize_size)
19311    && peep2_regno_dead_p (0, FLAGS_REG)"
19312   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19313               (clobber (reg:CC FLAGS_REG))])])
19314
19315 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19316 (define_peephole2
19317   [(set (match_operand 0 "register_operand" "")
19318         (const_int -1))]
19319   "(GET_MODE (operands[0]) == HImode
19320     || GET_MODE (operands[0]) == SImode 
19321     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19322    && (optimize_size || TARGET_PENTIUM)
19323    && peep2_regno_dead_p (0, FLAGS_REG)"
19324   [(parallel [(set (match_dup 0) (const_int -1))
19325               (clobber (reg:CC FLAGS_REG))])]
19326   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19327                               operands[0]);")
19328
19329 ;; Attempt to convert simple leas to adds. These can be created by
19330 ;; move expanders.
19331 (define_peephole2
19332   [(set (match_operand:SI 0 "register_operand" "")
19333         (plus:SI (match_dup 0)
19334                  (match_operand:SI 1 "nonmemory_operand" "")))]
19335   "peep2_regno_dead_p (0, FLAGS_REG)"
19336   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19337               (clobber (reg:CC FLAGS_REG))])]
19338   "")
19339
19340 (define_peephole2
19341   [(set (match_operand:SI 0 "register_operand" "")
19342         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19343                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19344   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19345   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19346               (clobber (reg:CC FLAGS_REG))])]
19347   "operands[2] = gen_lowpart (SImode, operands[2]);")
19348
19349 (define_peephole2
19350   [(set (match_operand:DI 0 "register_operand" "")
19351         (plus:DI (match_dup 0)
19352                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19353   "peep2_regno_dead_p (0, FLAGS_REG)"
19354   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19355               (clobber (reg:CC FLAGS_REG))])]
19356   "")
19357
19358 (define_peephole2
19359   [(set (match_operand:SI 0 "register_operand" "")
19360         (mult:SI (match_dup 0)
19361                  (match_operand:SI 1 "const_int_operand" "")))]
19362   "exact_log2 (INTVAL (operands[1])) >= 0
19363    && peep2_regno_dead_p (0, FLAGS_REG)"
19364   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19365               (clobber (reg:CC FLAGS_REG))])]
19366   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19367
19368 (define_peephole2
19369   [(set (match_operand:DI 0 "register_operand" "")
19370         (mult:DI (match_dup 0)
19371                  (match_operand:DI 1 "const_int_operand" "")))]
19372   "exact_log2 (INTVAL (operands[1])) >= 0
19373    && peep2_regno_dead_p (0, FLAGS_REG)"
19374   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19375               (clobber (reg:CC FLAGS_REG))])]
19376   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19377
19378 (define_peephole2
19379   [(set (match_operand:SI 0 "register_operand" "")
19380         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19381                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19382   "exact_log2 (INTVAL (operands[2])) >= 0
19383    && REGNO (operands[0]) == REGNO (operands[1])
19384    && peep2_regno_dead_p (0, FLAGS_REG)"
19385   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19386               (clobber (reg:CC FLAGS_REG))])]
19387   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19388
19389 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19390 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19391 ;; many CPUs it is also faster, since special hardware to avoid esp
19392 ;; dependencies is present.
19393
19394 ;; While some of these conversions may be done using splitters, we use peepholes
19395 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19396
19397 ;; Convert prologue esp subtractions to push.
19398 ;; We need register to push.  In order to keep verify_flow_info happy we have
19399 ;; two choices
19400 ;; - use scratch and clobber it in order to avoid dependencies
19401 ;; - use already live register
19402 ;; We can't use the second way right now, since there is no reliable way how to
19403 ;; verify that given register is live.  First choice will also most likely in
19404 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19405 ;; call clobbered registers are dead.  We may want to use base pointer as an
19406 ;; alternative when no register is available later.
19407
19408 (define_peephole2
19409   [(match_scratch:SI 0 "r")
19410    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19411               (clobber (reg:CC FLAGS_REG))
19412               (clobber (mem:BLK (scratch)))])]
19413   "optimize_size || !TARGET_SUB_ESP_4"
19414   [(clobber (match_dup 0))
19415    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19416               (clobber (mem:BLK (scratch)))])])
19417
19418 (define_peephole2
19419   [(match_scratch:SI 0 "r")
19420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19421               (clobber (reg:CC FLAGS_REG))
19422               (clobber (mem:BLK (scratch)))])]
19423   "optimize_size || !TARGET_SUB_ESP_8"
19424   [(clobber (match_dup 0))
19425    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19426    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19427               (clobber (mem:BLK (scratch)))])])
19428
19429 ;; Convert esp subtractions to push.
19430 (define_peephole2
19431   [(match_scratch:SI 0 "r")
19432    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19433               (clobber (reg:CC FLAGS_REG))])]
19434   "optimize_size || !TARGET_SUB_ESP_4"
19435   [(clobber (match_dup 0))
19436    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19437
19438 (define_peephole2
19439   [(match_scratch:SI 0 "r")
19440    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19441               (clobber (reg:CC FLAGS_REG))])]
19442   "optimize_size || !TARGET_SUB_ESP_8"
19443   [(clobber (match_dup 0))
19444    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19445    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19446
19447 ;; Convert epilogue deallocator to pop.
19448 (define_peephole2
19449   [(match_scratch:SI 0 "r")
19450    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19451               (clobber (reg:CC FLAGS_REG))
19452               (clobber (mem:BLK (scratch)))])]
19453   "optimize_size || !TARGET_ADD_ESP_4"
19454   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19455               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19456               (clobber (mem:BLK (scratch)))])]
19457   "")
19458
19459 ;; Two pops case is tricky, since pop causes dependency on destination register.
19460 ;; We use two registers if available.
19461 (define_peephole2
19462   [(match_scratch:SI 0 "r")
19463    (match_scratch:SI 1 "r")
19464    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19465               (clobber (reg:CC FLAGS_REG))
19466               (clobber (mem:BLK (scratch)))])]
19467   "optimize_size || !TARGET_ADD_ESP_8"
19468   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19469               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19470               (clobber (mem:BLK (scratch)))])
19471    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19472               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19473   "")
19474
19475 (define_peephole2
19476   [(match_scratch:SI 0 "r")
19477    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19478               (clobber (reg:CC FLAGS_REG))
19479               (clobber (mem:BLK (scratch)))])]
19480   "optimize_size"
19481   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19482               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19483               (clobber (mem:BLK (scratch)))])
19484    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19485               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19486   "")
19487
19488 ;; Convert esp additions to pop.
19489 (define_peephole2
19490   [(match_scratch:SI 0 "r")
19491    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19492               (clobber (reg:CC FLAGS_REG))])]
19493   ""
19494   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19495               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19496   "")
19497
19498 ;; Two pops case is tricky, since pop causes dependency on destination register.
19499 ;; We use two registers if available.
19500 (define_peephole2
19501   [(match_scratch:SI 0 "r")
19502    (match_scratch:SI 1 "r")
19503    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19504               (clobber (reg:CC FLAGS_REG))])]
19505   ""
19506   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19507               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19508    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19509               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19510   "")
19511
19512 (define_peephole2
19513   [(match_scratch:SI 0 "r")
19514    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19515               (clobber (reg:CC FLAGS_REG))])]
19516   "optimize_size"
19517   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19518               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19519    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19520               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19521   "")
19522 \f
19523 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19524 ;; required and register dies.  Similarly for 128 to plus -128.
19525 (define_peephole2
19526   [(set (match_operand 0 "flags_reg_operand" "")
19527         (match_operator 1 "compare_operator"
19528           [(match_operand 2 "register_operand" "")
19529            (match_operand 3 "const_int_operand" "")]))]
19530   "(INTVAL (operands[3]) == -1
19531     || INTVAL (operands[3]) == 1
19532     || INTVAL (operands[3]) == 128)
19533    && ix86_match_ccmode (insn, CCGCmode)
19534    && peep2_reg_dead_p (1, operands[2])"
19535   [(parallel [(set (match_dup 0)
19536                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19537               (clobber (match_dup 2))])]
19538   "")
19539 \f
19540 (define_peephole2
19541   [(match_scratch:DI 0 "r")
19542    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19543               (clobber (reg:CC FLAGS_REG))
19544               (clobber (mem:BLK (scratch)))])]
19545   "optimize_size || !TARGET_SUB_ESP_4"
19546   [(clobber (match_dup 0))
19547    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19548               (clobber (mem:BLK (scratch)))])])
19549
19550 (define_peephole2
19551   [(match_scratch:DI 0 "r")
19552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19553               (clobber (reg:CC FLAGS_REG))
19554               (clobber (mem:BLK (scratch)))])]
19555   "optimize_size || !TARGET_SUB_ESP_8"
19556   [(clobber (match_dup 0))
19557    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19558    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19559               (clobber (mem:BLK (scratch)))])])
19560
19561 ;; Convert esp subtractions to push.
19562 (define_peephole2
19563   [(match_scratch:DI 0 "r")
19564    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19565               (clobber (reg:CC FLAGS_REG))])]
19566   "optimize_size || !TARGET_SUB_ESP_4"
19567   [(clobber (match_dup 0))
19568    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19569
19570 (define_peephole2
19571   [(match_scratch:DI 0 "r")
19572    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19573               (clobber (reg:CC FLAGS_REG))])]
19574   "optimize_size || !TARGET_SUB_ESP_8"
19575   [(clobber (match_dup 0))
19576    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19577    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19578
19579 ;; Convert epilogue deallocator to pop.
19580 (define_peephole2
19581   [(match_scratch:DI 0 "r")
19582    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19583               (clobber (reg:CC FLAGS_REG))
19584               (clobber (mem:BLK (scratch)))])]
19585   "optimize_size || !TARGET_ADD_ESP_4"
19586   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19588               (clobber (mem:BLK (scratch)))])]
19589   "")
19590
19591 ;; Two pops case is tricky, since pop causes dependency on destination register.
19592 ;; We use two registers if available.
19593 (define_peephole2
19594   [(match_scratch:DI 0 "r")
19595    (match_scratch:DI 1 "r")
19596    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19597               (clobber (reg:CC FLAGS_REG))
19598               (clobber (mem:BLK (scratch)))])]
19599   "optimize_size || !TARGET_ADD_ESP_8"
19600   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19601               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19602               (clobber (mem:BLK (scratch)))])
19603    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19604               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19605   "")
19606
19607 (define_peephole2
19608   [(match_scratch:DI 0 "r")
19609    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19610               (clobber (reg:CC FLAGS_REG))
19611               (clobber (mem:BLK (scratch)))])]
19612   "optimize_size"
19613   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19614               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19615               (clobber (mem:BLK (scratch)))])
19616    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19617               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19618   "")
19619
19620 ;; Convert esp additions to pop.
19621 (define_peephole2
19622   [(match_scratch:DI 0 "r")
19623    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19624               (clobber (reg:CC FLAGS_REG))])]
19625   ""
19626   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19627               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19628   "")
19629
19630 ;; Two pops case is tricky, since pop causes dependency on destination register.
19631 ;; We use two registers if available.
19632 (define_peephole2
19633   [(match_scratch:DI 0 "r")
19634    (match_scratch:DI 1 "r")
19635    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19636               (clobber (reg:CC FLAGS_REG))])]
19637   ""
19638   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19640    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19641               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19642   "")
19643
19644 (define_peephole2
19645   [(match_scratch:DI 0 "r")
19646    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19647               (clobber (reg:CC FLAGS_REG))])]
19648   "optimize_size"
19649   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19650               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19651    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19652               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19653   "")
19654 \f
19655 ;; Convert imul by three, five and nine into lea
19656 (define_peephole2
19657   [(parallel
19658     [(set (match_operand:SI 0 "register_operand" "")
19659           (mult:SI (match_operand:SI 1 "register_operand" "")
19660                    (match_operand:SI 2 "const_int_operand" "")))
19661      (clobber (reg:CC FLAGS_REG))])]
19662   "INTVAL (operands[2]) == 3
19663    || INTVAL (operands[2]) == 5
19664    || INTVAL (operands[2]) == 9"
19665   [(set (match_dup 0)
19666         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19667                  (match_dup 1)))]
19668   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19669
19670 (define_peephole2
19671   [(parallel
19672     [(set (match_operand:SI 0 "register_operand" "")
19673           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19674                    (match_operand:SI 2 "const_int_operand" "")))
19675      (clobber (reg:CC FLAGS_REG))])]
19676   "!optimize_size 
19677    && (INTVAL (operands[2]) == 3
19678        || INTVAL (operands[2]) == 5
19679        || INTVAL (operands[2]) == 9)"
19680   [(set (match_dup 0) (match_dup 1))
19681    (set (match_dup 0)
19682         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19683                  (match_dup 0)))]
19684   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19685
19686 (define_peephole2
19687   [(parallel
19688     [(set (match_operand:DI 0 "register_operand" "")
19689           (mult:DI (match_operand:DI 1 "register_operand" "")
19690                    (match_operand:DI 2 "const_int_operand" "")))
19691      (clobber (reg:CC FLAGS_REG))])]
19692   "TARGET_64BIT
19693    && (INTVAL (operands[2]) == 3
19694        || INTVAL (operands[2]) == 5
19695        || INTVAL (operands[2]) == 9)"
19696   [(set (match_dup 0)
19697         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19698                  (match_dup 1)))]
19699   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19700
19701 (define_peephole2
19702   [(parallel
19703     [(set (match_operand:DI 0 "register_operand" "")
19704           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19705                    (match_operand:DI 2 "const_int_operand" "")))
19706      (clobber (reg:CC FLAGS_REG))])]
19707   "TARGET_64BIT
19708    && !optimize_size 
19709    && (INTVAL (operands[2]) == 3
19710        || INTVAL (operands[2]) == 5
19711        || INTVAL (operands[2]) == 9)"
19712   [(set (match_dup 0) (match_dup 1))
19713    (set (match_dup 0)
19714         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19715                  (match_dup 0)))]
19716   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19717
19718 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19719 ;; imul $32bit_imm, reg, reg is direct decoded.
19720 (define_peephole2
19721   [(match_scratch:DI 3 "r")
19722    (parallel [(set (match_operand:DI 0 "register_operand" "")
19723                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19724                             (match_operand:DI 2 "immediate_operand" "")))
19725               (clobber (reg:CC FLAGS_REG))])]
19726   "TARGET_K8 && !optimize_size
19727    && (GET_CODE (operands[2]) != CONST_INT
19728        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19729   [(set (match_dup 3) (match_dup 1))
19730    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19731               (clobber (reg:CC FLAGS_REG))])]
19732 "")
19733
19734 (define_peephole2
19735   [(match_scratch:SI 3 "r")
19736    (parallel [(set (match_operand:SI 0 "register_operand" "")
19737                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19738                             (match_operand:SI 2 "immediate_operand" "")))
19739               (clobber (reg:CC FLAGS_REG))])]
19740   "TARGET_K8 && !optimize_size
19741    && (GET_CODE (operands[2]) != CONST_INT
19742        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19743   [(set (match_dup 3) (match_dup 1))
19744    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19745               (clobber (reg:CC FLAGS_REG))])]
19746 "")
19747
19748 (define_peephole2
19749   [(match_scratch:SI 3 "r")
19750    (parallel [(set (match_operand:DI 0 "register_operand" "")
19751                    (zero_extend:DI
19752                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19753                               (match_operand:SI 2 "immediate_operand" ""))))
19754               (clobber (reg:CC FLAGS_REG))])]
19755   "TARGET_K8 && !optimize_size
19756    && (GET_CODE (operands[2]) != CONST_INT
19757        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19758   [(set (match_dup 3) (match_dup 1))
19759    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19760               (clobber (reg:CC FLAGS_REG))])]
19761 "")
19762
19763 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19764 ;; Convert it into imul reg, reg
19765 ;; It would be better to force assembler to encode instruction using long
19766 ;; immediate, but there is apparently no way to do so.
19767 (define_peephole2
19768   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19769                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19770                             (match_operand:DI 2 "const_int_operand" "")))
19771               (clobber (reg:CC FLAGS_REG))])
19772    (match_scratch:DI 3 "r")]
19773   "TARGET_K8 && !optimize_size
19774    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19775   [(set (match_dup 3) (match_dup 2))
19776    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778 {
19779   if (!rtx_equal_p (operands[0], operands[1]))
19780     emit_move_insn (operands[0], operands[1]);
19781 })
19782
19783 (define_peephole2
19784   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19785                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19786                             (match_operand:SI 2 "const_int_operand" "")))
19787               (clobber (reg:CC FLAGS_REG))])
19788    (match_scratch:SI 3 "r")]
19789   "TARGET_K8 && !optimize_size
19790    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19791   [(set (match_dup 3) (match_dup 2))
19792    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19793               (clobber (reg:CC FLAGS_REG))])]
19794 {
19795   if (!rtx_equal_p (operands[0], operands[1]))
19796     emit_move_insn (operands[0], operands[1]);
19797 })
19798
19799 (define_peephole2
19800   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19801                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19802                             (match_operand:HI 2 "immediate_operand" "")))
19803               (clobber (reg:CC FLAGS_REG))])
19804    (match_scratch:HI 3 "r")]
19805   "TARGET_K8 && !optimize_size"
19806   [(set (match_dup 3) (match_dup 2))
19807    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19808               (clobber (reg:CC FLAGS_REG))])]
19809 {
19810   if (!rtx_equal_p (operands[0], operands[1]))
19811     emit_move_insn (operands[0], operands[1]);
19812 })
19813 \f
19814 ;; Call-value patterns last so that the wildcard operand does not
19815 ;; disrupt insn-recog's switch tables.
19816
19817 (define_insn "*call_value_pop_0"
19818   [(set (match_operand 0 "" "")
19819         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19820               (match_operand:SI 2 "" "")))
19821    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19822                             (match_operand:SI 3 "immediate_operand" "")))]
19823   "!TARGET_64BIT"
19824 {
19825   if (SIBLING_CALL_P (insn))
19826     return "jmp\t%P1";
19827   else
19828     return "call\t%P1";
19829 }
19830   [(set_attr "type" "callv")])
19831
19832 (define_insn "*call_value_pop_1"
19833   [(set (match_operand 0 "" "")
19834         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19835               (match_operand:SI 2 "" "")))
19836    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19837                             (match_operand:SI 3 "immediate_operand" "i")))]
19838   "!TARGET_64BIT"
19839 {
19840   if (constant_call_address_operand (operands[1], Pmode))
19841     {
19842       if (SIBLING_CALL_P (insn))
19843         return "jmp\t%P1";
19844       else
19845         return "call\t%P1";
19846     }
19847   if (SIBLING_CALL_P (insn))
19848     return "jmp\t%A1";
19849   else
19850     return "call\t%A1";
19851 }
19852   [(set_attr "type" "callv")])
19853
19854 (define_insn "*call_value_0"
19855   [(set (match_operand 0 "" "")
19856         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19857               (match_operand:SI 2 "" "")))]
19858   "!TARGET_64BIT"
19859 {
19860   if (SIBLING_CALL_P (insn))
19861     return "jmp\t%P1";
19862   else
19863     return "call\t%P1";
19864 }
19865   [(set_attr "type" "callv")])
19866
19867 (define_insn "*call_value_0_rex64"
19868   [(set (match_operand 0 "" "")
19869         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19870               (match_operand:DI 2 "const_int_operand" "")))]
19871   "TARGET_64BIT"
19872 {
19873   if (SIBLING_CALL_P (insn))
19874     return "jmp\t%P1";
19875   else
19876     return "call\t%P1";
19877 }
19878   [(set_attr "type" "callv")])
19879
19880 (define_insn "*call_value_1"
19881   [(set (match_operand 0 "" "")
19882         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19883               (match_operand:SI 2 "" "")))]
19884   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19885 {
19886   if (constant_call_address_operand (operands[1], Pmode))
19887     return "call\t%P1";
19888   return "call\t%A1";
19889 }
19890   [(set_attr "type" "callv")])
19891
19892 (define_insn "*sibcall_value_1"
19893   [(set (match_operand 0 "" "")
19894         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19895               (match_operand:SI 2 "" "")))]
19896   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19897 {
19898   if (constant_call_address_operand (operands[1], Pmode))
19899     return "jmp\t%P1";
19900   return "jmp\t%A1";
19901 }
19902   [(set_attr "type" "callv")])
19903
19904 (define_insn "*call_value_1_rex64"
19905   [(set (match_operand 0 "" "")
19906         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19907               (match_operand:DI 2 "" "")))]
19908   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19909 {
19910   if (constant_call_address_operand (operands[1], Pmode))
19911     return "call\t%P1";
19912   return "call\t%A1";
19913 }
19914   [(set_attr "type" "callv")])
19915
19916 (define_insn "*sibcall_value_1_rex64"
19917   [(set (match_operand 0 "" "")
19918         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19919               (match_operand:DI 2 "" "")))]
19920   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19921   "jmp\t%P1"
19922   [(set_attr "type" "callv")])
19923
19924 (define_insn "*sibcall_value_1_rex64_v"
19925   [(set (match_operand 0 "" "")
19926         (call (mem:QI (reg:DI 40))
19927               (match_operand:DI 1 "" "")))]
19928   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19929   "jmp\t*%%r11"
19930   [(set_attr "type" "callv")])
19931 \f
19932 (define_insn "trap"
19933   [(trap_if (const_int 1) (const_int 5))]
19934   ""
19935   "int\t$5")
19936
19937 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19938 ;;; for the sake of bounds checking.  By emitting bounds checks as
19939 ;;; conditional traps rather than as conditional jumps around
19940 ;;; unconditional traps we avoid introducing spurious basic-block
19941 ;;; boundaries and facilitate elimination of redundant checks.  In
19942 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19943 ;;; interrupt 5.
19944 ;;; 
19945 ;;; FIXME: Static branch prediction rules for ix86 are such that
19946 ;;; forward conditional branches predict as untaken.  As implemented
19947 ;;; below, pseudo conditional traps violate that rule.  We should use
19948 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19949 ;;; section loaded at the end of the text segment and branch forward
19950 ;;; there on bounds-failure, and then jump back immediately (in case
19951 ;;; the system chooses to ignore bounds violations, or to report
19952 ;;; violations and continue execution).
19953
19954 (define_expand "conditional_trap"
19955   [(trap_if (match_operator 0 "comparison_operator"
19956              [(match_dup 2) (const_int 0)])
19957             (match_operand 1 "const_int_operand" ""))]
19958   ""
19959 {
19960   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19961                               ix86_expand_compare (GET_CODE (operands[0]),
19962                                                    NULL, NULL),
19963                               operands[1]));
19964   DONE;
19965 })
19966
19967 (define_insn "*conditional_trap_1"
19968   [(trap_if (match_operator 0 "comparison_operator"
19969              [(reg FLAGS_REG) (const_int 0)])
19970             (match_operand 1 "const_int_operand" ""))]
19971   ""
19972 {
19973   operands[2] = gen_label_rtx ();
19974   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19975   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19976                              CODE_LABEL_NUMBER (operands[2]));
19977   RET;
19978 })
19979
19980         ;; Pentium III SIMD instructions.
19981
19982 ;; Moves for SSE/MMX regs.
19983
19984 (define_insn "movv4sf_internal"
19985   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19986         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19987   "TARGET_SSE"
19988   "@
19989     xorps\t%0, %0
19990     movaps\t{%1, %0|%0, %1}
19991     movaps\t{%1, %0|%0, %1}"
19992   [(set_attr "type" "ssemov")
19993    (set_attr "mode" "V4SF")])
19994
19995 (define_split
19996   [(set (match_operand:V4SF 0 "register_operand" "")
19997         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19998   "TARGET_SSE"
19999   [(set (match_dup 0)
20000         (vec_merge:V4SF
20001          (vec_duplicate:V4SF (match_dup 1))
20002          (match_dup 2)
20003          (const_int 1)))]
20004 {
20005   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20006   operands[2] = CONST0_RTX (V4SFmode);
20007 })
20008
20009 (define_insn "movv4si_internal"
20010   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20011         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20012   "TARGET_SSE"
20013 {
20014   switch (which_alternative)
20015     {
20016     case 0:
20017       if (get_attr_mode (insn) == MODE_V4SF)
20018         return "xorps\t%0, %0";
20019       else
20020         return "pxor\t%0, %0";
20021     case 1:
20022     case 2:
20023       if (get_attr_mode (insn) == MODE_V4SF)
20024         return "movaps\t{%1, %0|%0, %1}";
20025       else
20026         return "movdqa\t{%1, %0|%0, %1}";
20027     default:
20028       abort ();
20029     }
20030 }
20031   [(set_attr "type" "ssemov")
20032    (set (attr "mode")
20033         (cond [(eq_attr "alternative" "0,1")
20034                  (if_then_else
20035                    (ne (symbol_ref "optimize_size")
20036                        (const_int 0))
20037                    (const_string "V4SF")
20038                    (const_string "TI"))
20039                (eq_attr "alternative" "2")
20040                  (if_then_else
20041                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20042                             (const_int 0))
20043                         (ne (symbol_ref "optimize_size")
20044                             (const_int 0)))
20045                    (const_string "V4SF")
20046                    (const_string "TI"))]
20047                (const_string "TI")))])
20048
20049 (define_insn "movv2di_internal"
20050   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20051         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20052   "TARGET_SSE"
20053 {
20054   switch (which_alternative)
20055     {
20056     case 0:
20057       if (get_attr_mode (insn) == MODE_V4SF)
20058         return "xorps\t%0, %0";
20059       else
20060         return "pxor\t%0, %0";
20061     case 1:
20062     case 2:
20063       if (get_attr_mode (insn) == MODE_V4SF)
20064         return "movaps\t{%1, %0|%0, %1}";
20065       else
20066         return "movdqa\t{%1, %0|%0, %1}";
20067     default:
20068       abort ();
20069     }
20070 }
20071   [(set_attr "type" "ssemov")
20072    (set (attr "mode")
20073         (cond [(eq_attr "alternative" "0,1")
20074                  (if_then_else
20075                    (ne (symbol_ref "optimize_size")
20076                        (const_int 0))
20077                    (const_string "V4SF")
20078                    (const_string "TI"))
20079                (eq_attr "alternative" "2")
20080                  (if_then_else
20081                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20082                             (const_int 0))
20083                         (ne (symbol_ref "optimize_size")
20084                             (const_int 0)))
20085                    (const_string "V4SF")
20086                    (const_string "TI"))]
20087                (const_string "TI")))])
20088
20089 (define_split
20090   [(set (match_operand:V2DF 0 "register_operand" "")
20091         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20092   "TARGET_SSE2"
20093   [(set (match_dup 0)
20094         (vec_merge:V2DF
20095          (vec_duplicate:V2DF (match_dup 1))
20096          (match_dup 2)
20097          (const_int 1)))]
20098 {
20099   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20100   operands[2] = CONST0_RTX (V2DFmode);
20101 })
20102
20103 (define_insn "movv8qi_internal"
20104   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20105         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20106   "TARGET_MMX
20107    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20108   "@
20109     pxor\t%0, %0
20110     movq\t{%1, %0|%0, %1}
20111     movq\t{%1, %0|%0, %1}
20112     movdq2q\t{%1, %0|%0, %1}
20113     movq2dq\t{%1, %0|%0, %1}
20114     movq\t{%1, %0|%0, %1}
20115     movq\t{%1, %0|%0, %1}"
20116   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20117    (set_attr "mode" "DI")])
20118
20119 (define_insn "movv4hi_internal"
20120   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20121         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20122   "TARGET_MMX
20123    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20124   "@
20125     pxor\t%0, %0
20126     movq\t{%1, %0|%0, %1}
20127     movq\t{%1, %0|%0, %1}
20128     movdq2q\t{%1, %0|%0, %1}
20129     movq2dq\t{%1, %0|%0, %1}
20130     movq\t{%1, %0|%0, %1}
20131     movq\t{%1, %0|%0, %1}"
20132   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20133    (set_attr "mode" "DI")])
20134
20135 (define_insn "*movv2si_internal"
20136   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20137         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20138   "TARGET_MMX
20139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20140   "@
20141     pxor\t%0, %0
20142     movq\t{%1, %0|%0, %1}
20143     movq\t{%1, %0|%0, %1}
20144     movdq2q\t{%1, %0|%0, %1}
20145     movq2dq\t{%1, %0|%0, %1}
20146     movq\t{%1, %0|%0, %1}
20147     movq\t{%1, %0|%0, %1}"
20148   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20149    (set_attr "mode" "DI")])
20150
20151 (define_insn "movv2sf_internal"
20152   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20153         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20154   "TARGET_3DNOW
20155    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20156   "@
20157     pxor\t%0, %0
20158     movq\t{%1, %0|%0, %1}
20159     movq\t{%1, %0|%0, %1}
20160     movdq2q\t{%1, %0|%0, %1}
20161     movq2dq\t{%1, %0|%0, %1}
20162     movlps\t{%1, %0|%0, %1}
20163     movlps\t{%1, %0|%0, %1}"
20164   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20165    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20166
20167 (define_expand "movti"
20168   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20169         (match_operand:TI 1 "nonimmediate_operand" ""))]
20170   "TARGET_SSE || TARGET_64BIT"
20171 {
20172   if (TARGET_64BIT)
20173     ix86_expand_move (TImode, operands);
20174   else
20175     ix86_expand_vector_move (TImode, operands);
20176   DONE;
20177 })
20178
20179 (define_expand "movtf"
20180   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20181         (match_operand:TF 1 "nonimmediate_operand" ""))]
20182   "TARGET_64BIT"
20183 {
20184   if (TARGET_64BIT)
20185     ix86_expand_move (TFmode, operands);
20186   else
20187     ix86_expand_vector_move (TFmode, operands);
20188   DONE;
20189 })
20190
20191 (define_insn "movv2df_internal"
20192   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20193         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20194   "TARGET_SSE2
20195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20196 {
20197   switch (which_alternative)
20198     {
20199     case 0:
20200       if (get_attr_mode (insn) == MODE_V4SF)
20201         return "xorps\t%0, %0";
20202       else
20203         return "xorpd\t%0, %0";
20204     case 1:
20205     case 2:
20206       if (get_attr_mode (insn) == MODE_V4SF)
20207         return "movaps\t{%1, %0|%0, %1}";
20208       else
20209         return "movapd\t{%1, %0|%0, %1}";
20210     default:
20211       abort ();
20212     }
20213 }
20214   [(set_attr "type" "ssemov")
20215    (set (attr "mode")
20216         (cond [(eq_attr "alternative" "0,1")
20217                  (if_then_else
20218                    (ne (symbol_ref "optimize_size")
20219                        (const_int 0))
20220                    (const_string "V4SF")
20221                    (const_string "V2DF"))
20222                (eq_attr "alternative" "2")
20223                  (if_then_else
20224                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20225                             (const_int 0))
20226                         (ne (symbol_ref "optimize_size")
20227                             (const_int 0)))
20228                    (const_string "V4SF")
20229                    (const_string "V2DF"))]
20230                (const_string "V2DF")))])
20231
20232 (define_insn "movv8hi_internal"
20233   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20234         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20235   "TARGET_SSE2
20236    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20237 {
20238   switch (which_alternative)
20239     {
20240     case 0:
20241       if (get_attr_mode (insn) == MODE_V4SF)
20242         return "xorps\t%0, %0";
20243       else
20244         return "pxor\t%0, %0";
20245     case 1:
20246     case 2:
20247       if (get_attr_mode (insn) == MODE_V4SF)
20248         return "movaps\t{%1, %0|%0, %1}";
20249       else
20250         return "movdqa\t{%1, %0|%0, %1}";
20251     default:
20252       abort ();
20253     }
20254 }
20255   [(set_attr "type" "ssemov")
20256    (set (attr "mode")
20257         (cond [(eq_attr "alternative" "0,1")
20258                  (if_then_else
20259                    (ne (symbol_ref "optimize_size")
20260                        (const_int 0))
20261                    (const_string "V4SF")
20262                    (const_string "TI"))
20263                (eq_attr "alternative" "2")
20264                  (if_then_else
20265                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20266                             (const_int 0))
20267                         (ne (symbol_ref "optimize_size")
20268                             (const_int 0)))
20269                    (const_string "V4SF")
20270                    (const_string "TI"))]
20271                (const_string "TI")))])
20272
20273 (define_insn "movv16qi_internal"
20274   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20275         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20276   "TARGET_SSE2
20277    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20278 {
20279   switch (which_alternative)
20280     {
20281     case 0:
20282       if (get_attr_mode (insn) == MODE_V4SF)
20283         return "xorps\t%0, %0";
20284       else
20285         return "pxor\t%0, %0";
20286     case 1:
20287     case 2:
20288       if (get_attr_mode (insn) == MODE_V4SF)
20289         return "movaps\t{%1, %0|%0, %1}";
20290       else
20291         return "movdqa\t{%1, %0|%0, %1}";
20292     default:
20293       abort ();
20294     }
20295 }
20296   [(set_attr "type" "ssemov")
20297    (set (attr "mode")
20298         (cond [(eq_attr "alternative" "0,1")
20299                  (if_then_else
20300                    (ne (symbol_ref "optimize_size")
20301                        (const_int 0))
20302                    (const_string "V4SF")
20303                    (const_string "TI"))
20304                (eq_attr "alternative" "2")
20305                  (if_then_else
20306                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20307                             (const_int 0))
20308                         (ne (symbol_ref "optimize_size")
20309                             (const_int 0)))
20310                    (const_string "V4SF")
20311                    (const_string "TI"))]
20312                (const_string "TI")))])
20313
20314 (define_expand "movv2df"
20315   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20316         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20317   "TARGET_SSE2"
20318 {
20319   ix86_expand_vector_move (V2DFmode, operands);
20320   DONE;
20321 })
20322
20323 (define_expand "movv8hi"
20324   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20325         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20326   "TARGET_SSE2"
20327 {
20328   ix86_expand_vector_move (V8HImode, operands);
20329   DONE;
20330 })
20331
20332 (define_expand "movv16qi"
20333   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20334         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20335   "TARGET_SSE2"
20336 {
20337   ix86_expand_vector_move (V16QImode, operands);
20338   DONE;
20339 })
20340
20341 (define_expand "movv4sf"
20342   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20343         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20344   "TARGET_SSE"
20345 {
20346   ix86_expand_vector_move (V4SFmode, operands);
20347   DONE;
20348 })
20349
20350 (define_expand "movv4si"
20351   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20352         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20353   "TARGET_SSE"
20354 {
20355   ix86_expand_vector_move (V4SImode, operands);
20356   DONE;
20357 })
20358
20359 (define_expand "movv2di"
20360   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20361         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20362   "TARGET_SSE"
20363 {
20364   ix86_expand_vector_move (V2DImode, operands);
20365   DONE;
20366 })
20367
20368 (define_expand "movv2si"
20369   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20370         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20371   "TARGET_MMX"
20372 {
20373   ix86_expand_vector_move (V2SImode, operands);
20374   DONE;
20375 })
20376
20377 (define_expand "movv4hi"
20378   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20379         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20380   "TARGET_MMX"
20381 {
20382   ix86_expand_vector_move (V4HImode, operands);
20383   DONE;
20384 })
20385
20386 (define_expand "movv8qi"
20387   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20388         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20389   "TARGET_MMX"
20390 {
20391   ix86_expand_vector_move (V8QImode, operands);
20392   DONE;
20393 })
20394
20395 (define_expand "movv2sf"
20396   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20397         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20398    "TARGET_3DNOW"
20399 {
20400   ix86_expand_vector_move (V2SFmode, operands);
20401   DONE;
20402 })
20403
20404 (define_insn "*pushti"
20405   [(set (match_operand:TI 0 "push_operand" "=<")
20406         (match_operand:TI 1 "register_operand" "x"))]
20407   "TARGET_SSE"
20408   "#")
20409
20410 (define_insn "*pushv2df"
20411   [(set (match_operand:V2DF 0 "push_operand" "=<")
20412         (match_operand:V2DF 1 "register_operand" "x"))]
20413   "TARGET_SSE"
20414   "#")
20415
20416 (define_insn "*pushv2di"
20417   [(set (match_operand:V2DI 0 "push_operand" "=<")
20418         (match_operand:V2DI 1 "register_operand" "x"))]
20419   "TARGET_SSE2"
20420   "#")
20421
20422 (define_insn "*pushv8hi"
20423   [(set (match_operand:V8HI 0 "push_operand" "=<")
20424         (match_operand:V8HI 1 "register_operand" "x"))]
20425   "TARGET_SSE2"
20426   "#")
20427
20428 (define_insn "*pushv16qi"
20429   [(set (match_operand:V16QI 0 "push_operand" "=<")
20430         (match_operand:V16QI 1 "register_operand" "x"))]
20431   "TARGET_SSE2"
20432   "#")
20433
20434 (define_insn "*pushv4sf"
20435   [(set (match_operand:V4SF 0 "push_operand" "=<")
20436         (match_operand:V4SF 1 "register_operand" "x"))]
20437   "TARGET_SSE"
20438   "#")
20439
20440 (define_insn "*pushv4si"
20441   [(set (match_operand:V4SI 0 "push_operand" "=<")
20442         (match_operand:V4SI 1 "register_operand" "x"))]
20443   "TARGET_SSE2"
20444   "#")
20445
20446 (define_insn "*pushv2si"
20447   [(set (match_operand:V2SI 0 "push_operand" "=<")
20448         (match_operand:V2SI 1 "register_operand" "y"))]
20449   "TARGET_MMX"
20450   "#")
20451
20452 (define_insn "*pushv4hi"
20453   [(set (match_operand:V4HI 0 "push_operand" "=<")
20454         (match_operand:V4HI 1 "register_operand" "y"))]
20455   "TARGET_MMX"
20456   "#")
20457
20458 (define_insn "*pushv8qi"
20459   [(set (match_operand:V8QI 0 "push_operand" "=<")
20460         (match_operand:V8QI 1 "register_operand" "y"))]
20461   "TARGET_MMX"
20462   "#")
20463
20464 (define_insn "*pushv2sf"
20465   [(set (match_operand:V2SF 0 "push_operand" "=<")
20466         (match_operand:V2SF 1 "register_operand" "y"))]
20467   "TARGET_3DNOW"
20468   "#")
20469
20470 (define_split
20471   [(set (match_operand 0 "push_operand" "")
20472         (match_operand 1 "register_operand" ""))]
20473   "!TARGET_64BIT && reload_completed
20474    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20475   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20476    (set (match_dup 2) (match_dup 1))]
20477   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20478                                  stack_pointer_rtx);
20479    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20480
20481 (define_split
20482   [(set (match_operand 0 "push_operand" "")
20483         (match_operand 1 "register_operand" ""))]
20484   "TARGET_64BIT && reload_completed
20485    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20486   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20487    (set (match_dup 2) (match_dup 1))]
20488   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20489                                  stack_pointer_rtx);
20490    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20491
20492
20493 (define_insn "movti_internal"
20494   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20495         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20496   "TARGET_SSE && !TARGET_64BIT
20497    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20498 {
20499   switch (which_alternative)
20500     {
20501     case 0:
20502       if (get_attr_mode (insn) == MODE_V4SF)
20503         return "xorps\t%0, %0";
20504       else
20505         return "pxor\t%0, %0";
20506     case 1:
20507     case 2:
20508       if (get_attr_mode (insn) == MODE_V4SF)
20509         return "movaps\t{%1, %0|%0, %1}";
20510       else
20511         return "movdqa\t{%1, %0|%0, %1}";
20512     default:
20513       abort ();
20514     }
20515 }
20516   [(set_attr "type" "ssemov,ssemov,ssemov")
20517    (set (attr "mode")
20518         (cond [(eq_attr "alternative" "0,1")
20519                  (if_then_else
20520                    (ne (symbol_ref "optimize_size")
20521                        (const_int 0))
20522                    (const_string "V4SF")
20523                    (const_string "TI"))
20524                (eq_attr "alternative" "2")
20525                  (if_then_else
20526                    (ne (symbol_ref "optimize_size")
20527                        (const_int 0))
20528                    (const_string "V4SF")
20529                    (const_string "TI"))]
20530                (const_string "TI")))])
20531
20532 (define_insn "*movti_rex64"
20533   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20534         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20535   "TARGET_64BIT
20536    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20537 {
20538   switch (which_alternative)
20539     {
20540     case 0:
20541     case 1:
20542       return "#";
20543     case 2:
20544       if (get_attr_mode (insn) == MODE_V4SF)
20545         return "xorps\t%0, %0";
20546       else
20547         return "pxor\t%0, %0";
20548     case 3:
20549     case 4:
20550       if (get_attr_mode (insn) == MODE_V4SF)
20551         return "movaps\t{%1, %0|%0, %1}";
20552       else
20553         return "movdqa\t{%1, %0|%0, %1}";
20554     default:
20555       abort ();
20556     }
20557 }
20558   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20559    (set (attr "mode")
20560         (cond [(eq_attr "alternative" "2,3")
20561                  (if_then_else
20562                    (ne (symbol_ref "optimize_size")
20563                        (const_int 0))
20564                    (const_string "V4SF")
20565                    (const_string "TI"))
20566                (eq_attr "alternative" "4")
20567                  (if_then_else
20568                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20569                             (const_int 0))
20570                         (ne (symbol_ref "optimize_size")
20571                             (const_int 0)))
20572                    (const_string "V4SF")
20573                    (const_string "TI"))]
20574                (const_string "DI")))])
20575
20576 (define_insn "*movtf_rex64"
20577   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20578         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20579   "TARGET_64BIT
20580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20581 {
20582   switch (which_alternative)
20583     {
20584     case 0:
20585     case 1:
20586       return "#";
20587     case 2:
20588       if (get_attr_mode (insn) == MODE_V4SF)
20589         return "xorps\t%0, %0";
20590       else
20591         return "pxor\t%0, %0";
20592     case 3:
20593     case 4:
20594       if (get_attr_mode (insn) == MODE_V4SF)
20595         return "movaps\t{%1, %0|%0, %1}";
20596       else
20597         return "movdqa\t{%1, %0|%0, %1}";
20598     default:
20599       abort ();
20600     }
20601 }
20602   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20603    (set (attr "mode")
20604         (cond [(eq_attr "alternative" "2,3")
20605                  (if_then_else
20606                    (ne (symbol_ref "optimize_size")
20607                        (const_int 0))
20608                    (const_string "V4SF")
20609                    (const_string "TI"))
20610                (eq_attr "alternative" "4")
20611                  (if_then_else
20612                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20613                             (const_int 0))
20614                         (ne (symbol_ref "optimize_size")
20615                             (const_int 0)))
20616                    (const_string "V4SF")
20617                    (const_string "TI"))]
20618                (const_string "DI")))])
20619
20620 (define_split
20621   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20622         (match_operand:TI 1 "general_operand" ""))]
20623   "reload_completed && !SSE_REG_P (operands[0])
20624    && !SSE_REG_P (operands[1])"
20625   [(const_int 0)]
20626   "ix86_split_long_move (operands); DONE;")
20627
20628 (define_split
20629   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20630         (match_operand:TF 1 "general_operand" ""))]
20631   "reload_completed && !SSE_REG_P (operands[0])
20632    && !SSE_REG_P (operands[1])"
20633   [(const_int 0)]
20634   "ix86_split_long_move (operands); DONE;")
20635
20636 ;; These two patterns are useful for specifying exactly whether to use
20637 ;; movaps or movups
20638 (define_expand "sse_movaps"
20639   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20640         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20641                      UNSPEC_MOVA))]
20642   "TARGET_SSE"
20643 {
20644   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20645     {
20646       rtx tmp = gen_reg_rtx (V4SFmode);
20647       emit_insn (gen_sse_movaps (tmp, operands[1]));
20648       emit_move_insn (operands[0], tmp);
20649       DONE;
20650     }
20651 })
20652
20653 (define_insn "*sse_movaps_1"
20654   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20655         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20656                      UNSPEC_MOVA))]
20657   "TARGET_SSE
20658    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20659   "movaps\t{%1, %0|%0, %1}"
20660   [(set_attr "type" "ssemov,ssemov")
20661    (set_attr "mode" "V4SF")])
20662
20663 (define_expand "sse_movups"
20664   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20665         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20666                      UNSPEC_MOVU))]
20667   "TARGET_SSE"
20668 {
20669   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20670     {
20671       rtx tmp = gen_reg_rtx (V4SFmode);
20672       emit_insn (gen_sse_movups (tmp, operands[1]));
20673       emit_move_insn (operands[0], tmp);
20674       DONE;
20675     }
20676 })
20677
20678 (define_insn "*sse_movups_1"
20679   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20680         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20681                      UNSPEC_MOVU))]
20682   "TARGET_SSE
20683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20684   "movups\t{%1, %0|%0, %1}"
20685   [(set_attr "type" "ssecvt,ssecvt")
20686    (set_attr "mode" "V4SF")])
20687
20688 ;; SSE Strange Moves.
20689
20690 (define_insn "sse_movmskps"
20691   [(set (match_operand:SI 0 "register_operand" "=r")
20692         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20693                    UNSPEC_MOVMSK))]
20694   "TARGET_SSE"
20695   "movmskps\t{%1, %0|%0, %1}"
20696   [(set_attr "type" "ssecvt")
20697    (set_attr "mode" "V4SF")])
20698
20699 (define_insn "mmx_pmovmskb"
20700   [(set (match_operand:SI 0 "register_operand" "=r")
20701         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20702                    UNSPEC_MOVMSK))]
20703   "TARGET_SSE || TARGET_3DNOW_A"
20704   "pmovmskb\t{%1, %0|%0, %1}"
20705   [(set_attr "type" "ssecvt")
20706    (set_attr "mode" "V4SF")])
20707
20708
20709 (define_insn "mmx_maskmovq"
20710   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20711         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20712                       (match_operand:V8QI 2 "register_operand" "y")]
20713                      UNSPEC_MASKMOV))]
20714   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20715   ;; @@@ check ordering of operands in intel/nonintel syntax
20716   "maskmovq\t{%2, %1|%1, %2}"
20717   [(set_attr "type" "mmxcvt")
20718    (set_attr "mode" "DI")])
20719
20720 (define_insn "mmx_maskmovq_rex"
20721   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20722         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20723                       (match_operand:V8QI 2 "register_operand" "y")]
20724                      UNSPEC_MASKMOV))]
20725   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20726   ;; @@@ check ordering of operands in intel/nonintel syntax
20727   "maskmovq\t{%2, %1|%1, %2}"
20728   [(set_attr "type" "mmxcvt")
20729    (set_attr "mode" "DI")])
20730
20731 (define_insn "sse_movntv4sf"
20732   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20733         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20734                      UNSPEC_MOVNT))]
20735   "TARGET_SSE"
20736   "movntps\t{%1, %0|%0, %1}"
20737   [(set_attr "type" "ssemov")
20738    (set_attr "mode" "V4SF")])
20739
20740 (define_insn "sse_movntdi"
20741   [(set (match_operand:DI 0 "memory_operand" "=m")
20742         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20743                    UNSPEC_MOVNT))]
20744   "TARGET_SSE || TARGET_3DNOW_A"
20745   "movntq\t{%1, %0|%0, %1}"
20746   [(set_attr "type" "mmxmov")
20747    (set_attr "mode" "DI")])
20748
20749 (define_insn "sse_movhlps"
20750   [(set (match_operand:V4SF 0 "register_operand" "=x")
20751         (vec_merge:V4SF
20752          (match_operand:V4SF 1 "register_operand" "0")
20753          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20754                           (parallel [(const_int 2)
20755                                      (const_int 3)
20756                                      (const_int 0)
20757                                      (const_int 1)]))
20758          (const_int 3)))]
20759   "TARGET_SSE"
20760   "movhlps\t{%2, %0|%0, %2}"
20761   [(set_attr "type" "ssecvt")
20762    (set_attr "mode" "V4SF")])
20763
20764 (define_insn "sse_movlhps"
20765   [(set (match_operand:V4SF 0 "register_operand" "=x")
20766         (vec_merge:V4SF
20767          (match_operand:V4SF 1 "register_operand" "0")
20768          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20769                           (parallel [(const_int 2)
20770                                      (const_int 3)
20771                                      (const_int 0)
20772                                      (const_int 1)]))
20773          (const_int 12)))]
20774   "TARGET_SSE"
20775   "movlhps\t{%2, %0|%0, %2}"
20776   [(set_attr "type" "ssecvt")
20777    (set_attr "mode" "V4SF")])
20778
20779 (define_insn "sse_movhps"
20780   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20781         (vec_merge:V4SF
20782          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20783          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20784          (const_int 12)))]
20785   "TARGET_SSE
20786    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20787   "movhps\t{%2, %0|%0, %2}"
20788   [(set_attr "type" "ssecvt")
20789    (set_attr "mode" "V4SF")])
20790
20791 (define_insn "sse_movlps"
20792   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20793         (vec_merge:V4SF
20794          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20795          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20796          (const_int 3)))]
20797   "TARGET_SSE
20798    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20799   "movlps\t{%2, %0|%0, %2}"
20800   [(set_attr "type" "ssecvt")
20801    (set_attr "mode" "V4SF")])
20802
20803 (define_expand "sse_loadss"
20804   [(match_operand:V4SF 0 "register_operand" "")
20805    (match_operand:SF 1 "memory_operand" "")]
20806   "TARGET_SSE"
20807 {
20808   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20809                                CONST0_RTX (V4SFmode)));
20810   DONE;
20811 })
20812
20813 (define_insn "sse_loadss_1"
20814   [(set (match_operand:V4SF 0 "register_operand" "=x")
20815         (vec_merge:V4SF
20816          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20817          (match_operand:V4SF 2 "const0_operand" "X")
20818          (const_int 1)))]
20819   "TARGET_SSE"
20820   "movss\t{%1, %0|%0, %1}"
20821   [(set_attr "type" "ssemov")
20822    (set_attr "mode" "SF")])
20823
20824 (define_insn "sse_movss"
20825   [(set (match_operand:V4SF 0 "register_operand" "=x")
20826         (vec_merge:V4SF
20827          (match_operand:V4SF 1 "register_operand" "0")
20828          (match_operand:V4SF 2 "register_operand" "x")
20829          (const_int 14)))]
20830   "TARGET_SSE"
20831   "movss\t{%2, %0|%0, %2}"
20832   [(set_attr "type" "ssemov")
20833    (set_attr "mode" "SF")])
20834
20835 (define_insn "sse_storess"
20836   [(set (match_operand:SF 0 "memory_operand" "=m")
20837         (vec_select:SF
20838          (match_operand:V4SF 1 "register_operand" "x")
20839          (parallel [(const_int 0)])))]
20840   "TARGET_SSE"
20841   "movss\t{%1, %0|%0, %1}"
20842   [(set_attr "type" "ssemov")
20843    (set_attr "mode" "SF")])
20844
20845 (define_insn "sse_shufps"
20846   [(set (match_operand:V4SF 0 "register_operand" "=x")
20847         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20848                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20849                       (match_operand:SI 3 "immediate_operand" "i")]
20850                      UNSPEC_SHUFFLE))]
20851   "TARGET_SSE"
20852   ;; @@@ check operand order for intel/nonintel syntax
20853   "shufps\t{%3, %2, %0|%0, %2, %3}"
20854   [(set_attr "type" "ssecvt")
20855    (set_attr "mode" "V4SF")])
20856
20857
20858 ;; SSE arithmetic
20859
20860 (define_insn "addv4sf3"
20861   [(set (match_operand:V4SF 0 "register_operand" "=x")
20862         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20863                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20864   "TARGET_SSE"
20865   "addps\t{%2, %0|%0, %2}"
20866   [(set_attr "type" "sseadd")
20867    (set_attr "mode" "V4SF")])
20868
20869 (define_insn "vmaddv4sf3"
20870   [(set (match_operand:V4SF 0 "register_operand" "=x")
20871         (vec_merge:V4SF
20872          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20873                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20874          (match_dup 1)
20875          (const_int 1)))]
20876   "TARGET_SSE"
20877   "addss\t{%2, %0|%0, %2}"
20878   [(set_attr "type" "sseadd")
20879    (set_attr "mode" "SF")])
20880
20881 (define_insn "subv4sf3"
20882   [(set (match_operand:V4SF 0 "register_operand" "=x")
20883         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20884                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20885   "TARGET_SSE"
20886   "subps\t{%2, %0|%0, %2}"
20887   [(set_attr "type" "sseadd")
20888    (set_attr "mode" "V4SF")])
20889
20890 (define_insn "vmsubv4sf3"
20891   [(set (match_operand:V4SF 0 "register_operand" "=x")
20892         (vec_merge:V4SF
20893          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20894                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20895          (match_dup 1)
20896          (const_int 1)))]
20897   "TARGET_SSE"
20898   "subss\t{%2, %0|%0, %2}"
20899   [(set_attr "type" "sseadd")
20900    (set_attr "mode" "SF")])
20901
20902 ;; ??? Should probably be done by generic code instead.
20903 (define_expand "negv4sf2"
20904   [(set (match_operand:V4SF 0 "register_operand" "")
20905         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20906                   (match_dup 2)))]
20907   "TARGET_SSE"
20908 {
20909   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20910   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20911   operands[2] = force_reg (V4SFmode, vm0);
20912 })
20913
20914 (define_insn "mulv4sf3"
20915   [(set (match_operand:V4SF 0 "register_operand" "=x")
20916         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20917                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20918   "TARGET_SSE"
20919   "mulps\t{%2, %0|%0, %2}"
20920   [(set_attr "type" "ssemul")
20921    (set_attr "mode" "V4SF")])
20922
20923 (define_insn "vmmulv4sf3"
20924   [(set (match_operand:V4SF 0 "register_operand" "=x")
20925         (vec_merge:V4SF
20926          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20927                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20928          (match_dup 1)
20929          (const_int 1)))]
20930   "TARGET_SSE"
20931   "mulss\t{%2, %0|%0, %2}"
20932   [(set_attr "type" "ssemul")
20933    (set_attr "mode" "SF")])
20934
20935 (define_insn "divv4sf3"
20936   [(set (match_operand:V4SF 0 "register_operand" "=x")
20937         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20938                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20939   "TARGET_SSE"
20940   "divps\t{%2, %0|%0, %2}"
20941   [(set_attr "type" "ssediv")
20942    (set_attr "mode" "V4SF")])
20943
20944 (define_insn "vmdivv4sf3"
20945   [(set (match_operand:V4SF 0 "register_operand" "=x")
20946         (vec_merge:V4SF
20947          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20948                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20949          (match_dup 1)
20950          (const_int 1)))]
20951   "TARGET_SSE"
20952   "divss\t{%2, %0|%0, %2}"
20953   [(set_attr "type" "ssediv")
20954    (set_attr "mode" "SF")])
20955
20956
20957 ;; SSE square root/reciprocal
20958
20959 (define_insn "rcpv4sf2"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (unspec:V4SF
20962          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20963   "TARGET_SSE"
20964   "rcpps\t{%1, %0|%0, %1}"
20965   [(set_attr "type" "sse")
20966    (set_attr "mode" "V4SF")])
20967
20968 (define_insn "vmrcpv4sf2"
20969   [(set (match_operand:V4SF 0 "register_operand" "=x")
20970         (vec_merge:V4SF
20971          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20972                       UNSPEC_RCP)
20973          (match_operand:V4SF 2 "register_operand" "0")
20974          (const_int 1)))]
20975   "TARGET_SSE"
20976   "rcpss\t{%1, %0|%0, %1}"
20977   [(set_attr "type" "sse")
20978    (set_attr "mode" "SF")])
20979
20980 (define_insn "rsqrtv4sf2"
20981   [(set (match_operand:V4SF 0 "register_operand" "=x")
20982         (unspec:V4SF
20983          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20984   "TARGET_SSE"
20985   "rsqrtps\t{%1, %0|%0, %1}"
20986   [(set_attr "type" "sse")
20987    (set_attr "mode" "V4SF")])
20988
20989 (define_insn "vmrsqrtv4sf2"
20990   [(set (match_operand:V4SF 0 "register_operand" "=x")
20991         (vec_merge:V4SF
20992          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20993                       UNSPEC_RSQRT)
20994          (match_operand:V4SF 2 "register_operand" "0")
20995          (const_int 1)))]
20996   "TARGET_SSE"
20997   "rsqrtss\t{%1, %0|%0, %1}"
20998   [(set_attr "type" "sse")
20999    (set_attr "mode" "SF")])
21000
21001 (define_insn "sqrtv4sf2"
21002   [(set (match_operand:V4SF 0 "register_operand" "=x")
21003         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21004   "TARGET_SSE"
21005   "sqrtps\t{%1, %0|%0, %1}"
21006   [(set_attr "type" "sse")
21007    (set_attr "mode" "V4SF")])
21008
21009 (define_insn "vmsqrtv4sf2"
21010   [(set (match_operand:V4SF 0 "register_operand" "=x")
21011         (vec_merge:V4SF
21012          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21013          (match_operand:V4SF 2 "register_operand" "0")
21014          (const_int 1)))]
21015   "TARGET_SSE"
21016   "sqrtss\t{%1, %0|%0, %1}"
21017   [(set_attr "type" "sse")
21018    (set_attr "mode" "SF")])
21019
21020 ;; SSE logical operations.
21021
21022 ;; SSE defines logical operations on floating point values.  This brings
21023 ;; interesting challenge to RTL representation where logicals are only valid
21024 ;; on integral types.  We deal with this by representing the floating point
21025 ;; logical as logical on arguments casted to TImode as this is what hardware
21026 ;; really does.  Unfortunately hardware requires the type information to be
21027 ;; present and thus we must avoid subregs from being simplified and eliminated
21028 ;; in later compilation phases.
21029 ;;
21030 ;; We have following variants from each instruction:
21031 ;; sse_andsf3 - the operation taking V4SF vector operands
21032 ;;              and doing TImode cast on them
21033 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21034 ;;                      TImode, since backend insist on eliminating casts
21035 ;;                      on memory operands
21036 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21037 ;;                   We cannot accept memory operand here as instruction reads
21038 ;;                   whole scalar.  This is generated only post reload by GCC
21039 ;;                   scalar float operations that expands to logicals (fabs)
21040 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21041 ;;                   memory operand.  Eventually combine can be able
21042 ;;                   to synthesize these using splitter.
21043 ;; sse2_anddf3, *sse2_anddf3_memory
21044 ;;              
21045 ;; 
21046 ;; These are not called andti3 etc. because we really really don't want
21047 ;; the compiler to widen DImode ands to TImode ands and then try to move
21048 ;; into DImode subregs of SSE registers, and them together, and move out
21049 ;; of DImode subregs again!
21050 ;; SSE1 single precision floating point logical operation
21051 (define_expand "sse_andv4sf3"
21052   [(set (match_operand:V4SF 0 "register_operand" "")
21053         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21054                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21055   "TARGET_SSE"
21056   "")
21057
21058 (define_insn "*sse_andv4sf3"
21059   [(set (match_operand:V4SF 0 "register_operand" "=x")
21060         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21061                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21062   "TARGET_SSE
21063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21064   "andps\t{%2, %0|%0, %2}"
21065   [(set_attr "type" "sselog")
21066    (set_attr "mode" "V4SF")])
21067
21068 (define_expand "sse_nandv4sf3"
21069   [(set (match_operand:V4SF 0 "register_operand" "")
21070         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21071                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21072   "TARGET_SSE"
21073   "")
21074
21075 (define_insn "*sse_nandv4sf3"
21076   [(set (match_operand:V4SF 0 "register_operand" "=x")
21077         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21078                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21079   "TARGET_SSE"
21080   "andnps\t{%2, %0|%0, %2}"
21081   [(set_attr "type" "sselog")
21082    (set_attr "mode" "V4SF")])
21083
21084 (define_expand "sse_iorv4sf3"
21085   [(set (match_operand:V4SF 0 "register_operand" "")
21086         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21087                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21088   "TARGET_SSE"
21089   "")
21090
21091 (define_insn "*sse_iorv4sf3"
21092   [(set (match_operand:V4SF 0 "register_operand" "=x")
21093         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21094                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21095   "TARGET_SSE
21096    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21097   "orps\t{%2, %0|%0, %2}"
21098   [(set_attr "type" "sselog")
21099    (set_attr "mode" "V4SF")])
21100
21101 (define_expand "sse_xorv4sf3"
21102   [(set (match_operand:V4SF 0 "register_operand" "")
21103         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21104                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21105   "TARGET_SSE"
21106   "")
21107
21108 (define_insn "*sse_xorv4sf3"
21109   [(set (match_operand:V4SF 0 "register_operand" "=x")
21110         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21111                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21112   "TARGET_SSE
21113    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21114   "xorps\t{%2, %0|%0, %2}"
21115   [(set_attr "type" "sselog")
21116    (set_attr "mode" "V4SF")])
21117
21118 ;; SSE2 double precision floating point logical operation
21119
21120 (define_expand "sse2_andv2df3"
21121   [(set (match_operand:V2DF 0 "register_operand" "")
21122         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21123                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21124   "TARGET_SSE2"
21125   "")
21126
21127 (define_insn "*sse2_andv2df3"
21128   [(set (match_operand:V2DF 0 "register_operand" "=x")
21129         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21130                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21131   "TARGET_SSE2
21132    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21133   "andpd\t{%2, %0|%0, %2}"
21134   [(set_attr "type" "sselog")
21135    (set_attr "mode" "V2DF")])
21136
21137 (define_expand "sse2_nandv2df3"
21138   [(set (match_operand:V2DF 0 "register_operand" "")
21139         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21140                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21141   "TARGET_SSE2"
21142   "")
21143
21144 (define_insn "*sse2_nandv2df3"
21145   [(set (match_operand:V2DF 0 "register_operand" "=x")
21146         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21147                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21148   "TARGET_SSE2"
21149   "andnpd\t{%2, %0|%0, %2}"
21150   [(set_attr "type" "sselog")
21151    (set_attr "mode" "V2DF")])
21152
21153 (define_expand "sse2_iorv2df3"
21154   [(set (match_operand:V2DF 0 "register_operand" "")
21155         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21156                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21157   "TARGET_SSE2"
21158   "")
21159
21160 (define_insn "*sse2_iorv2df3"
21161   [(set (match_operand:V2DF 0 "register_operand" "=x")
21162         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21163                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21164   "TARGET_SSE2
21165    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21166   "orpd\t{%2, %0|%0, %2}"
21167   [(set_attr "type" "sselog")
21168    (set_attr "mode" "V2DF")])
21169
21170 (define_expand "sse2_xorv2df3"
21171   [(set (match_operand:V2DF 0 "register_operand" "")
21172         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21173                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21174   "TARGET_SSE2"
21175   "")
21176
21177 (define_insn "*sse2_xorv2df3"
21178   [(set (match_operand:V2DF 0 "register_operand" "=x")
21179         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21180                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21181   "TARGET_SSE2
21182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21183   "xorpd\t{%2, %0|%0, %2}"
21184   [(set_attr "type" "sselog")
21185    (set_attr "mode" "V2DF")])
21186
21187 ;; SSE2 integral logicals.  These patterns must always come after floating
21188 ;; point ones since we don't want compiler to use integer opcodes on floating
21189 ;; point SSE values to avoid matching of subregs in the match_operand.
21190 (define_insn "*sse2_andti3"
21191   [(set (match_operand:TI 0 "register_operand" "=x")
21192         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21193                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21194   "TARGET_SSE2
21195    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21196   "pand\t{%2, %0|%0, %2}"
21197   [(set_attr "type" "sselog")
21198    (set_attr "mode" "TI")])
21199
21200 (define_insn "sse2_andv2di3"
21201   [(set (match_operand:V2DI 0 "register_operand" "=x")
21202         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21203                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21204   "TARGET_SSE2
21205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21206   "pand\t{%2, %0|%0, %2}"
21207   [(set_attr "type" "sselog")
21208    (set_attr "mode" "TI")])
21209
21210 (define_insn "*sse2_nandti3"
21211   [(set (match_operand:TI 0 "register_operand" "=x")
21212         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21213                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21214   "TARGET_SSE2"
21215   "pandn\t{%2, %0|%0, %2}"
21216   [(set_attr "type" "sselog")
21217    (set_attr "mode" "TI")])
21218
21219 (define_insn "sse2_nandv2di3"
21220   [(set (match_operand:V2DI 0 "register_operand" "=x")
21221         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21222                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21223   "TARGET_SSE2
21224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21225   "pandn\t{%2, %0|%0, %2}"
21226   [(set_attr "type" "sselog")
21227    (set_attr "mode" "TI")])
21228
21229 (define_insn "*sse2_iorti3"
21230   [(set (match_operand:TI 0 "register_operand" "=x")
21231         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21232                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21233   "TARGET_SSE2
21234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21235   "por\t{%2, %0|%0, %2}"
21236   [(set_attr "type" "sselog")
21237    (set_attr "mode" "TI")])
21238
21239 (define_insn "sse2_iorv2di3"
21240   [(set (match_operand:V2DI 0 "register_operand" "=x")
21241         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21242                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21243   "TARGET_SSE2
21244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21245   "por\t{%2, %0|%0, %2}"
21246   [(set_attr "type" "sselog")
21247    (set_attr "mode" "TI")])
21248
21249 (define_insn "*sse2_xorti3"
21250   [(set (match_operand:TI 0 "register_operand" "=x")
21251         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21252                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21253   "TARGET_SSE2
21254    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21255   "pxor\t{%2, %0|%0, %2}"
21256   [(set_attr "type" "sselog")
21257    (set_attr "mode" "TI")])
21258
21259 (define_insn "sse2_xorv2di3"
21260   [(set (match_operand:V2DI 0 "register_operand" "=x")
21261         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21262                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21263   "TARGET_SSE2
21264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21265   "pxor\t{%2, %0|%0, %2}"
21266   [(set_attr "type" "sselog")
21267    (set_attr "mode" "TI")])
21268
21269 ;; Use xor, but don't show input operands so they aren't live before
21270 ;; this insn.
21271 (define_insn "sse_clrv4sf"
21272   [(set (match_operand:V4SF 0 "register_operand" "=x")
21273         (match_operand:V4SF 1 "const0_operand" "X"))]
21274   "TARGET_SSE"
21275 {
21276   if (get_attr_mode (insn) == MODE_TI)
21277     return "pxor\t{%0, %0|%0, %0}";
21278   else
21279     return "xorps\t{%0, %0|%0, %0}";
21280 }
21281   [(set_attr "type" "sselog")
21282    (set_attr "memory" "none")
21283    (set (attr "mode")
21284         (if_then_else
21285            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21286                          (const_int 0))
21287                      (ne (symbol_ref "TARGET_SSE2")
21288                          (const_int 0)))
21289                 (eq (symbol_ref "optimize_size")
21290                     (const_int 0)))
21291          (const_string "TI")
21292          (const_string "V4SF")))])
21293
21294 ;; Use xor, but don't show input operands so they aren't live before
21295 ;; this insn.
21296 (define_insn "sse_clrv2df"
21297   [(set (match_operand:V2DF 0 "register_operand" "=x")
21298         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21299   "TARGET_SSE2"
21300   "xorpd\t{%0, %0|%0, %0}"
21301   [(set_attr "type" "sselog")
21302    (set_attr "memory" "none")
21303    (set_attr "mode" "V4SF")])
21304
21305 ;; SSE mask-generating compares
21306
21307 (define_insn "maskcmpv4sf3"
21308   [(set (match_operand:V4SI 0 "register_operand" "=x")
21309         (match_operator:V4SI 3 "sse_comparison_operator"
21310                 [(match_operand:V4SF 1 "register_operand" "0")
21311                  (match_operand:V4SF 2 "register_operand" "x")]))]
21312   "TARGET_SSE"
21313   "cmp%D3ps\t{%2, %0|%0, %2}"
21314   [(set_attr "type" "ssecmp")
21315    (set_attr "mode" "V4SF")])
21316
21317 (define_insn "maskncmpv4sf3"
21318   [(set (match_operand:V4SI 0 "register_operand" "=x")
21319         (not:V4SI
21320          (match_operator:V4SI 3 "sse_comparison_operator"
21321                 [(match_operand:V4SF 1 "register_operand" "0")
21322                  (match_operand:V4SF 2 "register_operand" "x")])))]
21323   "TARGET_SSE"
21324 {
21325   if (GET_CODE (operands[3]) == UNORDERED)
21326     return "cmpordps\t{%2, %0|%0, %2}";
21327   else
21328     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21329 }
21330   [(set_attr "type" "ssecmp")
21331    (set_attr "mode" "V4SF")])
21332
21333 (define_insn "vmmaskcmpv4sf3"
21334   [(set (match_operand:V4SI 0 "register_operand" "=x")
21335         (vec_merge:V4SI
21336          (match_operator:V4SI 3 "sse_comparison_operator"
21337                 [(match_operand:V4SF 1 "register_operand" "0")
21338                  (match_operand:V4SF 2 "register_operand" "x")])
21339          (subreg:V4SI (match_dup 1) 0)
21340          (const_int 1)))]
21341   "TARGET_SSE"
21342   "cmp%D3ss\t{%2, %0|%0, %2}"
21343   [(set_attr "type" "ssecmp")
21344    (set_attr "mode" "SF")])
21345
21346 (define_insn "vmmaskncmpv4sf3"
21347   [(set (match_operand:V4SI 0 "register_operand" "=x")
21348         (vec_merge:V4SI
21349          (not:V4SI
21350           (match_operator:V4SI 3 "sse_comparison_operator"
21351                 [(match_operand:V4SF 1 "register_operand" "0")
21352                  (match_operand:V4SF 2 "register_operand" "x")]))
21353          (subreg:V4SI (match_dup 1) 0)
21354          (const_int 1)))]
21355   "TARGET_SSE"
21356 {
21357   if (GET_CODE (operands[3]) == UNORDERED)
21358     return "cmpordss\t{%2, %0|%0, %2}";
21359   else
21360     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21361 }
21362   [(set_attr "type" "ssecmp")
21363    (set_attr "mode" "SF")])
21364
21365 (define_insn "sse_comi"
21366   [(set (reg:CCFP FLAGS_REG)
21367         (compare:CCFP (vec_select:SF
21368                        (match_operand:V4SF 0 "register_operand" "x")
21369                        (parallel [(const_int 0)]))
21370                       (vec_select:SF
21371                        (match_operand:V4SF 1 "register_operand" "x")
21372                        (parallel [(const_int 0)]))))]
21373   "TARGET_SSE"
21374   "comiss\t{%1, %0|%0, %1}"
21375   [(set_attr "type" "ssecomi")
21376    (set_attr "mode" "SF")])
21377
21378 (define_insn "sse_ucomi"
21379   [(set (reg:CCFPU FLAGS_REG)
21380         (compare:CCFPU (vec_select:SF
21381                         (match_operand:V4SF 0 "register_operand" "x")
21382                         (parallel [(const_int 0)]))
21383                        (vec_select:SF
21384                         (match_operand:V4SF 1 "register_operand" "x")
21385                         (parallel [(const_int 0)]))))]
21386   "TARGET_SSE"
21387   "ucomiss\t{%1, %0|%0, %1}"
21388   [(set_attr "type" "ssecomi")
21389    (set_attr "mode" "SF")])
21390
21391
21392 ;; SSE unpack
21393
21394 (define_insn "sse_unpckhps"
21395   [(set (match_operand:V4SF 0 "register_operand" "=x")
21396         (vec_merge:V4SF
21397          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21398                           (parallel [(const_int 2)
21399                                      (const_int 0)
21400                                      (const_int 3)
21401                                      (const_int 1)]))
21402          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21403                           (parallel [(const_int 0)
21404                                      (const_int 2)
21405                                      (const_int 1)
21406                                      (const_int 3)]))
21407          (const_int 5)))]
21408   "TARGET_SSE"
21409   "unpckhps\t{%2, %0|%0, %2}"
21410   [(set_attr "type" "ssecvt")
21411    (set_attr "mode" "V4SF")])
21412
21413 (define_insn "sse_unpcklps"
21414   [(set (match_operand:V4SF 0 "register_operand" "=x")
21415         (vec_merge:V4SF
21416          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21417                           (parallel [(const_int 0)
21418                                      (const_int 2)
21419                                      (const_int 1)
21420                                      (const_int 3)]))
21421          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21422                           (parallel [(const_int 2)
21423                                      (const_int 0)
21424                                      (const_int 3)
21425                                      (const_int 1)]))
21426          (const_int 5)))]
21427   "TARGET_SSE"
21428   "unpcklps\t{%2, %0|%0, %2}"
21429   [(set_attr "type" "ssecvt")
21430    (set_attr "mode" "V4SF")])
21431
21432
21433 ;; SSE min/max
21434
21435 (define_insn "smaxv4sf3"
21436   [(set (match_operand:V4SF 0 "register_operand" "=x")
21437         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21438                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21439   "TARGET_SSE"
21440   "maxps\t{%2, %0|%0, %2}"
21441   [(set_attr "type" "sse")
21442    (set_attr "mode" "V4SF")])
21443
21444 (define_insn "vmsmaxv4sf3"
21445   [(set (match_operand:V4SF 0 "register_operand" "=x")
21446         (vec_merge:V4SF
21447          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21448                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21449          (match_dup 1)
21450          (const_int 1)))]
21451   "TARGET_SSE"
21452   "maxss\t{%2, %0|%0, %2}"
21453   [(set_attr "type" "sse")
21454    (set_attr "mode" "SF")])
21455
21456 (define_insn "sminv4sf3"
21457   [(set (match_operand:V4SF 0 "register_operand" "=x")
21458         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21459                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21460   "TARGET_SSE"
21461   "minps\t{%2, %0|%0, %2}"
21462   [(set_attr "type" "sse")
21463    (set_attr "mode" "V4SF")])
21464
21465 (define_insn "vmsminv4sf3"
21466   [(set (match_operand:V4SF 0 "register_operand" "=x")
21467         (vec_merge:V4SF
21468          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21469                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21470          (match_dup 1)
21471          (const_int 1)))]
21472   "TARGET_SSE"
21473   "minss\t{%2, %0|%0, %2}"
21474   [(set_attr "type" "sse")
21475    (set_attr "mode" "SF")])
21476
21477 ;; SSE <-> integer/MMX conversions
21478
21479 (define_insn "cvtpi2ps"
21480   [(set (match_operand:V4SF 0 "register_operand" "=x")
21481         (vec_merge:V4SF
21482          (match_operand:V4SF 1 "register_operand" "0")
21483          (vec_duplicate:V4SF
21484           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21485          (const_int 12)))]
21486   "TARGET_SSE"
21487   "cvtpi2ps\t{%2, %0|%0, %2}"
21488   [(set_attr "type" "ssecvt")
21489    (set_attr "mode" "V4SF")])
21490
21491 (define_insn "cvtps2pi"
21492   [(set (match_operand:V2SI 0 "register_operand" "=y")
21493         (vec_select:V2SI
21494          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21495          (parallel [(const_int 0) (const_int 1)])))]
21496   "TARGET_SSE"
21497   "cvtps2pi\t{%1, %0|%0, %1}"
21498   [(set_attr "type" "ssecvt")
21499    (set_attr "mode" "V4SF")])
21500
21501 (define_insn "cvttps2pi"
21502   [(set (match_operand:V2SI 0 "register_operand" "=y")
21503         (vec_select:V2SI
21504          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21505                       UNSPEC_FIX)
21506          (parallel [(const_int 0) (const_int 1)])))]
21507   "TARGET_SSE"
21508   "cvttps2pi\t{%1, %0|%0, %1}"
21509   [(set_attr "type" "ssecvt")
21510    (set_attr "mode" "SF")])
21511
21512 (define_insn "cvtsi2ss"
21513   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21514         (vec_merge:V4SF
21515          (match_operand:V4SF 1 "register_operand" "0,0")
21516          (vec_duplicate:V4SF
21517           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21518          (const_int 14)))]
21519   "TARGET_SSE"
21520   "cvtsi2ss\t{%2, %0|%0, %2}"
21521   [(set_attr "type" "sseicvt")
21522    (set_attr "athlon_decode" "vector,double")
21523    (set_attr "mode" "SF")])
21524
21525 (define_insn "cvtsi2ssq"
21526   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21527         (vec_merge:V4SF
21528          (match_operand:V4SF 1 "register_operand" "0,0")
21529          (vec_duplicate:V4SF
21530           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21531          (const_int 14)))]
21532   "TARGET_SSE && TARGET_64BIT"
21533   "cvtsi2ssq\t{%2, %0|%0, %2}"
21534   [(set_attr "type" "sseicvt")
21535    (set_attr "athlon_decode" "vector,double")
21536    (set_attr "mode" "SF")])
21537
21538 (define_insn "cvtss2si"
21539   [(set (match_operand:SI 0 "register_operand" "=r,r")
21540         (vec_select:SI
21541          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21542          (parallel [(const_int 0)])))]
21543   "TARGET_SSE"
21544   "cvtss2si\t{%1, %0|%0, %1}"
21545   [(set_attr "type" "sseicvt")
21546    (set_attr "athlon_decode" "double,vector")
21547    (set_attr "mode" "SI")])
21548
21549 (define_insn "cvtss2siq"
21550   [(set (match_operand:DI 0 "register_operand" "=r,r")
21551         (vec_select:DI
21552          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21553          (parallel [(const_int 0)])))]
21554   "TARGET_SSE"
21555   "cvtss2siq\t{%1, %0|%0, %1}"
21556   [(set_attr "type" "sseicvt")
21557    (set_attr "athlon_decode" "double,vector")
21558    (set_attr "mode" "DI")])
21559
21560 (define_insn "cvttss2si"
21561   [(set (match_operand:SI 0 "register_operand" "=r,r")
21562         (vec_select:SI
21563          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21564                       UNSPEC_FIX)
21565          (parallel [(const_int 0)])))]
21566   "TARGET_SSE"
21567   "cvttss2si\t{%1, %0|%0, %1}"
21568   [(set_attr "type" "sseicvt")
21569    (set_attr "mode" "SF")
21570    (set_attr "athlon_decode" "double,vector")])
21571
21572 (define_insn "cvttss2siq"
21573   [(set (match_operand:DI 0 "register_operand" "=r,r")
21574         (vec_select:DI
21575          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21576                       UNSPEC_FIX)
21577          (parallel [(const_int 0)])))]
21578   "TARGET_SSE && TARGET_64BIT"
21579   "cvttss2siq\t{%1, %0|%0, %1}"
21580   [(set_attr "type" "sseicvt")
21581    (set_attr "mode" "SF")
21582    (set_attr "athlon_decode" "double,vector")])
21583
21584
21585 ;; MMX insns
21586
21587 ;; MMX arithmetic
21588
21589 (define_insn "addv8qi3"
21590   [(set (match_operand:V8QI 0 "register_operand" "=y")
21591         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21592                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21593   "TARGET_MMX"
21594   "paddb\t{%2, %0|%0, %2}"
21595   [(set_attr "type" "mmxadd")
21596    (set_attr "mode" "DI")])
21597
21598 (define_insn "addv4hi3"
21599   [(set (match_operand:V4HI 0 "register_operand" "=y")
21600         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21601                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21602   "TARGET_MMX"
21603   "paddw\t{%2, %0|%0, %2}"
21604   [(set_attr "type" "mmxadd")
21605    (set_attr "mode" "DI")])
21606
21607 (define_insn "addv2si3"
21608   [(set (match_operand:V2SI 0 "register_operand" "=y")
21609         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21610                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21611   "TARGET_MMX"
21612   "paddd\t{%2, %0|%0, %2}"
21613   [(set_attr "type" "mmxadd")
21614    (set_attr "mode" "DI")])
21615
21616 (define_insn "mmx_adddi3"
21617   [(set (match_operand:DI 0 "register_operand" "=y")
21618         (unspec:DI
21619          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21620                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21621          UNSPEC_NOP))]
21622   "TARGET_MMX"
21623   "paddq\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxadd")
21625    (set_attr "mode" "DI")])
21626
21627 (define_insn "ssaddv8qi3"
21628   [(set (match_operand:V8QI 0 "register_operand" "=y")
21629         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21630                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21631   "TARGET_MMX"
21632   "paddsb\t{%2, %0|%0, %2}"
21633   [(set_attr "type" "mmxadd")
21634    (set_attr "mode" "DI")])
21635
21636 (define_insn "ssaddv4hi3"
21637   [(set (match_operand:V4HI 0 "register_operand" "=y")
21638         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21639                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21640   "TARGET_MMX"
21641   "paddsw\t{%2, %0|%0, %2}"
21642   [(set_attr "type" "mmxadd")
21643    (set_attr "mode" "DI")])
21644
21645 (define_insn "usaddv8qi3"
21646   [(set (match_operand:V8QI 0 "register_operand" "=y")
21647         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21648                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21649   "TARGET_MMX"
21650   "paddusb\t{%2, %0|%0, %2}"
21651   [(set_attr "type" "mmxadd")
21652    (set_attr "mode" "DI")])
21653
21654 (define_insn "usaddv4hi3"
21655   [(set (match_operand:V4HI 0 "register_operand" "=y")
21656         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21657                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21658   "TARGET_MMX"
21659   "paddusw\t{%2, %0|%0, %2}"
21660   [(set_attr "type" "mmxadd")
21661    (set_attr "mode" "DI")])
21662
21663 (define_insn "subv8qi3"
21664   [(set (match_operand:V8QI 0 "register_operand" "=y")
21665         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21666                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21667   "TARGET_MMX"
21668   "psubb\t{%2, %0|%0, %2}"
21669   [(set_attr "type" "mmxadd")
21670    (set_attr "mode" "DI")])
21671
21672 (define_insn "subv4hi3"
21673   [(set (match_operand:V4HI 0 "register_operand" "=y")
21674         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21675                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21676   "TARGET_MMX"
21677   "psubw\t{%2, %0|%0, %2}"
21678   [(set_attr "type" "mmxadd")
21679    (set_attr "mode" "DI")])
21680
21681 (define_insn "subv2si3"
21682   [(set (match_operand:V2SI 0 "register_operand" "=y")
21683         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21684                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21685   "TARGET_MMX"
21686   "psubd\t{%2, %0|%0, %2}"
21687   [(set_attr "type" "mmxadd")
21688    (set_attr "mode" "DI")])
21689
21690 (define_insn "mmx_subdi3"
21691   [(set (match_operand:DI 0 "register_operand" "=y")
21692         (unspec:DI
21693          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21694                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21695          UNSPEC_NOP))]
21696   "TARGET_MMX"
21697   "psubq\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxadd")
21699    (set_attr "mode" "DI")])
21700
21701 (define_insn "sssubv8qi3"
21702   [(set (match_operand:V8QI 0 "register_operand" "=y")
21703         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21704                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21705   "TARGET_MMX"
21706   "psubsb\t{%2, %0|%0, %2}"
21707   [(set_attr "type" "mmxadd")
21708    (set_attr "mode" "DI")])
21709
21710 (define_insn "sssubv4hi3"
21711   [(set (match_operand:V4HI 0 "register_operand" "=y")
21712         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21713                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21714   "TARGET_MMX"
21715   "psubsw\t{%2, %0|%0, %2}"
21716   [(set_attr "type" "mmxadd")
21717    (set_attr "mode" "DI")])
21718
21719 (define_insn "ussubv8qi3"
21720   [(set (match_operand:V8QI 0 "register_operand" "=y")
21721         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21722                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21723   "TARGET_MMX"
21724   "psubusb\t{%2, %0|%0, %2}"
21725   [(set_attr "type" "mmxadd")
21726    (set_attr "mode" "DI")])
21727
21728 (define_insn "ussubv4hi3"
21729   [(set (match_operand:V4HI 0 "register_operand" "=y")
21730         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21731                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21732   "TARGET_MMX"
21733   "psubusw\t{%2, %0|%0, %2}"
21734   [(set_attr "type" "mmxadd")
21735    (set_attr "mode" "DI")])
21736
21737 (define_insn "mulv4hi3"
21738   [(set (match_operand:V4HI 0 "register_operand" "=y")
21739         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21740                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21741   "TARGET_MMX"
21742   "pmullw\t{%2, %0|%0, %2}"
21743   [(set_attr "type" "mmxmul")
21744    (set_attr "mode" "DI")])
21745
21746 (define_insn "smulv4hi3_highpart"
21747   [(set (match_operand:V4HI 0 "register_operand" "=y")
21748         (truncate:V4HI
21749          (lshiftrt:V4SI
21750           (mult:V4SI (sign_extend:V4SI
21751                       (match_operand:V4HI 1 "register_operand" "0"))
21752                      (sign_extend:V4SI
21753                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21754           (const_int 16))))]
21755   "TARGET_MMX"
21756   "pmulhw\t{%2, %0|%0, %2}"
21757   [(set_attr "type" "mmxmul")
21758    (set_attr "mode" "DI")])
21759
21760 (define_insn "umulv4hi3_highpart"
21761   [(set (match_operand:V4HI 0 "register_operand" "=y")
21762         (truncate:V4HI
21763          (lshiftrt:V4SI
21764           (mult:V4SI (zero_extend:V4SI
21765                       (match_operand:V4HI 1 "register_operand" "0"))
21766                      (zero_extend:V4SI
21767                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21768           (const_int 16))))]
21769   "TARGET_SSE || TARGET_3DNOW_A"
21770   "pmulhuw\t{%2, %0|%0, %2}"
21771   [(set_attr "type" "mmxmul")
21772    (set_attr "mode" "DI")])
21773
21774 (define_insn "mmx_pmaddwd"
21775   [(set (match_operand:V2SI 0 "register_operand" "=y")
21776         (plus:V2SI
21777          (mult:V2SI
21778           (sign_extend:V2SI
21779            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21780                             (parallel [(const_int 0) (const_int 2)])))
21781           (sign_extend:V2SI
21782            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21783                             (parallel [(const_int 0) (const_int 2)]))))
21784          (mult:V2SI
21785           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21786                                              (parallel [(const_int 1)
21787                                                         (const_int 3)])))
21788           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21789                                              (parallel [(const_int 1)
21790                                                         (const_int 3)]))))))]
21791   "TARGET_MMX"
21792   "pmaddwd\t{%2, %0|%0, %2}"
21793   [(set_attr "type" "mmxmul")
21794    (set_attr "mode" "DI")])
21795
21796
21797 ;; MMX logical operations
21798 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21799 ;; normal code that also wants to use the FPU from getting broken.
21800 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21801 (define_insn "mmx_iordi3"
21802   [(set (match_operand:DI 0 "register_operand" "=y")
21803         (unspec:DI
21804          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21805                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21806          UNSPEC_NOP))]
21807   "TARGET_MMX"
21808   "por\t{%2, %0|%0, %2}"
21809   [(set_attr "type" "mmxadd")
21810    (set_attr "mode" "DI")])
21811
21812 (define_insn "mmx_xordi3"
21813   [(set (match_operand:DI 0 "register_operand" "=y")
21814         (unspec:DI
21815          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21816                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21817          UNSPEC_NOP))]
21818   "TARGET_MMX"
21819   "pxor\t{%2, %0|%0, %2}"
21820   [(set_attr "type" "mmxadd")
21821    (set_attr "mode" "DI")
21822    (set_attr "memory" "none")])
21823
21824 ;; Same as pxor, but don't show input operands so that we don't think
21825 ;; they are live.
21826 (define_insn "mmx_clrdi"
21827   [(set (match_operand:DI 0 "register_operand" "=y")
21828         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21829   "TARGET_MMX"
21830   "pxor\t{%0, %0|%0, %0}"
21831   [(set_attr "type" "mmxadd")
21832    (set_attr "mode" "DI")
21833    (set_attr "memory" "none")])
21834
21835 (define_insn "mmx_anddi3"
21836   [(set (match_operand:DI 0 "register_operand" "=y")
21837         (unspec:DI
21838          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21839                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21840          UNSPEC_NOP))]
21841   "TARGET_MMX"
21842   "pand\t{%2, %0|%0, %2}"
21843   [(set_attr "type" "mmxadd")
21844    (set_attr "mode" "DI")])
21845
21846 (define_insn "mmx_nanddi3"
21847   [(set (match_operand:DI 0 "register_operand" "=y")
21848         (unspec:DI
21849          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21850                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21851          UNSPEC_NOP))]
21852   "TARGET_MMX"
21853   "pandn\t{%2, %0|%0, %2}"
21854   [(set_attr "type" "mmxadd")
21855    (set_attr "mode" "DI")])
21856
21857
21858 ;; MMX unsigned averages/sum of absolute differences
21859
21860 (define_insn "mmx_uavgv8qi3"
21861   [(set (match_operand:V8QI 0 "register_operand" "=y")
21862         (ashiftrt:V8QI
21863          (plus:V8QI (plus:V8QI
21864                      (match_operand:V8QI 1 "register_operand" "0")
21865                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21866                     (const_vector:V8QI [(const_int 1)
21867                                         (const_int 1)
21868                                         (const_int 1)
21869                                         (const_int 1)
21870                                         (const_int 1)
21871                                         (const_int 1)
21872                                         (const_int 1)
21873                                         (const_int 1)]))
21874          (const_int 1)))]
21875   "TARGET_SSE || TARGET_3DNOW_A"
21876   "pavgb\t{%2, %0|%0, %2}"
21877   [(set_attr "type" "mmxshft")
21878    (set_attr "mode" "DI")])
21879
21880 (define_insn "mmx_uavgv4hi3"
21881   [(set (match_operand:V4HI 0 "register_operand" "=y")
21882         (ashiftrt:V4HI
21883          (plus:V4HI (plus:V4HI
21884                      (match_operand:V4HI 1 "register_operand" "0")
21885                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21886                     (const_vector:V4HI [(const_int 1)
21887                                         (const_int 1)
21888                                         (const_int 1)
21889                                         (const_int 1)]))
21890          (const_int 1)))]
21891   "TARGET_SSE || TARGET_3DNOW_A"
21892   "pavgw\t{%2, %0|%0, %2}"
21893   [(set_attr "type" "mmxshft")
21894    (set_attr "mode" "DI")])
21895
21896 (define_insn "mmx_psadbw"
21897   [(set (match_operand:DI 0 "register_operand" "=y")
21898         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21899                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21900                    UNSPEC_PSADBW))]
21901   "TARGET_SSE || TARGET_3DNOW_A"
21902   "psadbw\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "mmxshft")
21904    (set_attr "mode" "DI")])
21905
21906
21907 ;; MMX insert/extract/shuffle
21908
21909 (define_insn "mmx_pinsrw"
21910   [(set (match_operand:V4HI 0 "register_operand" "=y")
21911         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21912                         (vec_duplicate:V4HI
21913                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21914                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21915   "TARGET_SSE || TARGET_3DNOW_A"
21916   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21917   [(set_attr "type" "mmxcvt")
21918    (set_attr "mode" "DI")])
21919
21920 (define_insn "mmx_pextrw"
21921   [(set (match_operand:SI 0 "register_operand" "=r")
21922         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21923                                        (parallel
21924                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21925   "TARGET_SSE || TARGET_3DNOW_A"
21926   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21927   [(set_attr "type" "mmxcvt")
21928    (set_attr "mode" "DI")])
21929
21930 (define_insn "mmx_pshufw"
21931   [(set (match_operand:V4HI 0 "register_operand" "=y")
21932         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21933                       (match_operand:SI 2 "immediate_operand" "i")]
21934                      UNSPEC_SHUFFLE))]
21935   "TARGET_SSE || TARGET_3DNOW_A"
21936   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21937   [(set_attr "type" "mmxcvt")
21938    (set_attr "mode" "DI")])
21939
21940
21941 ;; MMX mask-generating comparisons
21942
21943 (define_insn "eqv8qi3"
21944   [(set (match_operand:V8QI 0 "register_operand" "=y")
21945         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21946                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21947   "TARGET_MMX"
21948   "pcmpeqb\t{%2, %0|%0, %2}"
21949   [(set_attr "type" "mmxcmp")
21950    (set_attr "mode" "DI")])
21951
21952 (define_insn "eqv4hi3"
21953   [(set (match_operand:V4HI 0 "register_operand" "=y")
21954         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21955                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21956   "TARGET_MMX"
21957   "pcmpeqw\t{%2, %0|%0, %2}"
21958   [(set_attr "type" "mmxcmp")
21959    (set_attr "mode" "DI")])
21960
21961 (define_insn "eqv2si3"
21962   [(set (match_operand:V2SI 0 "register_operand" "=y")
21963         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21964                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21965   "TARGET_MMX"
21966   "pcmpeqd\t{%2, %0|%0, %2}"
21967   [(set_attr "type" "mmxcmp")
21968    (set_attr "mode" "DI")])
21969
21970 (define_insn "gtv8qi3"
21971   [(set (match_operand:V8QI 0 "register_operand" "=y")
21972         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21973                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21974   "TARGET_MMX"
21975   "pcmpgtb\t{%2, %0|%0, %2}"
21976   [(set_attr "type" "mmxcmp")
21977    (set_attr "mode" "DI")])
21978
21979 (define_insn "gtv4hi3"
21980   [(set (match_operand:V4HI 0 "register_operand" "=y")
21981         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21982                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21983   "TARGET_MMX"
21984   "pcmpgtw\t{%2, %0|%0, %2}"
21985   [(set_attr "type" "mmxcmp")
21986    (set_attr "mode" "DI")])
21987
21988 (define_insn "gtv2si3"
21989   [(set (match_operand:V2SI 0 "register_operand" "=y")
21990         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21991                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21992   "TARGET_MMX"
21993   "pcmpgtd\t{%2, %0|%0, %2}"
21994   [(set_attr "type" "mmxcmp")
21995    (set_attr "mode" "DI")])
21996
21997
21998 ;; MMX max/min insns
21999
22000 (define_insn "umaxv8qi3"
22001   [(set (match_operand:V8QI 0 "register_operand" "=y")
22002         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22003                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22004   "TARGET_SSE || TARGET_3DNOW_A"
22005   "pmaxub\t{%2, %0|%0, %2}"
22006   [(set_attr "type" "mmxadd")
22007    (set_attr "mode" "DI")])
22008
22009 (define_insn "smaxv4hi3"
22010   [(set (match_operand:V4HI 0 "register_operand" "=y")
22011         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22012                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22013   "TARGET_SSE || TARGET_3DNOW_A"
22014   "pmaxsw\t{%2, %0|%0, %2}"
22015   [(set_attr "type" "mmxadd")
22016    (set_attr "mode" "DI")])
22017
22018 (define_insn "uminv8qi3"
22019   [(set (match_operand:V8QI 0 "register_operand" "=y")
22020         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22021                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22022   "TARGET_SSE || TARGET_3DNOW_A"
22023   "pminub\t{%2, %0|%0, %2}"
22024   [(set_attr "type" "mmxadd")
22025    (set_attr "mode" "DI")])
22026
22027 (define_insn "sminv4hi3"
22028   [(set (match_operand:V4HI 0 "register_operand" "=y")
22029         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22030                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22031   "TARGET_SSE || TARGET_3DNOW_A"
22032   "pminsw\t{%2, %0|%0, %2}"
22033   [(set_attr "type" "mmxadd")
22034    (set_attr "mode" "DI")])
22035
22036
22037 ;; MMX shifts
22038
22039 (define_insn "ashrv4hi3"
22040   [(set (match_operand:V4HI 0 "register_operand" "=y")
22041         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22042                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22043   "TARGET_MMX"
22044   "psraw\t{%2, %0|%0, %2}"
22045   [(set_attr "type" "mmxshft")
22046    (set_attr "mode" "DI")])
22047
22048 (define_insn "ashrv2si3"
22049   [(set (match_operand:V2SI 0 "register_operand" "=y")
22050         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22051                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22052   "TARGET_MMX"
22053   "psrad\t{%2, %0|%0, %2}"
22054   [(set_attr "type" "mmxshft")
22055    (set_attr "mode" "DI")])
22056
22057 (define_insn "lshrv4hi3"
22058   [(set (match_operand:V4HI 0 "register_operand" "=y")
22059         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22060                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22061   "TARGET_MMX"
22062   "psrlw\t{%2, %0|%0, %2}"
22063   [(set_attr "type" "mmxshft")
22064    (set_attr "mode" "DI")])
22065
22066 (define_insn "lshrv2si3"
22067   [(set (match_operand:V2SI 0 "register_operand" "=y")
22068         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22069                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22070   "TARGET_MMX"
22071   "psrld\t{%2, %0|%0, %2}"
22072   [(set_attr "type" "mmxshft")
22073    (set_attr "mode" "DI")])
22074
22075 ;; See logical MMX insns.
22076 (define_insn "mmx_lshrdi3"
22077   [(set (match_operand:DI 0 "register_operand" "=y")
22078         (unspec:DI
22079           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22080                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22081           UNSPEC_NOP))]
22082   "TARGET_MMX"
22083   "psrlq\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxshft")
22085    (set_attr "mode" "DI")])
22086
22087 (define_insn "ashlv4hi3"
22088   [(set (match_operand:V4HI 0 "register_operand" "=y")
22089         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22090                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22091   "TARGET_MMX"
22092   "psllw\t{%2, %0|%0, %2}"
22093   [(set_attr "type" "mmxshft")
22094    (set_attr "mode" "DI")])
22095
22096 (define_insn "ashlv2si3"
22097   [(set (match_operand:V2SI 0 "register_operand" "=y")
22098         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22099                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22100   "TARGET_MMX"
22101   "pslld\t{%2, %0|%0, %2}"
22102   [(set_attr "type" "mmxshft")
22103    (set_attr "mode" "DI")])
22104
22105 ;; See logical MMX insns.
22106 (define_insn "mmx_ashldi3"
22107   [(set (match_operand:DI 0 "register_operand" "=y")
22108         (unspec:DI
22109          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22110                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22111          UNSPEC_NOP))]
22112   "TARGET_MMX"
22113   "psllq\t{%2, %0|%0, %2}"
22114   [(set_attr "type" "mmxshft")
22115    (set_attr "mode" "DI")])
22116
22117
22118 ;; MMX pack/unpack insns.
22119
22120 (define_insn "mmx_packsswb"
22121   [(set (match_operand:V8QI 0 "register_operand" "=y")
22122         (vec_concat:V8QI
22123          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22124          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22125   "TARGET_MMX"
22126   "packsswb\t{%2, %0|%0, %2}"
22127   [(set_attr "type" "mmxshft")
22128    (set_attr "mode" "DI")])
22129
22130 (define_insn "mmx_packssdw"
22131   [(set (match_operand:V4HI 0 "register_operand" "=y")
22132         (vec_concat:V4HI
22133          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22134          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22135   "TARGET_MMX"
22136   "packssdw\t{%2, %0|%0, %2}"
22137   [(set_attr "type" "mmxshft")
22138    (set_attr "mode" "DI")])
22139
22140 (define_insn "mmx_packuswb"
22141   [(set (match_operand:V8QI 0 "register_operand" "=y")
22142         (vec_concat:V8QI
22143          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22144          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22145   "TARGET_MMX"
22146   "packuswb\t{%2, %0|%0, %2}"
22147   [(set_attr "type" "mmxshft")
22148    (set_attr "mode" "DI")])
22149
22150 (define_insn "mmx_punpckhbw"
22151   [(set (match_operand:V8QI 0 "register_operand" "=y")
22152         (vec_merge:V8QI
22153          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22154                           (parallel [(const_int 4)
22155                                      (const_int 0)
22156                                      (const_int 5)
22157                                      (const_int 1)
22158                                      (const_int 6)
22159                                      (const_int 2)
22160                                      (const_int 7)
22161                                      (const_int 3)]))
22162          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22163                           (parallel [(const_int 0)
22164                                      (const_int 4)
22165                                      (const_int 1)
22166                                      (const_int 5)
22167                                      (const_int 2)
22168                                      (const_int 6)
22169                                      (const_int 3)
22170                                      (const_int 7)]))
22171          (const_int 85)))]
22172   "TARGET_MMX"
22173   "punpckhbw\t{%2, %0|%0, %2}"
22174   [(set_attr "type" "mmxcvt")
22175    (set_attr "mode" "DI")])
22176
22177 (define_insn "mmx_punpckhwd"
22178   [(set (match_operand:V4HI 0 "register_operand" "=y")
22179         (vec_merge:V4HI
22180          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22181                           (parallel [(const_int 0)
22182                                      (const_int 2)
22183                                      (const_int 1)
22184                                      (const_int 3)]))
22185          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22186                           (parallel [(const_int 2)
22187                                      (const_int 0)
22188                                      (const_int 3)
22189                                      (const_int 1)]))
22190          (const_int 5)))]
22191   "TARGET_MMX"
22192   "punpckhwd\t{%2, %0|%0, %2}"
22193   [(set_attr "type" "mmxcvt")
22194    (set_attr "mode" "DI")])
22195
22196 (define_insn "mmx_punpckhdq"
22197   [(set (match_operand:V2SI 0 "register_operand" "=y")
22198         (vec_merge:V2SI
22199          (match_operand:V2SI 1 "register_operand" "0")
22200          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22201                           (parallel [(const_int 1)
22202                                      (const_int 0)]))
22203          (const_int 1)))]
22204   "TARGET_MMX"
22205   "punpckhdq\t{%2, %0|%0, %2}"
22206   [(set_attr "type" "mmxcvt")
22207    (set_attr "mode" "DI")])
22208
22209 (define_insn "mmx_punpcklbw"
22210   [(set (match_operand:V8QI 0 "register_operand" "=y")
22211         (vec_merge:V8QI
22212          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22213                           (parallel [(const_int 0)
22214                                      (const_int 4)
22215                                      (const_int 1)
22216                                      (const_int 5)
22217                                      (const_int 2)
22218                                      (const_int 6)
22219                                      (const_int 3)
22220                                      (const_int 7)]))
22221          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22222                           (parallel [(const_int 4)
22223                                      (const_int 0)
22224                                      (const_int 5)
22225                                      (const_int 1)
22226                                      (const_int 6)
22227                                      (const_int 2)
22228                                      (const_int 7)
22229                                      (const_int 3)]))
22230          (const_int 85)))]
22231   "TARGET_MMX"
22232   "punpcklbw\t{%2, %0|%0, %2}"
22233   [(set_attr "type" "mmxcvt")
22234    (set_attr "mode" "DI")])
22235
22236 (define_insn "mmx_punpcklwd"
22237   [(set (match_operand:V4HI 0 "register_operand" "=y")
22238         (vec_merge:V4HI
22239          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22240                           (parallel [(const_int 2)
22241                                      (const_int 0)
22242                                      (const_int 3)
22243                                      (const_int 1)]))
22244          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22245                           (parallel [(const_int 0)
22246                                      (const_int 2)
22247                                      (const_int 1)
22248                                      (const_int 3)]))
22249          (const_int 5)))]
22250   "TARGET_MMX"
22251   "punpcklwd\t{%2, %0|%0, %2}"
22252   [(set_attr "type" "mmxcvt")
22253    (set_attr "mode" "DI")])
22254
22255 (define_insn "mmx_punpckldq"
22256   [(set (match_operand:V2SI 0 "register_operand" "=y")
22257         (vec_merge:V2SI
22258          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22259                            (parallel [(const_int 1)
22260                                       (const_int 0)]))
22261          (match_operand:V2SI 2 "register_operand" "y")
22262          (const_int 1)))]
22263   "TARGET_MMX"
22264   "punpckldq\t{%2, %0|%0, %2}"
22265   [(set_attr "type" "mmxcvt")
22266    (set_attr "mode" "DI")])
22267
22268
22269 ;; Miscellaneous stuff
22270
22271 (define_insn "emms"
22272   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22273    (clobber (reg:XF 8))
22274    (clobber (reg:XF 9))
22275    (clobber (reg:XF 10))
22276    (clobber (reg:XF 11))
22277    (clobber (reg:XF 12))
22278    (clobber (reg:XF 13))
22279    (clobber (reg:XF 14))
22280    (clobber (reg:XF 15))
22281    (clobber (reg:DI 29))
22282    (clobber (reg:DI 30))
22283    (clobber (reg:DI 31))
22284    (clobber (reg:DI 32))
22285    (clobber (reg:DI 33))
22286    (clobber (reg:DI 34))
22287    (clobber (reg:DI 35))
22288    (clobber (reg:DI 36))]
22289   "TARGET_MMX"
22290   "emms"
22291   [(set_attr "type" "mmx")
22292    (set_attr "memory" "unknown")])
22293
22294 (define_insn "ldmxcsr"
22295   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22296                     UNSPECV_LDMXCSR)]
22297   "TARGET_SSE"
22298   "ldmxcsr\t%0"
22299   [(set_attr "type" "sse")
22300    (set_attr "memory" "load")])
22301
22302 (define_insn "stmxcsr"
22303   [(set (match_operand:SI 0 "memory_operand" "=m")
22304         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22305   "TARGET_SSE"
22306   "stmxcsr\t%0"
22307   [(set_attr "type" "sse")
22308    (set_attr "memory" "store")])
22309
22310 (define_expand "sfence"
22311   [(set (match_dup 0)
22312         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22313   "TARGET_SSE || TARGET_3DNOW_A"
22314 {
22315   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22316   MEM_VOLATILE_P (operands[0]) = 1;
22317 })
22318
22319 (define_insn "*sfence_insn"
22320   [(set (match_operand:BLK 0 "" "")
22321         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22322   "TARGET_SSE || TARGET_3DNOW_A"
22323   "sfence"
22324   [(set_attr "type" "sse")
22325    (set_attr "memory" "unknown")])
22326
22327 (define_expand "sse_prologue_save"
22328   [(parallel [(set (match_operand:BLK 0 "" "")
22329                    (unspec:BLK [(reg:DI 21)
22330                                 (reg:DI 22)
22331                                 (reg:DI 23)
22332                                 (reg:DI 24)
22333                                 (reg:DI 25)
22334                                 (reg:DI 26)
22335                                 (reg:DI 27)
22336                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22337               (use (match_operand:DI 1 "register_operand" ""))
22338               (use (match_operand:DI 2 "immediate_operand" ""))
22339               (use (label_ref:DI (match_operand 3 "" "")))])]
22340   "TARGET_64BIT"
22341   "")
22342
22343 (define_insn "*sse_prologue_save_insn"
22344   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22345                           (match_operand:DI 4 "const_int_operand" "n")))
22346         (unspec:BLK [(reg:DI 21)
22347                      (reg:DI 22)
22348                      (reg:DI 23)
22349                      (reg:DI 24)
22350                      (reg:DI 25)
22351                      (reg:DI 26)
22352                      (reg:DI 27)
22353                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22354    (use (match_operand:DI 1 "register_operand" "r"))
22355    (use (match_operand:DI 2 "const_int_operand" "i"))
22356    (use (label_ref:DI (match_operand 3 "" "X")))]
22357   "TARGET_64BIT
22358    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22359    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22360   "*
22361 {
22362   int i;
22363   operands[0] = gen_rtx_MEM (Pmode,
22364                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22365   output_asm_insn (\"jmp\\t%A1\", operands);
22366   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22367     {
22368       operands[4] = adjust_address (operands[0], DImode, i*16);
22369       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22370       PUT_MODE (operands[4], TImode);
22371       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22372         output_asm_insn (\"rex\", operands);
22373       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22374     }
22375   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22376                              CODE_LABEL_NUMBER (operands[3]));
22377   RET;
22378 }
22379   "
22380   [(set_attr "type" "other")
22381    (set_attr "length_immediate" "0")
22382    (set_attr "length_address" "0")
22383    (set_attr "length" "135")
22384    (set_attr "memory" "store")
22385    (set_attr "modrm" "0")
22386    (set_attr "mode" "DI")])
22387
22388 ;; 3Dnow! instructions
22389
22390 (define_insn "addv2sf3"
22391   [(set (match_operand:V2SF 0 "register_operand" "=y")
22392         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22393                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22394   "TARGET_3DNOW"
22395   "pfadd\\t{%2, %0|%0, %2}"
22396   [(set_attr "type" "mmxadd")
22397    (set_attr "mode" "V2SF")])
22398
22399 (define_insn "subv2sf3"
22400   [(set (match_operand:V2SF 0 "register_operand" "=y")
22401         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22402                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22403   "TARGET_3DNOW"
22404   "pfsub\\t{%2, %0|%0, %2}"
22405   [(set_attr "type" "mmxadd")
22406    (set_attr "mode" "V2SF")])
22407
22408 (define_insn "subrv2sf3"
22409   [(set (match_operand:V2SF 0 "register_operand" "=y")
22410         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22411                     (match_operand:V2SF 1 "register_operand" "0")))]
22412   "TARGET_3DNOW"
22413   "pfsubr\\t{%2, %0|%0, %2}"
22414   [(set_attr "type" "mmxadd")
22415    (set_attr "mode" "V2SF")])
22416
22417 (define_insn "gtv2sf3"
22418   [(set (match_operand:V2SI 0 "register_operand" "=y")
22419         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22420                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22421  "TARGET_3DNOW"
22422   "pfcmpgt\\t{%2, %0|%0, %2}"
22423   [(set_attr "type" "mmxcmp")
22424    (set_attr "mode" "V2SF")])
22425
22426 (define_insn "gev2sf3"
22427   [(set (match_operand:V2SI 0 "register_operand" "=y")
22428         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22429                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22430   "TARGET_3DNOW"
22431   "pfcmpge\\t{%2, %0|%0, %2}"
22432   [(set_attr "type" "mmxcmp")
22433    (set_attr "mode" "V2SF")])
22434
22435 (define_insn "eqv2sf3"
22436   [(set (match_operand:V2SI 0 "register_operand" "=y")
22437         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22438                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22439   "TARGET_3DNOW"
22440   "pfcmpeq\\t{%2, %0|%0, %2}"
22441   [(set_attr "type" "mmxcmp")
22442    (set_attr "mode" "V2SF")])
22443
22444 (define_insn "pfmaxv2sf3"
22445   [(set (match_operand:V2SF 0 "register_operand" "=y")
22446         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22447                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22448   "TARGET_3DNOW"
22449   "pfmax\\t{%2, %0|%0, %2}"
22450   [(set_attr "type" "mmxadd")
22451    (set_attr "mode" "V2SF")])
22452
22453 (define_insn "pfminv2sf3"
22454   [(set (match_operand:V2SF 0 "register_operand" "=y")
22455         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22456                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22457   "TARGET_3DNOW"
22458   "pfmin\\t{%2, %0|%0, %2}"
22459   [(set_attr "type" "mmxadd")
22460    (set_attr "mode" "V2SF")])
22461
22462 (define_insn "mulv2sf3"
22463   [(set (match_operand:V2SF 0 "register_operand" "=y")
22464         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22465                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22466   "TARGET_3DNOW"
22467   "pfmul\\t{%2, %0|%0, %2}"
22468   [(set_attr "type" "mmxmul")
22469    (set_attr "mode" "V2SF")])
22470
22471 (define_insn "femms"
22472   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22473    (clobber (reg:XF 8))
22474    (clobber (reg:XF 9))
22475    (clobber (reg:XF 10))
22476    (clobber (reg:XF 11))
22477    (clobber (reg:XF 12))
22478    (clobber (reg:XF 13))
22479    (clobber (reg:XF 14))
22480    (clobber (reg:XF 15))
22481    (clobber (reg:DI 29))
22482    (clobber (reg:DI 30))
22483    (clobber (reg:DI 31))
22484    (clobber (reg:DI 32))
22485    (clobber (reg:DI 33))
22486    (clobber (reg:DI 34))
22487    (clobber (reg:DI 35))
22488    (clobber (reg:DI 36))]
22489   "TARGET_3DNOW"
22490   "femms"
22491   [(set_attr "type" "mmx")
22492    (set_attr "memory" "none")]) 
22493
22494 (define_insn "pf2id"
22495   [(set (match_operand:V2SI 0 "register_operand" "=y")
22496         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22497   "TARGET_3DNOW"
22498   "pf2id\\t{%1, %0|%0, %1}"
22499   [(set_attr "type" "mmxcvt")
22500    (set_attr "mode" "V2SF")])
22501
22502 (define_insn "pf2iw"
22503   [(set (match_operand:V2SI 0 "register_operand" "=y")
22504         (sign_extend:V2SI
22505            (ss_truncate:V2HI
22506               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22507   "TARGET_3DNOW_A"
22508   "pf2iw\\t{%1, %0|%0, %1}"
22509   [(set_attr "type" "mmxcvt")
22510    (set_attr "mode" "V2SF")])
22511
22512 (define_insn "pfacc"
22513   [(set (match_operand:V2SF 0 "register_operand" "=y")
22514         (vec_concat:V2SF
22515            (plus:SF
22516               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22517                              (parallel [(const_int  0)]))
22518               (vec_select:SF (match_dup 1)
22519                              (parallel [(const_int 1)])))
22520            (plus:SF
22521               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22522                              (parallel [(const_int  0)]))
22523               (vec_select:SF (match_dup 2)
22524                              (parallel [(const_int 1)])))))]
22525   "TARGET_3DNOW"
22526   "pfacc\\t{%2, %0|%0, %2}"
22527   [(set_attr "type" "mmxadd")
22528    (set_attr "mode" "V2SF")])
22529
22530 (define_insn "pfnacc"
22531   [(set (match_operand:V2SF 0 "register_operand" "=y")
22532         (vec_concat:V2SF
22533            (minus:SF
22534               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22535                              (parallel [(const_int 0)]))
22536               (vec_select:SF (match_dup 1)
22537                              (parallel [(const_int 1)])))
22538            (minus:SF
22539               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22540                              (parallel [(const_int  0)]))
22541               (vec_select:SF (match_dup 2)
22542                              (parallel [(const_int 1)])))))]
22543   "TARGET_3DNOW_A"
22544   "pfnacc\\t{%2, %0|%0, %2}"
22545   [(set_attr "type" "mmxadd")
22546    (set_attr "mode" "V2SF")])
22547
22548 (define_insn "pfpnacc"
22549   [(set (match_operand:V2SF 0 "register_operand" "=y")
22550         (vec_concat:V2SF
22551            (minus:SF
22552               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22553                              (parallel [(const_int 0)]))
22554               (vec_select:SF (match_dup 1)
22555                              (parallel [(const_int 1)])))
22556            (plus:SF
22557               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22558                              (parallel [(const_int 0)]))
22559               (vec_select:SF (match_dup 2)
22560                              (parallel [(const_int 1)])))))]
22561   "TARGET_3DNOW_A"
22562   "pfpnacc\\t{%2, %0|%0, %2}"
22563   [(set_attr "type" "mmxadd")
22564    (set_attr "mode" "V2SF")])
22565
22566 (define_insn "pi2fw"
22567   [(set (match_operand:V2SF 0 "register_operand" "=y")
22568         (float:V2SF
22569            (vec_concat:V2SI
22570               (sign_extend:SI
22571                  (truncate:HI
22572                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22573                                    (parallel [(const_int 0)]))))
22574               (sign_extend:SI
22575                  (truncate:HI
22576                     (vec_select:SI (match_dup 1)
22577                                    (parallel [(const_int  1)])))))))]
22578   "TARGET_3DNOW_A"
22579   "pi2fw\\t{%1, %0|%0, %1}"
22580   [(set_attr "type" "mmxcvt")
22581    (set_attr "mode" "V2SF")])
22582
22583 (define_insn "floatv2si2"
22584   [(set (match_operand:V2SF 0 "register_operand" "=y")
22585         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22586   "TARGET_3DNOW"
22587   "pi2fd\\t{%1, %0|%0, %1}"
22588   [(set_attr "type" "mmxcvt")
22589    (set_attr "mode" "V2SF")])
22590
22591 ;; This insn is identical to pavgb in operation, but the opcode is
22592 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22593
22594 (define_insn "pavgusb"
22595  [(set (match_operand:V8QI 0 "register_operand" "=y")
22596        (unspec:V8QI
22597           [(match_operand:V8QI 1 "register_operand" "0")
22598            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22599           UNSPEC_PAVGUSB))]
22600   "TARGET_3DNOW"
22601   "pavgusb\\t{%2, %0|%0, %2}"
22602   [(set_attr "type" "mmxshft")
22603    (set_attr "mode" "TI")])
22604
22605 ;; 3DNow reciprocal and sqrt
22606  
22607 (define_insn "pfrcpv2sf2"
22608   [(set (match_operand:V2SF 0 "register_operand" "=y")
22609         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22610         UNSPEC_PFRCP))]
22611   "TARGET_3DNOW"
22612   "pfrcp\\t{%1, %0|%0, %1}"
22613   [(set_attr "type" "mmx")
22614    (set_attr "mode" "TI")])
22615
22616 (define_insn "pfrcpit1v2sf3"
22617   [(set (match_operand:V2SF 0 "register_operand" "=y")
22618         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22619                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22620                      UNSPEC_PFRCPIT1))]
22621   "TARGET_3DNOW"
22622   "pfrcpit1\\t{%2, %0|%0, %2}"
22623   [(set_attr "type" "mmx")
22624    (set_attr "mode" "TI")])
22625
22626 (define_insn "pfrcpit2v2sf3"
22627   [(set (match_operand:V2SF 0 "register_operand" "=y")
22628         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22629                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22630                      UNSPEC_PFRCPIT2))]
22631   "TARGET_3DNOW"
22632   "pfrcpit2\\t{%2, %0|%0, %2}"
22633   [(set_attr "type" "mmx")
22634    (set_attr "mode" "TI")])
22635
22636 (define_insn "pfrsqrtv2sf2"
22637   [(set (match_operand:V2SF 0 "register_operand" "=y")
22638         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22639                      UNSPEC_PFRSQRT))]
22640   "TARGET_3DNOW"
22641   "pfrsqrt\\t{%1, %0|%0, %1}"
22642   [(set_attr "type" "mmx")
22643    (set_attr "mode" "TI")])
22644                 
22645 (define_insn "pfrsqit1v2sf3"
22646   [(set (match_operand:V2SF 0 "register_operand" "=y")
22647         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22648                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22649                      UNSPEC_PFRSQIT1))]
22650   "TARGET_3DNOW"
22651   "pfrsqit1\\t{%2, %0|%0, %2}"
22652   [(set_attr "type" "mmx")
22653    (set_attr "mode" "TI")])
22654
22655 (define_insn "pmulhrwv4hi3"
22656   [(set (match_operand:V4HI 0 "register_operand" "=y")
22657         (truncate:V4HI
22658            (lshiftrt:V4SI
22659               (plus:V4SI
22660                  (mult:V4SI
22661                     (sign_extend:V4SI
22662                        (match_operand:V4HI 1 "register_operand" "0"))
22663                     (sign_extend:V4SI
22664                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22665                  (const_vector:V4SI [(const_int 32768)
22666                                      (const_int 32768)
22667                                      (const_int 32768)
22668                                      (const_int 32768)]))
22669               (const_int 16))))]
22670   "TARGET_3DNOW"
22671   "pmulhrw\\t{%2, %0|%0, %2}"
22672   [(set_attr "type" "mmxmul")
22673    (set_attr "mode" "TI")])
22674
22675 (define_insn "pswapdv2si2"
22676   [(set (match_operand:V2SI 0 "register_operand" "=y")
22677         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22678                          (parallel [(const_int 1) (const_int 0)])))]
22679   "TARGET_3DNOW_A"
22680   "pswapd\\t{%1, %0|%0, %1}"
22681   [(set_attr "type" "mmxcvt")
22682    (set_attr "mode" "TI")])
22683
22684 (define_insn "pswapdv2sf2"
22685   [(set (match_operand:V2SF 0 "register_operand" "=y")
22686         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22687                          (parallel [(const_int 1) (const_int 0)])))]
22688   "TARGET_3DNOW_A"
22689   "pswapd\\t{%1, %0|%0, %1}"
22690   [(set_attr "type" "mmxcvt")
22691    (set_attr "mode" "TI")])
22692
22693 (define_expand "prefetch"
22694   [(prefetch (match_operand 0 "address_operand" "")
22695              (match_operand:SI 1 "const_int_operand" "")
22696              (match_operand:SI 2 "const_int_operand" ""))]
22697   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22698 {
22699   int rw = INTVAL (operands[1]);
22700   int locality = INTVAL (operands[2]);
22701
22702   if (rw != 0 && rw != 1)
22703     abort ();
22704   if (locality < 0 || locality > 3)
22705     abort ();
22706   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22707     abort ();
22708
22709   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22710      suported by SSE counterpart or the SSE prefetch is not available
22711      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22712      of locality.  */
22713   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22714     operands[2] = GEN_INT (3);
22715   else
22716     operands[1] = const0_rtx;
22717 })
22718
22719 (define_insn "*prefetch_sse"
22720   [(prefetch (match_operand:SI 0 "address_operand" "p")
22721              (const_int 0)
22722              (match_operand:SI 1 "const_int_operand" ""))]
22723   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22724 {
22725   static const char * const patterns[4] = {
22726    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22727   };
22728
22729   int locality = INTVAL (operands[1]);
22730   if (locality < 0 || locality > 3)
22731     abort ();
22732
22733   return patterns[locality];  
22734 }
22735   [(set_attr "type" "sse")
22736    (set_attr "memory" "none")])
22737
22738 (define_insn "*prefetch_sse_rex"
22739   [(prefetch (match_operand:DI 0 "address_operand" "p")
22740              (const_int 0)
22741              (match_operand:SI 1 "const_int_operand" ""))]
22742   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22743 {
22744   static const char * const patterns[4] = {
22745    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22746   };
22747
22748   int locality = INTVAL (operands[1]);
22749   if (locality < 0 || locality > 3)
22750     abort ();
22751
22752   return patterns[locality];  
22753 }
22754   [(set_attr "type" "sse")
22755    (set_attr "memory" "none")])
22756
22757 (define_insn "*prefetch_3dnow"
22758   [(prefetch (match_operand:SI 0 "address_operand" "p")
22759              (match_operand:SI 1 "const_int_operand" "n")
22760              (const_int 3))]
22761   "TARGET_3DNOW && !TARGET_64BIT"
22762 {
22763   if (INTVAL (operands[1]) == 0)
22764     return "prefetch\t%a0";
22765   else
22766     return "prefetchw\t%a0";
22767 }
22768   [(set_attr "type" "mmx")
22769    (set_attr "memory" "none")])
22770
22771 (define_insn "*prefetch_3dnow_rex"
22772   [(prefetch (match_operand:DI 0 "address_operand" "p")
22773              (match_operand:SI 1 "const_int_operand" "n")
22774              (const_int 3))]
22775   "TARGET_3DNOW && TARGET_64BIT"
22776 {
22777   if (INTVAL (operands[1]) == 0)
22778     return "prefetch\t%a0";
22779   else
22780     return "prefetchw\t%a0";
22781 }
22782   [(set_attr "type" "mmx")
22783    (set_attr "memory" "none")])
22784
22785 ;; SSE2 support
22786
22787 (define_insn "addv2df3"
22788   [(set (match_operand:V2DF 0 "register_operand" "=x")
22789         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22790                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22791   "TARGET_SSE2"
22792   "addpd\t{%2, %0|%0, %2}"
22793   [(set_attr "type" "sseadd")
22794    (set_attr "mode" "V2DF")])
22795
22796 (define_insn "vmaddv2df3"
22797   [(set (match_operand:V2DF 0 "register_operand" "=x")
22798         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22799                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22800                         (match_dup 1)
22801                         (const_int 1)))]
22802   "TARGET_SSE2"
22803   "addsd\t{%2, %0|%0, %2}"
22804   [(set_attr "type" "sseadd")
22805    (set_attr "mode" "DF")])
22806
22807 (define_insn "subv2df3"
22808   [(set (match_operand:V2DF 0 "register_operand" "=x")
22809         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22810                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22811   "TARGET_SSE2"
22812   "subpd\t{%2, %0|%0, %2}"
22813   [(set_attr "type" "sseadd")
22814    (set_attr "mode" "V2DF")])
22815
22816 (define_insn "vmsubv2df3"
22817   [(set (match_operand:V2DF 0 "register_operand" "=x")
22818         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22819                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22820                         (match_dup 1)
22821                         (const_int 1)))]
22822   "TARGET_SSE2"
22823   "subsd\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "sseadd")
22825    (set_attr "mode" "DF")])
22826
22827 (define_insn "mulv2df3"
22828   [(set (match_operand:V2DF 0 "register_operand" "=x")
22829         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22830                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22831   "TARGET_SSE2"
22832   "mulpd\t{%2, %0|%0, %2}"
22833   [(set_attr "type" "ssemul")
22834    (set_attr "mode" "V2DF")])
22835
22836 (define_insn "vmmulv2df3"
22837   [(set (match_operand:V2DF 0 "register_operand" "=x")
22838         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22839                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22840                         (match_dup 1)
22841                         (const_int 1)))]
22842   "TARGET_SSE2"
22843   "mulsd\t{%2, %0|%0, %2}"
22844   [(set_attr "type" "ssemul")
22845    (set_attr "mode" "DF")])
22846
22847 (define_insn "divv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22851   "TARGET_SSE2"
22852   "divpd\t{%2, %0|%0, %2}"
22853   [(set_attr "type" "ssediv")
22854    (set_attr "mode" "V2DF")])
22855
22856 (define_insn "vmdivv2df3"
22857   [(set (match_operand:V2DF 0 "register_operand" "=x")
22858         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22859                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22860                         (match_dup 1)
22861                         (const_int 1)))]
22862   "TARGET_SSE2"
22863   "divsd\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "ssediv")
22865    (set_attr "mode" "DF")])
22866
22867 ;; SSE min/max
22868
22869 (define_insn "smaxv2df3"
22870   [(set (match_operand:V2DF 0 "register_operand" "=x")
22871         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22872                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22873   "TARGET_SSE2"
22874   "maxpd\t{%2, %0|%0, %2}"
22875   [(set_attr "type" "sseadd")
22876    (set_attr "mode" "V2DF")])
22877
22878 (define_insn "vmsmaxv2df3"
22879   [(set (match_operand:V2DF 0 "register_operand" "=x")
22880         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22881                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22882                         (match_dup 1)
22883                         (const_int 1)))]
22884   "TARGET_SSE2"
22885   "maxsd\t{%2, %0|%0, %2}"
22886   [(set_attr "type" "sseadd")
22887    (set_attr "mode" "DF")])
22888
22889 (define_insn "sminv2df3"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x")
22891         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22892                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22893   "TARGET_SSE2"
22894   "minpd\t{%2, %0|%0, %2}"
22895   [(set_attr "type" "sseadd")
22896    (set_attr "mode" "V2DF")])
22897
22898 (define_insn "vmsminv2df3"
22899   [(set (match_operand:V2DF 0 "register_operand" "=x")
22900         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22901                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22902                         (match_dup 1)
22903                         (const_int 1)))]
22904   "TARGET_SSE2"
22905   "minsd\t{%2, %0|%0, %2}"
22906   [(set_attr "type" "sseadd")
22907    (set_attr "mode" "DF")])
22908 ;; SSE2 square root.  There doesn't appear to be an extension for the
22909 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22910
22911 (define_insn "sqrtv2df2"
22912   [(set (match_operand:V2DF 0 "register_operand" "=x")
22913         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22914   "TARGET_SSE2"
22915   "sqrtpd\t{%1, %0|%0, %1}"
22916   [(set_attr "type" "sse")
22917    (set_attr "mode" "V2DF")])
22918
22919 (define_insn "vmsqrtv2df2"
22920   [(set (match_operand:V2DF 0 "register_operand" "=x")
22921         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22922                         (match_operand:V2DF 2 "register_operand" "0")
22923                         (const_int 1)))]
22924   "TARGET_SSE2"
22925   "sqrtsd\t{%1, %0|%0, %1}"
22926   [(set_attr "type" "sse")
22927    (set_attr "mode" "SF")])
22928
22929 ;; SSE mask-generating compares
22930
22931 (define_insn "maskcmpv2df3"
22932   [(set (match_operand:V2DI 0 "register_operand" "=x")
22933         (match_operator:V2DI 3 "sse_comparison_operator"
22934                              [(match_operand:V2DF 1 "register_operand" "0")
22935                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22936   "TARGET_SSE2"
22937   "cmp%D3pd\t{%2, %0|%0, %2}"
22938   [(set_attr "type" "ssecmp")
22939    (set_attr "mode" "V2DF")])
22940
22941 (define_insn "maskncmpv2df3"
22942   [(set (match_operand:V2DI 0 "register_operand" "=x")
22943         (not:V2DI
22944          (match_operator:V2DI 3 "sse_comparison_operator"
22945                               [(match_operand:V2DF 1 "register_operand" "0")
22946                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22947   "TARGET_SSE2"
22948 {
22949   if (GET_CODE (operands[3]) == UNORDERED)
22950     return "cmpordps\t{%2, %0|%0, %2}";
22951   else
22952     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22953 }
22954   [(set_attr "type" "ssecmp")
22955    (set_attr "mode" "V2DF")])
22956
22957 (define_insn "vmmaskcmpv2df3"
22958   [(set (match_operand:V2DI 0 "register_operand" "=x")
22959         (vec_merge:V2DI
22960          (match_operator:V2DI 3 "sse_comparison_operator"
22961                               [(match_operand:V2DF 1 "register_operand" "0")
22962                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22963          (subreg:V2DI (match_dup 1) 0)
22964          (const_int 1)))]
22965   "TARGET_SSE2"
22966   "cmp%D3sd\t{%2, %0|%0, %2}"
22967   [(set_attr "type" "ssecmp")
22968    (set_attr "mode" "DF")])
22969
22970 (define_insn "vmmaskncmpv2df3"
22971   [(set (match_operand:V2DI 0 "register_operand" "=x")
22972         (vec_merge:V2DI
22973          (not:V2DI
22974           (match_operator:V2DI 3 "sse_comparison_operator"
22975                                [(match_operand:V2DF 1 "register_operand" "0")
22976                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22977          (subreg:V2DI (match_dup 1) 0)
22978          (const_int 1)))]
22979   "TARGET_SSE2"
22980 {
22981   if (GET_CODE (operands[3]) == UNORDERED)
22982     return "cmpordsd\t{%2, %0|%0, %2}";
22983   else
22984     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22985 }
22986   [(set_attr "type" "ssecmp")
22987    (set_attr "mode" "DF")])
22988
22989 (define_insn "sse2_comi"
22990   [(set (reg:CCFP FLAGS_REG)
22991         (compare:CCFP (vec_select:DF
22992                        (match_operand:V2DF 0 "register_operand" "x")
22993                        (parallel [(const_int 0)]))
22994                       (vec_select:DF
22995                        (match_operand:V2DF 1 "register_operand" "x")
22996                        (parallel [(const_int 0)]))))]
22997   "TARGET_SSE2"
22998   "comisd\t{%1, %0|%0, %1}"
22999   [(set_attr "type" "ssecomi")
23000    (set_attr "mode" "DF")])
23001
23002 (define_insn "sse2_ucomi"
23003   [(set (reg:CCFPU FLAGS_REG)
23004         (compare:CCFPU (vec_select:DF
23005                          (match_operand:V2DF 0 "register_operand" "x")
23006                          (parallel [(const_int 0)]))
23007                         (vec_select:DF
23008                          (match_operand:V2DF 1 "register_operand" "x")
23009                          (parallel [(const_int 0)]))))]
23010   "TARGET_SSE2"
23011   "ucomisd\t{%1, %0|%0, %1}"
23012   [(set_attr "type" "ssecomi")
23013    (set_attr "mode" "DF")])
23014
23015 ;; SSE Strange Moves.
23016
23017 (define_insn "sse2_movmskpd"
23018   [(set (match_operand:SI 0 "register_operand" "=r")
23019         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23020                    UNSPEC_MOVMSK))]
23021   "TARGET_SSE2"
23022   "movmskpd\t{%1, %0|%0, %1}"
23023   [(set_attr "type" "ssecvt")
23024    (set_attr "mode" "V2DF")])
23025
23026 (define_insn "sse2_pmovmskb"
23027   [(set (match_operand:SI 0 "register_operand" "=r")
23028         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23029                    UNSPEC_MOVMSK))]
23030   "TARGET_SSE2"
23031   "pmovmskb\t{%1, %0|%0, %1}"
23032   [(set_attr "type" "ssecvt")
23033    (set_attr "mode" "V2DF")])
23034
23035 (define_insn "sse2_maskmovdqu"
23036   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23037         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23038                        (match_operand:V16QI 2 "register_operand" "x")]
23039                       UNSPEC_MASKMOV))]
23040   "TARGET_SSE2"
23041   ;; @@@ check ordering of operands in intel/nonintel syntax
23042   "maskmovdqu\t{%2, %1|%1, %2}"
23043   [(set_attr "type" "ssecvt")
23044    (set_attr "mode" "TI")])
23045
23046 (define_insn "sse2_maskmovdqu_rex64"
23047   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23048         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23049                        (match_operand:V16QI 2 "register_operand" "x")]
23050                       UNSPEC_MASKMOV))]
23051   "TARGET_SSE2"
23052   ;; @@@ check ordering of operands in intel/nonintel syntax
23053   "maskmovdqu\t{%2, %1|%1, %2}"
23054   [(set_attr "type" "ssecvt")
23055    (set_attr "mode" "TI")])
23056
23057 (define_insn "sse2_movntv2df"
23058   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23059         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23060                      UNSPEC_MOVNT))]
23061   "TARGET_SSE2"
23062   "movntpd\t{%1, %0|%0, %1}"
23063   [(set_attr "type" "ssecvt")
23064    (set_attr "mode" "V2DF")])
23065
23066 (define_insn "sse2_movntv2di"
23067   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23068         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23069                      UNSPEC_MOVNT))]
23070   "TARGET_SSE2"
23071   "movntdq\t{%1, %0|%0, %1}"
23072   [(set_attr "type" "ssecvt")
23073    (set_attr "mode" "TI")])
23074
23075 (define_insn "sse2_movntsi"
23076   [(set (match_operand:SI 0 "memory_operand" "=m")
23077         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23078                    UNSPEC_MOVNT))]
23079   "TARGET_SSE2"
23080   "movnti\t{%1, %0|%0, %1}"
23081   [(set_attr "type" "ssecvt")
23082    (set_attr "mode" "V2DF")])
23083
23084 ;; SSE <-> integer/MMX conversions
23085
23086 ;; Conversions between SI and SF
23087
23088 (define_insn "cvtdq2ps"
23089   [(set (match_operand:V4SF 0 "register_operand" "=x")
23090         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23091   "TARGET_SSE2"
23092   "cvtdq2ps\t{%1, %0|%0, %1}"
23093   [(set_attr "type" "ssecvt")
23094    (set_attr "mode" "V2DF")])
23095
23096 (define_insn "cvtps2dq"
23097   [(set (match_operand:V4SI 0 "register_operand" "=x")
23098         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23099   "TARGET_SSE2"
23100   "cvtps2dq\t{%1, %0|%0, %1}"
23101   [(set_attr "type" "ssecvt")
23102    (set_attr "mode" "TI")])
23103
23104 (define_insn "cvttps2dq"
23105   [(set (match_operand:V4SI 0 "register_operand" "=x")
23106         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23107                      UNSPEC_FIX))]
23108   "TARGET_SSE2"
23109   "cvttps2dq\t{%1, %0|%0, %1}"
23110   [(set_attr "type" "ssecvt")
23111    (set_attr "mode" "TI")])
23112
23113 ;; Conversions between SI and DF
23114
23115 (define_insn "cvtdq2pd"
23116   [(set (match_operand:V2DF 0 "register_operand" "=x")
23117         (float:V2DF (vec_select:V2SI
23118                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23119                      (parallel
23120                       [(const_int 0)
23121                        (const_int 1)]))))]
23122   "TARGET_SSE2"
23123   "cvtdq2pd\t{%1, %0|%0, %1}"
23124   [(set_attr "type" "ssecvt")
23125    (set_attr "mode" "V2DF")])
23126
23127 (define_insn "cvtpd2dq"
23128   [(set (match_operand:V4SI 0 "register_operand" "=x")
23129         (vec_concat:V4SI
23130          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23131          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23132   "TARGET_SSE2"
23133   "cvtpd2dq\t{%1, %0|%0, %1}"
23134   [(set_attr "type" "ssecvt")
23135    (set_attr "mode" "TI")])
23136
23137 (define_insn "cvttpd2dq"
23138   [(set (match_operand:V4SI 0 "register_operand" "=x")
23139         (vec_concat:V4SI
23140          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23141                       UNSPEC_FIX)
23142          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23143   "TARGET_SSE2"
23144   "cvttpd2dq\t{%1, %0|%0, %1}"
23145   [(set_attr "type" "ssecvt")
23146    (set_attr "mode" "TI")])
23147
23148 (define_insn "cvtpd2pi"
23149   [(set (match_operand:V2SI 0 "register_operand" "=y")
23150         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23151   "TARGET_SSE2"
23152   "cvtpd2pi\t{%1, %0|%0, %1}"
23153   [(set_attr "type" "ssecvt")
23154    (set_attr "mode" "TI")])
23155
23156 (define_insn "cvttpd2pi"
23157   [(set (match_operand:V2SI 0 "register_operand" "=y")
23158         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23159                      UNSPEC_FIX))]
23160   "TARGET_SSE2"
23161   "cvttpd2pi\t{%1, %0|%0, %1}"
23162   [(set_attr "type" "ssecvt")
23163    (set_attr "mode" "TI")])
23164
23165 (define_insn "cvtpi2pd"
23166   [(set (match_operand:V2DF 0 "register_operand" "=x")
23167         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23168   "TARGET_SSE2"
23169   "cvtpi2pd\t{%1, %0|%0, %1}"
23170   [(set_attr "type" "ssecvt")
23171    (set_attr "mode" "TI")])
23172
23173 ;; Conversions between SI and DF
23174
23175 (define_insn "cvtsd2si"
23176   [(set (match_operand:SI 0 "register_operand" "=r,r")
23177         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23178                                (parallel [(const_int 0)]))))]
23179   "TARGET_SSE2"
23180   "cvtsd2si\t{%1, %0|%0, %1}"
23181   [(set_attr "type" "sseicvt")
23182    (set_attr "athlon_decode" "double,vector")
23183    (set_attr "mode" "SI")])
23184
23185 (define_insn "cvtsd2siq"
23186   [(set (match_operand:DI 0 "register_operand" "=r,r")
23187         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23188                                (parallel [(const_int 0)]))))]
23189   "TARGET_SSE2 && TARGET_64BIT"
23190   "cvtsd2siq\t{%1, %0|%0, %1}"
23191   [(set_attr "type" "sseicvt")
23192    (set_attr "athlon_decode" "double,vector")
23193    (set_attr "mode" "DI")])
23194
23195 (define_insn "cvttsd2si"
23196   [(set (match_operand:SI 0 "register_operand" "=r,r")
23197         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23198                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23199   "TARGET_SSE2"
23200   "cvttsd2si\t{%1, %0|%0, %1}"
23201   [(set_attr "type" "sseicvt")
23202    (set_attr "mode" "SI")
23203    (set_attr "athlon_decode" "double,vector")])
23204
23205 (define_insn "cvttsd2siq"
23206   [(set (match_operand:DI 0 "register_operand" "=r,r")
23207         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23208                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23209   "TARGET_SSE2 && TARGET_64BIT"
23210   "cvttsd2siq\t{%1, %0|%0, %1}"
23211   [(set_attr "type" "sseicvt")
23212    (set_attr "mode" "DI")
23213    (set_attr "athlon_decode" "double,vector")])
23214
23215 (define_insn "cvtsi2sd"
23216   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23217         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23218                         (vec_duplicate:V2DF
23219                           (float:DF
23220                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23221                         (const_int 2)))]
23222   "TARGET_SSE2"
23223   "cvtsi2sd\t{%2, %0|%0, %2}"
23224   [(set_attr "type" "sseicvt")
23225    (set_attr "mode" "DF")
23226    (set_attr "athlon_decode" "double,direct")])
23227
23228 (define_insn "cvtsi2sdq"
23229   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23230         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23231                         (vec_duplicate:V2DF
23232                           (float:DF
23233                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23234                         (const_int 2)))]
23235   "TARGET_SSE2 && TARGET_64BIT"
23236   "cvtsi2sdq\t{%2, %0|%0, %2}"
23237   [(set_attr "type" "sseicvt")
23238    (set_attr "mode" "DF")
23239    (set_attr "athlon_decode" "double,direct")])
23240
23241 ;; Conversions between SF and DF
23242
23243 (define_insn "cvtsd2ss"
23244   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23245         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23246                         (vec_duplicate:V4SF
23247                           (float_truncate:V2SF
23248                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23249                         (const_int 14)))]
23250   "TARGET_SSE2"
23251   "cvtsd2ss\t{%2, %0|%0, %2}"
23252   [(set_attr "type" "ssecvt")
23253    (set_attr "athlon_decode" "vector,double")
23254    (set_attr "mode" "SF")])
23255
23256 (define_insn "cvtss2sd"
23257   [(set (match_operand:V2DF 0 "register_operand" "=x")
23258         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23259                         (float_extend:V2DF
23260                           (vec_select:V2SF
23261                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23262                             (parallel [(const_int 0)
23263                                        (const_int 1)])))
23264                         (const_int 2)))]
23265   "TARGET_SSE2"
23266   "cvtss2sd\t{%2, %0|%0, %2}"
23267   [(set_attr "type" "ssecvt")
23268    (set_attr "mode" "DF")])
23269
23270 (define_insn "cvtpd2ps"
23271   [(set (match_operand:V4SF 0 "register_operand" "=x")
23272         (subreg:V4SF
23273           (vec_concat:V4SI
23274             (subreg:V2SI (float_truncate:V2SF
23275                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23276             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23277   "TARGET_SSE2"
23278   "cvtpd2ps\t{%1, %0|%0, %1}"
23279   [(set_attr "type" "ssecvt")
23280    (set_attr "mode" "V4SF")])
23281
23282 (define_insn "cvtps2pd"
23283   [(set (match_operand:V2DF 0 "register_operand" "=x")
23284         (float_extend:V2DF
23285           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23286                            (parallel [(const_int 0)
23287                                       (const_int 1)]))))]
23288   "TARGET_SSE2"
23289   "cvtps2pd\t{%1, %0|%0, %1}"
23290   [(set_attr "type" "ssecvt")
23291    (set_attr "mode" "V2DF")])
23292
23293 ;; SSE2 variants of MMX insns
23294
23295 ;; MMX arithmetic
23296
23297 (define_insn "addv16qi3"
23298   [(set (match_operand:V16QI 0 "register_operand" "=x")
23299         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23300                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23301   "TARGET_SSE2"
23302   "paddb\t{%2, %0|%0, %2}"
23303   [(set_attr "type" "sseiadd")
23304    (set_attr "mode" "TI")])
23305
23306 (define_insn "addv8hi3"
23307   [(set (match_operand:V8HI 0 "register_operand" "=x")
23308         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23309                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23310   "TARGET_SSE2"
23311   "paddw\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "sseiadd")
23313    (set_attr "mode" "TI")])
23314
23315 (define_insn "addv4si3"
23316   [(set (match_operand:V4SI 0 "register_operand" "=x")
23317         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23318                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23319   "TARGET_SSE2"
23320   "paddd\t{%2, %0|%0, %2}"
23321   [(set_attr "type" "sseiadd")
23322    (set_attr "mode" "TI")])
23323
23324 (define_insn "addv2di3"
23325   [(set (match_operand:V2DI 0 "register_operand" "=x")
23326         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23327                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23328   "TARGET_SSE2"
23329   "paddq\t{%2, %0|%0, %2}"
23330   [(set_attr "type" "sseiadd")
23331    (set_attr "mode" "TI")])
23332
23333 (define_insn "ssaddv16qi3"
23334   [(set (match_operand:V16QI 0 "register_operand" "=x")
23335         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23336                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23337   "TARGET_SSE2"
23338   "paddsb\t{%2, %0|%0, %2}"
23339   [(set_attr "type" "sseiadd")
23340    (set_attr "mode" "TI")])
23341
23342 (define_insn "ssaddv8hi3"
23343   [(set (match_operand:V8HI 0 "register_operand" "=x")
23344         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23345                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23346   "TARGET_SSE2"
23347   "paddsw\t{%2, %0|%0, %2}"
23348   [(set_attr "type" "sseiadd")
23349    (set_attr "mode" "TI")])
23350
23351 (define_insn "usaddv16qi3"
23352   [(set (match_operand:V16QI 0 "register_operand" "=x")
23353         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23354                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23355   "TARGET_SSE2"
23356   "paddusb\t{%2, %0|%0, %2}"
23357   [(set_attr "type" "sseiadd")
23358    (set_attr "mode" "TI")])
23359
23360 (define_insn "usaddv8hi3"
23361   [(set (match_operand:V8HI 0 "register_operand" "=x")
23362         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23363                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23364   "TARGET_SSE2"
23365   "paddusw\t{%2, %0|%0, %2}"
23366   [(set_attr "type" "sseiadd")
23367    (set_attr "mode" "TI")])
23368
23369 (define_insn "subv16qi3"
23370   [(set (match_operand:V16QI 0 "register_operand" "=x")
23371         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23372                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23373   "TARGET_SSE2"
23374   "psubb\t{%2, %0|%0, %2}"
23375   [(set_attr "type" "sseiadd")
23376    (set_attr "mode" "TI")])
23377
23378 (define_insn "subv8hi3"
23379   [(set (match_operand:V8HI 0 "register_operand" "=x")
23380         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23381                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23382   "TARGET_SSE2"
23383   "psubw\t{%2, %0|%0, %2}"
23384   [(set_attr "type" "sseiadd")
23385    (set_attr "mode" "TI")])
23386
23387 (define_insn "subv4si3"
23388   [(set (match_operand:V4SI 0 "register_operand" "=x")
23389         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23390                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23391   "TARGET_SSE2"
23392   "psubd\t{%2, %0|%0, %2}"
23393   [(set_attr "type" "sseiadd")
23394    (set_attr "mode" "TI")])
23395
23396 (define_insn "subv2di3"
23397   [(set (match_operand:V2DI 0 "register_operand" "=x")
23398         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23399                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23400   "TARGET_SSE2"
23401   "psubq\t{%2, %0|%0, %2}"
23402   [(set_attr "type" "sseiadd")
23403    (set_attr "mode" "TI")])
23404
23405 (define_insn "sssubv16qi3"
23406   [(set (match_operand:V16QI 0 "register_operand" "=x")
23407         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23408                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23409   "TARGET_SSE2"
23410   "psubsb\t{%2, %0|%0, %2}"
23411   [(set_attr "type" "sseiadd")
23412    (set_attr "mode" "TI")])
23413
23414 (define_insn "sssubv8hi3"
23415   [(set (match_operand:V8HI 0 "register_operand" "=x")
23416         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23417                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23418   "TARGET_SSE2"
23419   "psubsw\t{%2, %0|%0, %2}"
23420   [(set_attr "type" "sseiadd")
23421    (set_attr "mode" "TI")])
23422
23423 (define_insn "ussubv16qi3"
23424   [(set (match_operand:V16QI 0 "register_operand" "=x")
23425         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23426                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23427   "TARGET_SSE2"
23428   "psubusb\t{%2, %0|%0, %2}"
23429   [(set_attr "type" "sseiadd")
23430    (set_attr "mode" "TI")])
23431
23432 (define_insn "ussubv8hi3"
23433   [(set (match_operand:V8HI 0 "register_operand" "=x")
23434         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23435                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23436   "TARGET_SSE2"
23437   "psubusw\t{%2, %0|%0, %2}"
23438   [(set_attr "type" "sseiadd")
23439    (set_attr "mode" "TI")])
23440
23441 (define_insn "mulv8hi3"
23442   [(set (match_operand:V8HI 0 "register_operand" "=x")
23443         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23444                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23445   "TARGET_SSE2"
23446   "pmullw\t{%2, %0|%0, %2}"
23447   [(set_attr "type" "sseimul")
23448    (set_attr "mode" "TI")])
23449
23450 (define_insn "smulv8hi3_highpart"
23451   [(set (match_operand:V8HI 0 "register_operand" "=x")
23452         (truncate:V8HI
23453          (lshiftrt:V8SI
23454           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23455                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23456           (const_int 16))))]
23457   "TARGET_SSE2"
23458   "pmulhw\t{%2, %0|%0, %2}"
23459   [(set_attr "type" "sseimul")
23460    (set_attr "mode" "TI")])
23461
23462 (define_insn "umulv8hi3_highpart"
23463   [(set (match_operand:V8HI 0 "register_operand" "=x")
23464         (truncate:V8HI
23465          (lshiftrt:V8SI
23466           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23467                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23468           (const_int 16))))]
23469   "TARGET_SSE2"
23470   "pmulhuw\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseimul")
23472    (set_attr "mode" "TI")])
23473
23474 (define_insn "sse2_umulsidi3"
23475   [(set (match_operand:DI 0 "register_operand" "=y")
23476         (mult:DI (zero_extend:DI (vec_select:SI
23477                                   (match_operand:V2SI 1 "register_operand" "0")
23478                                   (parallel [(const_int 0)])))
23479                  (zero_extend:DI (vec_select:SI
23480                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23481                                   (parallel [(const_int 0)])))))]
23482   "TARGET_SSE2"
23483   "pmuludq\t{%2, %0|%0, %2}"
23484   [(set_attr "type" "mmxmul")
23485    (set_attr "mode" "DI")])
23486
23487 (define_insn "sse2_umulv2siv2di3"
23488   [(set (match_operand:V2DI 0 "register_operand" "=x")
23489         (mult:V2DI (zero_extend:V2DI
23490                      (vec_select:V2SI
23491                        (match_operand:V4SI 1 "register_operand" "0")
23492                        (parallel [(const_int 0) (const_int 2)])))
23493                    (zero_extend:V2DI
23494                      (vec_select:V2SI
23495                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23496                        (parallel [(const_int 0) (const_int 2)])))))]
23497   "TARGET_SSE2"
23498   "pmuludq\t{%2, %0|%0, %2}"
23499   [(set_attr "type" "sseimul")
23500    (set_attr "mode" "TI")])
23501
23502 (define_insn "sse2_pmaddwd"
23503   [(set (match_operand:V4SI 0 "register_operand" "=x")
23504         (plus:V4SI
23505          (mult:V4SI
23506           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23507                                              (parallel [(const_int 0)
23508                                                         (const_int 2)
23509                                                         (const_int 4)
23510                                                         (const_int 6)])))
23511           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23512                                              (parallel [(const_int 0)
23513                                                         (const_int 2)
23514                                                         (const_int 4)
23515                                                         (const_int 6)]))))
23516          (mult:V4SI
23517           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23518                                              (parallel [(const_int 1)
23519                                                         (const_int 3)
23520                                                         (const_int 5)
23521                                                         (const_int 7)])))
23522           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23523                                              (parallel [(const_int 1)
23524                                                         (const_int 3)
23525                                                         (const_int 5)
23526                                                         (const_int 7)]))))))]
23527   "TARGET_SSE2"
23528   "pmaddwd\t{%2, %0|%0, %2}"
23529   [(set_attr "type" "sseiadd")
23530    (set_attr "mode" "TI")])
23531
23532 ;; Same as pxor, but don't show input operands so that we don't think
23533 ;; they are live.
23534 (define_insn "sse2_clrti"
23535   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23536   "TARGET_SSE2"
23537 {
23538   if (get_attr_mode (insn) == MODE_TI)
23539     return "pxor\t%0, %0";
23540   else
23541     return "xorps\t%0, %0";
23542 }
23543   [(set_attr "type" "ssemov")
23544    (set_attr "memory" "none")
23545    (set (attr "mode")
23546               (if_then_else
23547                 (ne (symbol_ref "optimize_size")
23548                     (const_int 0))
23549                 (const_string "V4SF")
23550                 (const_string "TI")))])
23551
23552 ;; MMX unsigned averages/sum of absolute differences
23553
23554 (define_insn "sse2_uavgv16qi3"
23555   [(set (match_operand:V16QI 0 "register_operand" "=x")
23556         (ashiftrt:V16QI
23557          (plus:V16QI (plus:V16QI
23558                      (match_operand:V16QI 1 "register_operand" "0")
23559                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23560                      (const_vector:V16QI [(const_int 1) (const_int 1)
23561                                           (const_int 1) (const_int 1)
23562                                           (const_int 1) (const_int 1)
23563                                           (const_int 1) (const_int 1)
23564                                           (const_int 1) (const_int 1)
23565                                           (const_int 1) (const_int 1)
23566                                           (const_int 1) (const_int 1)
23567                                           (const_int 1) (const_int 1)]))
23568          (const_int 1)))]
23569   "TARGET_SSE2"
23570   "pavgb\t{%2, %0|%0, %2}"
23571   [(set_attr "type" "sseiadd")
23572    (set_attr "mode" "TI")])
23573
23574 (define_insn "sse2_uavgv8hi3"
23575   [(set (match_operand:V8HI 0 "register_operand" "=x")
23576         (ashiftrt:V8HI
23577          (plus:V8HI (plus:V8HI
23578                      (match_operand:V8HI 1 "register_operand" "0")
23579                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23580                     (const_vector:V8HI [(const_int 1) (const_int 1)
23581                                         (const_int 1) (const_int 1)
23582                                         (const_int 1) (const_int 1)
23583                                         (const_int 1) (const_int 1)]))
23584          (const_int 1)))]
23585   "TARGET_SSE2"
23586   "pavgw\t{%2, %0|%0, %2}"
23587   [(set_attr "type" "sseiadd")
23588    (set_attr "mode" "TI")])
23589
23590 ;; @@@ this isn't the right representation.
23591 (define_insn "sse2_psadbw"
23592   [(set (match_operand:V2DI 0 "register_operand" "=x")
23593         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23594                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23595                      UNSPEC_PSADBW))]
23596   "TARGET_SSE2"
23597   "psadbw\t{%2, %0|%0, %2}"
23598   [(set_attr "type" "sseiadd")
23599    (set_attr "mode" "TI")])
23600
23601
23602 ;; MMX insert/extract/shuffle
23603
23604 (define_insn "sse2_pinsrw"
23605   [(set (match_operand:V8HI 0 "register_operand" "=x")
23606         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23607                         (vec_duplicate:V8HI
23608                          (truncate:HI
23609                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23610                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23611   "TARGET_SSE2"
23612   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23613   [(set_attr "type" "ssecvt")
23614    (set_attr "mode" "TI")])
23615
23616 (define_insn "sse2_pextrw"
23617   [(set (match_operand:SI 0 "register_operand" "=r")
23618         (zero_extend:SI
23619           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23620                          (parallel
23621                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23622   "TARGET_SSE2"
23623   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23624   [(set_attr "type" "ssecvt")
23625    (set_attr "mode" "TI")])
23626
23627 (define_insn "sse2_pshufd"
23628   [(set (match_operand:V4SI 0 "register_operand" "=x")
23629         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23630                       (match_operand:SI 2 "immediate_operand" "i")]
23631                      UNSPEC_SHUFFLE))]
23632   "TARGET_SSE2"
23633   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23634   [(set_attr "type" "ssecvt")
23635    (set_attr "mode" "TI")])
23636
23637 (define_insn "sse2_pshuflw"
23638   [(set (match_operand:V8HI 0 "register_operand" "=x")
23639         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23640                       (match_operand:SI 2 "immediate_operand" "i")]
23641                      UNSPEC_PSHUFLW))]
23642   "TARGET_SSE2"
23643   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23644   [(set_attr "type" "ssecvt")
23645    (set_attr "mode" "TI")])
23646
23647 (define_insn "sse2_pshufhw"
23648   [(set (match_operand:V8HI 0 "register_operand" "=x")
23649         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23650                       (match_operand:SI 2 "immediate_operand" "i")]
23651                      UNSPEC_PSHUFHW))]
23652   "TARGET_SSE2"
23653   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23654   [(set_attr "type" "ssecvt")
23655    (set_attr "mode" "TI")])
23656
23657 ;; MMX mask-generating comparisons
23658
23659 (define_insn "eqv16qi3"
23660   [(set (match_operand:V16QI 0 "register_operand" "=x")
23661         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23662                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23663   "TARGET_SSE2"
23664   "pcmpeqb\t{%2, %0|%0, %2}"
23665   [(set_attr "type" "ssecmp")
23666    (set_attr "mode" "TI")])
23667
23668 (define_insn "eqv8hi3"
23669   [(set (match_operand:V8HI 0 "register_operand" "=x")
23670         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23671                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23672   "TARGET_SSE2"
23673   "pcmpeqw\t{%2, %0|%0, %2}"
23674   [(set_attr "type" "ssecmp")
23675    (set_attr "mode" "TI")])
23676
23677 (define_insn "eqv4si3"
23678   [(set (match_operand:V4SI 0 "register_operand" "=x")
23679         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23680                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23681   "TARGET_SSE2"
23682   "pcmpeqd\t{%2, %0|%0, %2}"
23683   [(set_attr "type" "ssecmp")
23684    (set_attr "mode" "TI")])
23685
23686 (define_insn "gtv16qi3"
23687   [(set (match_operand:V16QI 0 "register_operand" "=x")
23688         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23689                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23690   "TARGET_SSE2"
23691   "pcmpgtb\t{%2, %0|%0, %2}"
23692   [(set_attr "type" "ssecmp")
23693    (set_attr "mode" "TI")])
23694
23695 (define_insn "gtv8hi3"
23696   [(set (match_operand:V8HI 0 "register_operand" "=x")
23697         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23698                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23699   "TARGET_SSE2"
23700   "pcmpgtw\t{%2, %0|%0, %2}"
23701   [(set_attr "type" "ssecmp")
23702    (set_attr "mode" "TI")])
23703
23704 (define_insn "gtv4si3"
23705   [(set (match_operand:V4SI 0 "register_operand" "=x")
23706         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23707                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23708   "TARGET_SSE2"
23709   "pcmpgtd\t{%2, %0|%0, %2}"
23710   [(set_attr "type" "ssecmp")
23711    (set_attr "mode" "TI")])
23712
23713
23714 ;; MMX max/min insns
23715
23716 (define_insn "umaxv16qi3"
23717   [(set (match_operand:V16QI 0 "register_operand" "=x")
23718         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23719                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23720   "TARGET_SSE2"
23721   "pmaxub\t{%2, %0|%0, %2}"
23722   [(set_attr "type" "sseiadd")
23723    (set_attr "mode" "TI")])
23724
23725 (define_insn "smaxv8hi3"
23726   [(set (match_operand:V8HI 0 "register_operand" "=x")
23727         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23728                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23729   "TARGET_SSE2"
23730   "pmaxsw\t{%2, %0|%0, %2}"
23731   [(set_attr "type" "sseiadd")
23732    (set_attr "mode" "TI")])
23733
23734 (define_insn "uminv16qi3"
23735   [(set (match_operand:V16QI 0 "register_operand" "=x")
23736         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23737                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23738   "TARGET_SSE2"
23739   "pminub\t{%2, %0|%0, %2}"
23740   [(set_attr "type" "sseiadd")
23741    (set_attr "mode" "TI")])
23742
23743 (define_insn "sminv8hi3"
23744   [(set (match_operand:V8HI 0 "register_operand" "=x")
23745         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23746                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23747   "TARGET_SSE2"
23748   "pminsw\t{%2, %0|%0, %2}"
23749   [(set_attr "type" "sseiadd")
23750    (set_attr "mode" "TI")])
23751
23752
23753 ;; MMX shifts
23754
23755 (define_insn "ashrv8hi3"
23756   [(set (match_operand:V8HI 0 "register_operand" "=x")
23757         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23758                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23759   "TARGET_SSE2"
23760   "psraw\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "sseishft")
23762    (set_attr "mode" "TI")])
23763
23764 (define_insn "ashrv4si3"
23765   [(set (match_operand:V4SI 0 "register_operand" "=x")
23766         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23767                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23768   "TARGET_SSE2"
23769   "psrad\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "sseishft")
23771    (set_attr "mode" "TI")])
23772
23773 (define_insn "lshrv8hi3"
23774   [(set (match_operand:V8HI 0 "register_operand" "=x")
23775         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23776                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23777   "TARGET_SSE2"
23778   "psrlw\t{%2, %0|%0, %2}"
23779   [(set_attr "type" "sseishft")
23780    (set_attr "mode" "TI")])
23781
23782 (define_insn "lshrv4si3"
23783   [(set (match_operand:V4SI 0 "register_operand" "=x")
23784         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23785                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23786   "TARGET_SSE2"
23787   "psrld\t{%2, %0|%0, %2}"
23788   [(set_attr "type" "sseishft")
23789    (set_attr "mode" "TI")])
23790
23791 (define_insn "lshrv2di3"
23792   [(set (match_operand:V2DI 0 "register_operand" "=x")
23793         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23794                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23795   "TARGET_SSE2"
23796   "psrlq\t{%2, %0|%0, %2}"
23797   [(set_attr "type" "sseishft")
23798    (set_attr "mode" "TI")])
23799
23800 (define_insn "ashlv8hi3"
23801   [(set (match_operand:V8HI 0 "register_operand" "=x")
23802         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23803                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23804   "TARGET_SSE2"
23805   "psllw\t{%2, %0|%0, %2}"
23806   [(set_attr "type" "sseishft")
23807    (set_attr "mode" "TI")])
23808
23809 (define_insn "ashlv4si3"
23810   [(set (match_operand:V4SI 0 "register_operand" "=x")
23811         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23812                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23813   "TARGET_SSE2"
23814   "pslld\t{%2, %0|%0, %2}"
23815   [(set_attr "type" "sseishft")
23816    (set_attr "mode" "TI")])
23817
23818 (define_insn "ashlv2di3"
23819   [(set (match_operand:V2DI 0 "register_operand" "=x")
23820         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23821                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23822   "TARGET_SSE2"
23823   "psllq\t{%2, %0|%0, %2}"
23824   [(set_attr "type" "sseishft")
23825    (set_attr "mode" "TI")])
23826
23827 (define_insn "ashrv8hi3_ti"
23828   [(set (match_operand:V8HI 0 "register_operand" "=x")
23829         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23830                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23831   "TARGET_SSE2"
23832   "psraw\t{%2, %0|%0, %2}"
23833   [(set_attr "type" "sseishft")
23834    (set_attr "mode" "TI")])
23835
23836 (define_insn "ashrv4si3_ti"
23837   [(set (match_operand:V4SI 0 "register_operand" "=x")
23838         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23839                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23840   "TARGET_SSE2"
23841   "psrad\t{%2, %0|%0, %2}"
23842   [(set_attr "type" "sseishft")
23843    (set_attr "mode" "TI")])
23844
23845 (define_insn "lshrv8hi3_ti"
23846   [(set (match_operand:V8HI 0 "register_operand" "=x")
23847         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23848                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23849   "TARGET_SSE2"
23850   "psrlw\t{%2, %0|%0, %2}"
23851   [(set_attr "type" "sseishft")
23852    (set_attr "mode" "TI")])
23853
23854 (define_insn "lshrv4si3_ti"
23855   [(set (match_operand:V4SI 0 "register_operand" "=x")
23856         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23857                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23858   "TARGET_SSE2"
23859   "psrld\t{%2, %0|%0, %2}"
23860   [(set_attr "type" "sseishft")
23861    (set_attr "mode" "TI")])
23862
23863 (define_insn "lshrv2di3_ti"
23864   [(set (match_operand:V2DI 0 "register_operand" "=x")
23865         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23866                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23867   "TARGET_SSE2"
23868   "psrlq\t{%2, %0|%0, %2}"
23869   [(set_attr "type" "sseishft")
23870    (set_attr "mode" "TI")])
23871
23872 (define_insn "ashlv8hi3_ti"
23873   [(set (match_operand:V8HI 0 "register_operand" "=x")
23874         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23875                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23876   "TARGET_SSE2"
23877   "psllw\t{%2, %0|%0, %2}"
23878   [(set_attr "type" "sseishft")
23879    (set_attr "mode" "TI")])
23880
23881 (define_insn "ashlv4si3_ti"
23882   [(set (match_operand:V4SI 0 "register_operand" "=x")
23883         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23884                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23885   "TARGET_SSE2"
23886   "pslld\t{%2, %0|%0, %2}"
23887   [(set_attr "type" "sseishft")
23888    (set_attr "mode" "TI")])
23889
23890 (define_insn "ashlv2di3_ti"
23891   [(set (match_operand:V2DI 0 "register_operand" "=x")
23892         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23893                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23894   "TARGET_SSE2"
23895   "psllq\t{%2, %0|%0, %2}"
23896   [(set_attr "type" "sseishft")
23897    (set_attr "mode" "TI")])
23898
23899 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23900 ;; we wouldn't need here it since we never generate TImode arithmetic.
23901
23902 ;; There has to be some kind of prize for the weirdest new instruction...
23903 (define_insn "sse2_ashlti3"
23904   [(set (match_operand:TI 0 "register_operand" "=x")
23905         (unspec:TI
23906          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23907                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23908                                (const_int 8)))] UNSPEC_NOP))]
23909   "TARGET_SSE2"
23910   "pslldq\t{%2, %0|%0, %2}"
23911   [(set_attr "type" "sseishft")
23912    (set_attr "mode" "TI")])
23913
23914 (define_insn "sse2_lshrti3"
23915   [(set (match_operand:TI 0 "register_operand" "=x")
23916         (unspec:TI
23917          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23918                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23919                                 (const_int 8)))] UNSPEC_NOP))]
23920   "TARGET_SSE2"
23921   "psrldq\t{%2, %0|%0, %2}"
23922   [(set_attr "type" "sseishft")
23923    (set_attr "mode" "TI")])
23924
23925 ;; SSE unpack
23926
23927 (define_insn "sse2_unpckhpd"
23928   [(set (match_operand:V2DF 0 "register_operand" "=x")
23929         (vec_concat:V2DF
23930          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23931                         (parallel [(const_int 1)]))
23932          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23933                         (parallel [(const_int 1)]))))]
23934   "TARGET_SSE2"
23935   "unpckhpd\t{%2, %0|%0, %2}"
23936   [(set_attr "type" "ssecvt")
23937    (set_attr "mode" "V2DF")])
23938
23939 (define_insn "sse2_unpcklpd"
23940   [(set (match_operand:V2DF 0 "register_operand" "=x")
23941         (vec_concat:V2DF
23942          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23943                         (parallel [(const_int 0)]))
23944          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23945                         (parallel [(const_int 0)]))))]
23946   "TARGET_SSE2"
23947   "unpcklpd\t{%2, %0|%0, %2}"
23948   [(set_attr "type" "ssecvt")
23949    (set_attr "mode" "V2DF")])
23950
23951 ;; MMX pack/unpack insns.
23952
23953 (define_insn "sse2_packsswb"
23954   [(set (match_operand:V16QI 0 "register_operand" "=x")
23955         (vec_concat:V16QI
23956          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23957          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23958   "TARGET_SSE2"
23959   "packsswb\t{%2, %0|%0, %2}"
23960   [(set_attr "type" "ssecvt")
23961    (set_attr "mode" "TI")])
23962
23963 (define_insn "sse2_packssdw"
23964   [(set (match_operand:V8HI 0 "register_operand" "=x")
23965         (vec_concat:V8HI
23966          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23967          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23968   "TARGET_SSE2"
23969   "packssdw\t{%2, %0|%0, %2}"
23970   [(set_attr "type" "ssecvt")
23971    (set_attr "mode" "TI")])
23972
23973 (define_insn "sse2_packuswb"
23974   [(set (match_operand:V16QI 0 "register_operand" "=x")
23975         (vec_concat:V16QI
23976          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23977          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23978   "TARGET_SSE2"
23979   "packuswb\t{%2, %0|%0, %2}"
23980   [(set_attr "type" "ssecvt")
23981    (set_attr "mode" "TI")])
23982
23983 (define_insn "sse2_punpckhbw"
23984   [(set (match_operand:V16QI 0 "register_operand" "=x")
23985         (vec_merge:V16QI
23986          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23987                            (parallel [(const_int 8) (const_int 0)
23988                                       (const_int 9) (const_int 1)
23989                                       (const_int 10) (const_int 2)
23990                                       (const_int 11) (const_int 3)
23991                                       (const_int 12) (const_int 4)
23992                                       (const_int 13) (const_int 5)
23993                                       (const_int 14) (const_int 6)
23994                                       (const_int 15) (const_int 7)]))
23995          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23996                            (parallel [(const_int 0) (const_int 8)
23997                                       (const_int 1) (const_int 9)
23998                                       (const_int 2) (const_int 10)
23999                                       (const_int 3) (const_int 11)
24000                                       (const_int 4) (const_int 12)
24001                                       (const_int 5) (const_int 13)
24002                                       (const_int 6) (const_int 14)
24003                                       (const_int 7) (const_int 15)]))
24004          (const_int 21845)))]
24005   "TARGET_SSE2"
24006   "punpckhbw\t{%2, %0|%0, %2}"
24007   [(set_attr "type" "ssecvt")
24008    (set_attr "mode" "TI")])
24009
24010 (define_insn "sse2_punpckhwd"
24011   [(set (match_operand:V8HI 0 "register_operand" "=x")
24012         (vec_merge:V8HI
24013          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24014                           (parallel [(const_int 4) (const_int 0)
24015                                      (const_int 5) (const_int 1)
24016                                      (const_int 6) (const_int 2)
24017                                      (const_int 7) (const_int 3)]))
24018          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24019                           (parallel [(const_int 0) (const_int 4)
24020                                      (const_int 1) (const_int 5)
24021                                      (const_int 2) (const_int 6)
24022                                      (const_int 3) (const_int 7)]))
24023          (const_int 85)))]
24024   "TARGET_SSE2"
24025   "punpckhwd\t{%2, %0|%0, %2}"
24026   [(set_attr "type" "ssecvt")
24027    (set_attr "mode" "TI")])
24028
24029 (define_insn "sse2_punpckhdq"
24030   [(set (match_operand:V4SI 0 "register_operand" "=x")
24031         (vec_merge:V4SI
24032          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24033                           (parallel [(const_int 2) (const_int 0)
24034                                      (const_int 3) (const_int 1)]))
24035          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24036                           (parallel [(const_int 0) (const_int 2)
24037                                      (const_int 1) (const_int 3)]))
24038          (const_int 5)))]
24039   "TARGET_SSE2"
24040   "punpckhdq\t{%2, %0|%0, %2}"
24041   [(set_attr "type" "ssecvt")
24042    (set_attr "mode" "TI")])
24043
24044 (define_insn "sse2_punpcklbw"
24045   [(set (match_operand:V16QI 0 "register_operand" "=x")
24046         (vec_merge:V16QI
24047          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24048                            (parallel [(const_int 0) (const_int 8)
24049                                       (const_int 1) (const_int 9)
24050                                       (const_int 2) (const_int 10)
24051                                       (const_int 3) (const_int 11)
24052                                       (const_int 4) (const_int 12)
24053                                       (const_int 5) (const_int 13)
24054                                       (const_int 6) (const_int 14)
24055                                       (const_int 7) (const_int 15)]))
24056          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24057                            (parallel [(const_int 8) (const_int 0)
24058                                       (const_int 9) (const_int 1)
24059                                       (const_int 10) (const_int 2)
24060                                       (const_int 11) (const_int 3)
24061                                       (const_int 12) (const_int 4)
24062                                       (const_int 13) (const_int 5)
24063                                       (const_int 14) (const_int 6)
24064                                       (const_int 15) (const_int 7)]))
24065          (const_int 21845)))]
24066   "TARGET_SSE2"
24067   "punpcklbw\t{%2, %0|%0, %2}"
24068   [(set_attr "type" "ssecvt")
24069    (set_attr "mode" "TI")])
24070
24071 (define_insn "sse2_punpcklwd"
24072   [(set (match_operand:V8HI 0 "register_operand" "=x")
24073         (vec_merge:V8HI
24074          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24075                           (parallel [(const_int 0) (const_int 4)
24076                                      (const_int 1) (const_int 5)
24077                                      (const_int 2) (const_int 6)
24078                                      (const_int 3) (const_int 7)]))
24079          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24080                           (parallel [(const_int 4) (const_int 0)
24081                                      (const_int 5) (const_int 1)
24082                                      (const_int 6) (const_int 2)
24083                                      (const_int 7) (const_int 3)]))
24084          (const_int 85)))]
24085   "TARGET_SSE2"
24086   "punpcklwd\t{%2, %0|%0, %2}"
24087   [(set_attr "type" "ssecvt")
24088    (set_attr "mode" "TI")])
24089
24090 (define_insn "sse2_punpckldq"
24091   [(set (match_operand:V4SI 0 "register_operand" "=x")
24092         (vec_merge:V4SI
24093          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24094                           (parallel [(const_int 0) (const_int 2)
24095                                      (const_int 1) (const_int 3)]))
24096          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24097                           (parallel [(const_int 2) (const_int 0)
24098                                      (const_int 3) (const_int 1)]))
24099          (const_int 5)))]
24100   "TARGET_SSE2"
24101   "punpckldq\t{%2, %0|%0, %2}"
24102   [(set_attr "type" "ssecvt")
24103    (set_attr "mode" "TI")])
24104
24105 (define_insn "sse2_punpcklqdq"
24106   [(set (match_operand:V2DI 0 "register_operand" "=x")
24107         (vec_merge:V2DI
24108          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24109                           (parallel [(const_int 1)
24110                                      (const_int 0)]))
24111          (match_operand:V2DI 1 "register_operand" "0")
24112          (const_int 1)))]
24113   "TARGET_SSE2"
24114   "punpcklqdq\t{%2, %0|%0, %2}"
24115   [(set_attr "type" "ssecvt")
24116    (set_attr "mode" "TI")])
24117
24118 (define_insn "sse2_punpckhqdq"
24119   [(set (match_operand:V2DI 0 "register_operand" "=x")
24120         (vec_merge:V2DI
24121          (match_operand:V2DI 1 "register_operand" "0")
24122          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24123                           (parallel [(const_int 1)
24124                                      (const_int 0)]))
24125          (const_int 1)))]
24126   "TARGET_SSE2"
24127   "punpckhqdq\t{%2, %0|%0, %2}"
24128   [(set_attr "type" "ssecvt")
24129    (set_attr "mode" "TI")])
24130
24131 ;; SSE2 moves
24132
24133 (define_insn "sse2_movapd"
24134   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24135         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24136                      UNSPEC_MOVA))]
24137   "TARGET_SSE2
24138    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24139   "movapd\t{%1, %0|%0, %1}"
24140   [(set_attr "type" "ssemov")
24141    (set_attr "mode" "V2DF")])
24142
24143 (define_insn "sse2_movupd"
24144   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24145         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24146                      UNSPEC_MOVU))]
24147   "TARGET_SSE2
24148    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24149   "movupd\t{%1, %0|%0, %1}"
24150   [(set_attr "type" "ssecvt")
24151    (set_attr "mode" "V2DF")])
24152
24153 (define_insn "sse2_movdqa"
24154   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24155         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24156                        UNSPEC_MOVA))]
24157   "TARGET_SSE2
24158    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24159   "movdqa\t{%1, %0|%0, %1}"
24160   [(set_attr "type" "ssemov")
24161    (set_attr "mode" "TI")])
24162
24163 (define_insn "sse2_movdqu"
24164   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24165         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24166                        UNSPEC_MOVU))]
24167   "TARGET_SSE2
24168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24169   "movdqu\t{%1, %0|%0, %1}"
24170   [(set_attr "type" "ssecvt")
24171    (set_attr "mode" "TI")])
24172
24173 (define_insn "sse2_movdq2q"
24174   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24175         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24176                        (parallel [(const_int 0)])))]
24177   "TARGET_SSE2 && !TARGET_64BIT"
24178   "@
24179    movq\t{%1, %0|%0, %1}
24180    movdq2q\t{%1, %0|%0, %1}"
24181   [(set_attr "type" "ssecvt")
24182    (set_attr "mode" "TI")])
24183
24184 (define_insn "sse2_movdq2q_rex64"
24185   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24186         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24187                        (parallel [(const_int 0)])))]
24188   "TARGET_SSE2 && TARGET_64BIT"
24189   "@
24190    movq\t{%1, %0|%0, %1}
24191    movdq2q\t{%1, %0|%0, %1}
24192    movd\t{%1, %0|%0, %1}"
24193   [(set_attr "type" "ssecvt")
24194    (set_attr "mode" "TI")])
24195
24196 (define_insn "sse2_movq2dq"
24197   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24198         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24199                          (const_int 0)))]
24200   "TARGET_SSE2 && !TARGET_64BIT"
24201   "@
24202    movq\t{%1, %0|%0, %1}
24203    movq2dq\t{%1, %0|%0, %1}"
24204   [(set_attr "type" "ssecvt,ssemov")
24205    (set_attr "mode" "TI")])
24206
24207 (define_insn "sse2_movq2dq_rex64"
24208   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24209         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24210                          (const_int 0)))]
24211   "TARGET_SSE2 && TARGET_64BIT"
24212   "@
24213    movq\t{%1, %0|%0, %1}
24214    movq2dq\t{%1, %0|%0, %1}
24215    movd\t{%1, %0|%0, %1}"
24216   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24217    (set_attr "mode" "TI")])
24218
24219 (define_insn "sse2_movq"
24220   [(set (match_operand:V2DI 0 "register_operand" "=x")
24221         (vec_concat:V2DI (vec_select:DI
24222                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24223                           (parallel [(const_int 0)]))
24224                          (const_int 0)))]
24225   "TARGET_SSE2"
24226   "movq\t{%1, %0|%0, %1}"
24227   [(set_attr "type" "ssemov")
24228    (set_attr "mode" "TI")])
24229
24230 (define_insn "sse2_loadd"
24231   [(set (match_operand:V4SI 0 "register_operand" "=x")
24232         (vec_merge:V4SI
24233          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24234          (const_vector:V4SI [(const_int 0)
24235                              (const_int 0)
24236                              (const_int 0)
24237                              (const_int 0)])
24238          (const_int 1)))]
24239   "TARGET_SSE2"
24240   "movd\t{%1, %0|%0, %1}"
24241   [(set_attr "type" "ssemov")
24242    (set_attr "mode" "TI")])
24243
24244 (define_insn "sse2_stored"
24245   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24246         (vec_select:SI
24247          (match_operand:V4SI 1 "register_operand" "x")
24248          (parallel [(const_int 0)])))]
24249   "TARGET_SSE2"
24250   "movd\t{%1, %0|%0, %1}"
24251   [(set_attr "type" "ssemov")
24252    (set_attr "mode" "TI")])
24253
24254 (define_insn "sse2_movhpd"
24255   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24256         (vec_merge:V2DF
24257          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24258          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24259          (const_int 1)))]
24260   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24261   "movhpd\t{%2, %0|%0, %2}"
24262   [(set_attr "type" "ssecvt")
24263    (set_attr "mode" "V2DF")])
24264
24265 (define_expand "sse2_loadsd"
24266   [(match_operand:V2DF 0 "register_operand" "")
24267    (match_operand:DF 1 "memory_operand" "")]
24268   "TARGET_SSE2"
24269 {
24270   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24271                                 CONST0_RTX (V2DFmode)));
24272   DONE;
24273 })
24274
24275 (define_insn "sse2_loadsd_1"
24276   [(set (match_operand:V2DF 0 "register_operand" "=x")
24277         (vec_merge:V2DF
24278          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24279          (match_operand:V2DF 2 "const0_operand" "X")
24280          (const_int 1)))]
24281   "TARGET_SSE2"
24282   "movsd\t{%1, %0|%0, %1}"
24283   [(set_attr "type" "ssecvt")
24284    (set_attr "mode" "DF")])
24285
24286 (define_insn "sse2_movsd"
24287   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24288         (vec_merge:V2DF
24289          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24290          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24291          (const_int 2)))]
24292   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24293   "@movsd\t{%2, %0|%0, %2}
24294     movlpd\t{%2, %0|%0, %2}
24295     movlpd\t{%2, %0|%0, %2}"
24296   [(set_attr "type" "ssecvt")
24297    (set_attr "mode" "DF,V2DF,V2DF")])
24298
24299 (define_insn "sse2_storesd"
24300   [(set (match_operand:DF 0 "memory_operand" "=m")
24301         (vec_select:DF
24302          (match_operand:V2DF 1 "register_operand" "x")
24303          (parallel [(const_int 0)])))]
24304   "TARGET_SSE2"
24305   "movsd\t{%1, %0|%0, %1}"
24306   [(set_attr "type" "ssecvt")
24307    (set_attr "mode" "DF")])
24308
24309 (define_insn "sse2_shufpd"
24310   [(set (match_operand:V2DF 0 "register_operand" "=x")
24311         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24312                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24313                       (match_operand:SI 3 "immediate_operand" "i")]
24314                      UNSPEC_SHUFFLE))]
24315   "TARGET_SSE2"
24316   ;; @@@ check operand order for intel/nonintel syntax
24317   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24318   [(set_attr "type" "ssecvt")
24319    (set_attr "mode" "V2DF")])
24320
24321 (define_insn "sse2_clflush"
24322   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24323                     UNSPECV_CLFLUSH)]
24324   "TARGET_SSE2"
24325   "clflush\t%a0"
24326   [(set_attr "type" "sse")
24327    (set_attr "memory" "unknown")])
24328
24329 (define_expand "sse2_mfence"
24330   [(set (match_dup 0)
24331         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24332   "TARGET_SSE2"
24333 {
24334   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24335   MEM_VOLATILE_P (operands[0]) = 1;
24336 })
24337
24338 (define_insn "*mfence_insn"
24339   [(set (match_operand:BLK 0 "" "")
24340         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24341   "TARGET_SSE2"
24342   "mfence"
24343   [(set_attr "type" "sse")
24344    (set_attr "memory" "unknown")])
24345
24346 (define_expand "sse2_lfence"
24347   [(set (match_dup 0)
24348         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24349   "TARGET_SSE2"
24350 {
24351   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24352   MEM_VOLATILE_P (operands[0]) = 1;
24353 })
24354
24355 (define_insn "*lfence_insn"
24356   [(set (match_operand:BLK 0 "" "")
24357         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24358   "TARGET_SSE2"
24359   "lfence"
24360   [(set_attr "type" "sse")
24361    (set_attr "memory" "unknown")])
24362
24363 ;; SSE3
24364
24365 (define_insn "mwait"
24366   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24367                      (match_operand:SI 1 "register_operand" "c")]
24368                     UNSPECV_MWAIT)]
24369   "TARGET_SSE3"
24370   "mwait\t%0, %1"
24371   [(set_attr "length" "3")])
24372
24373 (define_insn "monitor"
24374   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24375                      (match_operand:SI 1 "register_operand" "c")
24376                      (match_operand:SI 2 "register_operand" "d")]
24377                     UNSPECV_MONITOR)]
24378   "TARGET_SSE3"
24379   "monitor\t%0, %1, %2"
24380   [(set_attr "length" "3")])
24381
24382 ;; SSE3 arithmetic
24383
24384 (define_insn "addsubv4sf3"
24385   [(set (match_operand:V4SF 0 "register_operand" "=x")
24386         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24387                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24388                      UNSPEC_ADDSUB))]
24389   "TARGET_SSE3"
24390   "addsubps\t{%2, %0|%0, %2}"
24391   [(set_attr "type" "sseadd")
24392    (set_attr "mode" "V4SF")])
24393
24394 (define_insn "addsubv2df3"
24395   [(set (match_operand:V2DF 0 "register_operand" "=x")
24396         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24397                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24398                      UNSPEC_ADDSUB))]
24399   "TARGET_SSE3"
24400   "addsubpd\t{%2, %0|%0, %2}"
24401   [(set_attr "type" "sseadd")
24402    (set_attr "mode" "V2DF")])
24403
24404 (define_insn "haddv4sf3"
24405   [(set (match_operand:V4SF 0 "register_operand" "=x")
24406         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24407                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24408                      UNSPEC_HADD))]
24409   "TARGET_SSE3"
24410   "haddps\t{%2, %0|%0, %2}"
24411   [(set_attr "type" "sseadd")
24412    (set_attr "mode" "V4SF")])
24413
24414 (define_insn "haddv2df3"
24415   [(set (match_operand:V2DF 0 "register_operand" "=x")
24416         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24417                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24418                      UNSPEC_HADD))]
24419   "TARGET_SSE3"
24420   "haddpd\t{%2, %0|%0, %2}"
24421   [(set_attr "type" "sseadd")
24422    (set_attr "mode" "V2DF")])
24423
24424 (define_insn "hsubv4sf3"
24425   [(set (match_operand:V4SF 0 "register_operand" "=x")
24426         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24427                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24428                      UNSPEC_HSUB))]
24429   "TARGET_SSE3"
24430   "hsubps\t{%2, %0|%0, %2}"
24431   [(set_attr "type" "sseadd")
24432    (set_attr "mode" "V4SF")])
24433
24434 (define_insn "hsubv2df3"
24435   [(set (match_operand:V2DF 0 "register_operand" "=x")
24436         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24437                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24438                      UNSPEC_HSUB))]
24439   "TARGET_SSE3"
24440   "hsubpd\t{%2, %0|%0, %2}"
24441   [(set_attr "type" "sseadd")
24442    (set_attr "mode" "V2DF")])
24443
24444 (define_insn "movshdup"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF
24447          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24448   "TARGET_SSE3"
24449   "movshdup\t{%1, %0|%0, %1}"
24450   [(set_attr "type" "sse")
24451    (set_attr "mode" "V4SF")])
24452
24453 (define_insn "movsldup"
24454   [(set (match_operand:V4SF 0 "register_operand" "=x")
24455         (unspec:V4SF
24456          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24457   "TARGET_SSE3"
24458   "movsldup\t{%1, %0|%0, %1}"
24459   [(set_attr "type" "sse")
24460    (set_attr "mode" "V4SF")])
24461
24462 (define_insn "lddqu"
24463   [(set (match_operand:V16QI 0 "register_operand" "=x")
24464         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24465                        UNSPEC_LDQQU))]
24466   "TARGET_SSE3"
24467   "lddqu\t{%1, %0|%0, %1}"
24468   [(set_attr "type" "ssecvt")
24469    (set_attr "mode" "TI")])
24470
24471 (define_insn "loadddup"
24472   [(set (match_operand:V2DF 0 "register_operand" "=x")
24473         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24474   "TARGET_SSE3"
24475   "movddup\t{%1, %0|%0, %1}"
24476   [(set_attr "type" "ssecvt")
24477    (set_attr "mode" "DF")])
24478
24479 (define_insn "movddup"
24480   [(set (match_operand:V2DF 0 "register_operand" "=x")
24481         (vec_duplicate:V2DF
24482          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24483                         (parallel [(const_int 0)]))))]
24484   "TARGET_SSE3"
24485   "movddup\t{%1, %0|%0, %1}"
24486   [(set_attr "type" "ssecvt")
24487    (set_attr "mode" "DF")])